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