001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/csw/control/DisplayMapListener.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 037 package org.deegree.portal.standard.csw.control; 038 039 import java.io.File; 040 import java.io.FileOutputStream; 041 import java.io.IOException; 042 import java.io.InputStreamReader; 043 import java.io.Reader; 044 import java.net.MalformedURLException; 045 import java.net.URL; 046 import java.util.ArrayList; 047 import java.util.HashMap; 048 import java.util.Iterator; 049 import java.util.List; 050 051 import javax.servlet.http.HttpServletRequest; 052 import javax.servlet.http.HttpSession; 053 import javax.xml.transform.TransformerFactoryConfigurationError; 054 055 import org.deegree.enterprise.control.FormEvent; 056 import org.deegree.enterprise.control.RPCParameter; 057 import org.deegree.enterprise.control.RPCStruct; 058 import org.deegree.enterprise.control.RPCWebEvent; 059 import org.deegree.framework.log.ILogger; 060 import org.deegree.framework.log.LoggerFactory; 061 import org.deegree.framework.util.CharsetUtils; 062 import org.deegree.framework.util.NetWorker; 063 import org.deegree.framework.xml.XMLFragment; 064 import org.deegree.framework.xml.XMLParsingException; 065 import org.deegree.framework.xml.XMLTools; 066 import org.deegree.i18n.Messages; 067 import org.deegree.model.crs.CRSFactory; 068 import org.deegree.model.crs.CoordinateSystem; 069 import org.deegree.model.crs.UnknownCRSException; 070 import org.deegree.model.spatialschema.Envelope; 071 import org.deegree.model.spatialschema.GeometryFactory; 072 import org.deegree.model.spatialschema.Point; 073 import org.deegree.ogcbase.BaseURL; 074 import org.deegree.ogcbase.ImageURL; 075 import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException; 076 import org.deegree.ogcwebservices.wms.capabilities.Layer; 077 import org.deegree.ogcwebservices.wms.capabilities.LegendURL; 078 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities; 079 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument; 080 import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory; 081 import org.deegree.portal.PortalException; 082 import org.deegree.portal.context.ContextException; 083 import org.deegree.portal.context.Format; 084 import org.deegree.portal.context.FormatList; 085 import org.deegree.portal.context.General; 086 import org.deegree.portal.context.GeneralExtension; 087 import org.deegree.portal.context.LayerList; 088 import org.deegree.portal.context.Server; 089 import org.deegree.portal.context.Style; 090 import org.deegree.portal.context.StyleList; 091 import org.deegree.portal.context.ViewContext; 092 import org.deegree.portal.context.WebMapContextFactory; 093 import org.deegree.portal.context.XMLFactory; 094 import org.deegree.portal.standard.csw.CatalogClientException; 095 import org.deegree.portal.standard.csw.configuration.CSWClientConfiguration; 096 import org.deegree.portal.standard.csw.model.DataSessionRecord; 097 import org.deegree.portal.standard.csw.model.ServiceSessionRecord; 098 import org.deegree.portal.standard.csw.model.ShoppingCart; 099 import org.w3c.dom.Document; 100 import org.xml.sax.SAXException; 101 102 /** 103 * A <code>${type_name}</code> class.<br/> 104 * 105 * This listener is called when one or more items of the shopping cart shall be displayed in a map. For all chosen items 106 * of the cart the wms layers are collected and a new mapcontext containing these layers is created/saved in the users 107 * folder (user must be logged in). Then, the contextname is passed to the follow up page to be loaded in the portal. 108 * 109 * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a> 110 * @author last edited by: $Author: mschneider $ 111 * 112 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 113 * 114 * @deprecated Shopping cart will not be supported at the moment. update: new changes in deegree1_fork will not be 115 * carried here, since this class is still not used. Remove when this status changes 116 */ 117 @Deprecated 118 public class DisplayMapListener extends AddToShoppingCartListener { 119 // extends AddToShoppingCartListener --> SimpleSearchListener --> AbstractListener. 120 121 private static final ILogger LOG = LoggerFactory.getLogger( DisplayMapListener.class ); 122 123 private String userDir = "WEB-INF/conf/igeoportal/users/"; 124 125 /* 126 * (non-Javadoc) 127 * 128 * @see org.deegree.enterprise.control.WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent) 129 */ 130 @Override 131 public void actionPerformed( FormEvent event ) { 132 133 RPCWebEvent rpcEvent = (RPCWebEvent) event; 134 HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true ); 135 ShoppingCart cart = (ShoppingCart) session.getAttribute( Constants.SESSION_SHOPPINGCART ); 136 config = (CSWClientConfiguration) session.getAttribute( Constants.CSW_CLIENT_CONFIGURATION ); 137 138 try { 139 validateRequest( rpcEvent ); 140 } catch ( Exception e ) { 141 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_RPC_EVENT", e.getMessage() ) ); 142 LOG.logError( e.getMessage(), e ); 143 return; 144 } 145 146 List rpcDataSessionRecords = null; 147 148 try { 149 rpcDataSessionRecords = getDataSessionRecordsFromList( cart.getContents(), rpcEvent ); 150 } catch ( Exception e ) { 151 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_RPC_EVENT", e.getMessage() ) ); 152 LOG.logError( e.getMessage(), e ); 153 return; 154 } 155 156 try { 157 validateWMSAbility( rpcDataSessionRecords ); 158 } catch ( Exception e ) { 159 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_NOT_WMSABLE", e.getMessage() ) ); 160 LOG.logError( e.getMessage(), e ); 161 return; 162 } 163 164 // GetCapabilities block 165 166 // addressTitlesMap(k=address, v=titleList) 167 HashMap wmsAddressTitlesMap = createWMSAddressToTitlesMapping( rpcDataSessionRecords ); 168 169 // addressRequestMap(k=address, v=request) 170 HashMap wmsAddressRequestMap = createCapabilitiesRequests( wmsAddressTitlesMap ); 171 172 // addressCapabilitiesMap(k=address, v=WMSCapabilities) 173 HashMap wmsAddressCapabilityMap = null; 174 try { 175 wmsAddressCapabilityMap = createAddressToWMSCapabilitiesMapping( wmsAddressRequestMap ); 176 } catch ( Exception e ) { 177 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_CREATE_WMSCAPS", e.getMessage() ) ); 178 LOG.logError( e.getMessage(), e ); 179 return; 180 } 181 182 // HashMap titleCSWAddressMap = createTitleToCswAddressMap( rpcDataSessionRecords ); 183 // HashMap titleIdentifierMap = createTitleToIdentiferMap( rpcDataSessionRecords ); 184 185 ViewContext vc = null; 186 try { 187 vc = setContextLayers( wmsAddressTitlesMap, wmsAddressCapabilityMap, rpcDataSessionRecords ); 188 } catch ( Exception e ) { 189 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_CREATE_CNTXT_LAYERS", e.getMessage() ) ); 190 LOG.logError( e.getMessage(), e ); 191 return; 192 } 193 194 // identify user block 195 196 String contextName = "newContext"; 197 try { 198 contextName = extractContextName( rpcEvent ); 199 } catch ( Exception e ) { 200 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", "CONTEXT_NAME" ) ); 201 LOG.logError( e.getMessage(), e ); 202 return; 203 } 204 205 String sessionId; 206 try { 207 sessionId = extractSessionId( rpcEvent ); 208 } catch ( Exception e ) { 209 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", "SESSION_ID" ) ); 210 LOG.logError( e.getMessage(), e ); 211 return; 212 } 213 214 String userName = null; 215 try { 216 userName = getUserNameForId( sessionId ); 217 } catch ( Exception e ) { 218 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_DETERMIN_USERNAME", e.getMessage() ) ); 219 LOG.logError( e.getMessage(), e ); 220 return; 221 } 222 223 // create WebMapContext Document block 224 225 try { 226 vc.getGeneral().setTitle( contextName ); 227 } catch ( Exception e ) { 228 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_SET_CNTXT_TITLE", e.getMessage() ) ); 229 LOG.logError( e.getMessage(), e ); 230 return; 231 } 232 233 Envelope bbox = null; 234 String msg = null; 235 try { 236 msg = Messages.getMessage( "IGEO_STD_CSW_ERROR_DETERMIN_BBOX" ); 237 bbox = determinCombiningBBox( rpcDataSessionRecords ); 238 if ( bbox != null ) { 239 msg = Messages.getMessage( "IGEO_STD_CSW_ERROR_CHANGE_BBOX" ); 240 changeBBox( vc, bbox ); 241 } 242 } catch ( Exception e ) { 243 gotoErrorPage( msg + e.getMessage() ); 244 LOG.logError( e.getMessage(), e ); 245 return; 246 } 247 248 try { 249 storeContext( userName, contextName, vc ); 250 } catch ( Exception e ) { 251 gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_STORE_CNTXT", e.getMessage() ) ); 252 LOG.logError( e.getMessage(), e ); 253 return; 254 } 255 256 // write contextname to request 257 StringBuffer path2Dir = new StringBuffer( "users/" ); 258 path2Dir.append( userName ).append( "/" ).append( contextName ).append( ".xml" ); 259 this.getRequest().setAttribute( "CONTEXTNAME", path2Dir.toString() ); 260 261 return; 262 } 263 264 /* 265 * (non-Javadoc) 266 * 267 * @see org.deegree.portal.standard.csw.control.SimpleSearchListener#validateRequest(org.deegree.enterprise.control.RPCWebEvent) 268 */ 269 @Override 270 protected void validateRequest( RPCWebEvent rpcEvent ) 271 throws CatalogClientException { 272 273 try { 274 extractSessionId( rpcEvent ); 275 } catch ( CatalogClientException e ) { 276 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", "SESSION_ID" ) ); 277 } 278 String contextName = null; 279 try { 280 contextName = extractContextName( rpcEvent ); 281 } catch ( CatalogClientException e ) { 282 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", "CONTEXT_NAME" ) ); 283 } 284 if ( contextName == null || "null".equals( contextName ) ) { 285 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_CNTXT_NAME_IS_NULL" ) ); 286 } 287 288 RPCParameter[] params = extractRPCParameters( rpcEvent ); 289 for ( int i = 1; i < params.length; i++ ) { 290 291 RPCStruct struct = extractRPCStruct( rpcEvent, 0 ); 292 struct = extractRPCStruct( rpcEvent, i ); 293 Object o = extractRPCMember( struct, Constants.RPC_IDENTIFIER ); 294 if ( o == null ) { 295 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", 296 Constants.RPC_IDENTIFIER ) ); 297 } 298 o = extractRPCMember( struct, RPC_CATALOG ); 299 if ( o == null ) { 300 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", RPC_CATALOG ) ); 301 } 302 o = extractRPCMember( struct, RPC_TITLE ); 303 if ( o == null ) { 304 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAM", RPC_TITLE ) ); 305 } 306 307 RPCStruct bboxStruct = null; 308 if ( struct.getMember( Constants.RPC_BBOX ) != null ) { 309 bboxStruct = (RPCStruct) struct.getMember( Constants.RPC_BBOX ).getValue(); 310 } 311 if ( bboxStruct != null ) { 312 Double member = (Double) extractRPCMember( bboxStruct, Constants.RPC_BBOXMINX ); 313 if ( member == null ) { 314 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_INVALID_BBOX_VALUE", 315 Constants.RPC_BBOXMINX ) ); 316 } 317 member = (Double) extractRPCMember( bboxStruct, Constants.RPC_BBOXMINY ); 318 if ( member == null ) { 319 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_INVALID_BBOX_VALUE", 320 Constants.RPC_BBOXMINY ) ); 321 } 322 member = (Double) extractRPCMember( bboxStruct, Constants.RPC_BBOXMAXX ); 323 if ( member == null ) { 324 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_INVALID_BBOX_VALUE", 325 Constants.RPC_BBOXMAXX ) ); 326 } 327 member = (Double) extractRPCMember( bboxStruct, Constants.RPC_BBOXMAXY ); 328 if ( member == null ) { 329 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_INVALID_BBOX_VALUE", 330 Constants.RPC_BBOXMAXY ) ); 331 } 332 } 333 } 334 335 return; 336 } 337 338 /** 339 * @param contents 340 * The List of DataSessionRecords to get DataSessionRecords from. 341 * @param rpcEvent 342 * The RpcWebEvent contains the parameters defining the DataSessionRecords to get from the passed List. 343 * @return Returns a sublist of the passed contents, where each of the contained DataSessionRecords is defined by 344 * the parameters of the passed rpcEvent OR null, if no matches were found in the passed List. 345 * @throws CatalogClientException 346 * @throws IllegalArgumentException, 347 * if if at least one record defined by the passed rpcEvent is not part of the passed List. 348 */ 349 private List getDataSessionRecordsFromList( List contents, RPCWebEvent rpcEvent ) 350 throws CatalogClientException { 351 352 RPCParameter[] params = extractRPCParameters( rpcEvent ); 353 List<DataSessionRecord> dsrList = new ArrayList<DataSessionRecord>( params.length ); 354 boolean matches = false; 355 356 for ( int i = 1; i < params.length; i++ ) { 357 RPCStruct struct = extractRPCStruct( rpcEvent, i ); 358 String id = (String) struct.getMember( Constants.RPC_IDENTIFIER ).getValue(); 359 String catalog = (String) struct.getMember( RPC_CATALOG ).getValue(); 360 String title = (String) struct.getMember( RPC_TITLE ).getValue(); 361 362 DataSessionRecord dsr = getDataSessionRecordFromList( contents, id, catalog, title ); 363 if ( dsr == null ) { 364 throw new IllegalArgumentException( Messages.getMessage( "IGEO_STD_CSW_ILLEGAL_ARGS", id ) ); 365 } 366 dsrList.add( dsr ); 367 matches = true; 368 } 369 370 if ( matches ) { 371 return dsrList; 372 } 373 return null; 374 } 375 376 /** 377 * Checks, if each DataSessionRecord in the passed List contains at least one "OGC:WMS" serviceType. 378 * 379 * @param dataSessionRecords 380 * List of DataSessionRecords in the ShoppingCart. 381 * @throws CatalogClientException, 382 * if at least one record in the passed List has no WMS ability. 383 */ 384 private void validateWMSAbility( List dataSessionRecords ) 385 throws CatalogClientException { 386 387 for ( int i = 0; i < dataSessionRecords.size(); i++ ) { 388 boolean wmsAble = false; 389 DataSessionRecord dsr = (DataSessionRecord) dataSessionRecords.get( i ); 390 for ( int j = 0; j < dsr.getServices().length; j++ ) { 391 if ( "OGC:WMS".equals( dsr.getServices()[j].getServiceType() ) ) { 392 wmsAble = true; 393 break; 394 } 395 } 396 if ( !wmsAble ) { 397 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_NO_WMSABLE_ID", 398 dsr.getIdentifier() ) ); 399 } 400 } 401 402 return; 403 } 404 405 /** 406 * Creates a HashMap with the WebMapService address as key and a List of titles of the resources as value. Both 407 * titles and addresses are taken from the passed List of DataSessionRecords. For each DataSessionRecord only the 408 * first WMS address is used. 409 * 410 * @param dataSessionRecords 411 * @return Returns a HashMap containing the wmsAddress (as key) and the title (as value). 412 */ 413 private HashMap<String, List<String>> createWMSAddressToTitlesMapping( List dataSessionRecords ) { 414 415 HashMap<String, List<String>> wmsAddressToTitlesMap = new HashMap<String, List<String>>( 416 dataSessionRecords.size() ); 417 418 for ( int i = 0; i < dataSessionRecords.size(); i++ ) { 419 String title = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getTitle(); 420 ServiceSessionRecord[] ssrs = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getServices(); 421 for ( int j = 0; j < ssrs.length; j++ ) { 422 if ( "OGC:WMS".equals( ssrs[j].getServiceType() ) ) { 423 String addr = ssrs[j].getServiceAddress(); 424 425 // since a WMS address might be used by more than one DataSessionRecord, 426 // a List of titles for one address is needed. 427 ArrayList<String> titleList = null; 428 if ( wmsAddressToTitlesMap.get( addr ) != null ) { 429 titleList = (ArrayList<String>) wmsAddressToTitlesMap.get( addr ); 430 if ( !titleList.contains( title ) ) { 431 titleList.add( title ); 432 } 433 } else { 434 titleList = new ArrayList<String>( 10 ); 435 titleList.add( title ); 436 } 437 wmsAddressToTitlesMap.put( addr, titleList ); 438 break; // only use the first WMS address for each DataSessionRecord. 439 } 440 } 441 } 442 443 return wmsAddressToTitlesMap; 444 } 445 446 /** 447 * @param addressTitlesMap 448 * Map from which the WMS addresses are taken. 449 * @return Returns a HashMap containing the WMS address as key and the GetCapabilities request as value. 450 */ 451 private HashMap<String, String> createCapabilitiesRequests( HashMap addressTitlesMap ) { 452 453 HashMap<String, String> addressRequestMap = new HashMap<String, String>( addressTitlesMap.size() ); 454 455 for ( Iterator it = addressTitlesMap.keySet().iterator(); it.hasNext(); ) { 456 String address = (String) it.next(); 457 String request = null; 458 if ( address.endsWith( "?" ) ) { 459 request = address + "request=GetCapabilities&service=WMS"; 460 } else { 461 request = address + "?request=GetCapabilities&service=WMS"; 462 } 463 addressRequestMap.put( address, request ); 464 } 465 466 return addressRequestMap; 467 } 468 469 /** 470 * Creates a HashMap with the WebMapService address as key and a WMSCapabilities object as value. 471 * 472 * @param addressRequestMap 473 * The Map containing the address as key for the Map to be returned, and the request as String, with 474 * which to create the Capability object. 475 * @return Returns a HashMap containing the WMS address as key and a WMSCapabilities object as value. 476 * @throws MalformedURLException 477 * @throws SAXException 478 * @throws IOException 479 * @throws MalformedURLException 480 * @throws InvalidCapabilitiesException 481 * @throws XMLParsingException 482 */ 483 private HashMap<String, WMSCapabilities> createAddressToWMSCapabilitiesMapping( HashMap addressRequestMap ) 484 throws MalformedURLException, IOException, SAXException, InvalidCapabilitiesException, 485 XMLParsingException { 486 487 HashMap<String, WMSCapabilities> addressCapabilitiesMap = new HashMap<String, WMSCapabilities>( 488 addressRequestMap.size() ); 489 490 for ( Iterator it = addressRequestMap.keySet().iterator(); it.hasNext(); ) { 491 String address = (String) it.next(); 492 String request = (String) addressRequestMap.get( address ); 493 494 WMSCapabilitiesDocument capsDoc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( new URL( 495 request ) ); 496 WMSCapabilities capabilities = (WMSCapabilities) capsDoc.parseCapabilities(); 497 498 addressCapabilitiesMap.put( address, capabilities ); 499 500 } 501 502 return addressCapabilitiesMap; 503 } 504 505 /** 506 * Creates a new ViewContext and sets the context Layers from the passed WMSCapabilities objects that match the 507 * corresponding titles of the passed addressTitlesMap. 508 * 509 * @param wmsAddressTitlesMap 510 * The Map contains the titles for which to search the matching layers. 511 * @param wmsAddressCapabilitiesMap 512 * The Map contains the WMSCapabilities for each address. 513 * @param dataSessionRecords 514 * The List contains the DataSessionRecords. 515 * @return Returns a new ViewContext with the ContextLayers set. 516 * @throws ContextException 517 * @throws SAXException 518 * @throws IOException 519 * @throws XMLParsingException 520 * @throws UnknownCRSException 521 */ 522 private ViewContext setContextLayers( HashMap wmsAddressTitlesMap, HashMap wmsAddressCapabilitiesMap, 523 List dataSessionRecords ) 524 throws ContextException, IOException, SAXException, XMLParsingException, 525 UnknownCRSException { 526 527 List<org.deegree.portal.context.Layer> contextLayerList = new ArrayList<org.deegree.portal.context.Layer>( 10 ); 528 529 File file = new File( getHomePath() + config.getMapContextTemplatePath() ); 530 ViewContext vc = WebMapContextFactory.createViewContext( file.toURL(), null, null ); 531 Point[] env = vc.getGeneral().getBoundingBox(); 532 String[] srs = new String[] { env[0].getCoordinateSystem().getIdentifier() }; 533 534 Format[] formats = new Format[1]; 535 formats[0] = new Format( "image/jpeg", true ); 536 FormatList formatList = new FormatList( formats ); 537 538 for ( Iterator it = wmsAddressTitlesMap.keySet().iterator(); it.hasNext(); ) { 539 String address = (String) it.next(); 540 List titles = (List) wmsAddressTitlesMap.get( address ); 541 542 for ( int i = 0; i < titles.size(); i++ ) { 543 String title = (String) titles.get( i ); 544 545 WMSCapabilities capabilities = (WMSCapabilities) wmsAddressCapabilitiesMap.get( address ); 546 Layer layer = getLayer( capabilities, title ); 547 548 BaseURL metadataURL = createMetadataURL( dataSessionRecords, title ); 549 550 ImageURL imageURL = getLegendURL( address, capabilities, layer ); 551 Style[] styles = new Style[1]; 552 styles[0] = new Style( "default", "default", "", imageURL, true ); 553 StyleList styleList = new StyleList( styles ); 554 555 Server server = new Server( capabilities.getServiceIdentification().getTitle(), 556 capabilities.getVersion(), "OGC:WMS", new URL( address ), capabilities ); 557 558 org.deegree.portal.context.Layer contextLayer = new org.deegree.portal.context.Layer( 559 server, 560 layer.getName(), 561 layer.getTitle(), 562 layer.getAbstract(), 563 srs, 564 null, 565 metadataURL, 566 formatList, 567 styleList, 568 layer.isQueryable(), 569 false, null ); 570 contextLayerList.add( contextLayer ); 571 } 572 } 573 574 org.deegree.portal.context.Layer[] contextLayers = new org.deegree.portal.context.Layer[contextLayerList.size()]; 575 contextLayers = contextLayerList.toArray( contextLayers ); 576 577 vc.setLayerList( new LayerList( contextLayers ) ); 578 579 return vc; 580 } 581 582 /** 583 * Creates a MetadataURL for a layer of the passed title. 584 * 585 * @param dataSessionRecords 586 * The List contains information necessary for creating the URL. 587 * @param title 588 * The layer's title. 589 * @return Returns the MetadataURL for the passed title. 590 * @throws MalformedURLException 591 */ 592 private BaseURL createMetadataURL( List dataSessionRecords, String title ) 593 throws MalformedURLException { 594 595 String catalogAddress = getCatalogAddressToTitle( dataSessionRecords, title ); 596 String identifier = getIdentifierToTitel( dataSessionRecords, title ); 597 598 StringBuffer sb = new StringBuffer( catalogAddress ); 599 if ( sb.lastIndexOf( "?" ) != sb.length() - 1 ) { 600 sb.append( "?" ); 601 } 602 sb.append( "request=GetRecordById&version=2.0.0&elementsetname=full&id=" ); 603 sb.append( identifier ); 604 605 URL onlineResource = new URL( sb.toString() ); 606 String format = "text/xml"; 607 608 BaseURL metadataURL = new BaseURL( format, onlineResource ); 609 610 return metadataURL; 611 } 612 613 /** 614 * Gets the catalog address from the configuration file for the catalog that is part of the same DataSessionRecord 615 * in the passed list as the passed title. 616 * 617 * @param dataSessionRecords 618 * List of DataSessionRecords 619 * @param title 620 * @return Returns the catalog address for the passed title. 621 */ 622 private String getCatalogAddressToTitle( List dataSessionRecords, String title ) { 623 String catalogAddress = null; 624 String catalogName; 625 for ( int i = 0; i < dataSessionRecords.size(); i++ ) { 626 String dsrTitle = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getTitle(); 627 if ( title.equals( dsrTitle ) ) { 628 catalogName = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getCatalogName(); 629 catalogAddress = config.getCatalogServerAddress( catalogName ); 630 break; 631 } 632 } 633 return catalogAddress; 634 } 635 636 /** 637 * Gets the identifier that is part of the same DataSessionRecord in the passed list as the passed title. 638 * 639 * @param dataSessionRecords 640 * List of DataSessionRecords 641 * @param title 642 * @return Returns the catalog address for the passed title. 643 */ 644 private String getIdentifierToTitel( List dataSessionRecords, String title ) { 645 String identifier = null; 646 for ( int i = 0; i < dataSessionRecords.size(); i++ ) { 647 String dsrTitle = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getTitle(); 648 if ( title.equals( dsrTitle ) ) { 649 identifier = ( (DataSessionRecord) dataSessionRecords.get( i ) ).getIdentifier(); 650 break; 651 } 652 } 653 return identifier; 654 } 655 656 /** 657 * @param address 658 * @param capabilities 659 * @param layer 660 * @return Returns the getLegendGraphic request url. 661 * @throws MalformedURLException 662 */ 663 private ImageURL getLegendURL( String address, WMSCapabilities capabilities, Layer layer ) 664 throws MalformedURLException { 665 666 org.deegree.ogcwebservices.wms.capabilities.Style style = layer.getStyleResource( "default:" + layer.getName() ); 667 if ( style == null ) { 668 style = layer.getStyleResource( "default" ); 669 } 670 671 ImageURL imageURL = null; 672 if ( style != null && style.getLegendURL() != null && style.getLegendURL().length > 0 ) { 673 LegendURL lu = style.getLegendURL()[0]; 674 imageURL = new ImageURL( lu.getWidth(), lu.getHeight(), lu.getFormat(), lu.getOnlineResource() ); 675 } else { 676 StringBuffer sb = new StringBuffer( 5000 ); 677 sb.append( address ).append( "?VERSION=" ).append( capabilities.getVersion() ); 678 sb.append( "&STYLE=&REQUEST=GetLegendGraphic&FORMAT=image/jpeg&WIDTH=50&HEIGHT=50" ); 679 sb.append( "&EXCEPTIONS=application/vnd.ogc.se_inimage" ); 680 sb.append( "&LAYER=" ).append( layer.getName() ); 681 imageURL = new ImageURL( 50, 50, "image/jpeg", new URL( sb.toString() ) ); 682 } 683 684 return imageURL; 685 } 686 687 /** 688 * Returns the Layer identified by the submitted name. If no Layer matches the title <tt>null</tt> will be 689 * returned. 690 * 691 * @param capabilities 692 * @param title 693 * The title of the requested layer. 694 * @return Returns a layer object or <tt>null</tt> 695 */ 696 private Layer getLayer( WMSCapabilities capabilities, String title ) { 697 Layer layer = capabilities.getLayer(); 698 Layer lay = null; 699 700 if ( layer.getTitle() != null && title.equals( layer.getTitle() ) ) { 701 lay = layer; 702 } else { 703 lay = getLayer( title, layer.getLayer() ); 704 } 705 return lay; 706 } 707 708 /** 709 * Recursion over all layers to find the layer that matches the submitted title. If no layer can be found that 710 * fullfills the condition <tt>null</tt> will be returned. 711 * 712 * @param title 713 * The title of the layer to be found 714 * @param layers 715 * An array of layers to be searched. 716 * @return Returns a layer object or <tt>null</tt> 717 */ 718 private Layer getLayer( String title, Layer[] layers ) { 719 Layer lay = null; 720 721 if ( layers != null ) { 722 for ( int i = 0; i < layers.length; i++ ) { 723 // TODO 724 // remove break statements 725 if ( layers[i].getTitle() != null && title.equals( layers[i].getTitle() ) ) { 726 lay = layers[i]; 727 break; 728 } 729 lay = getLayer( title, layers[i].getLayer() ); 730 if ( lay != null ) 731 break; 732 } 733 } 734 return lay; 735 } 736 737 /** 738 * Extracts the context name from the RPCStruct of the first parameter in the passed RPCWebEvent. 739 * 740 * @param rpcEvent 741 * @return Returns the context (file) name from the rpcEvent. 742 * @throws CatalogClientException 743 */ 744 private String extractContextName( RPCWebEvent rpcEvent ) 745 throws CatalogClientException { 746 RPCStruct struct = extractRPCStruct( rpcEvent, 0 ); 747 return (String) extractRPCMember( struct, "CONTEXT_NAME" ); 748 } 749 750 /** 751 * Extracts the sessionId from the RPCStruct of the first parameter in the passed RPCWebEvent. 752 * 753 * @param rpcEvent 754 * @return Returns the sessionId from the rpcEvent. 755 * @throws CatalogClientException 756 */ 757 private String extractSessionId( RPCWebEvent rpcEvent ) 758 throws CatalogClientException { 759 RPCStruct struct = extractRPCStruct( rpcEvent, 0 ); 760 return (String) extractRPCMember( struct, "SESSION_ID" ); 761 } 762 763 /** 764 * Gets the user name assigned to the passed session ID from an authentication service. 765 * 766 * If the session ID equals "null", then the default user name is returned. If no user is assigned to the session ID 767 * a CatalogClientException will be returned. If the session is closed or expired an exception will be thrown. 768 * 769 * @param sessionId 770 * @return Returns the user name for the passed session id. 771 * @throws IOException 772 * @throws SAXException 773 * @throws CatalogClientException 774 * @throws XMLParsingException 775 */ 776 private String getUserNameForId( String sessionId ) 777 throws IOException, SAXException, CatalogClientException, XMLParsingException { 778 779 if ( "null".equals( sessionId ) ) { 780 LOG.logDebug( "sessionId is 'null' => user is 'default'\n" ); 781 return "default"; 782 } 783 784 HttpSession session = ( (HttpServletRequest) getRequest() ).getSession( true ); 785 ViewContext vc = (ViewContext) session.getAttribute( Constants.CURRENTMAPCONTEXT ); 786 GeneralExtension ge = vc.getGeneral().getExtension(); 787 788 BaseURL baseUrl = ge.getAuthentificationSettings().getAuthentificationURL(); 789 StringBuffer sb = new StringBuffer( NetWorker.url2String( baseUrl.getOnlineResource() ) ); 790 sb.append( "?request=GetUser&SESSIONID=" ).append( sessionId ); 791 792 NetWorker nw = new NetWorker( CharsetUtils.getSystemCharset(), new URL( sb.toString() ) ); 793 Reader reader = new InputStreamReader( nw.getInputStream() ); 794 Document doc = XMLTools.parse( reader ); 795 // Node nsNode = XMLTools.getNamespaceNode(new HashMap()); 796 797 String tmp = null; 798 tmp = XMLTools.getNodeAsString( doc.getDocumentElement(), "/User/Name", nsContext, null ); 799 if ( tmp == null ) { 800 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_GET_USERNAME", sessionId ) ); 801 } 802 803 return tmp; 804 } 805 806 /** 807 * Determins the minimum and maximum values for x and y for the bounding box of each DataSessionRecord in the passed 808 * <code>List</code> and uses these values to determin an all combining bounding box. If none of the passed 809 * records has a bounding box, then null is returned. 810 * 811 * @param rpcDataSessionRecords 812 * List of DataSessionRecords for which to determin a combining bounding box. 813 * @return Returns a new GM_Envelope for a combining bounding box, OR null, if no bounding box was set in any of the 814 * passed DataSessionRecords. 815 * @throws UnknownCRSException 816 */ 817 private Envelope determinCombiningBBox( List rpcDataSessionRecords ) 818 throws UnknownCRSException { 819 820 Envelope bbox = null; 821 822 // upper left corner of combining bounding box 823 double minx = Double.MAX_VALUE; 824 double maxy = Double.MIN_VALUE; 825 // lower right corner of combining bounding box 826 double maxx = Double.MIN_VALUE; 827 double miny = Double.MAX_VALUE; 828 829 int count = 0; 830 for ( int i = 0; i < rpcDataSessionRecords.size(); i++ ) { 831 DataSessionRecord dsr = (DataSessionRecord) rpcDataSessionRecords.get( i ); 832 if ( dsr.getBoundingBox() != null ) { 833 count++; 834 double tempMinx, tempMiny, tempMaxx, tempMaxy; 835 tempMinx = dsr.getBoundingBox().getMin().getX(); 836 tempMiny = dsr.getBoundingBox().getMin().getY(); 837 tempMaxx = dsr.getBoundingBox().getMax().getX(); 838 tempMaxy = dsr.getBoundingBox().getMax().getY(); 839 840 // find min for x and y 841 minx = Math.min( tempMinx, minx ); 842 miny = Math.min( tempMiny, miny ); 843 // find max for x and y 844 maxx = Math.max( tempMaxx, maxx ); 845 maxy = Math.max( tempMaxy, maxy ); 846 } 847 } 848 if ( count > 0 ) { 849 CoordinateSystem srs = CRSFactory.create( config.getSrs() ); 850 bbox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, srs ); 851 } 852 853 return bbox; 854 } 855 856 /** 857 * Changes the bounding box of a given view context. 858 * 859 * @param vc 860 * The view context to be changed 861 * @param bbox 862 * The new bounding box 863 * @throws ContextException 864 */ 865 private void changeBBox( ViewContext vc, Envelope bbox ) 866 throws ContextException { 867 General general = vc.getGeneral(); 868 CoordinateSystem cs = general.getBoundingBox()[0].getCoordinateSystem(); 869 Point[] p = new Point[] { GeometryFactory.createPoint( bbox.getMin(), cs ), 870 GeometryFactory.createPoint( bbox.getMax(), cs ) }; 871 general.setBoundingBox( p ); 872 } 873 874 /** 875 * @param userName 876 * @param contextName 877 * @param vc 878 * @throws TransformerFactoryConfigurationError 879 * @throws PortalException 880 */ 881 private void storeContext( String userName, String contextName, ViewContext vc ) 882 throws PortalException, TransformerFactoryConfigurationError { 883 884 // save new context 885 StringBuffer path2Dir = new StringBuffer( getHomePath() ); 886 path2Dir.append( userDir ); 887 path2Dir.append( userName ); 888 File file = new File( path2Dir.toString() ); 889 if ( !file.exists() ) { 890 // create directory if not existent 891 file.mkdir(); 892 } 893 path2Dir.append( "/" ).append( contextName ).append( ".xml" ); 894 895 // Document doc = XMLFactory.export( vc ); 896 // FileOutputStream fos = new FileOutputStream( path2Dir.toString() ); 897 // internalSave( new StreamResult(fos), doc ); 898 // fos.close(); 899 saveDocument( vc, path2Dir.toString() ); 900 901 return; 902 } 903 904 // /** 905 // * common method to save xml 906 // * 907 // * @param result 908 // * @param doc 909 // * @throws TransformerFactoryConfigurationError 910 // * @throws TransformerException 911 // */ 912 // protected static void internalSave(Result result, Document doc) 913 // throws TransformerFactoryConfigurationError, TransformerException { 914 // Source source = new DOMSource(doc); 915 // Transformer transformer = 916 // TransformerFactory.newInstance().newTransformer(); 917 // transformer.transform(source, result); 918 // } 919 920 /** 921 * saves the new context as xml 922 * 923 * @param vc 924 * @param filename 925 * @throws PortalException 926 */ 927 public static final void saveDocument( ViewContext vc, String filename ) 928 throws PortalException { 929 try { 930 XMLFragment xml = XMLFactory.export( vc ); 931 FileOutputStream fos = new FileOutputStream( filename ); 932 xml.write( fos ); 933 fos.close(); 934 } catch ( Exception e ) { 935 throw new PortalException( Messages.getMessage( "IGEO_STD_CSW_ERROR_SAVE_FILE", filename ) ); 936 } 937 } 938 939 }