001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wfs/operation/GetFeatureWithLock.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, 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: Aennchenstr. 19
030: 53115 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: ---------------------------------------------------------------------------*/
044: package org.deegree.ogcwebservices.wfs.operation;
045:
046: import java.util.Map;
047:
048: import org.deegree.datatypes.QualifiedName;
049: import org.deegree.framework.log.ILogger;
050: import org.deegree.framework.log.LoggerFactory;
051: import org.deegree.framework.util.KVP2Map;
052: import org.deegree.i18n.Messages;
053: import org.deegree.model.filterencoding.Filter;
054: import org.deegree.ogcbase.PropertyPath;
055: import org.deegree.ogcbase.SortProperty;
056: import org.deegree.ogcwebservices.InconsistentRequestException;
057: import org.deegree.ogcwebservices.InvalidParameterValueException;
058: import org.deegree.ogcwebservices.OGCWebServiceException;
059: import org.deegree.ogcwebservices.wfs.operation.LockFeature.ALL_SOME_TYPE;
060: import org.w3c.dom.Element;
061:
062: /**
063: * Represents a <code>GetFeatureWithLock</code> request to a web feature service.
064: * <p>
065: * This is identical to a {@link GetFeature} request, except that the features matching the request
066: * will also be locked.
067: *
068: * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
069: * @author last edited by: $Author: apoth $
070: *
071: * @version $Revision: 9345 $
072: */
073: public class GetFeatureWithLock extends GetFeature {
074:
075: private static final ILogger LOG = LoggerFactory
076: .getLogger(GetFeatureWithLock.class);
077:
078: private static final long serialVersionUID = 8885456550385437651L;
079:
080: /** Duration until timeout (in milliseconds). */
081: private long expiry;
082:
083: private ALL_SOME_TYPE lockAction;
084:
085: /**
086: * Creates a new <code>GetFeatureWithLock</code> instance.
087: *
088: * @param version
089: * request version
090: * @param id
091: * id of the request
092: * @param handle
093: * @param resultType
094: * desired result type (results | hits)
095: * @param outputFormat
096: * requested result format
097: * @param maxFeatures
098: * @param startPosition
099: * deegree specific parameter defining where to start considering features
100: * @param traverseXLinkDepth
101: * @param traverseXLinkExpiry
102: * @param queries
103: * @param vendorSpecificParam
104: * @param expiry
105: * the limit on how long the web feature service keeps the lock (in milliseconds)
106: * @param lockAction
107: * method for lock acquisition
108: */
109: GetFeatureWithLock(String version, String id, String handle,
110: RESULT_TYPE resultType, String outputFormat,
111: int maxFeatures, int startPosition, int traverseXLinkDepth,
112: int traverseXLinkExpiry, Query[] queries,
113: Map<String, String> vendorSpecificParam, long expiry,
114: ALL_SOME_TYPE lockAction) {
115: super (version, id, handle, resultType, outputFormat,
116: maxFeatures, startPosition, traverseXLinkDepth,
117: traverseXLinkExpiry, queries, vendorSpecificParam);
118: this .expiry = expiry;
119: this .lockAction = lockAction;
120: }
121:
122: /**
123: * Creates a new <code>GetFeatureWithLock</code> instance from the given parameters.
124: *
125: * @param version
126: * request version
127: * @param id
128: * id of the request
129: * @param handle
130: * @param resultType
131: * desired result type (results | hits)
132: * @param outputFormat
133: * requested result format
134: * @param maxFeatures
135: * @param startPosition
136: * deegree specific parameter defining where to start considering features
137: * @param traverseXLinkDepth
138: * @param traverseXLinkExpiry
139: * @param queries
140: * @param vendorSpecificParam
141: * @param expiry
142: * the limit on how long the web feature service keeps the lock (in milliseconds)
143: * @param lockAction
144: * method for lock acquisition
145: * @return new <code>GetFeatureWithLock</code> request
146: */
147: public static GetFeatureWithLock create(String version, String id,
148: String handle, RESULT_TYPE resultType, String outputFormat,
149: int maxFeatures, int startPosition, int traverseXLinkDepth,
150: int traverseXLinkExpiry, Query[] queries,
151: Map<String, String> vendorSpecificParam, long expiry,
152: ALL_SOME_TYPE lockAction) {
153: return new GetFeatureWithLock(version, id, handle, resultType,
154: outputFormat, maxFeatures, startPosition,
155: traverseXLinkDepth, traverseXLinkExpiry, queries,
156: vendorSpecificParam, expiry, lockAction);
157: }
158:
159: /**
160: * Creates a new <code>GetFeatureWithLock</code> instance from a document that contains the
161: * DOM representation of the request.
162: *
163: * @param id
164: * of the request
165: * @param root
166: * element that contains the DOM representation of the request
167: * @return new <code>GetFeatureWithLock</code> request
168: * @throws OGCWebServiceException
169: */
170: public static GetFeatureWithLock create(String id, Element root)
171: throws OGCWebServiceException {
172: GetFeatureWithLockDocument doc = new GetFeatureWithLockDocument();
173: doc.setRootElement(root);
174: GetFeatureWithLock request;
175: try {
176: request = doc.parse(id);
177: } catch (Exception e) {
178: LOG.logError(e.getMessage(), e);
179: throw new OGCWebServiceException("GetFeatureWithLock", e
180: .getMessage());
181: }
182: return request;
183: }
184:
185: /**
186: * Creates a new <code>GetFeatureWithLock</code> instance from the given key-value pair
187: * encoded request.
188: *
189: * @param id
190: * request identifier
191: * @param request
192: * @return new <code>GetFeatureWithLock</code> request
193: * @throws InvalidParameterValueException
194: * @throws InconsistentRequestException
195: */
196: public static GetFeatureWithLock create(String id, String request)
197: throws InconsistentRequestException,
198: InvalidParameterValueException {
199: Map<String, String> map = KVP2Map.toMap(request);
200: map.put("ID", id);
201: return create(map);
202: }
203:
204: /**
205: * Creates a new <code>GetFeatureWithLock</code> request from the given map.
206: *
207: * @param kvp
208: * key-value pairs, keys have to be uppercase
209: * @return new <code>GetFeatureWithLock</code> request
210: * @throws InconsistentRequestException
211: * @throws InvalidParameterValueException
212: */
213: public static GetFeatureWithLock create(Map<String, String> kvp)
214: throws InconsistentRequestException,
215: InvalidParameterValueException {
216:
217: // SERVICE
218: checkServiceParameter(kvp);
219:
220: // ID (deegree specific)
221: String id = kvp.get("ID");
222:
223: // VERSION
224: String version = checkVersionParameter(kvp);
225:
226: // OUTPUTFORMAT
227: String outputFormat = getParam("OUTPUTFORMAT", kvp, FORMAT_GML3);
228:
229: // RESULTTYPE
230: RESULT_TYPE resultType = RESULT_TYPE.RESULTS;
231: String resultTypeString = kvp.get("RESULTTYPE");
232: if ("hits".equals(resultTypeString)) {
233: resultType = RESULT_TYPE.HITS;
234: }
235:
236: // FEATUREVERSION
237: String featureVersion = kvp.get("FEATUREVERSION");
238:
239: // MAXFEATURES
240: String maxFeaturesString = kvp.get("MAXFEATURES");
241: // -1: fetch all features
242: int maxFeatures = -1;
243: if (maxFeaturesString != null) {
244: try {
245: maxFeatures = Integer.parseInt(maxFeaturesString);
246: if (maxFeatures < 1) {
247: throw new NumberFormatException();
248: }
249: } catch (NumberFormatException e) {
250: LOG.logError(e.getMessage(), e);
251: String msg = Messages.getMessage(
252: "WFS_PARAMETER_INVALID_INT", maxFeaturesString,
253: "MAXFEATURES");
254: throw new InvalidParameterValueException(msg);
255: }
256: }
257:
258: // STARTPOSITION (deegree specific)
259: String startPosString = getParam("STARTPOSITION", kvp, "1");
260: int startPosition = 1;
261: try {
262: startPosition = Integer.parseInt(startPosString);
263: if (startPosition < 1) {
264: throw new NumberFormatException();
265: }
266: } catch (NumberFormatException e) {
267: LOG.logError(e.getMessage(), e);
268: String msg = Messages.getMessage(
269: "WFS_PARAMETER_INVALID_INT", startPosString,
270: "STARTPOSITION");
271: throw new InvalidParameterValueException(msg);
272: }
273:
274: // SRSNAME
275: String srsName = kvp.get("SRSNAME");
276:
277: // TYPENAME
278: QualifiedName[] typeNames = extractTypeNames(kvp);
279: if (typeNames == null) {
280: // no TYPENAME parameter -> FEATUREID must be present
281: String featureId = kvp.get("FEATUREID");
282: if (featureId != null) {
283: String msg = Messages
284: .getMessage("WFS_FEATUREID_PARAM_UNSUPPORTED");
285: throw new InvalidParameterValueException(msg);
286: }
287: String msg = Messages
288: .getMessage("WFS_TYPENAME+FID_PARAMS_MISSING");
289: throw new InvalidParameterValueException(msg);
290: }
291:
292: // BBOX
293: Filter bboxFilter = extractBBOXFilter(kvp);
294:
295: // FILTER (prequisite: TYPENAME)
296: Map<QualifiedName, Filter> filterMap = extractFilters(kvp,
297: typeNames);
298: if (bboxFilter != null && filterMap.size() > 0) {
299: String msg = Messages.getMessage("WFS_BBOX_FILTER_INVALID");
300: throw new InvalidParameterValueException(msg);
301: }
302:
303: // PROPERTYNAME
304: Map<QualifiedName, PropertyPath[]> propertyNameMap = extractPropNames(
305: kvp, typeNames);
306:
307: // SORTBY
308: SortProperty[] sortProperties = null;
309:
310: // TRAVERSEXLINKDEPTH
311: int traverseXLinkDepth = -1;
312:
313: // TRAVERSEXLINKEXPIRY
314: int traverseXLinkExpiry = -1;
315:
316: // build a Query instance for each requested feature type (later also for each featureid...)
317: Query[] queries = new Query[typeNames.length];
318: for (int i = 0; i < queries.length; i++) {
319: QualifiedName ftName = typeNames[i];
320: PropertyPath[] properties = propertyNameMap.get(ftName);
321: Filter filter;
322: if (bboxFilter != null) {
323: filter = bboxFilter;
324: } else {
325: filter = filterMap.get(ftName);
326: }
327: QualifiedName[] ftNames = new QualifiedName[] { ftName };
328: queries[i] = new Query(properties, null, sortProperties,
329: null, featureVersion, ftNames, null, srsName,
330: filter, resultType, maxFeatures, startPosition);
331: }
332:
333: // EXPIRY
334: String expiryString = getParam("EXPIRY", kvp,
335: LockFeature.DEFAULT_EXPIRY);
336: int expiry = 0;
337: try {
338: expiry = Integer.parseInt(expiryString);
339: if (expiry < 1) {
340: throw new NumberFormatException();
341: }
342: } catch (NumberFormatException e) {
343: String msg = Messages
344: .getMessage("WFS_PARAMETER_INVALID_INT",
345: expiryString, "EXPIRY");
346: throw new InvalidParameterValueException(msg);
347: }
348:
349: // LOCKACTION
350: String lockActionString = getParam("LOCKACTION", kvp, "ALL");
351: ALL_SOME_TYPE lockAction = LockFeature
352: .validateLockAction(lockActionString);
353:
354: // build a GetFeatureLock request that contains all queries
355: GetFeatureWithLock request = new GetFeatureWithLock(version,
356: id, null, resultType, outputFormat, maxFeatures,
357: startPosition, traverseXLinkDepth, traverseXLinkExpiry,
358: queries, kvp, expiry, lockAction);
359: return request;
360: }
361:
362: /**
363: * Returns the limit on how long the web feature service holds the lock in the event that a
364: * transaction is never issued that would release the lock. The expiry limit is specified in
365: * milliseconds.
366: *
367: * @return the limit on how long the web feature service holds the lock (in milliseconds)
368: */
369: public long getExpiry() {
370: return this .expiry;
371: }
372:
373: /**
374: * Returns the mode for lock acquisition.
375: *
376: * @see ALL_SOME_TYPE
377: *
378: * @return the mode for lock acquisition
379: */
380: public ALL_SOME_TYPE getLockAction() {
381: return this.lockAction;
382: }
383: }
|