    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/portal/standard/wms/control/PrintListener.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.standard.wms.control;
    037
    038    import java.awt.Color;
    039    import java.awt.Font;
    040    import java.awt.Graphics;
    041    import java.awt.Rectangle;
    042    import java.awt.geom.Rectangle2D;
    043    import java.awt.image.BufferedImage;
    044    import java.io.File;
    045    import java.io.FileOutputStream;
    046    import java.io.IOException;
    047    import java.io.InputStream;
    048    import java.io.UnsupportedEncodingException;
    049    import java.net.MalformedURLException;
    050    import java.net.URL;
    051    import java.net.URLDecoder;
    052    import java.util.ArrayList;
    053    import java.util.HashMap;
    054    import java.util.Map;
    055    import java.util.StringTokenizer;
    056
    057    import javax.imageio.ImageIO;
    058    import javax.servlet.http.HttpServletRequest;
    059    import javax.servlet.http.HttpSession;
    060
    061    import org.deegree.enterprise.control.FormEvent;
    062    import org.deegree.enterprise.control.RPCMember;
    063    import org.deegree.enterprise.control.RPCMethodCall;
    064    import org.deegree.enterprise.control.RPCParameter;
    065    import org.deegree.enterprise.control.RPCStruct;
    066    import org.deegree.enterprise.control.RPCWebEvent;
    067    import org.deegree.framework.log.ILogger;
    068    import org.deegree.framework.log.LoggerFactory;
    069    import org.deegree.framework.util.CharsetUtils;
    070    import org.deegree.framework.util.IDGenerator;
    071    import org.deegree.framework.util.ImageUtils;
    072    import org.deegree.framework.util.StringTools;
    073    import org.deegree.framework.xml.XMLParsingException;
    074    import org.deegree.model.crs.UnknownCRSException;
    075    import org.deegree.ogcwebservices.InconsistentRequestException;
    076    import org.deegree.ogcwebservices.OGCWebServiceException;
    077    import org.deegree.ogcwebservices.OWSUtils;
    078    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
    079    import org.deegree.ogcwebservices.wms.operation.GetMap;
    080    import org.deegree.portal.Constants;
    081    import org.deegree.portal.context.GeneralExtension;
    082    import org.deegree.portal.context.IOSettings;
    083    import org.deegree.portal.context.ViewContext;
    084
    085    /**
    086     * will be called if the client forces a print action.
    087     *
    088     * @deprecated use @see org.deegree.portal.common.control.AbstractSimplePrintListener
    089     *
    090     * @author <a href="mailto:lupp@lat-lon.de">Katharina Lupp</a>
    091     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    092     * @author last edited by: $Author: apoth $
    093     *
    094     * @version $Revision: 21678 $ $Date: 2009-12-29 14:44:02 +0100 (Di, 29. Dez 2009) $
    095     */
    096    @Deprecated
    097    public class PrintListener extends AbstractMapListener {
    098
    099        private static final ILogger LOG = LoggerFactory.getLogger( PrintListener.class );
    100
    101        /*
    102         * the method will be called if a print action/event occurs.
    103         *
    104         * (non-Javadoc)
    105         *
    106         * @see org.deegree.enterprise.control.WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
    107         */
    108        @Override
    109        public void actionPerformed( FormEvent event ) {
    110
    111            super.actionPerformed( event );
    112
    113            RPCWebEvent rpc = (RPCWebEvent) event;
    114            RPCMethodCall mc = rpc.getRPCMethodCall();
    115            RPCParameter[] para = mc.getParameters();
    116            RPCStruct struct = (RPCStruct) para[0].getValue(); // paperFormat, resolution, orientation, format
    117            RPCStruct struct2 = (RPCStruct) para[1].getValue(); // wmsRequest_0 .. wmsRequest_i
    118
    119            HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
    120            ViewContext vc = null;
    121            if ( session.getAttribute( Constants.CURRENTMAPCONTEXT ) != null ) {
    122                vc = (ViewContext) session.getAttribute( Constants.CURRENTMAPCONTEXT );
    123            } else {
    124                vc = (ViewContext) session.getAttribute( "DefaultMapContext" );
    125            }
    126
    127            Map<String, String>[] model = createWMSRequestModel( struct2 );
    128            int[] imageSize = calcImageSize( struct, model[0] );
    129            int width = imageSize[0];
    130            // int height = imageSize[1];
    131            int xmap = imageSize[2];
    132            int ymap = imageSize[3];
    133            int mapStart = imageSize[4];
    134
    135            try {
    136                GetLegendGraphic legendParam = getLegendRequestParameter();
    137                // HashMap with legend
    138                Map<String, Object> symbols = getLegend( struct, legendParam, model );
    139                Rectangle rectLegend = calcLegendSize( struct, symbols );
    140                Rectangle rectMap = calcMapSize( model, rectLegend, width );
    141                // sets new size of map und creates the adequate BufferedImage
    142                model = modifyModelSize( rectMap, model, xmap, ymap );
    143                Map<String,String>[] copy = createCopy( model );
    144                BufferedImage biReq = getMap( copy );
    145
    146                // creates BufferedImage with required size and creates graphic
    147                BufferedImage bi = createBackgroundImage( rectMap, rectLegend );
    148
    149                bi = drawMapToBI( biReq, bi, mapStart );
    150                bi = drawLegendToBI( symbols, bi, ( mapStart + rectMap.width ) );
    151
    152                saveImage( vc, struct, bi );
    153
    154            } catch ( Exception e ) {
    155                e.printStackTrace();
    156            }
    157
    158        }
    159
    160        /**
    161         * creates a background BufferedImage for the attributes (map, legend, scalebar)
    162         *
    163         * @param rectMap
    164         * @param rectLegend
    165         * @return
    166         */
    167        private BufferedImage createBackgroundImage( Rectangle rectMap, Rectangle rectLegend ) {
    168            BufferedImage bi = null;
    169
    170            if ( rectMap.height > rectLegend.height ) {
    171                bi = new BufferedImage( rectMap.width + rectLegend.width + 40, rectMap.height + 100,
    172                                        BufferedImage.TYPE_INT_RGB );
    173            } else {
    174                bi = new BufferedImage( rectMap.width + rectLegend.width + 40, rectLegend.height + 100,
    175                                        BufferedImage.TYPE_INT_RGB );
    176            }
    177
    178            Graphics g = bi.getGraphics();
    179            g.setColor( Color.WHITE );
    180            g.fillRect( 1, 1, bi.getWidth() - 2, bi.getHeight() - 2 );
    181            g.dispose();
    182
    183            return bi;
    184        }
    185
    186        /**
    187         * creates copy of the model
    188         *
    189         * @param model
    190         * @return the copy of the model
    191         */
    192        @SuppressWarnings("unchecked")
    193        private Map<String,String>[] createCopy( Map<String,String>[] model ) {
    194            Map<String,String>[] copy = new Map[model.length];
    195            synchronized ( this ) {
    196                for ( int i = 0; i < model.length; i++ ) {
    197                    copy[i] = (Map<String,String>) ((HashMap<String, String>)model[i]).clone();
    198                }
    199            }
    200
    201            return copy;
    202        }
    203
    204        /**
    205         * creates model with WMS request from the RPCStruct request parameter.
    206         *
    207         * @param struc
    208         * @return
    209         */
    210        @SuppressWarnings("unchecked")
    211        private Map<String, String>[] createWMSRequestModel( RPCStruct struc ) {
    212
    213            RPCMember[] member = struc.getMembers();
    214            Map<String, String>[] getMR = new HashMap[member.length];
    215
    216            String request = "";
    217            // for ( int i = 0; i < member.length; i++ ) {
    218            for ( int i = member.length - 1; i >= 0; i-- ) {
    219                request = (String) member[i].getValue();
    220                getMR[i] = toMap( request );
    221                StringTokenizer st = new StringTokenizer( request, "?" );
    222                getMR[i].put( "URL", st.nextToken() );
    223            }
    224            return getMR;
    225        }
    226
    227        /**
    228         * calculates images size in dependency on chosen paperFormat, resolution and orientation.
    229         *
    230         * @param struct
    231         * @param model
    232         * @return
    233         */
    234        private int[] calcImageSize( RPCStruct struct, Map<String, String> model ) {
    235            double width = 0;
    236            double height = 0;
    237            double mapSize = 0;
    238
    239            double mapWI = Double.parseDouble( (String) model.get( "WIDTH" ) );
    240            double mapHE = Double.parseDouble( (String) model.get( "HEIGHT" ) );
    241
    242            String paperFormat = (String) struct.getMember( "paperFormat" ).getValue();
    243            String resolution = (String) struct.getMember( "resolution" ).getValue();
    244            String orientation = (String) struct.getMember( "orientation" ).getValue();
    245
    246            if ( paperFormat.equals( "A4" ) ) {
    247                if ( orientation.equals( "hoch" ) ) {
    248                    width = 8.2;
    249                    height = 11.6;
    250                    mapSize = 6.5; // legend beside
    251                } else {
    252                    width = 11.6;
    253                    height = 8.2;
    254                    mapSize = 9.5;
    255                }
    256            } else if ( paperFormat.equals( "A3" ) ) {
    257                if ( orientation.equals( "hoch" ) ) {
    258                    width = 11.6;
    259                    height = 16.5;
    260                    mapSize = 9.8; // legend beside
    261                } else {
    262                    width = 16.5;
    263                    height = 11.6;
    264                    mapSize = 14;
    265                }
    266            } else if ( paperFormat.equals( "A5" ) ) {
    267                if ( orientation.equals( "hoch" ) ) {
    268                    width = 5.8;
    269                    height = 8.2;
    270                    mapSize = 4.1; // legend beside
    271                } else {
    272                    width = 8.2;
    273                    height = 5.8;
    274                    mapSize = 6.5;
    275                }
    276            }
    277
    278            width = width * Double.parseDouble( resolution );
    279            height = height * Double.parseDouble( resolution );
    280            mapSize = mapSize * Double.parseDouble( resolution );
    281
    282            int xmap = (int) Math.round( mapSize );
    283            double fac = mapWI / mapHE;
    284            int ymap = (int) Math.round( mapSize / fac );
    285            int mapStart = 45;
    286            int[] imagesize = new int[] { (int) Math.round( width ), (int) Math.round( height ), xmap, ymap, mapStart };
    287
    288            return imagesize;
    289        }
    290
    291        /**
    292         * calculates size (width and height) of legend depending on chosen paperFormat and resolution.
    293         *
    294         * @param struct
    295         * @param map
    296         * @return
    297         */
    298        private Rectangle calcLegendSize( RPCStruct struct, Map<String, Object> map ) {
    299
    300            String paperFormat = (String) struct.getMember( "paperFormat" ).getValue();
    301            String resolution = (String) struct.getMember( "resolution" ).getValue();
    302
    303            String[] layers = (String[]) map.get( "NAMES" );
    304            BufferedImage[] legs = (BufferedImage[]) map.get( "IMAGES" );
    305
    306            int w = 0;
    307            int h = 0;
    308            int size = 12;
    309            double tmph1 = 0;
    310            double tmph2 = 0;
    311
    312            if ( paperFormat.equals( "A4" ) ) {
    313                tmph1 = size / 3d;
    314            } else if ( paperFormat.equals( "A3" ) ) {
    315                tmph1 += 2 * size / 3;
    316            }
    317
    318            double res = Double.parseDouble( resolution );
    319            tmph2 = ( ( res - 150 ) / 150d ) * size;
    320            size += (int) Math.round( tmph2 + tmph1 );
    321            for ( int i = 0; i < layers.length; i++ ) {
    322                h += ( legs[i].getHeight() + 6 );
    323
    324                Graphics g = legs[i].getGraphics();
    325                Font f = new Font( g.getFont().getFontName(), g.getFont().getStyle(), size );
    326                g.setFont( f );
    327                Rectangle2D rect = g.getFontMetrics().getStringBounds( layers[i], g );
    328                g.dispose();
    329
    330                if ( rect.getWidth() > w ) {
    331                    w = (int) rect.getWidth();
    332                }
    333            }
    334            w += 150;
    335
    336            return new Rectangle( w, h );
    337        }
    338
    339        /**
    340         * calculates map size in dependency of the chosen paperFormat and resolution.
    341         *
    342         * @param model
    343         * @param rectLegend
    344         * @param width
    345         * @return
    346         */
    347        private Rectangle calcMapSize( Map<String, String>[] model, Rectangle rectLegend, int width ) {
    348            int w = width - rectLegend.width - 20;
    349            double wi = Double.parseDouble( (String) model[0].get( "WIDTH" ) );
    350            double he = Double.parseDouble( (String) model[0].get( "HEIGHT" ) );
    351            double fac = he / wi;
    352            int h = (int) Math.round( fac * w );
    353
    354            return new Rectangle( w, h );
    355        }
    356
    357        /**
    358         * draws legend with symbols and name of the layers to the background BufferedImage.
    359         *
    360         * @param map
    361         * @param bi
    362         * @param start
    363         * @return
    364         */
    365        private BufferedImage drawLegendToBI( Map<String,Object> map, BufferedImage bi, int start ) {
    366
    367            int h = 5;
    368            Graphics g = bi.getGraphics();
    369            g.setColor( Color.WHITE );
    370            String[] layers = (String[]) map.get( "NAMES" );
    371            BufferedImage[] legs = (BufferedImage[]) map.get( "IMAGES" );
    372
    373            for ( int i = layers.length - 1; i >= 0; i-- ) {
    374                g.drawImage( legs[i], start + 10, h, null );
    375                g.setColor( Color.BLACK );
    376
    377                if ( legs[i].getHeight() < 50 ) {
    378                    g.drawString( layers[i], start + 25 + legs[i].getWidth(), h + (int) ( legs[i].getHeight() / 1.2 ) );
    379                }
    380
    381                h += ( legs[i].getHeight() + 5 );
    382            }
    383
    384            g.dispose();
    385            return bi;
    386        }
    387
    388        /**
    389         * modifies width and height in the WMSGetMapRequest in dependency of the chosen paperFormat and resolution. New
    390         * width and height are calculated in the method "calcMapSize".
    391         *
    392         * @param rectMap
    393         * @param model
    394         * @param width
    395         * @param height
    396         * @return
    397         */
    398        private Map<String, String>[] modifyModelSize( Rectangle rectMap, Map<String, String>[] model, int width, int height ) {
    399            int w = rectMap.width;
    400            double fac = (double) height / (double) width;
    401            double h = fac * w;
    402
    403            for ( int i = 0; i < model.length; i++ ) {
    404                model[i].put( "HEIGHT", "" + (int) Math.round( h ) );
    405                model[i].put( "WIDTH", "" + w );
    406            }
    407
    408            return model;
    409        }
    410
    411        /**
    412         * gets the map with corresponding mapsizes built-in the urls.
    413         *
    414         * @throws UnknownCRSException
    415         *
    416         * @param model
    417         * @return
    418         * @throws MalformedURLException
    419         * @throws IOException
    420         * @throws XMLParsingException
    421         * @throws InconsistentRequestException
    422         * @throws OGCWebServiceException
    423         * @throws UnknownCRSException
    424         */
    425        private BufferedImage getMap( Map<String, String>[] model )
    426                                throws MalformedURLException, IOException, XMLParsingException,
    427                                InconsistentRequestException, OGCWebServiceException {
    428            int w = Integer.parseInt( model[0].get( "WIDTH" ) );
    429            int h = Integer.parseInt( model[0].get( "HEIGHT" ) );
    430            BufferedImage bJ = new BufferedImage( w, h, BufferedImage.TYPE_INT_RGB );
    431            Graphics g = bJ.getGraphics();
    432            g.setColor( Color.WHITE );
    433            g.fillRect( 1, 1, bJ.getWidth() - 2, bJ.getHeight() - 2 );
    434            g.dispose();
    435            GetMap gmr = null;
    436
    437            for ( int i = model.length - 1; i >= 0; i-- ) {
    438                String urls = OWSUtils.validateHTTPGetBaseURL( model[i].remove( "URL" ) );
    439                String s = URLDecoder.decode( model[i].get( "FORMAT" ), CharsetUtils.getSystemCharset() );
    440                model[i].put( "FORMAT", s );
    441                model[i].put( "ID", "1.1.1" );
    442                gmr = GetMap.create( model[i] );
    443                /*
    444                 * if ( sessionid != null ) { urls = StringTools.concat( 1000, urls, "&sessionID=", sessionid.getValue(),
    445                 * '&' ); }
    446                 */
    447                URL url = new URL( urls + gmr.getRequestParameter() );
    448                InputStream is = url.openStream();
    449                BufferedImage tmp = ImageIO.read( is );
    450                is.close();
    451                g = bJ.getGraphics();
    452                g.drawImage( tmp, 0, 0, null );
    453                g.dispose();
    454            }
    455
    456            return bJ;
    457        }
    458
    459        /**
    460         * draws the map to the background BufferedImage
    461         *
    462         * @param reqIm
    463         * @param bi
    464         * @param mapStart
    465         * @return
    466         */
    467        private BufferedImage drawMapToBI( BufferedImage reqIm, BufferedImage bi, int mapStart ) {
    468            Graphics g = bi.getGraphics();
    469            g.drawImage( reqIm, mapStart, mapStart, null );
    470            g.dispose();
    471
    472            return bi;
    473        }
    474
    475        /**
    476         * saves image with BufferedImage including map, legend and scalebar in chosen image format and directory set in
    477         * mapcontext.xml file. Via the attribute "ImageSource" the image can be called for.
    478         *
    479         * @param vc
    480         * @param struct
    481         * @param bg
    482         */
    483        private void saveImage( ViewContext vc, RPCStruct struct, BufferedImage bg ) {
    484            String format = (String) struct.getMember( "format" ).getValue();
    485            format = format.substring( format.indexOf( '/' ) + 1, format.length() );
    486            GeneralExtension ge = vc.getGeneral().getExtension();
    487            IOSettings ios = ge.getIOSettings();
    488            String dir = ios.getPrintDirectory().getDirectoryName();
    489
    490            long l = IDGenerator.getInstance().generateUniqueID() % 100;
    491            String file = "Map" + l + '.' + format;
    492
    493            try {
    494                String outPut = new URL( dir ).getFile() + '/' + file;
    495                File f = new File( outPut );
    496                f.deleteOnExit();
    497                FileOutputStream fos = new FileOutputStream( f );
    498                ImageUtils.saveImage( bg, fos, format, 1 );
    499            } catch ( Exception e ) {
    500                LOG.logError( "Error occurred in saving image_: ", e );
    501            }
    502
    503            String access = OWSUtils.validateHTTPGetBaseURL( ios.getPrintDirectory().getOnlineResource().toExternalForm() )
    504                            + "request=download&filename=" + file;
    505
    506            this.getRequest().setAttribute( "ImageSource", access );
    507            this.getRequest().setAttribute( "ImageWidth", new Integer( bg.getWidth() ) );
    508            this.getRequest().setAttribute( "ImageHeight", new Integer( bg.getHeight() ) );
    509
    510        }
    511
    512        /**
    513         * gets parameters of the LegendRequest
    514         *
    515         * @return
    516         * @throws InconsistentRequestException
    517         */
    518        private GetLegendGraphic getLegendRequestParameter()
    519                                throws InconsistentRequestException {
    520            HashMap<String, String> legend = toMap( "VERSION=1.1.1&REQUEST=GetLegendGraphic&FORMAT=image/png&WIDTH=50&HEIGHT=50&"
    521                                                    + "EXCEPTIONS=application/vnd.ogc.se_inimage&LAYER=europe:major_rivers&STYLE=default&"
    522                                                    + "SLD=file:///C:/Projekte/UmweltInfo/deegreewms/WEB-INF/xml/styles.xml" );
    523            return GetLegendGraphic.create( legend );
    524
    525        }
    526
    527        /**
    528         * gets legend with layers and styles. The size of the symbols is adjusted to the chosen paperFomrat and resolution.
    529         *
    530         * @param struct
    531         * @param glr
    532         * @param model
    533         * @return
    534         */
    535        private Map<String, Object> getLegend( RPCStruct struct, GetLegendGraphic glr, Map<String, String>[] model ) {
    536
    537            ArrayList<String> list1 = new ArrayList<String>();
    538            ArrayList<BufferedImage> list2 = new ArrayList<BufferedImage>();
    539
    540            String format = glr.getFormat();
    541            if ( format.equals( "image/jpg" ) )
    542                format = "image/jpeg";
    543
    544            String legendURL = "";
    545
    546            String paperFormat = (String) struct.getMember( "paperFormat" ).getValue();
    547            String resolution = (String) struct.getMember( "resolution" ).getValue();
    548            int h = 15;
    549            int w = 15;
    550            double tmph1 = 0;
    551            double tmpw1 = 0;
    552            double tmph2 = 0;
    553            double tmpw2 = 0;
    554
    555            if ( paperFormat.equals( "A4" ) ) {
    556                tmph1 = h / 3d;
    557                tmpw1 = w / 3d;
    558            } else if ( paperFormat.equals( "A3" ) ) {
    559                tmph1 = 2 * h / 3d;
    560                tmpw1 = 2 * w / 3d;
    561            }
    562
    563            double res = Double.parseDouble( resolution );
    564            tmph2 = ( ( res - 150 ) / 150d ) * h;
    565            tmpw2 = ( ( res - 150 ) / 150d ) * w;
    566
    567            w += (int) Math.round( tmpw1 + tmpw2 );
    568            h += (int) Math.round( tmph1 + tmph2 );
    569
    570            for ( int i = 0; i < model.length; i++ ) {
    571                if ( model[i].get( "SLD" ) != null ) {
    572                    continue;
    573                }
    574                String[] lays = StringTools.toArray( (String) model[i].get( "LAYERS" ), ",", false );
    575
    576                String style = (String) model[i].get( "STYLES" );
    577                String[] styles = new String[lays.length];
    578                for ( int j = 0; j < styles.length; j++ ) {
    579                    styles[j] = "default";
    580                }
    581
    582                if ( style != null && !style.trim().equals( "" ) ) {
    583                    // styles = StringTools.toArray(style,",",false);
    584                    if ( ( StringTools.toArray( style, ",", false ) ).length != 0 ) {
    585                        styles = StringTools.toArray( style, ",", false );
    586                    }
    587                } else {
    588                    styles = new String[lays.length];
    589                    for ( int j = 0; j < styles.length; j++ ) {
    590                        styles[j] = "default";
    591                    }
    592                }
    593
    594                if ( styles == null ) {
    595                    styles = new String[lays.length];
    596                    for ( int j = 0; j < styles.length; j++ ) {
    597                        styles[j] = "default";
    598                    }
    599                }
    600
    601                for ( int j = 0; j < lays.length; j++ ) {
    602                    String layer = lays[j];
    603
    604                    // added to prevent ArrayOutOfBoundsException
    605                    String stl = "default";
    606                    if ( j < styles.length ) {
    607                        stl = styles[j];
    608                    }
    609
    610                    legendURL = createLegendURL( w, h, layer, stl, format, glr, model[i] );
    611                    BufferedImage legendGraphic = null;
    612                    try {
    613                        InputStream is = new URL( legendURL ).openStream();
    614                        legendGraphic = ImageIO.read( is );
    615                        is.close();
    616                    } catch ( Exception e ) {
    617                        System.out.println( "\n\nLegend graphic for layer '" + layer + "' is not available. Skipping.\n\n" );
    618                        legendGraphic = null;
    619                        e.printStackTrace();
    620                    }
    621                    if ( legendGraphic != null ) {
    622                        list1.add( layer );
    623                        list2.add( legendGraphic );
    624                    }
    625                }
    626            }
    627
    628            String[] layers = list1.toArray( new String[list1.size()] );
    629            BufferedImage[] legs = list2.toArray( new BufferedImage[list2.size()] );
    630            HashMap<String, Object> map = new HashMap<String, Object>();
    631            map.put( "NAMES", layers );
    632            map.put( "IMAGES", legs );
    633
    634            return map;
    635        }
    636
    637        /**
    638         * creates legend URL with corresponding key values.
    639         *
    640         * @param w
    641         * @param h
    642         * @param layer
    643         * @param style
    644         * @param format
    645         * @param glr
    646         * @param model
    647         * @return
    648         */
    649        private String createLegendURL( int w, int h, String layer, String style, String format, GetLegendGraphic glr,
    650                                        Map<String,String> model ) {
    651
    652            String s = null;
    653            try {
    654                if ( "default".equals( style ) ) {
    655                    style = "";
    656                }
    657                String url = OWSUtils.validateHTTPGetBaseURL( (String) model.get( "URL" ) );
    658                s = StringTools.concat( 500, url, "service=WMS", "&VERSION=", glr.getVersion(),
    659                                        "&REQUEST=GetLegendGraphic", "&FORMAT=", format, "&WIDTH=", w, "&HEIGHT=", h,
    660                                        "&EXCEPTIONS=application/vnd.ogc.se_inimage&LAYER=",
    661                                        URLDecoder.decode( layer, CharsetUtils.getSystemCharset() ), "&STYLE=", style );
    662                // insufficient information available for user restrictions
    663                // TODO
    664                // HttpServletRequest req = (HttpServletRequest) getRequest();
    665                // if ( req.getUserPrincipal() != null ) {
    666                // String user = req.getUserPrincipal().getName();
    667                // if ( user.indexOf( "\\" ) > 1 ) {
    668                // String[] us = StringTools.toArray( user, "\\", false );
    669                // user = us[us.length - 1];
    670                // }
    671                // s = StringTools.concat( 500, s, "&user=", user );
    672                // }
    673
    674            } catch ( UnsupportedEncodingException e ) {
    675                // should never happen
    676                e.printStackTrace();
    677            }
    678            return s;
    679        }
    680    }