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