001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/GetMapServiceInvoker.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: 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.wms;
044:
045: import java.io.IOException;
046: import java.net.MalformedURLException;
047: import java.net.URI;
048: import java.net.URL;
049: import java.util.ArrayList;
050: import java.util.HashMap;
051: import java.util.List;
052: import java.util.Map;
053:
054: import org.deegree.datatypes.QualifiedName;
055: import org.deegree.framework.log.ILogger;
056: import org.deegree.framework.log.LoggerFactory;
057: import org.deegree.framework.xml.NamespaceContext;
058: import org.deegree.framework.xml.XMLParsingException;
059: import org.deegree.framework.xml.schema.XMLSchemaException;
060: import org.deegree.graphics.sld.AbstractLayer;
061: import org.deegree.graphics.sld.FeatureTypeConstraint;
062: import org.deegree.graphics.sld.LayerFeatureConstraints;
063: import org.deegree.graphics.sld.UserLayer;
064: import org.deegree.model.crs.UnknownCRSException;
065: import org.deegree.model.feature.schema.FeatureType;
066: import org.deegree.model.feature.schema.GMLSchema;
067: import org.deegree.model.feature.schema.GMLSchemaDocument;
068: import org.deegree.model.feature.schema.GeometryPropertyType;
069: import org.deegree.ogcbase.ElementStep;
070: import org.deegree.ogcbase.PropertyPath;
071: import org.deegree.ogcbase.PropertyPathStep;
072: import org.deegree.ogcwebservices.InconsistentRequestException;
073: import org.deegree.ogcwebservices.InvalidParameterValueException;
074: import org.deegree.ogcwebservices.OGCWebServiceException;
075: import org.deegree.ogcwebservices.OWSUtils;
076: import org.deegree.ogcwebservices.wfs.WFService;
077: import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType;
078: import org.deegree.ogcwebservices.wfs.operation.FeatureTypeDescription;
079: import org.deegree.ogcwebservices.wms.capabilities.Layer;
080: import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource;
081: import org.xml.sax.SAXException;
082:
083: /**
084: *
085: *
086: *
087: * @version $Revision: 9345 $
088: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
089: * @author last edited by: $Author: apoth $
090: *
091: * @version 1.0. $Revision: 9345 $, $Date: 2007-12-27 08:22:25 -0800 (Thu, 27 Dec 2007) $
092: *
093: * @since 2.0
094: */
095: public abstract class GetMapServiceInvoker {
096:
097: private static final ILogger LOG = LoggerFactory
098: .getLogger(GetMapServiceInvoker.class);
099:
100: private static Map<QualifiedName, List<PropertyPath>> geoProps;
101:
102: static {
103: if (geoProps == null) {
104: geoProps = new HashMap<QualifiedName, List<PropertyPath>>();
105: }
106: }
107:
108: protected final DefaultGetMapHandler handler;
109:
110: protected double scaleDen = 0;
111:
112: /**
113: *
114: * @param handler
115: * @param scaleDen
116: */
117: public GetMapServiceInvoker(DefaultGetMapHandler handler,
118: double scaleDen) {
119: this .handler = handler;
120: this .scaleDen = scaleDen;
121: }
122:
123: /**
124: * the method accesses the GML schema of the feature types being part of the passed
125: * FeatureTypeConstraints and extracts the geometry property definition. The names of the
126: * geometry properties will be added as PropertyPath's to passed list
127: *
128: * @param layer
129: * @param ftc
130: * @param pp
131: * @return the list of property paths
132: * @throws OGCWebServiceException
133: * @throws SAXException
134: * @throws IOException
135: * @throws XMLParsingException
136: * @throws XMLSchemaException
137: * @throws UnknownCRSException
138: */
139: protected List<PropertyPath> findGeoProperties(AbstractLayer layer,
140: FeatureTypeConstraint[] ftc, List<PropertyPath> pp)
141: throws OGCWebServiceException, IOException, SAXException,
142: XMLSchemaException, XMLParsingException,
143: UnknownCRSException {
144:
145: GMLSchemaDocument doc = null;
146: for (int i = 0; i < ftc.length; i++) {
147: if (geoProps.get(ftc[i].getFeatureTypeName()) == null) {
148: if (layer instanceof UserLayer
149: && ((UserLayer) layer).getRemoteOWS() != null) {
150: doc = getSchemaFromRemoteWFS((UserLayer) layer,
151: ftc[i]);
152: } else {
153: doc = getSchemaFromLocalWFS(layer, ftc[i]);
154: }
155: GMLSchema schema = doc.parseGMLSchema();
156: FeatureType ft = schema.getFeatureType(ftc[i]
157: .getFeatureTypeName());
158: GeometryPropertyType[] gpt = ft.getGeometryProperties();
159:
160: List<PropertyPath> tmp = new ArrayList<PropertyPath>(
161: gpt.length);
162: for (int j = 0; j < gpt.length; j++) {
163: try {
164: String pre = ftc[i].getFeatureTypeName()
165: .getPrefix();
166: QualifiedName qn = new QualifiedName(pre,
167: gpt[j].getName().getLocalName(), gpt[j]
168: .getName().getNamespace());
169: PropertyPathStep step = new ElementStep(qn);
170: List<PropertyPathStep> steps = new ArrayList<PropertyPathStep>();
171: steps.add(step);
172: PropertyPath prop = new PropertyPath(steps);
173: pp.add(prop);
174: tmp.add(prop);
175: } catch (Exception e) {
176: e.printStackTrace();
177: }
178: }
179: geoProps.put(ftc[i].getFeatureTypeName(), tmp);
180: } else {
181: List<PropertyPath> tmp = geoProps.get(ftc[i]
182: .getFeatureTypeName());
183: pp.addAll(tmp);
184: }
185:
186: }
187:
188: return pp;
189: }
190:
191: /**
192: * accesses the GML schema assigned to the feature type contained within the passed
193: * FeatureTypeConstraint from a remote WFS by performing a DescribeFeatureType request
194: *
195: * @param layer
196: * @param ftc
197: * @return the schema document
198: * @throws InconsistentRequestException
199: * @throws InvalidParameterValueException
200: * @throws OGCWebServiceException
201: */
202: private GMLSchemaDocument getSchemaFromLocalWFS(
203: AbstractLayer layer, FeatureTypeConstraint ftc)
204: throws InconsistentRequestException,
205: InvalidParameterValueException, OGCWebServiceException {
206: StringBuffer sb = new StringBuffer(300);
207: sb
208: .append("SERVICE=WFS&VERSION=1.1.0&REQUEST=DescribeFeatureType&TYPENAME=");
209: QualifiedName qn = ftc.getFeatureTypeName();
210: sb.append(qn.getPrefixedName());
211: sb.append("&NAMESPACE=xmlns(").append(qn.getPrefix()).append(
212: '=');
213: sb.append(qn.getNamespace().toASCIIString()).append(')');
214: LOG.logDebug("DescribeFeaturetType for UserLayer: ", sb);
215: DescribeFeatureType dft = DescribeFeatureType.create("rt", sb
216: .toString());
217: WFService wfs = getResponsibleService(layer);
218: FeatureTypeDescription ftd = (FeatureTypeDescription) wfs
219: .doService(dft);
220: GMLSchemaDocument doc = new GMLSchemaDocument();
221: doc.setRootElement(ftd.getFeatureTypeSchema().getRootElement());
222: return doc;
223: }
224:
225: /**
226: * accesses the GML schema assigned to the feature type contained within the passed
227: * FeatureTypeConstraint from a local WFS by performing a DescribeFeatureType request
228: *
229: * @param ftc
230: * @return the schema document
231: * @throws IOException
232: * @throws SAXException
233: * @throws MalformedURLException
234: */
235: private GMLSchemaDocument getSchemaFromRemoteWFS(UserLayer layer,
236: FeatureTypeConstraint ftc) throws IOException,
237: SAXException, MalformedURLException {
238: URL url = layer.getRemoteOWS().getOnlineResource();
239: StringBuffer sb = new StringBuffer(300);
240: sb
241: .append(OWSUtils.validateHTTPGetBaseURL(url
242: .toExternalForm()));
243: sb
244: .append("SERVICE=WFS&VERSION=1.1.0&REQUEST=DescribeFeatureType&TYPENAME=");
245: QualifiedName qn = ftc.getFeatureTypeName();
246: sb.append(qn.getPrefixedName());
247: sb.append("&NAMESPACE=xmlns(").append(qn.getPrefix()).append(
248: '=');
249: sb.append(qn.getNamespace().toASCIIString()).append(')');
250: LOG.logDebug("DescribeFeaturetType for UserLayer: ", sb);
251: GMLSchemaDocument doc = new GMLSchemaDocument();
252: doc.load(new URL(sb.toString()));
253: return doc;
254: }
255:
256: /**
257: * @return the service instance
258: * @throws OGCWebServiceException
259: * if no service could be found
260: */
261: protected WFService getResponsibleService(AbstractLayer layer)
262: throws OGCWebServiceException {
263:
264: LayerFeatureConstraints lfc = layer
265: .getLayerFeatureConstraints();
266: FeatureTypeConstraint[] ftc = lfc.getFeatureTypeConstraint();
267: Layer root = handler.getConfiguration().getLayer();
268: WFService wfs = findService(root, ftc[0].getFeatureTypeName());
269: if (wfs == null) {
270: throw new OGCWebServiceException(this .getClass().getName(),
271: "feature type: " + ftc[0].getFeatureTypeName()
272: + " is not served by this WMS/WFS");
273: }
274:
275: return wfs;
276: }
277:
278: /**
279: * searches/findes the WFService that is resposible for handling the feature types of the
280: * current request. If no WFService instance can be found <code>null</code> will be returned
281: * to indicated that the current feature type is not served by the internal WFS of a WMS
282: *
283: * @param layer
284: * @param featureType
285: * @return the service instance or null
286: * @throws OGCWebServiceException
287: */
288: private WFService findService(Layer layer, QualifiedName featureType)
289: throws OGCWebServiceException {
290: Layer[] layers = layer.getLayer();
291: for (int i = 0; i < layers.length; i++) {
292: AbstractDataSource[] ad = layers[i].getDataSource();
293: if (ad != null) {
294: for (int j = 0; j < ad.length; j++) {
295: if (ad[j].getName().equals(featureType)) {
296: return (WFService) ad[j].getOGCWebService();
297: }
298: }
299: }
300: // recursion
301: WFService wfs = findService(layers[i], featureType);
302: if (wfs != null) {
303: return wfs;
304: }
305: }
306:
307: return null;
308: }
309:
310: /**
311: * extracts all used namespace definitions from a set of PropertyPath's
312: *
313: * @param pp
314: * @return the used namespace definitions from a set of PropertyPath's
315: */
316: protected Map<String, URI> extractNameSpaceDef(List<PropertyPath> pp) {
317: Map<String, URI> map = new HashMap<String, URI>();
318: for (int i = 0; i < pp.size(); i++) {
319: NamespaceContext nsc = pp.get(i).getNamespaceContext();
320: map.putAll(nsc.getNamespaceMap());
321: }
322: return map;
323: }
324:
325: }
|