001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wfs/RemoteWFService.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;
044:
045: import java.io.InputStreamReader;
046: import java.io.StringReader;
047: import java.io.StringWriter;
048: import java.net.URL;
049: import java.util.HashMap;
050: import java.util.Map;
051:
052: import org.deegree.framework.log.ILogger;
053: import org.deegree.framework.log.LoggerFactory;
054: import org.deegree.framework.util.CharsetUtils;
055: import org.deegree.framework.util.MimeTypeMapper;
056: import org.deegree.framework.util.NetWorker;
057: import org.deegree.framework.util.StringTools;
058: import org.deegree.framework.xml.XMLFragment;
059: import org.deegree.model.feature.FeatureCollection;
060: import org.deegree.model.feature.GMLFeatureCollectionDocument;
061: import org.deegree.ogcwebservices.OGCWebService;
062: import org.deegree.ogcwebservices.OGCWebServiceException;
063: import org.deegree.ogcwebservices.OGCWebServiceRequest;
064: import org.deegree.ogcwebservices.OWSUtils;
065: import org.deegree.ogcwebservices.getcapabilities.DCPType;
066: import org.deegree.ogcwebservices.getcapabilities.HTTP;
067: import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
068: import org.deegree.ogcwebservices.getcapabilities.Operation;
069: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
070: import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
071: import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata;
072: import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType;
073: import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
074: import org.deegree.ogcwebservices.wfs.operation.FeatureTypeDescription;
075: import org.deegree.ogcwebservices.wfs.operation.GetFeature;
076: import org.deegree.ogcwebservices.wfs.operation.LockFeature;
077: import org.deegree.ogcwebservices.wfs.operation.WFSGetCapabilities;
078: import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
079:
080: /**
081: * An instance of the class acts as a wrapper to a remote WFS.
082: *
083: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
084: * @author last edited by: $Author: apoth $
085: *
086: * @version $Revision: 9345 $
087: */
088: public class RemoteWFService implements OGCWebService {
089:
090: private static final ILogger LOG = LoggerFactory
091: .getLogger(RemoteWFService.class);
092:
093: protected static final String GETCAPABILITIES = "GETCAPABILITIES";
094:
095: protected static final String GETFEATURE = "GETFEATURE";
096:
097: protected static final String GETFEATUREWITHLOCK = "GETFEATUREWITHLOCK";
098:
099: protected static final String DESCRIBEFEATURETYPE = "DESCRIBEFEATURETYPE";
100:
101: protected static final String TRANSACTION = "TRANSACTION";
102:
103: protected static final String LOCKFEATURE = "LOCKFEATURE";
104:
105: protected WFSCapabilities capabilities = null;
106:
107: protected Map<String, URL> addresses = new HashMap<String, URL>();
108:
109: /**
110: * Creates a new instance of RemoteWFService
111: *
112: * @param capabilities
113: * @throws OGCWebServiceException
114: */
115: public RemoteWFService(WFSCapabilities capabilities)
116: throws OGCWebServiceException {
117:
118: this .capabilities = capabilities;
119:
120: WFSOperationsMetadata om = (WFSOperationsMetadata) capabilities
121: .getOperationsMetadata();
122: Operation op = om.getGetCapabilitiesOperation();
123:
124: // get GetCapabilities address
125: DCPType[] dcp = op.getDCPs();
126: URL[] get = ((HTTP) dcp[0].getProtocol())
127: .getGetOnlineResources();
128: addresses.put(GETCAPABILITIES, get[0]);
129:
130: // get GetFeature address
131: op = om.getGetFeature();
132: dcp = op.getDCPs();
133: boolean po = false;
134: for (int i = 0; i < dcp.length; i++) {
135: get = ((HTTP) dcp[i].getProtocol())
136: .getPostOnlineResources();
137: if (get != null && get.length > 0) {
138: addresses.put(GETFEATURE, get[0]);
139: po = true;
140: }
141: }
142: if (!po) {
143: String s = "WFS: "
144: + capabilities.getServiceIdentification()
145: .getTitle() + " doesn't "
146: + "support HTTP POST for GetFeature requests";
147: LOG.logDebug(s);
148: throw new OGCWebServiceException(s);
149: }
150:
151: // get DescribeFeatureType address
152: op = om.getDescribeFeatureType();
153: dcp = op.getDCPs();
154: get = ((HTTP) dcp[0].getProtocol()).getGetOnlineResources();
155: addresses.put(DESCRIBEFEATURETYPE, get[0]);
156:
157: op = om.getGetFeatureWithLock();
158: if (op != null) {
159: // get GetFeatureWithLock address
160: dcp = op.getDCPs();
161: po = false;
162: for (int i = 0; i < dcp.length; i++) {
163: get = ((HTTP) dcp[i].getProtocol())
164: .getPostOnlineResources();
165: if (get != null && get.length > 0) {
166: addresses.put(GETFEATUREWITHLOCK, get[0]);
167: po = true;
168: }
169: }
170: if (!po) {
171: String s = "WFS: "
172: + capabilities.getServiceIdentification()
173: .getTitle()
174: + " doesn't support HTTP POST for GetFeatureWithLock requests";
175: LOG.logDebug(s);
176: throw new OGCWebServiceException(s);
177: }
178: }
179:
180: op = om.getTransaction();
181: if (op != null) {
182: // get Transaction address
183: dcp = op.getDCPs();
184: po = false;
185: for (int i = 0; i < dcp.length; i++) {
186: get = ((HTTP) dcp[i].getProtocol())
187: .getPostOnlineResources();
188: if (get != null && get.length > 0) {
189: addresses.put(TRANSACTION, get[0]);
190: po = true;
191: }
192: }
193: if (!po) {
194: String s = "WFS: "
195: + capabilities.getServiceIdentification()
196: .getTitle()
197: + " doesn't support HTTP POST for Transaction requests";
198: LOG.logDebug(s);
199: throw new OGCWebServiceException(s);
200: }
201: }
202:
203: op = om.getLockFeature();
204: if (op != null) {
205: // get LockFeature address
206: dcp = op.getDCPs();
207: get = ((HTTP) dcp[0].getProtocol()).getGetOnlineResources();
208: if (get != null && get.length > 0) {
209: addresses.put(LOCKFEATURE, get[0]);
210: }
211: }
212:
213: }
214:
215: /**
216: *
217: * @return capabilities
218: */
219: public WFSCapabilities getWFSCapabilities() {
220: return capabilities;
221: }
222:
223: /*
224: * (non-Javadoc)
225: *
226: * @see org.deegree.ogcwebservices.OGCWebService#doService(org.deegree.ogcwebservices.OGCWebServiceRequest)
227: */
228: public Object doService(OGCWebServiceRequest request)
229: throws OGCWebServiceException {
230: Object response = null;
231: if (request instanceof GetFeature) {
232: response = handleGetFeature((GetFeature) request);
233: } else if (request instanceof DescribeFeatureType) {
234: response = handleDescribeFeatureType((DescribeFeatureType) request);
235: } else if (request instanceof WFSGetCapabilities) {
236: response = handleGetCapabilities((WFSGetCapabilities) request);
237: } else if (request instanceof LockFeature) {
238: response = handleLockFeature((LockFeature) request);
239: } else if (request instanceof Transaction) {
240: response = handleTransaction((Transaction) request);
241: }
242: return response;
243: }
244:
245: /**
246: * performs a GetFeature request against the remote service. The method uses http-POST to call
247: * the remote WFS
248: *
249: * @param request
250: * get feature request
251: */
252: private FeatureResult handleGetFeature(GetFeature request)
253: throws OGCWebServiceException {
254:
255: URL url = addresses.get(GETFEATURE);
256: StringWriter writer = new StringWriter(1000);
257: try {
258: XMLFactory.export(request).write(writer);
259: } catch (Exception e) {
260: LOG.logError(e.getMessage(), e);
261: throw new OGCWebServiceException(
262: "could not transform GetFeature requst to its string representation");
263: }
264: String param = writer.getBuffer().toString();
265:
266: FeatureCollection result = null;
267: try {
268: // get map from the remote service
269: NetWorker nw = new NetWorker(CharsetUtils
270: .getSystemCharset(), url, param);
271: String contentType = nw.getContentType();
272: if (contentType == null
273: || MimeTypeMapper.isKnownMimeType(contentType)) {
274: try {
275: InputStreamReader isr = new InputStreamReader(nw
276: .getInputStream(), CharsetUtils
277: .getSystemCharset());
278: GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument();
279: doc.load(isr, url.toString());
280: result = doc.parse();
281: } catch (Exception e) {
282: throw new OGCWebServiceException(e.toString());
283: }
284: } else {
285: String msg = StringTools
286: .concat(
287: 500,
288: "Response of the remote WFS contains unknown content type: ",
289: contentType, ";request: ", param);
290: throw new OGCWebServiceException(
291: "RemoteWFS:handleGetFeature", msg);
292: }
293: } catch (Exception e) {
294: LOG.logError(e.getMessage(), e);
295: String msg = StringTools.concat(500,
296: "Could not get feature from RemoteWFS: ",
297: capabilities.getServiceIdentification().getTitle(),
298: "; request: ", param, ';');
299: throw new OGCWebServiceException(
300: "RemoteWFS:handleGetFeature", msg);
301:
302: }
303:
304: FeatureResult fr = new FeatureResult(request, result);
305:
306: return fr;
307:
308: }
309:
310: /**
311: * Pefroms a describe feature type request against a remote WFS. The method uses http-GET to
312: * call the remote WFS
313: *
314: * @param request
315: * describe feature type request
316: * @param client
317: * receiver of the response to the request
318: */
319: private FeatureTypeDescription handleDescribeFeatureType(
320: DescribeFeatureType request) throws OGCWebServiceException {
321:
322: URL url = addresses.get(DESCRIBEFEATURETYPE);
323:
324: String param = request.getRequestParameter();
325:
326: String result = null;
327: try {
328: String us = OWSUtils.validateHTTPGetBaseURL(url
329: .toExternalForm())
330: + param;
331: URL ur = new URL(us);
332: // get map from the remote service
333: NetWorker nw = new NetWorker(CharsetUtils
334: .getSystemCharset(), ur);
335: byte[] b = nw.getDataAsByteArr(20000);
336: String contentType = nw.getContentType();
337: if (MimeTypeMapper.isKnownMimeType(contentType)) {
338: // create a WFSCapabilities instance from the result
339: result = new String(b);
340: } else {
341: String msg = StringTools
342: .concat(
343: 500,
344: "Response of the remote WFS contains unknown content type: ",
345: contentType, ";request: ", param);
346: throw new OGCWebServiceException(
347: "RemoteWFS:handleDescribeFeatureType", msg);
348: }
349: } catch (Exception e) {
350: LOG.logError(e.getMessage(), e);
351: String msg = StringTools.concat(500,
352: "Could not get map from RemoteWFS: ", capabilities
353: .getServiceIdentification().getTitle(),
354: "; request: ", param, ';');
355: throw new OGCWebServiceException(
356: "RemoteWFS:handleDescribeFeatureType", msg);
357:
358: }
359:
360: FeatureTypeDescription ftd = null;
361: try {
362: XMLFragment frag = new XMLFragment(
363: new StringReader(result), null);
364: ftd = new FeatureTypeDescription(frag);
365: } catch (Exception e1) {
366: LOG.logError(e1.getMessage(), e1);
367: throw new OGCWebServiceException(this .getClass().getName()
368: + "Could not create response", StringTools
369: .stackTraceToString(e1));
370: }
371:
372: return ftd;
373: }
374:
375: /**
376: * reads the capabilities from the remote WFS by performing a GetCapabilities request against
377: * it. The method uses http-GET to call the remote WFS
378: *
379: * @param request
380: * capabilities request
381: * @param client
382: * receiver of the response to the request
383: */
384: private WFSCapabilities handleGetCapabilities(
385: WFSGetCapabilities request) throws OGCWebServiceException {
386:
387: URL url = addresses.get(GETCAPABILITIES);
388: String param = request.getRequestParameter();
389:
390: WFSCapabilities response = null;
391: try {
392: String remoteAddress = OWSUtils.validateHTTPGetBaseURL(url
393: .toExternalForm());
394: URL ur = new URL(remoteAddress + param);
395: WFSCapabilitiesDocument capabilitiesDoc = new WFSCapabilitiesDocument();
396: capabilitiesDoc.load(ur);
397: response = (WFSCapabilities) capabilitiesDoc
398: .parseCapabilities();
399: } catch (Exception e) {
400: LOG.logError(e.getMessage(), e);
401: String msg = StringTools.concat(500,
402: "Could not get map from RemoteWFS: ", capabilities
403: .getServiceIdentification().getTitle(),
404: "; request: ", param, ';');
405: throw new OGCWebServiceException(
406: "RemoteWFS:handleGetCapabilities", msg);
407:
408: }
409:
410: return response;
411:
412: }
413:
414: /**
415: * @param request
416: */
417: private Object handleLockFeature(LockFeature request) {
418: // FIXME
419: // TODO
420: return null;
421: }
422:
423: /**
424: * @param request
425: */
426: private Object handleTransaction(Transaction request) {
427: // FIXME
428: // TODO
429: return null;
430: }
431:
432: /*
433: * (non-Javadoc)
434: *
435: * @see org.deegree.ogcwebservices.OGCWebService#getCapabilities()
436: */
437: public OGCCapabilities getCapabilities() {
438: return capabilities;
439: }
440:
441: }
|