001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/ogcwebservices/wms/operation/GetLegendGraphic.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.ogcwebservices.wms.operation;
037    
038    import java.net.URL;
039    import java.net.URLEncoder;
040    import java.util.Map;
041    
042    import org.deegree.framework.util.CharsetUtils;
043    import org.deegree.framework.util.MimeTypeMapper;
044    import org.deegree.ogcwebservices.InconsistentRequestException;
045    import org.deegree.ogcwebservices.OGCWebServiceException;
046    import org.deegree.ogcwebservices.wms.InvalidFormatException;
047    
048    /**
049     *
050     * @author Katharina Lupp <a href="mailto:k.lupp@web.de">Katharina Lupp</a>
051     * @version $Revision: 24806 $ $Date: 2010-06-09 16:41:16 +0200 (Mi, 09 Jun 2010) $
052     */
053    public class GetLegendGraphic extends WMSRequestBase {
054    
055        private static final long serialVersionUID = -3632596487434212256L;
056    
057        private String rule = null;
058    
059        private String sLD_Body = null;
060    
061        private String featureType = null;
062    
063        private String format = null;
064    
065        private String layer = null;
066    
067        private URL sLD = null;
068    
069        private String style = null;
070    
071        private double scale = 0;
072    
073        private int width = 0;
074    
075        private int height = 0;
076    
077        private String exceptions = null;
078    
079        /**
080         * @param model
081         *            key-value-pair representation of the request
082         * @return an instance
083         * @throws InconsistentRequestException
084         */
085        public static GetLegendGraphic create( Map<String, String> model )
086                                throws InconsistentRequestException {
087            // version
088            String version = model.remove( "VERSION" );
089    
090            if ( version == null ) {
091                throw new InconsistentRequestException( "Parameter VERSION must be set." );
092            }
093            if ( version.compareTo( "1.1.1" ) < 0 ) {
094                throw new InconsistentRequestException( "Version must be >= 1.1.1." );
095            }
096    
097            // format
098            String format = model.remove( "FORMAT" );
099            if ( format == null ) {
100                throw new InconsistentRequestException( "Parameter FORMAT must be set." );
101            }
102            if ( !MimeTypeMapper.isKnownImageType( format ) ) {
103                throw new InvalidFormatException( format + " is not a valid image/result format" );
104            }
105    
106            // layer
107            String layer = model.remove( "LAYER" );
108            if ( layer == null ) {
109                throw new InconsistentRequestException( "Parameter LAYER must be set." );
110            }
111    
112            // style
113            String style = model.remove( "STYLE" );
114            if ( style == null || style.equals( "" ) || "DEFAULT".equalsIgnoreCase( style ) ) {
115                style = "default:" + layer;
116            }
117    
118            // featureType
119            String featureType = model.remove( "FEATURETYPE" );
120    
121            // rule
122            String rule = model.remove( "RULE" );
123    
124            // scale
125            String tmp = model.remove( "SCALE" );
126            if ( tmp != null && rule != null ) {
127                throw new InconsistentRequestException(
128                                                        "SCALE or RULE can be set in a request but not both" );
129            }
130            double scale = -1;
131            if ( tmp != null ) {
132                try {
133                    scale = Double.parseDouble( tmp );
134                } catch ( Exception e ) {
135                    throw new InconsistentRequestException( "Scale, if set, must be a valid number" );
136                }
137            }
138    
139            // SLD
140            tmp = model.remove( "SLD" );
141            URL sld = null;
142            if ( tmp != null ) {
143                try {
144                    sld = new URL( tmp );
145                } catch ( Exception e ) {
146                    throw new InconsistentRequestException(
147                                                            "If SLD parameter is set it must be a valid URL" );
148                }
149            }
150    
151            // SLD_BODY
152            String sld_body = model.remove( "SLD_BODY" );
153            if ( sld_body != null && sld != null ) {
154                throw new InconsistentRequestException(
155                                                        "SLD or SLD_BODY can be set in a request but not both" );
156            }
157    
158            // width
159            tmp = model.remove( "WIDTH" );
160            if ( tmp == null ) {
161                tmp = "20";
162            }
163    
164            int width = 0;
165            try {
166                width = Integer.parseInt( tmp );
167            } catch ( Exception e ) {
168                throw new InconsistentRequestException( "WIDTH must be a valid integer number" );
169            }
170    
171            // height
172            tmp = model.remove( "HEIGHT" );
173            if ( tmp == null ) {
174                tmp = "20";
175            }
176    
177            int height = 0;
178            try {
179                height = Integer.parseInt( tmp );
180            } catch ( Exception e ) {
181                throw new InconsistentRequestException( "HEIGHT must be a valid integer number" );
182            }
183    
184            // exceptions
185            String exceptions = model.remove( "EXCEPTIONS" );
186            if ( exceptions == null ) {
187                exceptions = "application/vnd.ogc.se_xml";
188            }
189    
190            String id = model.remove( "ID" );
191            Map<String, String> vendorSpecificParameter = model;
192    
193            return create( id, version, layer, style, featureType, rule, scale, sld, sld_body, format,
194                           width, height, exceptions, vendorSpecificParameter );
195        }
196    
197        /**
198         * @param id
199         *            unique id of the request
200         * @param version
201         *            version of the target WMS
202         * @param layer
203         *            name of the layer the style is assigned to
204         * @param style
205         *            name of the style (optional; if not present -> 'default')
206         * @param featureType
207         *            name of the feature type a legend element shall be created for --> SLD
208         * @param rule
209         *            name of the rule a legend element shall be created for --> SLD
210         * @param scale
211         *            scale for which a rule must be valid --> SLD
212         * @param sld
213         *            refernce to a SLD document
214         * @param sld_body
215         *            SLD document
216         * @param format
217         *            image format of the returned legend element
218         * @param width
219         * @param height
220         * @param exceptions
221         *            format of the excpetion if something went wrong
222         * @param vendorSpecificParameter
223         * @return instance of <tt>GetLegendGraphic</tt>
224         */
225        public static GetLegendGraphic create( String id, String version, String layer, String style,
226                                               String featureType, String rule, double scale, URL sld,
227                                               String sld_body, String format, int width, int height,
228                                               String exceptions,
229                                               Map<String, String> vendorSpecificParameter ) {
230            return new GetLegendGraphic( id, version, layer, style, featureType, rule, scale, sld,
231                                         sld_body, format, width, height, exceptions,
232                                         vendorSpecificParameter );
233        }
234    
235        /**
236         * Creates a new GetLegendGraphic object.
237         *
238         * @param layer
239         * @param style
240         * @param featureType
241         * @param rule
242         * @param scale
243         * @param sLD
244         * @param sLD_Body
245         * @param format
246         * @param version
247         * @param id
248         * @param vendorSpecificParameter
249         */
250        private GetLegendGraphic( String id, String version, String layer, String style,
251                                  String featureType, String rule, double scale, URL sLD,
252                                  String sLD_Body, String format, int width, int height,
253                                  String exceptions, Map<String, String> vendorSpecificParameter ) {
254            super( version, id, vendorSpecificParameter );
255            setLayer( layer );
256            setStyle( style );
257            setFeatureType( featureType );
258            setRule( rule );
259            setScale( scale );
260            setSLD( sLD );
261            setSLD_Body( sLD_Body );
262            setFormat( format );
263            this.width = width;
264            this.height = height;
265            this.exceptions = exceptions;
266        }
267    
268        /**
269         * @return the &lt;Layer&gt;. A Map Server MUST include at least one <Layer> element for each
270         *         map layer offered. If desired, data layers MAY be repeated in different categories
271         *         when relevant. A Layer element MAY state the Name by which a map of the layer is
272         *         requested, MUST give a Title to be used in human-readable menus, and MAY include: a
273         *         human-readable Abstract containing further description, available Spatial Reference
274         *         Systems (SRS), bounding boxes in Lat/Lon and SRS-specific coordinates indicating the
275         *         available geographic coverage, styles in which the layer is available, a URL for more
276         *         information about the data, and a hint concerning appropriate map scales for
277         *         displaying this layer. Use of the nesting hierarchy is optional.
278         */
279        public String getLayer() {
280            return layer;
281        }
282    
283        /**
284         * sets the
285         *
286         * @param layer
287         *            &lt;Layer&gt;
288         */
289        public void setLayer( String layer ) {
290            this.layer = layer;
291        }
292    
293        /**
294         * @return the &lt;Style&gt;. Named style that can be used for rendering the layer.
295         */
296        public String getStyle() {
297            return style;
298        }
299    
300        /**
301         * sets the
302         *
303         * @param style
304         *            &lt;Style&gt;
305         */
306        public void setStyle( String style ) {
307            this.style = style;
308        }
309    
310        /**
311         * @return the &lt;FeatureType&gt;
312         */
313        public String getFeatureType() {
314            return featureType;
315        }
316    
317        /**
318         * sets the
319         *
320         * @param featureType
321         *            &lt;FeatureType&gt;
322         */
323        public void setFeatureType( String featureType ) {
324            this.featureType = featureType;
325        }
326    
327        /**
328         * @return the &lt;Rule&gt;
329         */
330        public String getRule() {
331            return rule;
332        }
333    
334        /**
335         * sets the
336         *
337         * @param rule
338         *            &lt;Rule&gt;
339         */
340        public void setRule( String rule ) {
341            this.rule = rule;
342        }
343    
344        /**
345         * @return the &lt;Scale&gt;. Comma-seperated min and max scale values of a layer.
346         */
347        public double getScale() {
348            return scale;
349        }
350    
351        /**
352         * Comma-seperated min and max scale values of a layer. sets the
353         *
354         * @param scale
355         *            &lt;Scale&gt;.
356         */
357        public void setScale( double scale ) {
358            this.scale = scale;
359        }
360    
361        /**
362         * @return a reference (URL) to a SLD document
363         */
364        public URL getSLD() {
365            return sLD;
366        }
367    
368        /**
369         * sets a reference (URL) to a SLD document
370         *
371         * @param sLD
372         *            the URL
373         */
374        public void setSLD( URL sLD ) {
375            this.sLD = sLD;
376        }
377    
378        /**
379         * @return the body of a SLD document. If SLD_BODY parameter is set, the SLD parameter isn't set
380         *         and vice versa
381         */
382        public String getSLD_Body() {
383            return sLD_Body;
384        }
385    
386        /**
387         * sets the body of a SLD document. If SLD_BODY parameter is set, the SLD parameter isn't set
388         * and vice versa
389         *
390         * @param sLD_Body
391         *            the body
392         */
393        public void setSLD_Body( String sLD_Body ) {
394            this.sLD_Body = sLD_Body;
395        }
396    
397        /**
398         * @return the name of the image format the legend graphics shall have
399         */
400        public String getFormat() {
401            return format;
402        }
403    
404        /**
405         * sets the name of the image format the legend graphics shall have
406         *
407         * @param format
408         *            the format string
409         */
410        public void setFormat( String format ) {
411            this.format = format;
412        }
413    
414        /**
415         * This gives a hint for the height of the returned graphic in pixels. Vector-graphics can use
416         * this value as a hint for the level of detail to include.
417         *
418         * @return the height
419         */
420        public int getHeight() {
421            return height;
422        }
423    
424        /**
425         * @see GetLegendGraphic#getHeight()
426         * @param height
427         */
428        public void setHeight( int height ) {
429            this.height = height;
430        }
431    
432        /**
433         * This gives a hint for the width of the returned graphic in pixels. Vector-graphics can use
434         * this value as a hint for the level of detail to include.
435         *
436         * @return the width
437         */
438        public int getWidth() {
439            return width;
440        }
441    
442        /**
443         * @see GetLegendGraphic#getWidth()
444         * @param width
445         */
446        public void setWidth( int width ) {
447            this.width = width;
448        }
449    
450        /**
451         * This gives the MIME type of the format in which to return exceptions. Allowed values are the
452         * same as for the EXCEPTIONS= parameter of the WMS GetMap request.
453         *
454         * @return the exception format
455         */
456        public String getExceptions() {
457            return exceptions;
458        }
459    
460        /**
461         * @see GetLegendGraphic#getExceptions()
462         * @param exceptions
463         */
464        public void setExceptions( String exceptions ) {
465            this.exceptions = exceptions;
466        }
467    
468        /**
469         * method for creating a OGC WMS 1.1.1 conform legend graphic request
470         */
471        @Override
472        public String getRequestParameter()
473                                throws OGCWebServiceException {
474    
475            StringBuffer url = new StringBuffer( "SERVICE=WMS&VERSION=" + getVersion() );
476            url.append( "&REQUEST=GetLegendGraphic");
477            url.append( "&LAYER=" ).append( getLayer() );
478    
479            if ( getStyle() != null && getStyle().length() > 0 ) {
480                url.append( "&STYLE=" + getStyle() );
481            }
482    
483            if ( getFeatureType() != null && getFeatureType().length() > 0 ) {
484                url.append( "&FEATURETYPE=" + getFeatureType() );
485            }
486    
487            if ( getSLD() != null ) {
488                url.append( "&SLD=" + getSLD().toExternalForm() );
489            } else if ( getSLD_Body() != null ) {
490                String tmp = null;
491                try {
492                    tmp = URLEncoder.encode( getSLD_Body(), CharsetUtils.getSystemCharset() );
493                } catch ( Exception e ) {
494                    throw new OGCWebServiceException( e.toString() );
495                }
496                url.append( "&SLD_BODY=" + tmp );
497            }
498    
499            url.append( "&FORMAT=" + getFormat() );
500            url.append( "&WIDTH=" + getWidth() );
501            url.append( "&HEIGHT=" + getHeight() );
502    
503            if ( ( getExceptions() != null ) && ( getExceptions().length() > 0 ) ) {
504                url.append( "&EXCEPTIONS=" + getExceptions() );
505            }
506    
507            return url.toString();
508        }
509    
510    }