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 (https://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: https://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: https://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
145        /** Hybrid map type. */
146        hybrid,
147
148        /** Road map type. */
149        roadmap,
150
151        /** Satellite image type. */
152        satellite,
153
154        /** Terrain map type. */
155        terrain;
156
157        /**
158         * Checks if <code>this</code> is {@link #hybrid}.<p>
159         *
160         * @return <code>true</code>, if <code>this</code> is {@link #hybrid}
161         */
162        public boolean isHybrid() {
163
164            return this == hybrid;
165        }
166
167        /**
168         * Checks if <code>this</code> is {@link #roadmap}.<p>
169         *
170         * @return <code>true</code>, if <code>this</code> is {@link #roadmap}
171         */
172        public boolean isMap() {
173
174            return this == roadmap;
175        }
176
177        /**
178         * Checks if <code>this</code> is {@link #satellite}.<p>
179         *
180         * @return <code>true</code>, if <code>this</code> is {@link #satellite}
181         */
182        public boolean isSatellite() {
183
184            return this == satellite;
185        }
186
187        /**
188         * Checks if <code>this</code> is {@link #terrain}.<p>
189         *
190         * @return <code>true</code>, if <code>this</code> is {@link #terrain}
191         */
192        public boolean isTerrain() {
193
194            return this == terrain;
195        }
196    }
197
198    /** The default map height in pixels. */
199    public static final int DEFAULT_HEIGHT = 300;
200
201    /** The default latitude. */
202    public static final float DEFAULT_LAT = 0;
203
204    /** The default longitude. */
205    public static final float DEFAULT_LNG = 0;
206
207    /** The default map mode. */
208    public static final MapMode DEFAULT_MODE = MapMode.dynamicMode;
209
210    /** The default map type. */
211    public static final MapType DEFAULT_TYPE = MapType.roadmap;
212
213    /** The default map width in pixels. */
214    public static final int DEFAULT_WIDTH = 400;
215
216    /** The default zoom level. */
217    public static final int DEFAULT_ZOOM = 10;
218
219    /** Option height. */
220    public static final String OPTION_HEIGHT = "height";
221
222    /** Option lat. */
223    public static final String OPTION_LAT = "lat";
224
225    /** Option lng. */
226    public static final String OPTION_LNG = "lng";
227
228    /** Option mode. */
229    public static final String OPTION_MODE = "mode";
230
231    /** Option type. */
232    public static final String OPTION_TYPE = "type";
233
234    /** Option width. */
235    public static final String OPTION_WIDTH = "width";
236
237    /** Option zoom. */
238    public static final String OPTION_ZOOM = "zoom";
239
240    /** The log object for this class. */
241    private static final Log LOG = CmsLog.getLog(CmsLocationPickerWidgetValue.class);
242
243    /** Map height value. */
244    private int m_height;
245
246    /** Map center latitude value. */
247    private float m_lat;
248
249    /** Map center longitude value. */
250    private float m_lng;
251
252    /** Map mode value. */
253    private MapMode m_mode;
254
255    /** Map type value. */
256    private MapType m_type;
257
258    /** Map width value. */
259    private int m_width;
260
261    /** Map zoom value. */
262    private int m_zoom;
263
264    /**
265     * Creates a new empty widget option object.<p>
266     */
267    public CmsLocationPickerWidgetValue() {
268
269        // initialize the members
270        m_zoom = DEFAULT_ZOOM;
271        m_height = DEFAULT_HEIGHT;
272        m_width = DEFAULT_WIDTH;
273        m_mode = DEFAULT_MODE;
274        m_type = DEFAULT_TYPE;
275        m_lat = DEFAULT_LAT;
276        m_lng = DEFAULT_LNG;
277    }
278
279    /**
280     * Creates a new widget value object, configured by the given value String.<p>
281     *
282     * @param value the value String to parse
283     */
284    public CmsLocationPickerWidgetValue(String value) {
285
286        this();
287        parseOptions(value);
288    }
289
290    /**
291     * Returns the height.<p>
292     *
293     * @return the height
294     */
295    public int getHeight() {
296
297        return m_height;
298    }
299
300    /**
301     * Returns the lat.<p>
302     *
303     * @return the lat
304     */
305    public float getLat() {
306
307        return m_lat;
308    }
309
310    /**
311     * Returns the longitude.<p>
312     *
313     * @return the longitude
314     */
315    public float getLng() {
316
317        return m_lng;
318    }
319
320    /**
321     * Returns the mode.<p>
322     *
323     * @return the mode
324     */
325    public MapMode getMode() {
326
327        return m_mode;
328    }
329
330    /**
331     * Returns the type.<p>
332     *
333     * @return the type
334     */
335    public MapType getType() {
336
337        return m_type;
338    }
339
340    /**
341     * Returns the width.<p>
342     *
343     * @return the width
344     */
345    public int getWidth() {
346
347        return m_width;
348    }
349
350    /**
351     * Returns the zoom.<p>
352     *
353     * @return the zoom
354     */
355    public int getZoom() {
356
357        return m_zoom;
358    }
359
360    /**
361     * Sets the height.<p>
362     *
363     * @param height the height to set
364     */
365    public void setHeight(int height) {
366
367        m_height = height;
368    }
369
370    /**
371     * Sets the latitude.<p>
372     *
373     * @param lat the latitude to set
374     */
375    public void setLat(float lat) {
376
377        m_lat = lat;
378    }
379
380    /**
381     * Sets the longitude.<p>
382     *
383     * @param lng the longitude to set
384     */
385    public void setLng(float lng) {
386
387        m_lng = lng;
388    }
389
390    /**
391     * Sets the mode.<p>
392     *
393     * @param mode the mode to set
394     */
395    public void setMode(MapMode mode) {
396
397        m_mode = mode;
398    }
399
400    /**
401     * Sets the type.<p>
402     *
403     * @param type the type to set
404     */
405    public void setType(MapType type) {
406
407        m_type = type;
408    }
409
410    /**
411     * Sets the width.<p>
412     *
413     * @param width the width to set
414     */
415    public void setWidth(int width) {
416
417        m_width = width;
418    }
419
420    /**
421     * Sets the value that is wrapped.
422     * The method is added for convenient usage of the class in JSPs.
423     * In a formatter JSP you can use
424     * <pre><code>
425     * &lt;jsp:useBean id="map" class="org.opencms.widgets.CmsLocationPickerWidgetValue" /&gt;
426     * &lt;jsp:setProperty name="map" property="wrappedValue" value="${content.value.Map}" /&gt;
427     * </code></pre>
428     * instead of setting the value directly via the constructor.
429     * @param value The string value that should be wrapped as CmsLocationPickerWidgetValue.
430     */
431    public void setWrappedValue(final String value) {
432
433        parseOptions(value);
434    }
435
436    /**
437     * Sets the zoom.<p>
438     *
439     * @param zoom the zoom to set
440     */
441    public void setZoom(int zoom) {
442
443        m_zoom = zoom;
444    }
445
446    /**
447     * @see java.lang.Object#toString()
448     */
449    @Override
450    public String toString() {
451
452        JSONObject json = new JSONObject();
453
454        try {
455            json.put(OPTION_LAT, getLat());
456        } catch (JSONException e) {
457            if (LOG.isErrorEnabled()) {
458                LOG.error(e.getLocalizedMessage(), e);
459            }
460        }
461        try {
462            json.put(OPTION_LNG, getLng());
463        } catch (JSONException e) {
464            if (LOG.isErrorEnabled()) {
465                LOG.error(e.getLocalizedMessage(), e);
466            }
467        }
468        try {
469            json.put(OPTION_ZOOM, getZoom());
470        } catch (JSONException e) {
471            if (LOG.isErrorEnabled()) {
472                LOG.error(e.getLocalizedMessage(), e);
473            }
474        }
475        try {
476            json.put(OPTION_WIDTH, getWidth());
477        } catch (JSONException e) {
478            if (LOG.isErrorEnabled()) {
479                LOG.error(e.getLocalizedMessage(), e);
480            }
481        }
482        try {
483            json.put(OPTION_HEIGHT, getHeight());
484        } catch (JSONException e) {
485            if (LOG.isErrorEnabled()) {
486                LOG.error(e.getLocalizedMessage(), e);
487            }
488        }
489        try {
490            json.put(OPTION_TYPE, getType().toString());
491        } catch (JSONException e) {
492            if (LOG.isErrorEnabled()) {
493                LOG.error(e.getLocalizedMessage(), e);
494            }
495        }
496        try {
497            json.put(OPTION_MODE, getMode().getMode());
498        } catch (JSONException e) {
499            if (LOG.isErrorEnabled()) {
500                LOG.error(e.getLocalizedMessage(), e);
501            }
502        }
503
504        return json.toString();
505    }
506
507    /**
508     * Parses the given configuration String.<p>
509     *
510     * @param configuration the configuration String to parse
511     */
512    protected void parseOptions(String configuration) {
513
514        if (CmsStringUtil.isEmptyOrWhitespaceOnly(configuration)) {
515            return;
516        }
517        if (!configuration.startsWith("{")) {
518            // add curly braces if not present
519            configuration = "{" + configuration + "}";
520        }
521        try {
522            JSONObject json = new JSONObject(configuration);
523            if (json.has(OPTION_LAT)) {
524                setLat((float)json.getDouble(OPTION_LAT));
525            }
526            if (json.has(OPTION_LNG)) {
527                setLng((float)json.getDouble(OPTION_LNG));
528            }
529            if (json.has(OPTION_ZOOM)) {
530                setZoom(json.getInt(OPTION_ZOOM));
531            }
532            if (json.has(OPTION_WIDTH)) {
533                setWidth(json.getInt(OPTION_WIDTH));
534            }
535            if (json.has(OPTION_HEIGHT)) {
536                setHeight(json.getInt(OPTION_HEIGHT));
537            }
538            if (json.has(OPTION_TYPE)) {
539                setType(MapType.valueOf(json.getString(OPTION_TYPE)));
540            }
541            if (json.has(OPTION_MODE)) {
542                // do not use value of, as the client side string is not equal to the enumeration mode name
543                setMode(MapMode.parseMode(json.getString(OPTION_MODE)));
544            }
545        } catch (JSONException e) {
546            // something went wrong
547            if (LOG.isErrorEnabled()) {
548                LOG.error(e.getLocalizedMessage(), e);
549            }
550            return;
551        }
552    }
553}