001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/common/control/AbstractSimplePrintListener.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.common.control; 037 038 import java.awt.Color; 039 import java.awt.Graphics; 040 import java.awt.Image; 041 import java.awt.image.BufferedImage; 042 import java.io.File; 043 import java.io.FileOutputStream; 044 import java.io.IOException; 045 import java.io.RandomAccessFile; 046 import java.net.URI; 047 import java.net.URL; 048 import java.text.SimpleDateFormat; 049 import java.util.ArrayList; 050 import java.util.GregorianCalendar; 051 import java.util.HashMap; 052 import java.util.List; 053 import java.util.Locale; 054 import java.util.Map; 055 import java.util.UUID; 056 057 import javax.servlet.ServletContext; 058 import javax.servlet.http.HttpServletRequest; 059 060 import net.sf.jasperreports.engine.JRDataSource; 061 import net.sf.jasperreports.engine.JREmptyDataSource; 062 import net.sf.jasperreports.engine.JRException; 063 import net.sf.jasperreports.engine.JasperFillManager; 064 import net.sf.jasperreports.engine.JasperPrint; 065 import net.sf.jasperreports.engine.JasperPrintManager; 066 import net.sf.jasperreports.engine.JasperRunManager; 067 068 import org.deegree.enterprise.control.AbstractListener; 069 import org.deegree.enterprise.control.FormEvent; 070 import org.deegree.enterprise.control.RPCMember; 071 import org.deegree.enterprise.control.RPCStruct; 072 import org.deegree.enterprise.control.RPCWebEvent; 073 import org.deegree.framework.log.ILogger; 074 import org.deegree.framework.log.LoggerFactory; 075 import org.deegree.framework.util.CharsetUtils; 076 import org.deegree.framework.util.ImageUtils; 077 import org.deegree.framework.util.KVP2Map; 078 import org.deegree.framework.util.MapUtils; 079 import org.deegree.framework.util.Pair; 080 import org.deegree.framework.util.StringTools; 081 import org.deegree.framework.xml.NamespaceContext; 082 import org.deegree.framework.xml.XMLFragment; 083 import org.deegree.framework.xml.XMLParsingException; 084 import org.deegree.framework.xml.XMLTools; 085 import org.deegree.model.spatialschema.Envelope; 086 import org.deegree.model.spatialschema.GeometryFactory; 087 import org.deegree.model.spatialschema.Point; 088 import org.deegree.ogcbase.CommonNamespaces; 089 import org.deegree.ogcwebservices.InconsistentRequestException; 090 import org.deegree.ogcwebservices.wms.operation.GetMap; 091 import org.deegree.portal.PortalException; 092 import org.deegree.portal.PortalUtils; 093 import org.deegree.portal.context.Layer; 094 import org.deegree.portal.context.Style; 095 import org.deegree.portal.context.ViewContext; 096 import org.deegree.security.drm.model.User; 097 import org.xml.sax.SAXException; 098 099 /** 100 * performs a print request/event by creating a PDF document from the current map. For this JASPER is used. Well known 101 * parameters that can be passed to a jaser report are:<br> 102 * <ul> 103 * <li>MAP</li> 104 * <li>LEGEND</li> 105 * <li>DATE</li> 106 * <li>MAPSCALE</li> 107 * </ul> 108 * <br> 109 * Additionaly parameters named 'TA:XXXX' can be used. deegree will create a k-v-p for each TA:XXXX passed as part of 110 * RPC. 111 * 112 * 113 * @version $Revision: 28670 $ 114 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 115 * @author last edited by: $Author: apoth $ 116 * 117 * @version $Revision: 28670 $, $Date: 2010-12-10 09:34:18 +0100 (Fr, 10 Dez 2010) $ 118 */ 119 public abstract class AbstractSimplePrintListener extends AbstractListener { 120 121 private static ILogger LOG = LoggerFactory.getLogger( AbstractSimplePrintListener.class ); 122 123 private String defaultTemplateDir = "/WEB-INF/igeoportal/print"; 124 125 /** 126 * @param e 127 */ 128 @Override 129 public void actionPerformed( FormEvent e ) { 130 RPCWebEvent rpc = (RPCWebEvent) e; 131 try { 132 validate( rpc ); 133 } catch ( Exception ex ) { 134 LOG.logError( ex.getMessage(), ex ); 135 gotoErrorPage( ex.getMessage() ); 136 } 137 138 ViewContext vc = getViewContext( rpc ); 139 if ( vc == null ) { 140 LOG.logError( "no valid ViewContext available; maybe your session has reached timeout limit" ); //$NON-NLS-1$ 141 gotoErrorPage( Messages.getString( "AbstractSimplePrintListener.MISSINGCONTEXT" ) ); 142 setNextPage( "error.jsp" ); 143 return; 144 } 145 try { 146 printMap( vc, rpc ); 147 } catch ( Exception ex ) { 148 ex.printStackTrace(); 149 LOG.logError( ex.getMessage(), ex ); 150 gotoErrorPage( ex.getMessage() ); 151 } 152 } 153 154 /** 155 * 156 * @param vc 157 * @param rpc 158 * @throws PortalException 159 * @throws IOException 160 * @throws SAXException 161 * @throws XMLParsingException 162 * @throws InconsistentRequestException 163 */ 164 private void printMap( ViewContext vc, RPCWebEvent rpc ) 165 throws Exception { 166 167 RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[1].getValue(); 168 String printTemplate = (String) struct.getMember( "TEMPLATE" ).getValue(); 169 170 // read print template directory from defaultTemplateDir, or, if available, from the init 171 // parameters 172 String templateDir = getInitParameter( "TEMPLATE_DIR" ); 173 if ( templateDir == null ) { 174 templateDir = defaultTemplateDir; 175 } 176 ServletContext sc = ( (HttpServletRequest) getRequest() ).getSession( true ).getServletContext(); 177 String path = sc.getRealPath( templateDir ) + '/' + printTemplate + ".jasper"; 178 String pathx = sc.getRealPath( templateDir ) + '/' + printTemplate + ".jrxml"; 179 Pair<Integer, Integer> size = getMapTemplateSize( pathx ); 180 181 List<String> getMap = createGetMapRequests( vc, rpc, size ); 182 String image = performGetMapRequests( getMap ); 183 184 String legend = accessLegend( createLegendURLs( vc ) ); 185 186 String format = (String) rpc.getRPCMethodCall().getParameters()[0].getValue(); 187 188 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 189 LOG.logDebug( "The jasper template is read from: ", path ); 190 LOG.logDebug( "The jrxml template is read from: ", pathx ); 191 } 192 193 Map<String, Object> parameter = new HashMap<String, Object>(); 194 parameter.put( "MAP", image ); 195 parameter.put( "LEGEND", legend ); 196 197 // enable 198 if ( getInitParameter( "LOGO_URL" ) != null ) { 199 String logoUrl = getHomePath() + getInitParameter( "LOGO_URL" ); 200 if ( new File( logoUrl ).exists() ) { 201 parameter.put( "LOGO_URL", logoUrl ); 202 } 203 } 204 205 parameter.put( "ROOT", getHomePath() ); 206 207 SimpleDateFormat sdf = new SimpleDateFormat( "dd.MM.yyyy", Locale.getDefault() ); 208 // TODO deprecated - will be remove in future versions 209 parameter.put( "DATUM", sdf.format( new GregorianCalendar().getTime() ) ); 210 // -------------------------------------------------------- 211 parameter.put( "DATE", sdf.format( new GregorianCalendar().getTime() ) ); 212 213 double scale = calcScale( size, getMap.get( 0 ) ); 214 parameter.put( "MAPSCALE", "" + Math.round( scale ) ); 215 LOG.logDebug( "print map scale: ", scale ); 216 // set text area values 217 RPCMember[] members = struct.getMembers(); 218 for ( int i = 0; i < members.length; i++ ) { 219 if ( members[i].getName().startsWith( "TA:" ) ) { 220 String s = members[i].getName().substring( 3, members[i].getName().length() ); 221 String val = (String) members[i].getValue(); 222 if ( val != null ) { 223 val = new String( val.getBytes(), CharsetUtils.getSystemCharset() ); 224 } 225 LOG.logDebug( "text area name: ", s ); 226 LOG.logDebug( "text area value: ", val ); 227 parameter.put( s, val ); 228 } 229 } 230 System.out.println( parameter ); 231 if ( "application/pdf".equals( format ) ) { 232 233 // create the pdf 234 Object result = null; 235 try { 236 JRDataSource ds = new JREmptyDataSource(); 237 result = JasperRunManager.runReportToPdf( path, parameter, ds ); 238 } catch ( JRException e ) { 239 LOG.logError( "Template: " + path ); 240 LOG.logError( e.getLocalizedMessage(), e ); 241 throw new PortalException( Messages.getString( "AbstractSimplePrintListener.REPORTCREATION" ) ); 242 } finally { 243 File file = new File( image ); 244 file.delete(); 245 file = new File( legend ); 246 file.delete(); 247 } 248 249 forwardPDF( result ); 250 251 } else if ( "image/png".equals( format ) ) { 252 253 // create the image 254 Image result = null; 255 try { 256 JRDataSource ds = new JREmptyDataSource(); 257 JasperPrint prt = JasperFillManager.fillReport( path, parameter, ds ); 258 result = JasperPrintManager.printPageToImage( prt, 0, 1 ); 259 } catch ( JRException e ) { 260 LOG.logError( e.getLocalizedMessage(), e ); 261 throw new PortalException( Messages.getString( "AbstractSimplePrintListener.REPORTCREATION" ) ); 262 } finally { 263 File file = new File( image ); 264 file.delete(); 265 file = new File( legend ); 266 file.delete(); 267 } 268 269 forwardImage( result, format ); 270 271 } 272 } 273 274 private Pair<Integer, Integer> getMapTemplateSize( String path ) 275 throws Exception { 276 File file = new File( path ); 277 XMLFragment xml = new XMLFragment( file.toURL() ); 278 279 String xpathW = "detail/band/image/reportElement[./@key = 'image-1']/@width"; 280 String xpathH = "detail/band/image/reportElement[./@key = 'image-1']/@height"; 281 NamespaceContext nsc = CommonNamespaces.getNamespaceContext(); 282 int w = XMLTools.getNodeAsInt( xml.getRootElement(), xpathW, nsc, -1 ); 283 int h = XMLTools.getNodeAsInt( xml.getRootElement(), xpathH, nsc, -1 ); 284 if ( w < 0 ) { 285 nsc.addNamespace( "jasper", URI.create( "http://jasperreports.sourceforge.net/jasperreports" ) ); 286 xpathW = "jasper:detail/jasper:band/jasper:image/jasper:reportElement[./@key = 'image-1']/@width"; 287 xpathH = "jasper:detail/jasper:band/jasper:image/jasper:reportElement[./@key = 'image-1']/@height"; 288 w = XMLTools.getRequiredNodeAsInt( xml.getRootElement(), xpathW, nsc ); 289 h = XMLTools.getRequiredNodeAsInt( xml.getRootElement(), xpathH, nsc ); 290 } 291 return new Pair<Integer, Integer>( w, h ); 292 } 293 294 protected double calcScale( Pair<Integer, Integer> size, String getmap ) 295 throws InconsistentRequestException, XMLParsingException, IOException, SAXException { 296 // TODO The map path is static. It should be instead read from somewhere else. 297 // A good idea would be to save the path in the web.xml of the corresponding application, 298 // or in controller.xml of the PdfPrintListener and sends it with rpc request 299 300 Map<String, String> model = KVP2Map.toMap( getmap ); 301 model.put( "ID", "22" ); 302 GetMap gm = GetMap.create( model ); 303 304 // CoordinateSystem crs = CRSFactory.create( gm.getSrs() ); 305 306 // map size in template in metre; templates generated by iReport are designed 307 // to assume a resolution of 72dpi 308 double ms = ( size.first / 72d ) * 0.0254; 309 // TODO 310 // consider no metric CRS 311 return gm.getBoundingBox().getWidth() / ms; 312 } 313 314 /** 315 * accesses the legend URLs passed, draws the result onto an image that are stored in a temporary file. The name of 316 * the file will be returned. 317 * 318 * @param legends 319 * @return filename of image file 320 */ 321 private String accessLegend( List<String[]> legends ) 322 throws IOException { 323 int width = Integer.parseInt( getInitParameter( "LEGENDWIDTH" ) ); 324 int height = Integer.parseInt( getInitParameter( "LEGENDHEIGHT" ) ); 325 String tmp = getInitParameter( "LEGENDBGCOLOR" ); 326 if ( tmp == null ) { 327 tmp = "0xFFFFFF"; 328 } 329 Color bg = Color.decode( tmp ); 330 BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); 331 Graphics g = bi.getGraphics(); 332 g.setColor( bg ); 333 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() ); 334 g.setColor( Color.BLACK ); 335 int k = 10; 336 337 for ( int i = 0; i < legends.size(); i++ ) { 338 if ( k > bi.getHeight() ) { 339 if ( LOG.getLevel() <= ILogger.LOG_WARNING ) { 340 LOG.logWarning( "The necessary legend size is larger than the available legend space." ); 341 } 342 } 343 String[] s = legends.get( i ); 344 if ( s[1] != null ) { 345 LOG.logDebug( "reading legend: " + s[1] ); 346 Image img = null; 347 try { 348 img = ImageUtils.loadImage( new URL( s[1] ) ); 349 } catch ( Exception e ) { 350 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 351 String msg = StringTools.concat( 400, "Exception for Layer: ", s[0], " - ", s[1] ); 352 LOG.logDebug( msg ); 353 LOG.logDebug( e.getLocalizedMessage() ); 354 } 355 if ( getInitParameter( "MISSING_IMAGE" ) != null ) { 356 String missingImageUrl = getHomePath() + getInitParameter( "MISSING_IMAGE" ); 357 File missingImage = new File( missingImageUrl ); 358 if ( missingImage.exists() ) { 359 img = ImageUtils.loadImage( missingImage ); 360 } 361 } 362 } 363 if ( img != null ) { 364 if ( img.getWidth( null ) < 50 ) { 365 // it is assumed that no label is assigned 366 g.drawImage( img, 0, k, null ); 367 g.drawString( s[0], img.getWidth( null ) + 10, k + img.getHeight( null ) / 2 ); 368 } else { 369 g.drawImage( img, 0, k, null ); 370 } 371 k = k + img.getHeight( null ) + 10; 372 } 373 } else { 374 g.drawString( "- " + s[0], 0, k + 10 ); 375 k = k + 20; 376 } 377 } 378 g.dispose(); 379 380 return storeImage( bi ); 381 } 382 383 /** 384 * performs the GetMap requests passed, draws the result onto an image that are stored in a temporary file. The name 385 * of the file will be returned. 386 * 387 * @param list 388 * @return filename of image file 389 * @throws PortalException 390 * @throws IOException 391 */ 392 private String performGetMapRequests( List<String> list ) 393 throws PortalException, IOException { 394 395 Map<String, String> map = KVP2Map.toMap( list.get( 0 ) ); 396 map.put( "ID", "ww" ); 397 GetMap getMap = null; 398 try { 399 getMap = GetMap.create( map ); 400 } catch ( Exception e ) { 401 LOG.logError( e.getMessage(), e ); 402 String s = Messages.format( "AbstractSimplePrintListener.GETMAPCREATION", list.get( 0 ) ); 403 throw new PortalException( s ); 404 } 405 BufferedImage bi = new BufferedImage( getMap.getWidth(), getMap.getHeight(), BufferedImage.TYPE_INT_ARGB ); 406 Graphics g = bi.getGraphics(); 407 for ( int i = 0; i < list.size(); i++ ) { 408 URL url = new URL( list.get( i ) ); 409 Image img = null; 410 try { 411 img = ImageUtils.loadImage( url ); 412 } catch ( Exception e ) { 413 // This is the case where a getmap request produces an error. This does not definitly mean that 414 // the wms is not working, it could also be because the bounding box is not correct or too big. Try to 415 // zoom 416 // in, you might find something 417 LOG.logInfo( "could not load map from: ", url.toExternalForm() ); 418 } 419 g.drawImage( img, 0, 0, null ); 420 } 421 g.dispose(); 422 return storeImage( bi ); 423 } 424 425 /** 426 * stores the passed image in the defined temporary directory and returns the dynamicly created filename 427 * 428 * @param bi 429 * @return filename of image file 430 * @throws IOException 431 */ 432 private String storeImage( BufferedImage bi ) 433 throws IOException { 434 435 String s = UUID.randomUUID().toString(); 436 String tempDir = getInitParameter( "TEMPDIR" ); 437 if ( !tempDir.endsWith( "/" ) ) { 438 tempDir = tempDir + '/'; 439 } 440 if ( tempDir.startsWith( "/" ) ) { 441 tempDir = tempDir.substring( 1, tempDir.length() ); 442 } 443 ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext(); 444 String fileName = StringTools.concat( 300, sc.getRealPath( tempDir ), '/', s, ".png" ); 445 446 FileOutputStream fos = new FileOutputStream( new File( fileName ) ); 447 448 ImageUtils.saveImage( bi, fos, "png", 1 ); 449 fos.close(); 450 451 return fileName; 452 } 453 454 private void forwardPDF( Object result ) 455 throws PortalException { 456 // must be a byte array 457 String tempDir = getInitParameter( "TEMPDIR" ); 458 if ( !tempDir.endsWith( "/" ) ) { 459 tempDir = tempDir + '/'; 460 } 461 if ( tempDir.startsWith( "/" ) ) { 462 tempDir = tempDir.substring( 1, tempDir.length() ); 463 } 464 ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext(); 465 466 String fileName = UUID.randomUUID().toString(); 467 String s = StringTools.concat( 200, sc.getRealPath( tempDir ), '/', fileName, ".pdf" ); 468 try { 469 RandomAccessFile raf = new RandomAccessFile( s, "rw" ); 470 raf.write( (byte[]) result ); 471 raf.close(); 472 } catch ( Exception e ) { 473 e.printStackTrace(); 474 LOG.logError( "could not write temporary pdf file: " + s, e ); 475 throw new PortalException( Messages.format( "AbstractSimplePrintListener.PDFCREATION", s ), e ); 476 } 477 478 getRequest().setAttribute( "PDF", StringTools.concat( 200, tempDir, fileName, ".pdf" ) ); 479 } 480 481 private void forwardImage( Image result, String format ) 482 throws PortalException { 483 484 format = format.substring( format.indexOf( '/' ) + 1 ); 485 486 String tempDir = getInitParameter( "TEMPDIR" ); 487 if ( !tempDir.endsWith( "/" ) ) { 488 tempDir = tempDir + '/'; 489 } 490 if ( tempDir.startsWith( "/" ) ) { 491 tempDir = tempDir.substring( 1, tempDir.length() ); 492 } 493 ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext(); 494 495 String fileName = UUID.randomUUID().toString(); 496 String s = StringTools.concat( 200, sc.getRealPath( tempDir ), "/", fileName, ".", format ); 497 try { 498 // make sure we have a BufferedImage 499 if ( !( result instanceof BufferedImage ) ) { 500 BufferedImage img = new BufferedImage( result.getWidth( null ), result.getHeight( null ), 501 BufferedImage.TYPE_INT_ARGB ); 502 503 Graphics g = img.getGraphics(); 504 g.drawImage( result, 0, 0, null ); 505 g.dispose(); 506 result = img; 507 } 508 509 ImageUtils.saveImage( (BufferedImage) result, s, 1 ); 510 } catch ( Exception e ) { 511 LOG.logError( "could not write temporary pdf file: " + s, e ); 512 throw new PortalException( Messages.format( "AbstractSimplePrintListener.PDFCREATION", s ), e ); 513 } 514 515 getRequest().setAttribute( "PDF", StringTools.concat( 200, tempDir, fileName, ".", format ) ); 516 } 517 518 /** 519 * fills the passed PrintMap request template with required values 520 * 521 * @param vc 522 * @return returns a list with all base requests 523 */ 524 private List<String> createGetMapRequests( ViewContext vc, RPCWebEvent rpc, Pair<Integer, Integer> size ) { 525 526 RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[1].getValue(); 527 Integer dpi = null; 528 if ( struct.getMember( "DPI" ) != null ) { 529 dpi = Integer.parseInt( struct.getMember( "DPI" ).getValue().toString() ); 530 } 531 LOG.logInfo( "dpi: ", dpi ); 532 533 User user = getUser(); 534 String vsp = getVendorspecificParameters( rpc ); 535 536 // set boundingbox/envelope 537 Point[] points = vc.getGeneral().getBoundingBox(); 538 Envelope bbox = GeometryFactory.createEnvelope( points[0].getPosition(), points[1].getPosition(), 539 points[0].getCoordinateSystem() ); 540 541 int width = Integer.parseInt( getInitParameter( "WIDTH" ) ); 542 int height = Integer.parseInt( getInitParameter( "HEIGHT" ) ); 543 if ( dpi != null ) { 544 width = (int) Math.round( size.first * ( dpi / 72d ) ); 545 height = (int) Math.round( size.second * ( dpi / 72d ) ); 546 } 547 548 bbox = MapUtils.ensureAspectRatio( bbox, width, height ); 549 550 StringBuffer sb = new StringBuffer( 1000 ); 551 sb.append( "&BBOX=" ).append( bbox.getMin().getX() ).append( ',' ); 552 sb.append( bbox.getMin().getY() ).append( ',' ).append( bbox.getMax().getX() ); 553 sb.append( ',' ).append( bbox.getMax().getY() ).append( "&WIDTH=" ); 554 sb.append( width ).append( "&HEIGHT=" ).append( height ); 555 if ( user != null ) { 556 sb.append( "&user=" ).append( user.getName() ); 557 sb.append( "&password=" ).append( user.getPassword() ); 558 } 559 if ( vsp != null ) { 560 sb.append( "&" ).append( vsp ); 561 } 562 String sessionId = (String) ( (HttpServletRequest) getRequest() ).getSession().getAttribute( "SESSIONID" ); 563 if ( sessionId != null ) { 564 sb.append( "&sessionid=" ).append( sessionId ); 565 } 566 String[] reqs = PortalUtils.createBaseRequests( vc ); 567 List<String> list = new ArrayList<String>( reqs.length ); 568 for ( int i = 0; i < reqs.length; i++ ) { 569 list.add( reqs[i] + sb.toString() ); 570 LOG.logDebug( "GetMap request:", reqs[i] + sb.toString() ); 571 } 572 573 return list; 574 } 575 576 /** 577 * returns <code>null</code> and should be overwritten by an extending class 578 * 579 * @return <code>null</code> 580 */ 581 protected String getVendorspecificParameters( RPCWebEvent rpc ) { 582 // TODO Auto-generated method stub 583 return null; 584 } 585 586 /** 587 * returns <code>null</code> and should be overwritten by an extending class 588 * 589 * @return <code>null</code> 590 */ 591 protected User getUser() { 592 return null; 593 } 594 595 /** 596 * reads the view context to print from the users session 597 * 598 * @param rpc 599 * @return the viewcontext defined by the rpc 600 */ 601 abstract protected ViewContext getViewContext( RPCWebEvent rpc ); 602 603 /** 604 * returns legend access URLs for all visible layers of the passed view context. If a visible layer does not define 605 * a LegendURL 606 * 607 * @param vc 608 * @return legend access URLs for all visible layers of the passed view context. If a visible layer does not define 609 * a LegendURL 610 */ 611 private List<String[]> createLegendURLs( ViewContext vc ) { 612 Layer[] layers = vc.getLayerList().getLayers(); 613 List<String[]> list = new ArrayList<String[]>(); 614 for ( int i = 0; i < layers.length; i++ ) { 615 if ( !layers[i].isHidden() ) { 616 Style style = layers[i].getStyleList().getCurrentStyle(); 617 String[] s = new String[2]; 618 s[0] = layers[i].getTitle(); 619 if ( style.getLegendURL() != null ) { 620 s[1] = style.getLegendURL().getOnlineResource().toExternalForm(); 621 } 622 list.add( s ); 623 } 624 } 625 return list; 626 } 627 628 /** 629 * validates the incoming request/RPC if conatins all required elements 630 * 631 * @param rpc 632 * @throws PortalException 633 */ 634 protected void validate( RPCWebEvent rpc ) 635 throws PortalException { 636 RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[1].getValue(); 637 if ( struct.getMember( "TEMPLATE" ) == null ) { 638 throw new PortalException( Messages.getString( "portal.common.control.VALIDATIONERROR" ) ); 639 } 640 641 if ( rpc.getRPCMethodCall().getParameters()[0].getValue() == null ) { 642 throw new PortalException( Messages.getString( "portal.common.control.VALIDATIONERROR" ) ); 643 } 644 } 645 646 }