001: //$HeadURL: svn+ssh://mschneider@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/io/datastore/sql/transaction/delete/FeatureGraph.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstraße 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.io.datastore.sql;
044:
045: import java.sql.Connection;
046: import java.util.HashSet;
047: import java.util.List;
048: import java.util.Set;
049: import java.util.TreeSet;
050:
051: import org.deegree.datatypes.QualifiedName;
052: import org.deegree.framework.log.ILogger;
053: import org.deegree.framework.log.LoggerFactory;
054: import org.deegree.io.datastore.DatastoreException;
055: import org.deegree.io.datastore.FeatureId;
056: import org.deegree.io.datastore.schema.MappedFeatureType;
057: import org.deegree.io.datastore.sql.transaction.delete.FeatureGraph;
058: import org.deegree.ogcwebservices.wfs.operation.Lock;
059: import org.deegree.ogcwebservices.wfs.operation.LockFeature;
060:
061: /**
062: * Responsible for the handling of {@link LockFeature} requests.
063: *
064: * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
065: * @author last edited by: $Author:$
066: *
067: * @version $Revision:$, $Date:$
068: */
069: public class LockHandler extends AbstractRequestHandler {
070:
071: protected static final ILogger LOG = LoggerFactory
072: .getLogger(LockHandler.class);
073:
074: private List<Lock> requestParts;
075:
076: /**
077: * Creates a new <code>LockHandler</code> from the given parameters.
078: *
079: * @param ds
080: * @param aliasGenerator
081: * @param conn
082: * @param requestParts
083: */
084: LockHandler(AbstractSQLDatastore ds,
085: TableAliasGenerator aliasGenerator, Connection conn,
086: List<Lock> requestParts) {
087: super (ds, aliasGenerator, conn);
088: this .requestParts = requestParts;
089: }
090:
091: /**
092: * Determines all {@link FeatureId}s that have to be locked.
093: *
094: * @return all <code>FeatureId</code>s that have to be locked
095: * @throws DatastoreException
096: */
097: Set<FeatureId> determineFidsToLock() throws DatastoreException {
098:
099: Set<FeatureId> rootFids = determineRootFids();
100: if (LOG.getLevel() == ILogger.LOG_DEBUG) {
101: LOG.logDebug("Root features to be locked: ");
102: for (FeatureId id : rootFids) {
103: LOG.logDebug(id.getAsString());
104: }
105: }
106:
107: // build the feature graph to determine all descendant features
108: FeatureGraph featureGraph = new FeatureGraph(rootFids, this );
109: Set<FeatureId> lockedFids = new TreeSet<FeatureId>();
110: lockedFids.addAll(featureGraph.getAllFids());
111:
112: // also add ids of super features (and super-super features, etc.)
113: addSuperFids(lockedFids);
114:
115: return lockedFids;
116: }
117:
118: private void addSuperFids(Set<FeatureId> fids)
119: throws DatastoreException {
120: FeatureId[] origFids = fids.toArray(new FeatureId[fids.size()]);
121: for (FeatureId fid : origFids) {
122: Set<FeatureId> super Fids = determineSuperFeatures(fid);
123: for (FeatureId super Fid : super Fids) {
124: addSuperFids(super Fid, fids);
125: }
126: }
127: }
128:
129: private void addSuperFids(FeatureId fid, Set<FeatureId> fids)
130: throws DatastoreException {
131: if (!fids.contains(fid)) {
132: fids.add(fid);
133: Set<FeatureId> super Fids = determineSuperFeatures(fid);
134: for (FeatureId super Fid : super Fids) {
135: addSuperFids(super Fid, fids);
136: }
137: }
138: }
139:
140: /**
141: * Determines all "root" features that have to be locked by the associated {@link LockFeature}
142: * request (and that are served by the associated {@link AbstractSQLDatastore}.
143: * <p>
144: * NOTE: The returned set only contains the feature ids that are <b>directly</b> targeted by
145: * the request, but not necessarily all the subfeatures or superfeatures that have to be locked
146: * as well.
147: *
148: * @return <b>directly</b> affected feature ids
149: * @throws DatastoreException
150: */
151: private Set<FeatureId> determineRootFids()
152: throws DatastoreException {
153: Set<FeatureId> fids = new HashSet<FeatureId>();
154: for (Lock lock : this .requestParts) {
155: QualifiedName ftName = lock.getTypeName();
156: MappedFeatureType ft = this.datastore
157: .getFeatureType(ftName);
158: if (ft != null) {
159: fids
160: .addAll(determineAffectedFIDs(ft, lock
161: .getFilter()));
162: }
163: }
164: return fids;
165: }
166: }
|