001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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: 22700 $
114 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
115 * @author last edited by: $Author: apoth $
116 *
117 * @version $Revision: 22700 $, $Date: 2010-02-23 14:00:28 +0100 (Di, 23. Feb 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( "igeoportal/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[] reqs = PortalUtils.createBaseRequests( vc );
563 List<String> list = new ArrayList<String>( reqs.length );
564 for ( int i = 0; i < reqs.length; i++ ) {
565 list.add( reqs[i] + sb.toString() );
566 LOG.logDebug( "GetMap request:", reqs[i] + sb.toString() );
567 }
568
569 return list;
570 }
571
572 /**
573 * returns <code>null</code> and should be overwritten by an extending class
574 *
575 * @return <code>null</code>
576 */
577 protected String getVendorspecificParameters( RPCWebEvent rpc ) {
578 // TODO Auto-generated method stub
579 return null;
580 }
581
582 /**
583 * returns <code>null</code> and should be overwritten by an extending class
584 *
585 * @return <code>null</code>
586 */
587 protected User getUser() {
588 return null;
589 }
590
591 /**
592 * reads the view context to print from the users session
593 *
594 * @param rpc
595 * @return the viewcontext defined by the rpc
596 */
597 abstract protected ViewContext getViewContext( RPCWebEvent rpc );
598
599 /**
600 * returns legend access URLs for all visible layers of the passed view context. If a visible layer does not define
601 * a LegendURL
602 *
603 * @param vc
604 * @return legend access URLs for all visible layers of the passed view context. If a visible layer does not define
605 * a LegendURL
606 */
607 private List<String[]> createLegendURLs( ViewContext vc ) {
608 Layer[] layers = vc.getLayerList().getLayers();
609 List<String[]> list = new ArrayList<String[]>();
610 for ( int i = 0; i < layers.length; i++ ) {
611 if ( !layers[i].isHidden() ) {
612 Style style = layers[i].getStyleList().getCurrentStyle();
613 String[] s = new String[2];
614 s[0] = layers[i].getTitle();
615 if ( style.getLegendURL() != null ) {
616 s[1] = style.getLegendURL().getOnlineResource().toExternalForm();
617 }
618 list.add( s );
619 }
620 }
621 return list;
622 }
623
624 /**
625 * validates the incoming request/RPC if conatins all required elements
626 *
627 * @param rpc
628 * @throws PortalException
629 */
630 protected void validate( RPCWebEvent rpc )
631 throws PortalException {
632 RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[1].getValue();
633 if ( struct.getMember( "TEMPLATE" ) == null ) {
634 throw new PortalException( Messages.getString( "portal.common.control.VALIDATIONERROR" ) );
635 }
636
637 if ( rpc.getRPCMethodCall().getParameters()[0].getValue() == null ) {
638 throw new PortalException( Messages.getString( "portal.common.control.VALIDATIONERROR" ) );
639 }
640 }
641
642 }