001/*
002 * File   : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.v8.geomap/src/com/alkacon/opencms/v8/geomap/CmsGoogleMapWidgetValue.java,v $
003 * Date   : $Date: 2011/02/16 13:05:25 $
004 * Version: $Revision: 1.1 $
005 *
006 * This library is part of OpenCms -
007 * the Open Source Content Management System
008 *
009 * Copyright (c) 2002 - 2008 Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
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 * For further information about Alkacon Software GmbH & Co. KG, please see the
022 * company website: http://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: http://www.opencms.org
026 *
027 * You should have received a copy of the GNU Lesser General Public
028 * License along with this library; if not, write to the Free Software
029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030 */
031
032package org.opencms.widgets;
033
034import org.opencms.json.JSONException;
035import org.opencms.json.JSONObject;
036import org.opencms.main.CmsLog;
037import org.opencms.util.CmsStringUtil;
038
039import org.apache.commons.logging.Log;
040
041/**
042 * A value of the google map widget.<p>
043 *
044 * This is the parsed value of an element of the type <code>String</code> using the widget <code>GoogleMapWidget</code>.
045 *
046 * <code>lat:50.953412,lng:6.956534,zoom:13,width:400,height:300,mode:dynamic,type:hybrid</code><p>
047 *
048 * Available options are:
049 * <ul>
050 * <li><code>lat:50.953412</code>: the latitude</li>
051 * <li><code>lng:6.956534</code>: the longitude</li>
052 * <li><code>zoom:7</code>: initial zoom level</li>
053 * <li><code>width:300</code>: map width in pixels or %</li>
054 * <li><code>height:200</code>: map height in pixels or %</li>
055 * <li><code>mode:'static'</code>: the front-end map's mode should be dynamic or static</li>
056 * <li><code>type:'hybrid'</code>: the map type, which can be normal, hybrid, satellite and physical</li>
057 * </ul>
058 *
059 * @author Michael Moossen
060 *
061 * @version $Revision: 1.1 $
062 *
063 * @since 7.0.5
064 */
065public class CmsLocationPickerWidgetValue {
066
067    /**
068     * Enumeration class for defining the map mode.<p>
069     */
070    public static enum MapMode {
071
072        /** The dynamic map mode. */
073        dynamicMode("dynamic"),
074
075        /** The static map mode. */
076        staticMode("static");
077
078        /** The mode value. */
079        private String m_modeValue;
080
081        /**
082         * Constructor.<p>
083         *
084         * @param modeValue the mode value
085         */
086        private MapMode(String modeValue) {
087
088            m_modeValue = modeValue;
089        }
090
091        /**
092         * Parses the client side mode representation, required as 'static' is a java keyword.<p>
093         *
094         * @param mode the mode name
095         *
096         * @return the mode
097         */
098        public static MapMode parseMode(String mode) {
099
100            MapMode result = null;
101            if (dynamicMode.getMode().equals(mode)) {
102                result = dynamicMode;
103            } else if (staticMode.getMode().equals(mode)) {
104                result = staticMode;
105            }
106            return result;
107        }
108
109        /**
110         * Returns the mode.<p>
111         *
112         * @return the mode
113         */
114        public String getMode() {
115
116            return m_modeValue;
117        }
118
119        /**
120         * Checks if <code>this</code> is {@link #dynamicMode}.<p>
121         *
122         * @return <code>true</code>, if <code>this</code> is {@link #dynamicMode}
123         */
124        public boolean isDynamic() {
125
126            return this == dynamicMode;
127        }
128
129        /**
130         * Checks if <code>this</code> is {@link #staticMode}.<p>
131         *
132         * @return <code>true</code>, if <code>this</code> is {@link #staticMode}
133         */
134        public boolean isStatic() {
135
136            return this == staticMode;
137        }
138    }
139
140    /**
141     * Enumeration class for defining the map types.<p>
142     */
143    public static enum MapType {
144        /** Hybrid map type. */
145        hybrid,
146
147        /** Road map type. */
148        roadmap,
149
150        /** Satellite image type. */
151        satellite,
152
153        /** Terrain map type. */
154        terrain;
155
156        /**
157         * Checks if <code>this</code> is {@link #hybrid}.<p>
158         *
159         * @return <code>true</code>, if <code>this</code> is {@link #hybrid}
160         */
161        public boolean isHybrid() {
162
163            return this == hybrid;
164        }
165
166        /**
167         * Checks if <code>this</code> is {@link #roadmap}.<p>
168         *
169         * @return <code>true</code>, if <code>this</code> is {@link #roadmap}
170         */
171        public boolean isMap() {
172
173            return this == roadmap;
174        }
175
176        /**
177         * Checks if <code>this</code> is {@link #satellite}.<p>
178         *
179         * @return <code>true</code>, if <code>this</code> is {@link #satellite}
180         */
181        public boolean isSatellite() {
182
183            return this == satellite;
184        }
185
186        /**
187         * Checks if <code>this</code> is {@link #terrain}.<p>
188         *
189         * @return <code>true</code>, if <code>this</code> is {@link #terrain}
190         */
191        public boolean isTerrain() {
192
193            return this == terrain;
194        }
195    }
196
197    /** The default map height in pixels. */
198    public static final int DEFAULT_HEIGHT = 300;
199
200    /** The default latitude. */
201    public static final float DEFAULT_LAT = 0;
202
203    /** The default longitude. */
204    public static final float DEFAULT_LNG = 0;
205
206    /** The default map mode. */
207    public static final MapMode DEFAULT_MODE = MapMode.dynamicMode;
208
209    /** The default map type. */
210    public static final MapType DEFAULT_TYPE = MapType.roadmap;
211
212    /** The default map width in pixels. */
213    public static final int DEFAULT_WIDTH = 400;
214
215    /** The default zoom level. */
216    public static final int DEFAULT_ZOOM = 10;
217
218    /** Option height. */
219    public static final String OPTION_HEIGHT = "height";
220
221    /** Option lat. */
222    public static final String OPTION_LAT = "lat";
223
224    /** Option lng. */
225    public static final String OPTION_LNG = "lng";
226
227    /** Option mode. */
228    public static final String OPTION_MODE = "mode";
229
230    /** Option type. */
231    public static final String OPTION_TYPE = "type";
232
233    /** Option width. */
234    public static final String OPTION_WIDTH = "width";
235
236    /** Option zoom. */
237    public static final String OPTION_ZOOM = "zoom";
238
239    /** The log object for this class. */
240    private static final Log LOG = CmsLog.getLog(CmsLocationPickerWidgetValue.class);
241
242    /** Map height value. */
243    private int m_height;
244
245    /** Map center latitude value. */
246    private float m_lat;
247
248    /** Map center longitude value. */
249    private float m_lng;
250
251    /** Map mode value. */
252    private MapMode m_mode;
253
254    /** Map type value. */
255    private MapType m_type;
256
257    /** Map width value. */
258    private int m_width;
259
260    /** Map zoom value. */
261    private int m_zoom;
262
263    /**
264     * Creates a new empty widget option object.<p>
265     */
266    public CmsLocationPickerWidgetValue() {
267
268        // initialize the members
269        m_zoom = DEFAULT_ZOOM;
270        m_height = DEFAULT_HEIGHT;
271        m_width = DEFAULT_WIDTH;
272        m_mode = DEFAULT_MODE;
273        m_type = DEFAULT_TYPE;
274        m_lat = DEFAULT_LAT;
275        m_lng = DEFAULT_LNG;
276    }
277
278    /**
279     * Creates a new widget value object, configured by the given value String.<p>
280     *
281     * @param value the value String to parse
282     */
283    public CmsLocationPickerWidgetValue(String value) {
284
285        this();
286        parseOptions(value);
287    }
288
289    /**
290     * Returns the height.<p>
291     *
292     * @return the height
293     */
294    public int getHeight() {
295
296        return m_height;
297    }
298
299    /**
300     * Returns the lat.<p>
301     *
302     * @return the lat
303     */
304    public float getLat() {
305
306        return m_lat;
307    }
308
309    /**
310     * Returns the longitude.<p>
311     *
312     * @return the longitude
313     */
314    public float getLng() {
315
316        return m_lng;
317    }
318
319    /**
320     * Returns the mode.<p>
321     *
322     * @return the mode
323     */
324    public MapMode getMode() {
325
326        return m_mode;
327    }
328
329    /**
330     * Returns the type.<p>
331     *
332     * @return the type
333     */
334    public MapType getType() {
335
336        return m_type;
337    }
338
339    /**
340     * Returns the width.<p>
341     *
342     * @return the width
343     */
344    public int getWidth() {
345
346        return m_width;
347    }
348
349    /**
350     * Returns the zoom.<p>
351     *
352     * @return the zoom
353     */
354    public int getZoom() {
355
356        return m_zoom;
357    }
358
359    /**
360     * Sets the height.<p>
361     *
362     * @param height the height to set
363     */
364    public void setHeight(int height) {
365
366        m_height = height;
367    }
368
369    /**
370     * Sets the latitude.<p>
371     *
372     * @param lat the latitude to set
373     */
374    public void setLat(float lat) {
375
376        m_lat = lat;
377    }
378
379    /**
380     * Sets the longitude.<p>
381     *
382     * @param lng the longitude to set
383     */
384    public void setLng(float lng) {
385
386        m_lng = lng;
387    }
388
389    /**
390     * Sets the mode.<p>
391     *
392     * @param mode the mode to set
393     */
394    public void setMode(MapMode mode) {
395
396        m_mode = mode;
397    }
398
399    /**
400     * Sets the type.<p>
401     *
402     * @param type the type to set
403     */
404    public void setType(MapType type) {
405
406        m_type = type;
407    }
408
409    /**
410     * Sets the width.<p>
411     *
412     * @param width the width to set
413     */
414    public void setWidth(int width) {
415
416        m_width = width;
417    }
418
419    /**
420     * Sets the value that is wrapped.
421     * The method is added for convenient usage of the class in JSPs.
422     * In a formatter JSP you can use
423     * <pre><code>
424     * <jsp:useBean id="map" class="org.opencms.widgets.CmsLocationPickerWidgetValue" />
425     * <jsp:setProperty name="map" property="wrappedValue" value="${content.value.Map}" />
426     * </code></pre>
427     * instead of setting the value directly via the constructor.
428     * @param value The string value that should be wrapped as CmsLocationPickerWidgetValue.
429     */
430    public void setWrappedValue(final String value) {
431
432        parseOptions(value);
433    }
434
435    /**
436     * Sets the zoom.<p>
437     *
438     * @param zoom the zoom to set
439     */
440    public void setZoom(int zoom) {
441
442        m_zoom = zoom;
443    }
444
445    /**
446     * @see java.lang.Object#toString()
447     */
448    @Override
449    public String toString() {
450
451        JSONObject json = new JSONObject();
452
453        try {
454            json.put(OPTION_LAT, getLat());
455        } catch (JSONException e) {
456            if (LOG.isErrorEnabled()) {
457                LOG.error(e.getLocalizedMessage(), e);
458            }
459        }
460        try {
461            json.put(OPTION_LNG, getLng());
462        } catch (JSONException e) {
463            if (LOG.isErrorEnabled()) {
464                LOG.error(e.getLocalizedMessage(), e);
465            }
466        }
467        try {
468            json.put(OPTION_ZOOM, getZoom());
469        } catch (JSONException e) {
470            if (LOG.isErrorEnabled()) {
471                LOG.error(e.getLocalizedMessage(), e);
472            }
473        }
474        try {
475            json.put(OPTION_WIDTH, getWidth());
476        } catch (JSONException e) {
477            if (LOG.isErrorEnabled()) {
478                LOG.error(e.getLocalizedMessage(), e);
479            }
480        }
481        try {
482            json.put(OPTION_HEIGHT, getHeight());
483        } catch (JSONException e) {
484            if (LOG.isErrorEnabled()) {
485                LOG.error(e.getLocalizedMessage(), e);
486            }
487        }
488        try {
489            json.put(OPTION_TYPE, getType().toString());
490        } catch (JSONException e) {
491            if (LOG.isErrorEnabled()) {
492                LOG.error(e.getLocalizedMessage(), e);
493            }
494        }
495        try {
496            json.put(OPTION_MODE, getMode().getMode());
497        } catch (JSONException e) {
498            if (LOG.isErrorEnabled()) {
499                LOG.error(e.getLocalizedMessage(), e);
500            }
501        }
502
503        return json.toString();
504    }
505
506    /**
507     * Parses the given configuration String.<p>
508     *
509     * @param configuration the configuration String to parse
510     */
511    protected void parseOptions(String configuration) {
512
513        if (CmsStringUtil.isEmptyOrWhitespaceOnly(configuration)) {
514            return;
515        }
516        if (!configuration.startsWith("{")) {
517            // add curly braces if not present
518            configuration = "{" + configuration + "}";
519        }
520        try {
521            JSONObject json = new JSONObject(configuration);
522            if (json.has(OPTION_LAT)) {
523                setLat((float)json.getDouble(OPTION_LAT));
524            }
525            if (json.has(OPTION_LNG)) {
526                setLng((float)json.getDouble(OPTION_LNG));
527            }
528            if (json.has(OPTION_ZOOM)) {
529                setZoom(json.getInt(OPTION_ZOOM));
530            }
531            if (json.has(OPTION_WIDTH)) {
532                setWidth(json.getInt(OPTION_WIDTH));
533            }
534            if (json.has(OPTION_HEIGHT)) {
535                setHeight(json.getInt(OPTION_HEIGHT));
536            }
537            if (json.has(OPTION_TYPE)) {
538                setType(MapType.valueOf(json.getString(OPTION_TYPE)));
539            }
540            if (json.has(OPTION_MODE)) {
541                // do not use value of, as the client side string is not equal to the enumeration mode name
542                setMode(MapMode.parseMode(json.getString(OPTION_MODE)));
543            }
544        } catch (JSONException e) {
545            // something went wrong
546            if (LOG.isErrorEnabled()) {
547                LOG.error(e.getLocalizedMessage(), e);
548            }
549            return;
550        }
551    }
552}