/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, 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
Aennchenstr. 19
53115 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.wmps;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import org.deegree.datatypes.QualifiedName;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
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.ogcwebservices.OGCWebService;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.OGCWebServiceRequest;
import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
import org.deegree.ogcwebservices.wms.operation.GetMap;
import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilities;
import org.deegree.ogcwebservices.wms.operation.WMSProtocolFactory;
import org.deegree.owscommon_new.DCP;
import org.deegree.owscommon_new.HTTP;
import org.deegree.owscommon_new.OperationsMetadata;
import com.sun.media.jai.codec.MemoryCacheSeekableStream;
/**
* An instance of the class acts as a wrapper to a remote WMS.
*
* @version $Revision: 1.17 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
*/
public class RemoteWMService implements OGCWebService {
private static ILogger LOG = LoggerFactory.getLogger( RemoteWMService.class );
protected HashMap<String, URL> addresses = null;
protected WMSCapabilities capabilities = null;
/**
* Creates a new instance of RemoteWMService
*
* @param capabilities
*/
public RemoteWMService( WMSCapabilities capabilities ) {
this.capabilities = capabilities;
this.addresses = new HashMap<String, URL>();
// get GetCapabilities operation address
List<DCP> dcps = null;
HTTP http = null;
OperationsMetadata om = capabilities.getOperationMetadata();
if ( capabilities.getVersion().equals( "1.0.0" ) ) {
dcps = om.getOperation( new QualifiedName( "Capabilities" ) ).getDCP();
for( DCP dcp : dcps ) if( dcp instanceof HTTP ) http = (HTTP) dcp;
this.addresses.put( "Capabilities", http.getLinks().get( 0 ).getLinkage().getHref() );
} else {
dcps = om.getOperation( new QualifiedName( "GetCapabilities" ) ).getDCP();
for( DCP dcp : dcps ) if( dcp instanceof HTTP ) http = (HTTP) dcp;
this.addresses.put( "GetCapabilities", http.getLinks().get( 0 ).getLinkage().getHref() );
}
// get GetMap operation address
if ( capabilities.getVersion().equals( "1.0.0" ) ) {
// hui, is this the right name? Though it is all lowercase or 'Map'?
dcps = om.getOperation( new QualifiedName( "MAP" ) ).getDCP();
for( DCP dcp : dcps ) if( dcp instanceof HTTP ) http = (HTTP) dcp;
this.addresses.put( "MAP", http.getLinks().get( 0 ).getLinkage().getHref() );
} else {
dcps = om.getOperation( new QualifiedName( "GetMap" ) ).getDCP();
for( DCP dcp : dcps ) if( dcp instanceof HTTP ) http = (HTTP) dcp;
this.addresses.put("GetMap", http.getLinks().get( 0 ).getLinkage().getHref() );
}
}
/**
* Returns the OGCCapabilities
*
* @return OGCCapabilities
*/
public OGCCapabilities getCapabilities() {
return this.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
* @return Object
* @throws OGCWebServiceException
*/
public Object doService( OGCWebServiceRequest request )
throws OGCWebServiceException {
Object object = null;
if ( request instanceof GetMap ) {
object = handleGetMap( (GetMap) request );
object = WMSProtocolFactory.createGetMapResponse( request, null, object );
}
return object;
}
/**
* performs a GetMap request against the remote service. The result contains the map decoded in
* the desired format as a byte array.
*
* @param request
* GetMap request
* @return Object
* @throws OGCWebServiceException
*/
protected Object handleGetMap( GetMap request )
throws OGCWebServiceException {
URL url = null;
if ( request.getVersion().equals( "1.0.0" ) ) {
url = this.addresses.get( "MAP" );
} else {
url = this.addresses.get( "GetMap" );
}
String param = request.getRequestParameter();
String us = url.toExternalForm();
if ( !us.endsWith( "?" ) ) {
us = us + '?';
}
us = us + param;
LOG.logDebug( "remote wms getmap", us );
if ( this.capabilities.getVersion().compareTo( "1.0.0" ) <= 0 ) {
us = StringTools.replace( us, "TRANSPARENCY", "TRANSPARENT", false );
us = StringTools.replace( us, "GetMap", "map", false );
us = StringTools.replace( us, "image/", "", false );
}
Object result = null;
try {
URL ur = new URL( us );
// get map from the remote service
NetWorker nw = new NetWorker( ur );
InputStream is = nw.getInputStream();
String contentType = nw.getContentType();
String[] tmp = StringTools.toArray( contentType, ";", true );
for ( int i = 0; i < tmp.length; i++ ) {
if ( tmp[i].indexOf( "image" ) > -1 ) {
contentType = tmp[i];
break;
}
contentType = tmp[0];
}
if ( MimeTypeMapper.isImageType( contentType )
&& MimeTypeMapper.isKnownImageType( contentType ) ) {
MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream( is );
RenderedOp rop = JAI.create( "stream", mcss );
result = rop.getAsBufferedImage();
mcss.close();
} else {
// extract remote (error) message if the response
// contains a known mime type
String res = "";
if ( MimeTypeMapper.isKnownMimeType( contentType ) ) {
res = "; remote message: ";
res += getInputStreamContent( is );
}
throw new OGCWebServiceException( "RemoteWMS:handleGetMap",
"Response of the remote " + "WMS " + "contains "
+ "wrong content type: "
+ contentType
+ ";request: " + param
+ res );
}
} catch ( Exception e ) {
throw new OGCWebServiceException(
"RemoteWMS:handleGetMap",
"Could not get map from RemoteWMS: "
+ this.capabilities.getServiceIdentification().getTitle()
+ "; " + "request: " + param
+ " " + e.toString() );
}
return result;
}
/**
* reads the capabilities from the remote WMS by performing a GetCapabilities request
* against it.
*
* @param request
* capabilities request
* @return WMSCapabilities
* @throws OGCWebServiceException
*/
protected WMSCapabilities handleGetCapabilities( WMSGetCapabilities request )
throws OGCWebServiceException {
URL url = null;
if ( request.getVersion().equals( "1.0.0" ) ) {
url = this.addresses.get( "capabilites" );
} else {
url = this.addresses.get( "GetCapabilities" );
}
String param = request.getRequestParameter();
String us = url.toExternalForm();
if ( !us.endsWith( "?" ) ) {
us = us + '?';
}
us = us + param;
WMSCapabilities result = null;
try {
URL ur = new URL( us );
// get map from the remote service
NetWorker nw = new NetWorker( ur );
byte[] b = nw.getDataAsByteArr( 20000 );
String contentType = nw.getContentType();
if ( MimeTypeMapper.isKnownMimeType( contentType ) ) {
// create a WMSCapabilitiesTEMP instance from the result
StringReader reader = new StringReader( new String( b ) );
WMSCapabilitiesDocument doc = new WMSCapabilitiesDocument();
doc.load( reader, XMLFragment.DEFAULT_URL );
result = (WMSCapabilities) doc.parseCapabilities();
} else {
throw new OGCWebServiceException(
"RemoteWMS:handleGetCapabilities",
"Response of the "
+ "remote WMS "
+ "contains "
+ "unknown content type: "
+ contentType
+ ";request: " + param );
}
} catch ( Exception e ) {
throw new OGCWebServiceException(
"RemoteWMS:handleGetCapabilities",
"Could not get map from RemoteWMS: "
+ this.capabilities.getServiceIdentification().getTitle()
+ "; request: " + param
+ "; " + e.toString() );
}
return result;
}
// /**
// * Returns the legend graphics
// *
// * @param request
// * describe layer request (WMS 1.1.1 - SLD)
// * @return Object
// * @throws OGCWebServiceException
// */
// protected Object handleGetLegendGraphic( GetLegendGraphic request )
// throws OGCWebServiceException {
//
// URL url = addresses.get( WMPSConstants.GETLEGENDGRAPHIC );
//
// if ( url == null ) {
// throw new OGCWebServiceException( "GETLEGENDGRAPHIC is not supported by "
// + "the RemoteWMS: "
// + capabilities.getServiceIdentification().getTitle() );
// }
//
// String param = request.getRequestParameter();
// String us = url.toExternalForm();
// if ( !us.endsWith( "?" ) ) {
// us = us + '?';
// }
// us = us + param;
// // FIXME
// return null;
// }
/**
*
*
* @param is
*
* @return String
*
* @throws IOException
*/
protected String getInputStreamContent( InputStream is )
throws IOException {
StringBuffer sb = new StringBuffer( 1000 );
int c = 0;
while ( ( c = is.read() ) >= 0 ) {
sb.append( (char) c );
}
is.close();
return sb.toString();
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to: $Log: RemoteWMService.java,v $
* Changes to this class. What the people have been up to: Revision 1.17 2006/11/27 09:07:52 poth
* Changes to this class. What the people have been up to: JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
* Changes to this class. What the people have been up to:
* Changes to this class. What the people have been up to: Revision 1.16 2006/10/22 20:36:05 poth
* Changes to this class. What the people have been up to: operations not supported by WMPS removed
* Changes to this class. What the people have been up to:
* Changes to this class. What the people have been up to: Revision 1.15 2006/08/23 07:10:22 schmitz
* Changes to this class. What the people have been up to: Renamed the owscommon_neu package to owscommon_new.
* Changes to this class. What the people have been up to:
* Changes to this class. What the people have been up to: Revision 1.14 2006/08/22 10:25:01 schmitz
* Changes to this class. What the people have been up to: Updated the WMS to use the new OWS common package.
* Changes to this class. What the people have been up to: Updated the rest of deegree to use the new data classes returned
* Changes to this class. What the people have been up to: by the updated WMS methods/capabilities.
* Changes to this class. What the people have been up to:
* Changes to this class. What the people have been up to: Revision 1.13 2006/08/10 07:11:35 deshmukh
* Changes to this class. What the people have been up to: WMPS has been modified to support the new configuration changes and the excess code not needed has been replaced.
* Changes to this class. What the people have been up to: Changes to
* this class. What the people have been up to: Revision 1.12 2006/08/01 13:41:48 deshmukh Changes
* to this class. What the people have been up to: The wmps configuration has been modified and
* extended. Also fixed the javadoc. Changes to this class. What the people have been up to:
* Revision 1.11 2006/07/12 14:46:16 poth comment footer added
*
**************************************************************************************************/