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