    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    }