001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wfs/operation/GetFeatureDocument.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.ogcwebservices.wfs.operation;
044:
045: import java.util.HashSet;
046: import java.util.List;
047: import java.util.Map;
048: import java.util.Set;
049:
050: import org.deegree.datatypes.QualifiedName;
051: import org.deegree.framework.xml.XMLParsingException;
052: import org.deegree.framework.xml.XMLTools;
053: import org.deegree.i18n.Messages;
054: import org.deegree.model.filterencoding.AbstractFilter;
055: import org.deegree.model.filterencoding.Filter;
056: import org.deegree.model.filterencoding.Function;
057: import org.deegree.ogcbase.OGCDocument;
058: import org.deegree.ogcbase.PropertyPath;
059: import org.deegree.ogcbase.SortProperty;
060: import org.deegree.ogcwebservices.wfs.operation.GetFeature.RESULT_TYPE;
061: import org.w3c.dom.Element;
062: import org.w3c.dom.Node;
063: import org.w3c.dom.Text;
064:
065: /**
066: * Parser for "wfs:GetFeature" requests.
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 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
072: */
073: public class GetFeatureDocument extends AbstractWFSRequestDocument {
074:
075: private static final long serialVersionUID = -3411186861123355322L;
076:
077: /**
078: * Parses the underlying document into a <code>GetFeature</code> request object.
079: *
080: * @param id
081: * @return corresponding <code>GetFeature</code> object
082: * @throws XMLParsingException
083: */
084: public GetFeature parse(String id) throws XMLParsingException {
085:
086: checkServiceAttribute();
087: String version = checkVersionAttribute();
088: boolean useVersion_1_0_0 = "1.0.0".equals(version);
089:
090: Element root = getRootElement();
091: String handle = XMLTools.getNodeAsString(root, "@handle",
092: nsContext, null);
093: String outputFormat = XMLTools.getNodeAsString(root,
094: "@outputFormat", nsContext,
095: AbstractWFSRequest.FORMAT_GML3);
096:
097: int maxFeatures = XMLTools.getNodeAsInt(root, "@maxFeatures",
098: nsContext, -1);
099: int startPosition = XMLTools.getNodeAsInt(root,
100: "@startPosition", nsContext, 1);
101: if (startPosition < 1) {
102: String msg = Messages.getMessage(
103: "WFS_INVALID_STARTPOSITION", Integer
104: .toString(startPosition));
105: throw new XMLParsingException(msg);
106: }
107:
108: int traverseXLinkDepth = XMLTools.getNodeAsInt(root,
109: "@traverseXLinkDepth", nsContext, -1);
110: int traverseXLinkExpiry = XMLTools.getNodeAsInt(root,
111: "@traverseXLinkExpiry", nsContext, -1);
112:
113: String resultTypeString = XMLTools.getNodeAsString(root,
114: "@resultType", nsContext, "results");
115: RESULT_TYPE resultType;
116: if ("results".equals(resultTypeString)) {
117: resultType = RESULT_TYPE.RESULTS;
118: } else if ("hits".equals(resultTypeString)) {
119: resultType = RESULT_TYPE.HITS;
120: } else {
121: String msg = Messages.getMessage("WFS_INVALID_RESULT_TYPE",
122: resultTypeString);
123: throw new XMLParsingException(msg);
124: }
125:
126: List<Element> nl = XMLTools.getRequiredElements(root,
127: "wfs:Query", nsContext);
128: Query[] queries = new Query[nl.size()];
129: for (int i = 0; i < queries.length; i++) {
130: queries[i] = parseQuery(nl.get(i), useVersion_1_0_0);
131: }
132:
133: // vendorspecific attributes; required by deegree rights management
134: Map<String, String> vendorSpecificParams = parseDRMParams(root);
135:
136: GetFeature req = new GetFeature(version, id, handle,
137: resultType, outputFormat, maxFeatures, startPosition,
138: traverseXLinkDepth, traverseXLinkExpiry, queries,
139: vendorSpecificParams);
140: return req;
141: }
142:
143: /**
144: * Parses the given query element into a {@link Query} object with filter encoding 1.1.0.
145: * <p>
146: * Note that the following attributes from the surrounding element are also considered (if it is
147: * present):
148: * <ul>
149: * <li>resultType</li>
150: * <li>maxFeatures</li>
151: * <li>startPosition</li>
152: * </ul>
153: *
154: * @param element
155: * query element
156: * @return corresponding <code>Query</code> object
157: * @throws XMLParsingException
158: */
159: Query parseQuery(Element element) throws XMLParsingException {
160: return parseQuery(element, false);
161:
162: }
163:
164: /**
165: * Parses the given query element into a {@link Query} object.
166: * <p>
167: * Note that the following attributes from the surrounding element are also considered (if it is
168: * present):
169: * <ul>
170: * <li>resultType</li>
171: * <li>maxFeatures</li>
172: * <li>startPosition</li>
173: * </ul>
174: *
175: * @param element
176: * query element
177: * @return corresponding <code>Query</code> object
178: * @throws XMLParsingException
179: */
180: Query parseQuery(Element element, boolean useVersion_1_0_0)
181: throws XMLParsingException {
182:
183: String handle = XMLTools.getNodeAsString(element, "@handle",
184: nsContext, null);
185:
186: String typeNameList = XMLTools.getRequiredNodeAsString(element,
187: "@typeName", nsContext);
188: // handle both 1.1.0 and 1.2.0 delimiters
189: String[] values = typeNameList.split("[,\\s]");
190: QualifiedName[] typeNames = transformToQualifiedNames(values,
191: element);
192: String[] aliases = null;
193: String aliasesList = XMLTools.getNodeAsString(element,
194: "@aliases", nsContext, null);
195: if (aliasesList != null) {
196: aliases = aliasesList.split("\\s");
197: if (aliases.length != typeNames.length) {
198: String msg = Messages.getMessage(
199: "WFS_QUERY_ALIAS_WRONG_COUNT", Integer
200: .toString(typeNames.length), Integer
201: .toString(aliases.length));
202: throw new XMLParsingException(msg);
203: }
204: Set<String> tempSet = new HashSet<String>();
205: for (String alias : aliases) {
206: if (tempSet.contains(alias)) {
207: String msg = Messages.getMessage(
208: "WFS_QUERY_ALIAS_NOT_UNIQUE", alias);
209: throw new XMLParsingException(msg);
210: }
211: tempSet.add(alias);
212: }
213: }
214:
215: String featureVersion = XMLTools.getNodeAsString(element,
216: "@featureVersion", nsContext, null);
217: String srsName = XMLTools.getNodeAsString(element, "@srsName",
218: nsContext, null);
219:
220: List<Node> nl = null;
221: if (useVersion_1_0_0) {
222: nl = XMLTools.getNodes(element, "ogc:PropertyName/text()",
223: nsContext);
224: } else {
225: nl = XMLTools.getNodes(element, "wfs:PropertyName/text()",
226: nsContext);
227: }
228: PropertyPath[] propertyNames = new PropertyPath[nl.size()];
229: for (int i = 0; i < propertyNames.length; i++) {
230: propertyNames[i] = OGCDocument.parsePropertyPath((Text) nl
231: .get(i));
232: }
233:
234: nl = XMLTools.getNodes(element, "ogc:Function", nsContext);
235: Function[] functions = new Function[nl.size()];
236: for (int i = 0; i < functions.length; i++) {
237: functions[i] = (Function) Function
238: .buildFromDOM((Element) nl.get(i));
239: }
240:
241: Filter filter = null;
242: Element filterElement = (Element) XMLTools.getNode(element,
243: "ogc:Filter", nsContext);
244: if (filterElement != null) {
245: filter = AbstractFilter.buildFromDOM(filterElement,
246: useVersion_1_0_0);
247: }
248:
249: SortProperty[] sortProps = null;
250: Element sortByElement = (Element) XMLTools.getNode(element,
251: "ogc:SortBy", nsContext);
252: if (sortByElement != null) {
253: sortProps = parseSortBy(sortByElement);
254: }
255:
256: // ----------------------------------------------------------------------------------------
257: // parse "inherited" attributes from GetFeature element (but very kindly)
258: // ----------------------------------------------------------------------------------------
259:
260: String resultTypeString = "results";
261: RESULT_TYPE resultType;
262: try {
263: resultTypeString = XMLTools.getNodeAsString(element,
264: "../@resultType", nsContext, "results");
265: } catch (XMLParsingException doNothing) {
266: // it's o.k. - let's be really kind here
267: }
268:
269: if ("results".equals(resultTypeString)) {
270: resultType = RESULT_TYPE.RESULTS;
271: } else if ("hits".equals(resultTypeString)) {
272: resultType = RESULT_TYPE.HITS;
273: } else {
274: String msg = Messages.getMessage("WFS_INVALID_RESULT_TYPE",
275: resultTypeString);
276: throw new XMLParsingException(msg);
277: }
278:
279: int maxFeatures = -1;
280: try {
281: maxFeatures = XMLTools.getNodeAsInt(element,
282: "../@maxFeatures", nsContext, -1);
283: } catch (XMLParsingException doNothing) {
284: // it's o.k. - let's be really kind here
285: }
286:
287: int startPosition = -1;
288: try {
289: startPosition = XMLTools.getNodeAsInt(element,
290: "../@startPosition", nsContext, 0);
291: } catch (XMLParsingException doNothing) {
292: // it's o.k. - let's be really kind here
293: }
294:
295: return new Query(propertyNames, functions, sortProps, handle,
296: featureVersion, typeNames, aliases, srsName, filter,
297: resultType, maxFeatures, startPosition);
298: }
299:
300: /**
301: * Parses the given "ogc:SortBy" element.
302: *
303: * @param root
304: * "ogc:SortBy" element
305: * @return corresponding <code>SortProperty</code> instances (in original order)
306: */
307: private SortProperty[] parseSortBy(Element root)
308: throws XMLParsingException {
309:
310: List<Node> nl = XMLTools.getRequiredNodes(root,
311: "ogc:SortProperty", nsContext);
312: SortProperty[] sortProps = new SortProperty[nl.size()];
313: for (int i = 0; i < nl.size(); i++) {
314: sortProps[i] = SortProperty.create((Element) nl.get(i));
315: }
316: return sortProps;
317: }
318: }
|