//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wfs/RemoteWFService.java,v 1.30 2006/12/04 18:22:44 mschneider Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstraße 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.ogcwebservices.wfs;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.HashMap;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.CharsetUtils;
import org.deegree.framework.util.MimeTypeMapper;
import org.deegree.framework.util.NetWorker;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.XMLFragment;
import org.deegree.model.feature.FeatureCollection;
import org.deegree.model.feature.GMLFeatureCollectionDocument;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.OGCWebServiceRequest;
import org.deegree.ogcwebservices.OWSUtils;
import org.deegree.ogcwebservices.getcapabilities.DCPType;
import org.deegree.ogcwebservices.getcapabilities.HTTP;
import org.deegree.ogcwebservices.getcapabilities.Operation;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
import org.deegree.ogcwebservices.wfs.capabilities.WFSOperationsMetadata;
import org.deegree.ogcwebservices.wfs.operation.DescribeFeatureType;
import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
import org.deegree.ogcwebservices.wfs.operation.FeatureTypeDescription;
import org.deegree.ogcwebservices.wfs.operation.GetFeature;
import org.deegree.ogcwebservices.wfs.operation.LockFeature;
import org.deegree.ogcwebservices.wfs.operation.WFSGetCapabilities;
import org.deegree.ogcwebservices.wfs.operation.transaction.Transaction;
/**
* An instance of the class acts as a wrapper to a remote WFS.
*
* @version $Revision: 1.30 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a>
*/
public class RemoteWFService extends WFService {
private static final ILogger LOG = LoggerFactory.getLogger( RemoteWFService.class );
protected static final String GETCAPABILITIES = "GETCAPABILITIES";
protected static final String GETFEATURE = "GETFEATURE";
protected static final String GETFEATUREWITHLOCK = "GETFEATUREWITHLOCK";
protected static final String DESCRIBEFEATURETYPE = "DESCRIBEFEATURETYPE";
protected static final String TRANSACTION = "TRANSACTION";
protected static final String LOCKFEATURE = "LOCKFEATURE";
protected WFSCapabilities capabilities = null;
protected HashMap addresses = new HashMap();
/**
* Creates a new instance of RemoteWFService
*
* @param capabilities
* @throws OGCWebServiceException
*/
public RemoteWFService(WFSCapabilities capabilities) throws OGCWebServiceException {
super( null );
this.capabilities = capabilities;
WFSOperationsMetadata om = (WFSOperationsMetadata)capabilities.getOperationsMetadata();
Operation op = om.getGetCapabilitiesOperation();
// get GetCapabilities address
DCPType[] dcp = op.getDCPs();
URL[] get = ((HTTP) dcp[0].getProtocol()).getGetOnlineResources();
addresses.put(GETCAPABILITIES, get[0]);
// get GetFeature address
op = om.getGetFeature();
dcp = op.getDCPs();
boolean po = false;
for (int i = 0; i < dcp.length; i++) {
get = ((HTTP) dcp[i].getProtocol()).getPostOnlineResources();
if (get != null && get.length > 0) {
addresses.put(GETFEATURE, get[0]);
po = true;
}
}
if (!po) {
String s = "WFS: " + capabilities.getServiceIdentification().getTitle()
+ " doesn't " + "support HTTP POST for GetFeature requests";
LOG.logDebug( s );
throw new OGCWebServiceException(s);
}
// get DescribeFeatureType address
op = om.getDescribeFeatureType();
dcp = op.getDCPs();
get = ((HTTP) dcp[0].getProtocol()).getGetOnlineResources();
addresses.put(DESCRIBEFEATURETYPE, get[0]);
op = om.getGetFeatureWithLock();
if ( op != null ) {
// get GetFeatureWithLock address
dcp = op.getDCPs();
po = false;
for (int i = 0; i < dcp.length; i++) {
get = ((HTTP) dcp[i].getProtocol()).getPostOnlineResources();
if (get != null && get.length > 0) {
addresses.put(GETFEATUREWITHLOCK, get[0]);
po = true;
}
}
if (!po) {
String s = "WFS: " + capabilities.getServiceIdentification().getTitle()
+ " doesn't support HTTP POST for GetFeatureWithLock requests";
LOG.logDebug( s );
throw new OGCWebServiceException(s);
}
}
op = om.getTransaction();
if ( op != null ) {
// get Transaction address
dcp = op.getDCPs();
po = false;
for (int i = 0; i < dcp.length; i++) {
get = ((HTTP) dcp[i].getProtocol()).getPostOnlineResources();
if (get != null && get.length > 0) {
addresses.put(TRANSACTION, get[0]);
po = true;
}
}
if (!po) {
String s = "WFS: " + capabilities.getServiceIdentification().getTitle()
+ " doesn't support HTTP POST for Transaction requests";
LOG.logDebug( s );
throw new OGCWebServiceException(s);
}
}
op = om.getLockFeature();
if ( op != null ) {
// get LockFeature address
dcp = op.getDCPs();
get = ((HTTP) dcp[0].getProtocol()).getGetOnlineResources();
if (get != null && get.length > 0) {
addresses.put(LOCKFEATURE, get[0]);
}
}
}
/**
*
* @return
*/
public WFSCapabilities getWFSCapabilities() {
return capabilities;
}
/**
* the method performs the handling of the passed OGCWebServiceEvent
* directly and returns the result to the calling class/method
*
* @param request
* request (WMS, WCS, WFS, WCAS, WCTS, WTS, Gazetter) to perform
*
* @throws WebServiceException
*
* @todo not implemented yet!
*/
public Object doService(OGCWebServiceRequest request) throws OGCWebServiceException {
Object response = null;
if (request instanceof GetFeature) {
response = handleGetFeature((GetFeature) request);
} else if (request instanceof DescribeFeatureType) {
response = handleDescribeFeatureType((DescribeFeatureType) request );
} else if (request instanceof WFSGetCapabilities) {
response = handleGetCapabilities((WFSGetCapabilities) request );
} else if (request instanceof LockFeature) {
response = handleLockFeature((LockFeature) request);
} else if (request instanceof Transaction) {
response = handleTransaction((Transaction) request);
}
return response;
}
/**
* performs a GetFeature request against the remote service. The method uses
* http-POST to call the remote WFS
*
* @param request
* get feature request
*/
private FeatureResult handleGetFeature(GetFeature request) throws OGCWebServiceException {
URL url = (URL) addresses.get(GETFEATURE);
StringWriter writer = new StringWriter(1000);
try {
XMLFactory.export( request ).write( writer );
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
throw new OGCWebServiceException( "could not transform GetFeature requst to its " +
"string representation" +
StringTools.stackTraceToString(e) );
}
String param = writer.getBuffer().toString();
FeatureCollection result = null;
try {
// get map from the remote service
NetWorker nw = new NetWorker( CharsetUtils.getSystemCharset(), url, param);
String contentType = nw.getContentType();
if (contentType == null || MimeTypeMapper.isKnownMimeType(contentType)) {
try {
InputStreamReader isr = new InputStreamReader(nw
.getInputStream(), CharsetUtils.getSystemCharset());
GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument ();
doc.load(isr, url.toString());
result = doc.parse();
} catch (Exception e) {
throw new OGCWebServiceException(e.toString());
}
} else {
throw new OGCWebServiceException( "RemoteWFS:handleGetFeature",
"Response of the remote WFS contains unknown content "
+ "type: " + contentType + ";request: " + param);
}
} catch (Exception e) {
LOG.logError( e.getMessage(), e );
throw new OGCWebServiceException( "RemoteWFS:handleGetFeature",
"Could not get feature from RemoteWFS: "
+ capabilities.getServiceIdentification().getTitle()
+ "; request: " + param + "; " + e.toString());
}
FeatureResult fr = new FeatureResult( request, result );
return fr;
}
/**
* Pefroms a describe feature type request against a remote WFS. The method
* uses http-GET to call the remote WFS
*
* @param request
* describe feature type request
* @param client
* receiver of the response to the request
*/
private FeatureTypeDescription handleDescribeFeatureType(DescribeFeatureType request)
throws OGCWebServiceException {
URL url = (URL) addresses.get(DESCRIBEFEATURETYPE);
String param = request.getRequestParameter();
String result = null;
try {
String us = OWSUtils.validateHTTPGetBaseURL( url.toExternalForm() ) + param;
URL ur = new URL( us );
// get map from the remote service
NetWorker nw = new NetWorker( CharsetUtils.getSystemCharset(), ur);
byte[] b = nw.getDataAsByteArr(20000);
String contentType = nw.getContentType();
if (MimeTypeMapper.isKnownMimeType(contentType)) {
// create a WFSCapabilities instance from the result
result = new String(b);
} else {
throw new OGCWebServiceException("RemoteWFS:handleDescribeFeatureType",
"Response of the remote WFS contains unknown content "
+ "type: " + contentType + ";request: " + param);
}
} catch (Exception e) {
LOG.logError( e.getMessage(), e );
throw new OGCWebServiceException( "RemoteWFS:handleDescribeFeatureType",
"Could not get map from RemoteWFS: "
+ capabilities.getServiceIdentification().getTitle()
+ "; request: " + param + "; " + e.toString());
}
FeatureTypeDescription ftd = null;
try {
XMLFragment frag = new XMLFragment( new StringReader(result), null );
ftd = new FeatureTypeDescription( frag );
} catch ( Exception e1 ) {
LOG.logError( e1.getMessage(), e1 );
throw new OGCWebServiceException( this.getClass().getName() +
"Could not create response",
StringTools.stackTraceToString( e1 ) );
}
return ftd;
}
/**
* reads the capabilities from the remote WFS by performing a
* GetCapabilities request against it. The method uses http-GET to call the
* remote WFS
*
* @param request
* capabilities request
* @param client
* receiver of the response to the request
*/
private WFSCapabilities handleGetCapabilities(WFSGetCapabilities request)
throws OGCWebServiceException {
URL url = (URL) addresses.get(GETCAPABILITIES);
String param = request.getRequestParameter();
WFSCapabilities response = null;
try {
String remoteAddress = OWSUtils.validateHTTPGetBaseURL( url.toExternalForm() );
URL ur = new URL( remoteAddress + param );
WFSCapabilitiesDocument capabilitiesDoc = new WFSCapabilitiesDocument();
capabilitiesDoc.load(ur);
response = (WFSCapabilities)capabilitiesDoc.parseCapabilities();
} catch (Exception e) {
LOG.logError( e.getMessage(), e );
throw new OGCWebServiceException( "RemoteWFS:handleGetCapabilities",
"Could not get map from RemoteWFS: "
+ capabilities.getServiceIdentification().getTitle()
+ "; request: " + param + "; " + e.toString());
}
return response;
}
/**
* @param request
*/
private Object handleLockFeature(LockFeature request) {
// FIXME
// TODO
return null;
}
/**
* @param request
*/
private Object handleTransaction(Transaction request) {
// FIXME
// TODO
return null;
}
/**
*
*/
public WFSCapabilities getCapabilities() {
return capabilities;
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: RemoteWFService.java,v $
Revision 1.30 2006/12/04 18:22:44 mschneider
Removed senseless assignments.
Revision 1.29 2006/11/07 11:09:36 mschneider
Added exceptions in case anything other than the 1.1.0 format is requested.
Revision 1.28 2006/10/17 20:31:19 poth
*** empty log message ***
Revision 1.27 2006/10/09 12:48:34 poth
bug fix - chanes required because results now extending DefaultOGCWebServiceResponse
Revision 1.26 2006/09/06 08:41:30 poth
code enhancment / removing references to deprecated class / use OWSUtil instead of mauelly creating a base URL
Revision 1.25 2006/08/14 13:16:47 mschneider
Fixed header.
Revision 1.24 2006/07/12 14:46:18 poth
comment footer added
********************************************************************** */