001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }