/** * Handles a {@link GetFeature} request by delegating the contained {@link Query} objects to * different Threads. * * <p>If at least one query fails an exception will be thrown and all running threads will be * stopped. * * @param getFeature * @return result of the request * @throws OGCWebServiceException */ FeatureResult handleRequest(GetFeature getFeature) throws OGCWebServiceException { LOG.entering(); if (getFeature.getMaxFeatures() > maxFeatures) { getFeature.setMaxFeatures(maxFeatures); } LOG.logDebug("maxFeatures " + getFeature.getMaxFeatures()); Query[] queries = getFeature.getQuery(); List<Callable<FeatureCollection>> queryTasks = new ArrayList<Callable<FeatureCollection>>(queries.length); for (Query query : queries) { QualifiedName[] ftNames = query.getTypeNames(); // TODO joins between feature types if (ftNames.length > 1) { String msg = "Multiple feature types in a Query (joins over feature types) " + "are not the supported by this WFS implementation."; throw new OGCWebServiceException(this.getClass().getName(), msg); } QualifiedName ftName = ftNames[0]; MappedFeatureType ft = this.service.getMappedFeatureType(ftName); if (ft == null) { String msg = Messages.getMessage("WFS_FEATURE_TYPE_UNKNOWN", ftName); throw new OGCWebServiceException(this.getClass().getName(), msg); } if (!ft.isVisible()) { String msg = Messages.getMessage("WFS_FEATURE_TYPE_INVISIBLE", ftName); throw new OGCWebServiceException(this.getClass().getName(), msg); } // check and normalized requested SRS String srsName = query.getSrsName(); if (srsName != null) { WFSFeatureType wfsFT = this.service.getCapabilities().getFeatureTypeList().getFeatureType(ftName); String normalizedSrsName = normalizeSrsName(srsName); query.setSrsName(normalizedSrsName); if (!(wfsFT.supportsSrs(normalizedSrsName))) { String msg = Messages.getMessage("WFS_FEATURE_TYPE_SRS_UNSUPPORTED", ftName, srsName); throw new OGCWebServiceException(this.getClass().getName(), msg); } } QueryTask task = new QueryTask(query, ft); queryTasks.add(task); } WFSConfiguration conf = (WFSConfiguration) service.getCapabilities(); long timeout = conf.getDeegreeParams().getRequestTimeLimit() * 1000; if (timeout > MAX_TIMEOUT_MILLIS) { // limit max timeout timeout = MAX_TIMEOUT_MILLIS; } List<ExecutionFinishedEvent<FeatureCollection>> finishedEvents = null; try { finishedEvents = Executor.getInstance().performSynchronously(queryTasks, timeout); } catch (InterruptedException e) { String msg = "Exception occured while waiting for the GetFeature results: " + e.getMessage(); throw new OGCWebServiceException(this.getClass().getName(), msg); } // use id of the request as id of the result feature collection // to allow identification of the original request that produced // the feature collection FeatureCollection fc = null; if (getFeature.getResultType() == RESULT_TYPE.RESULTS) { fc = mergeResults(getFeature.getId(), finishedEvents); } else { fc = mergeHits(getFeature.getId(), finishedEvents); } FeatureResult fr = new FeatureResult(getFeature, fc); LOG.exiting(); return fr; }
/** * Appends the XML representation of the given <code>Query</code> to an element. * * @param query */ private static void appendQuery(Element root, Query query) throws IOException, XMLParsingException { Element queryElem = XMLTools.appendElement(root, WFS, "wfs:Query"); if (query.getHandle() != null) { queryElem.setAttribute("handle", query.getHandle()); } if (query.getFeatureVersion() != null) { queryElem.setAttribute("featureVersion", query.getFeatureVersion()); } QualifiedName[] qn = query.getTypeNames(); String[] na = new String[qn.length]; for (int i = 0; i < na.length; i++) { na[i] = qn[i].getAsString(); queryElem.setAttribute("xmlns:" + qn[i].getPrefix(), qn[i].getNamespace().toASCIIString()); } String tn = StringTools.arrayToString(na, ','); queryElem.setAttribute("typeName", tn); PropertyPath[] propertyNames = query.getPropertyNames(); for (int i = 0; i < propertyNames.length; i++) { Element propertyNameElement = XMLTools.appendElement(queryElem, WFS, "wfs:PropertyName"); appendPropertyPath(propertyNameElement, propertyNames[i]); } Function[] fn = query.getFunctions(); // copy function definitions into query node if (fn != null) { for (int i = 0; i < fn.length; i++) { StringReader sr = new StringReader(fn[i].toXML().toString()); Document doc; try { doc = XMLTools.parse(sr); } catch (SAXException e) { throw new XMLParsingException("could not parse filter function", e); } XMLTools.copyNode(doc.getDocumentElement(), queryElem); } } // copy filter into query node if (query.getFilter() != null) { StringReader sr = new StringReader(query.getFilter().toXML().toString()); Document doc; try { doc = XMLTools.parse(sr); } catch (SAXException e) { throw new XMLParsingException("could not parse filter", e); } Element elem = XMLTools.appendElement(queryElem, OGCNS, "ogc:Filter"); XMLTools.copyNode(doc.getDocumentElement(), elem); } SortProperty[] sp = query.getSortProperties(); if (sp != null) { Element sortBy = XMLTools.appendElement(queryElem, OGCNS, "ogc:SortBy"); for (int i = 0; i < sp.length; i++) { Element sortProp = XMLTools.appendElement(sortBy, OGCNS, "ogc:SortProperty"); XMLTools.appendElement( sortProp, OGCNS, "ogc:PropertyName", sp[i].getSortProperty().getAsString()); if (!sp[i].getSortOrder()) { XMLTools.appendElement(sortBy, OGCNS, "ogc:SortOrder", "DESC"); } } } }