/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: 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 Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: klaus.greve@uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.portal.wac; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.KVP2Map; import org.deegree.framework.util.StringTools; import org.deegree.framework.util.TimeTools; import org.deegree.framework.xml.NamespaceContext; import org.deegree.framework.xml.XMLTools; import org.deegree.model.metadata.iso19115.Linkage; import org.deegree.model.metadata.iso19115.OnlineResource; import org.deegree.ogcbase.CommonNamespaces; import org.deegree.ogcwebservices.InvalidParameterValueException; import org.deegree.ogcwebservices.wms.XMLFactory; import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities; import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument; import org.deegree.owscommon_new.DCP; import org.deegree.owscommon_new.HTTP; import org.deegree.owscommon_new.Operation; import org.deegree.owscommon_new.OperationsMetadata; import org.w3c.dom.Document; /** * * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> * @author last edited by: $Author: schmitz $ * * @version 1.1, $Revision: 1.16 $, $Date: 2006/08/23 07:10:22 $ * * @since 1.1 */ public class WACServlet extends HttpServlet { private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); private Map users = new HashMap(); private Map passwords = new HashMap(); private Map sessionIDs = Collections.synchronizedMap( new HashMap() ); private Map expiration = new HashMap(); private String host = null; private int port = 443; private String path = null; private String certificate = null; private String wacURL = null; private static final ILogger LOG = LoggerFactory.getLogger( WACServlet.class ); public void init() throws ServletException { super.init(); String user = getInitParameter( "USER" ); if ( user == null ) { throw new ServletException( "user must be set!" ); } users.put( "*", user ); String password = getInitParameter( "PASSWORD" ); if ( password == null ) { throw new ServletException( "password must be set!" ); } passwords.put( "*", password ); host = getInitParameter( "HOST" ); if ( host == null ) { throw new ServletException( "WSS host must be set!" ); } try { port = Integer.parseInt( getInitParameter( "PORT" ) ); } catch (NumberFormatException e) { getServletContext().log( "-> using default SSL port 443" ); } path = getInitParameter( "PATH" ); if ( path == null ) { throw new ServletException( "path to web application on host must be set!" ); } certificate = getInitParameter( "CERTIFICATE" ); if ( certificate == null ) { getServletContext().log( "no certificate defined" ); } } /** * @param request * @param response * @throws ServletException * @throws IOException */ protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { wacURL = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + request.getServletPath(); String user = (String) users.get( "*" ); WAClient wac = new WAClient( host, path, port, certificate ); if ( sessionIDs.get( user ) == null ) { if ( !accessSessionID( wac, response ) ) { return; } } // get sessionID assigned to the user String sessionID = (String) sessionIDs.get( user ); String exp = (String) expiration.get( sessionID ); long tst1 = TimeTools.createCalendar( exp ).getTimeInMillis(); long tst2 = System.currentTimeMillis(); // check if sessionID is expired // if so, get a new one if ( tst1 > tst2 ) { if ( !accessSessionID( wac, response ) ) { return; } } InputStream is = null; try { StringBuffer sb = new StringBuffer( 2000 ); sb.append( request.getQueryString() ).append( "&sessionID=" ).append( sessionID ); is = wac.performDoService( request.getQueryString(), sessionID ); } catch (Exception e) { e.printStackTrace(); sendException( response, "GetSession", "could not perform DoService", StringTools .stackTraceToString( e ) ); } OutputStream os = null; try { os = response.getOutputStream(); postProcess( request.getQueryString(), is, os ); } catch (Exception e) { sendException( response, "GetSession", "could not post process capabilities", StringTools.stackTraceToString( e ) ); } finally { os.flush(); os.close(); is.close(); } } /** * access a sessionID from a WSS and stores it into an internal Map to use for DoService calls * against a WSS * * @param wac * @param response * @return */ private boolean accessSessionID( WAClient wac, HttpServletResponse response ) { String user = (String) users.get( "*" ); String password = (String) passwords.get( "*" ); try { Document doc = wac.performGetSession( user, password ); String sessionID = XMLTools.getRequiredNodeAsString( doc, "/wsssession:Session/@id", nsContext ); String exp = XMLTools.getRequiredNodeAsString( doc, "/wsssession:Session/@expirationDate", nsContext ); sessionIDs.put( user, sessionID ); expiration.put( sessionID, exp ); } catch (WACException e) { e.printStackTrace(); sendException( response, "GetSession", "could not perform GetSession", StringTools .stackTraceToString( e ) ); return false; } catch (Exception e) { e.printStackTrace(); sendException( response, "GetSession", "could not evaluate GetSession result", StringTools.stackTraceToString( e ) ); return false; } return true; } private void sendException( HttpServletResponse response, String req, String message, String stacktrace ) { this.getServletContext().log( message ); this.getServletContext().log( stacktrace ); response.setContentType( "text/xml" ); if ( req == null ) req = ""; if ( message == null ) message = ""; try { PrintWriter pw = response.getWriter(); pw.write( "<OGCWebServiceException>" ); pw.write( "<Message>" ); pw.write( req ); pw.write( ": failed! " ); pw.write( message ); pw.write( "</Message>" ); pw.write( "<Locator>" ); pw.write( stacktrace ); pw.write( "</Locator>" ); pw.write( "</OGCWebServiceException>" ); pw.close(); } catch (Exception ee) { ee.printStackTrace(); } } /** * forces a post processing of the wss response if a GetCapabilities request has been performed * by replacing contained the online resources * * @param request * @param is * @param os * stream to write the result too * @return * @throws Exception */ private void postProcess( String request, InputStream is, OutputStream os ) throws Exception { Map map = KVP2Map.toMap( request ); if ( map.get( "REQUEST" ).equals( "GetCapabilities" ) ) { Document doc = XMLTools.parse( is ); if ( map.get( "SERVICE" ).equals( "WMS" ) ) { adjustWMSCapabilities( doc, os ); } else if ( map.get( "SERVICE" ).equals( "WFS" ) ) { // TODO } else if ( map.get( "SERVICE" ).equals( "WCS" ) ) { // TODO } else if ( map.get( "SERVICE" ).equals( "CSW" ) ) { // TODO } else if ( map.get( "SERVICE" ).equals( "SCS" ) ) { // TODO } if ( map.get( "SERVICE" ).equals( "WFS-G" ) ) { // TODO } if ( map.get( "SERVICE" ).equals( "WTS" ) ) { // TODO } } } /** * adjusts the passed WMS capabilities document by replacing the contained online resources with * the address of the WAC * * @param xml * @param user * @throws InvalidParameterValueException */ private void adjustWMSCapabilities( Document doc, OutputStream os ) throws InvalidParameterValueException, IOException{ WMSCapabilities capa = null; try { WMSCapabilitiesDocument cdoc = new WMSCapabilitiesDocument(); cdoc.setRootElement( doc.getDocumentElement() ); capa = (WMSCapabilities) cdoc.parseCapabilities(); } catch (Exception e) { e.printStackTrace(); throw new InvalidParameterValueException( "no valid wms capabilities\n" + StringTools.stackTraceToString( e ) ); } OperationsMetadata om = capa.getOperationMetadata(); List<Operation> ops = om.getOperations(); for ( Operation operation : ops ) { setNewOnlineResource( operation ); } WMSCapabilitiesDocument cdoc = XMLFactory.export( capa ); cdoc.write( os ); } /** * sets a new online resource for the passed <tt>Operation</tt> * * @param op */ private void setNewOnlineResource( Operation op ) { List<DCP> dcps = op.getDCP(); if ( dcps != null ) { for( DCP dcp : dcps ) { HTTP http = (HTTP) dcp; try { URL url = new URL( wacURL ); OnlineResource link = new OnlineResource( new Linkage( url ) ); List<OnlineResource> resources = http.getLinks(); int size = resources.size(); resources.clear(); for( int i = 0; i < size; ++i ) resources.add( link ); } catch (MalformedURLException e1) { LOG.logError( e1.getLocalizedMessage(), e1 ); } } } } /** * @param request * @param response * @throws ServletException * @throws IOException */ protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: WACServlet.java,v $ Revision 1.16 2006/08/23 07:10:22 schmitz Renamed the owscommon_neu package to owscommon_new. Revision 1.15 2006/08/22 10:25:01 schmitz Updated the WMS to use the new OWS common package. Updated the rest of deegree to use the new data classes returned by the updated WMS methods/capabilities. Revision 1.14 2006/08/08 15:45:35 poth never thrown exception removed Revision 1.13 2006/07/12 14:46:18 poth comment footer added ********************************************************************** */