001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/wac/WACServlet.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.portal.wac; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.io.OutputStream; 041 import java.io.PrintWriter; 042 import java.net.MalformedURLException; 043 import java.net.URL; 044 import java.util.Collections; 045 import java.util.HashMap; 046 import java.util.List; 047 import java.util.Map; 048 049 import javax.servlet.ServletException; 050 import javax.servlet.http.HttpServlet; 051 import javax.servlet.http.HttpServletRequest; 052 import javax.servlet.http.HttpServletResponse; 053 054 import org.deegree.framework.log.ILogger; 055 import org.deegree.framework.log.LoggerFactory; 056 import org.deegree.framework.util.KVP2Map; 057 import org.deegree.framework.util.StringTools; 058 import org.deegree.framework.xml.XMLFragment; 059 import org.deegree.model.metadata.iso19115.Linkage; 060 import org.deegree.model.metadata.iso19115.OnlineResource; 061 import org.deegree.ogcwebservices.InvalidParameterValueException; 062 import org.deegree.ogcwebservices.wms.XMLFactory; 063 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities; 064 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument; 065 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory; 066 import org.deegree.owscommon_new.DCP; 067 import org.deegree.owscommon_new.HTTP; 068 import org.deegree.owscommon_new.Operation; 069 import org.deegree.owscommon_new.OperationsMetadata; 070 import org.w3c.dom.Document; 071 072 /** 073 * 074 * 075 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 076 * @author last edited by: $Author: mschneider $ 077 * 078 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 079 */ 080 public class WACServlet extends HttpServlet { 081 082 /** 083 * 084 */ 085 private static final long serialVersionUID = -4964542190148138040L; 086 087 private Map<String, String> users = new HashMap<String, String>(); 088 089 private Map<String, String> passwords = new HashMap<String, String>(); 090 091 private Map<String, String> sessionIDs = Collections.synchronizedMap( new HashMap<String, String>() ); 092 093 private String host = null; 094 095 private int port = 443; 096 097 private String path = null; 098 099 private String certificate = null; 100 101 private String wacURL = null; 102 103 private static final ILogger LOG = LoggerFactory.getLogger( WACServlet.class ); 104 105 @Override 106 public void init() 107 throws ServletException { 108 super.init(); 109 String user = getInitParameter( "USER" ); 110 if ( user == null ) { 111 throw new ServletException( "user must be set!" ); 112 } 113 users.put( "*", user ); 114 String password = getInitParameter( "PASSWORD" ); 115 if ( password == null ) { 116 throw new ServletException( "password must be set!" ); 117 } 118 passwords.put( "*", password ); 119 host = getInitParameter( "HOST" ); 120 if ( host == null ) { 121 throw new ServletException( "WSS host must be set!" ); 122 } 123 try { 124 port = Integer.parseInt( getInitParameter( "PORT" ) ); 125 } catch ( NumberFormatException e ) { 126 getServletContext().log( "-> using default SSL port 443" ); 127 } 128 path = getInitParameter( "PATH" ); 129 if ( path == null ) { 130 throw new ServletException( "path to web application on host must be set!" ); 131 } 132 certificate = getInitParameter( "CERTIFICATE" ); 133 if ( certificate == null ) { 134 getServletContext().log( "no certificate defined" ); 135 } 136 137 } 138 139 /** 140 * @param request 141 * @param response 142 * @throws IOException 143 */ 144 @Override 145 protected void doGet( HttpServletRequest request, HttpServletResponse response ) 146 throws IOException { 147 148 wacURL = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() 149 + request.getServletPath(); 150 151 String user = users.get( "*" ); 152 WAClient wac = new WAClient( host, path, port, certificate ); 153 if ( sessionIDs.get( user ) == null ) { 154 if ( !accessSessionID( wac, response ) ) { 155 return; 156 } 157 } 158 // get sessionID assigned to the user 159 String sessionID = sessionIDs.get( user ); 160 InputStream is = null; 161 try { 162 StringBuffer sb = new StringBuffer( 2000 ); 163 sb.append( request.getQueryString() ).append( "&sessionID=" ).append( sessionID ); 164 is = wac.performDoService( request.getQueryString(), sessionID ); 165 } catch ( Exception e ) { 166 e.printStackTrace(); 167 sendException( response, "GetSession", "could not perform DoService", StringTools.stackTraceToString( e ) ); 168 } 169 170 OutputStream os = null; 171 try { 172 os = response.getOutputStream(); 173 postProcess( request.getQueryString(), is, os ); 174 } catch ( Exception e ) { 175 sendException( response, "GetSession", "could not post process capabilities", 176 StringTools.stackTraceToString( e ) ); 177 } finally { 178 os.flush(); 179 os.close(); 180 is.close(); 181 } 182 } 183 184 /** 185 * access a sessionID from a WSS and stores it into an internal Map to use for DoService calls 186 * against a WSS 187 * 188 * @param wac 189 * @param response 190 * @return true if a valid session id could be retrieved. 191 */ 192 private boolean accessSessionID( WAClient wac, HttpServletResponse response ) { 193 String user = users.get( "*" ); 194 String password = passwords.get( "*" ); 195 try { 196 String sessionID = wac.performGetSession( user, password ); 197 sessionIDs.put( user, sessionID ); 198 } catch ( WACException e ) { 199 e.printStackTrace(); 200 sendException( response, "GetSession", "could not perform GetSession", StringTools.stackTraceToString( e ) ); 201 return false; 202 } catch ( Exception e ) { 203 e.printStackTrace(); 204 sendException( response, "GetSession", "could not evaluate GetSession result", 205 StringTools.stackTraceToString( e ) ); 206 return false; 207 } 208 return true; 209 } 210 211 private void sendException( HttpServletResponse response, String req, String message, String stacktrace ) { 212 this.getServletContext().log( message ); 213 this.getServletContext().log( stacktrace ); 214 response.setContentType( "text/xml" ); 215 if ( req == null ) 216 req = ""; 217 if ( message == null ) 218 message = ""; 219 try { 220 PrintWriter pw = response.getWriter(); 221 pw.write( "<OGCWebServiceException>" ); 222 pw.write( "<Message>" ); 223 pw.write( req ); 224 pw.write( ": failed! " ); 225 pw.write( message ); 226 pw.write( "</Message>" ); 227 pw.write( "<Locator>" ); 228 pw.write( stacktrace ); 229 pw.write( "</Locator>" ); 230 pw.write( "</OGCWebServiceException>" ); 231 pw.close(); 232 } catch ( Exception ee ) { 233 ee.printStackTrace(); 234 } 235 } 236 237 /** 238 * forces a post processing of the wss response if a GetCapabilities request has been performed 239 * by replacing contained the online resources 240 * 241 * @param request 242 * @param is 243 * @param os 244 * stream to write the result too 245 * @throws Exception 246 */ 247 private void postProcess( String request, InputStream is, OutputStream os ) 248 throws Exception { 249 Map<String, String> map = KVP2Map.toMap( request ); 250 if ( map.get( "REQUEST" ).equals( "GetCapabilities" ) ) { 251 XMLFragment xml = new XMLFragment(); 252 xml.load( is, XMLFragment.DEFAULT_URL ); 253 is.close(); 254 Document doc = xml.getRootElement().getOwnerDocument(); 255 if ( map.get( "SERVICE" ).equals( "WMS" ) ) { 256 adjustWMSCapabilities( doc, os ); 257 } else if ( map.get( "SERVICE" ).equals( "WFS" ) ) { 258 // TODO 259 } else if ( map.get( "SERVICE" ).equals( "WCS" ) ) { 260 // TODO 261 } else if ( map.get( "SERVICE" ).equals( "CSW" ) ) { 262 // TODO 263 } else if ( map.get( "SERVICE" ).equals( "SCS" ) ) { 264 // TODO 265 } 266 if ( map.get( "SERVICE" ).equals( "WFS-G" ) ) { 267 // TODO 268 } 269 if ( map.get( "SERVICE" ).equals( "WTS" ) ) { 270 // TODO 271 } 272 } else { 273 byte[] b = new byte[1024]; 274 int c = 0; 275 while ( ( c = is.read( b ) ) > 0 ) { 276 os.write( b, 0, c ); 277 } 278 os.close(); 279 is.close(); 280 } 281 } 282 283 /** 284 * adjusts the passed WMS capabilities document by replacing the contained online resources with 285 * the address of the WAC 286 * @param doc 287 * @param os 288 * @throws InvalidParameterValueException 289 */ 290 private void adjustWMSCapabilities( Document doc, OutputStream os ) 291 throws InvalidParameterValueException, IOException { 292 293 WMSCapabilities capa = null; 294 try { 295 WMSCapabilitiesDocument cdoc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getDocumentElement() ); 296 capa = (WMSCapabilities) cdoc.parseCapabilities(); 297 } catch ( Exception e ) { 298 e.printStackTrace(); 299 throw new InvalidParameterValueException( "no valid wms capabilities\n" 300 + StringTools.stackTraceToString( e ) ); 301 } 302 303 OperationsMetadata om = capa.getOperationMetadata(); 304 305 List<Operation> ops = om.getOperations(); 306 for ( Operation operation : ops ) { 307 setNewOnlineResource( operation ); 308 } 309 310 WMSCapabilitiesDocument cdoc = XMLFactory.export( capa ); 311 cdoc.write( os ); 312 } 313 314 /** 315 * sets a new online resource for the passed <tt>Operation</tt> 316 * 317 * @param op 318 */ 319 private void setNewOnlineResource( Operation op ) { 320 List<DCP> dcps = op.getDCP(); 321 if ( dcps != null ) { 322 for ( DCP dcp : dcps ) { 323 HTTP http = (HTTP) dcp; 324 try { 325 URL url = new URL( wacURL ); 326 OnlineResource link = new OnlineResource( new Linkage( url ) ); 327 List<OnlineResource> resources = http.getLinks(); 328 int size = resources.size(); 329 resources.clear(); 330 for ( int i = 0; i < size; ++i ) 331 resources.add( link ); 332 } catch ( MalformedURLException e1 ) { 333 LOG.logError( e1.getLocalizedMessage(), e1 ); 334 } 335 } 336 } 337 } 338 339 /** 340 * @param request 341 * @param response 342 * @throws ServletException 343 * @throws IOException 344 */ 345 @Override 346 protected void doPost( HttpServletRequest request, HttpServletResponse response ) 347 throws ServletException, IOException { 348 doGet( request, response ); 349 } 350 351 }