001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.shared.property;
029
030import org.opencms.util.CmsStringUtil;
031
032import java.util.HashMap;
033import java.util.Iterator;
034import java.util.Map;
035
036import com.google.common.base.Function;
037import com.google.gwt.user.client.rpc.IsSerializable;
038
039/**
040 * A client-side bean for representing an OpenCms property.<p>
041 *
042 * @since 8.0.0
043 */
044public class CmsClientProperty implements IsSerializable {
045
046    /**
047     * An enum used for addressing a specific value in a property.<p>
048     */
049    public enum Mode {
050        /** The effective value. */
051        effective,
052        /** The resource value. */
053        resource,
054        /** The structure value. */
055        structure;
056    }
057
058    /**
059     * Construction function which creates a new property with a given name.<p>
060     */
061    public static final Function<String, CmsClientProperty> CREATE_PROPERTY = new Function<String, CmsClientProperty>() {
062
063        /**
064         * Creates a new property.<p>
065         *
066         * @param name the property name
067         *
068         * @return the new property
069         */
070        public CmsClientProperty apply(String name) {
071
072            return new CmsClientProperty(name, "", "");
073        }
074    };
075
076    /** The path component identifying a resource value. */
077    public static final String PATH_RESOURCE_VALUE = "R";
078
079    /** The path component identifying a structure value. */
080    public static final String PATH_STRUCTURE_VALUE = "S";
081
082    /** The copyright property name. */
083    public static final String PROPERTY_COPYRIGHT = "Copyright";
084
085    /** The default-file property name. */
086    public static final String PROPERTY_DEFAULTFILE = "default-file";
087
088    /** The Description property name. */
089    public static final String PROPERTY_DESCRIPTION = "Description";
090
091    /** The NavPos property name. */
092    public static final String PROPERTY_NAVINFO = "NavInfo";
093
094    /** The NavPos property name. */
095    public static final String PROPERTY_NAVPOS = "NavPos";
096
097    /** The NavText property name. */
098    public static final String PROPERTY_NAVTEXT = "NavText";
099
100    /** The NavText property name. */
101    public static final String PROPERTY_TEMPLATE = "template";
102
103    /** The Title property name. */
104    public static final String PROPERTY_TITLE = "Title";
105
106    /** The name of the property. */
107    private String m_name;
108
109    /** The origin of the property (will usually be null). */
110    private String m_origin;
111
112    /** The resource value of the property. */
113    private String m_resourceValue;
114
115    /** The structure value of the property. */
116    private String m_structureValue;
117
118    /**
119     * Copy constructor.<p>
120     *
121     * @param property the object from which to copy the data
122     */
123    public CmsClientProperty(CmsClientProperty property) {
124
125        m_name = property.m_name;
126        m_structureValue = property.m_structureValue;
127        m_resourceValue = property.m_resourceValue;
128    }
129
130    /**
131     * Creates a new client property bean.<p>
132     *
133     * @param name the property name
134     * @param structureValue the structure value
135     * @param resourceValue the resource value
136     */
137    public CmsClientProperty(String name, String structureValue, String resourceValue) {
138
139        m_name = name;
140        m_structureValue = structureValue;
141        m_resourceValue = resourceValue;
142    }
143
144    /**
145     * Empty default constructor, used for serialization.<p>
146     */
147    protected CmsClientProperty() {
148
149        //empty constructor for serialization
150    }
151
152    /**
153     * Helper method for copying a map of properties.<p>
154     *
155     * @param props the property map to copy
156     *
157     * @return a copy of the property map
158     */
159    public static Map<String, CmsClientProperty> copyProperties(Map<String, CmsClientProperty> props) {
160
161        Map<String, CmsClientProperty> result = new HashMap<String, CmsClientProperty>();
162        for (Map.Entry<String, CmsClientProperty> entry : props.entrySet()) {
163            String key = entry.getKey();
164            CmsClientProperty copiedValue = new CmsClientProperty(entry.getValue());
165            result.put(key, copiedValue);
166        }
167        return result;
168    }
169
170    /**
171     * Gets the path value for a property object (which may be null) and a property access mode.<p>
172     *
173     * @param property the property which values to access
174     * @param mode the property access mode
175     *
176     * @return the path value for the property and access mode
177     */
178    public static CmsPathValue getPathValue(CmsClientProperty property, Mode mode) {
179
180        if (property != null) {
181            return property.getPathValue(mode);
182        }
183        switch (mode) {
184            case resource:
185                return new CmsPathValue("", PATH_RESOURCE_VALUE);
186            case structure:
187                return new CmsPathValue("", PATH_STRUCTURE_VALUE);
188            case effective:
189                return new CmsPathValue("", PATH_STRUCTURE_VALUE);
190            default:
191                throw new IllegalArgumentException();
192        }
193    }
194
195    /**
196     * Checks if a property is null or empty.<p>
197     *
198     * @param prop the property to check
199     *
200     * @return true if the property is null or empty
201     */
202    public static boolean isPropertyEmpty(CmsClientProperty prop) {
203
204        return (prop == null) || prop.isEmpty();
205    }
206
207    /**
208     * Makes a "lazy copy" of a map of properties, which will create properties on lookup if they don't already exist.<p>
209     *
210     * @param properties the properties to copy
211     *
212     * @return the lazy copy of the properties
213     */
214    public static Map<String, CmsClientProperty> makeLazyCopy(Map<String, CmsClientProperty> properties) {
215
216        if (properties == null) {
217            return null;
218        }
219        return toLazyMap(copyProperties(properties));
220    }
221
222    /**
223     * Helper method for removing empty properties from a map.<p>
224     *
225     * @param props the map from which to remove empty properties
226     */
227    public static void removeEmptyProperties(Map<String, CmsClientProperty> props) {
228
229        Iterator<Map.Entry<String, CmsClientProperty>> iter = props.entrySet().iterator();
230        while (iter.hasNext()) {
231            Map.Entry<String, CmsClientProperty> entry = iter.next();
232            CmsClientProperty value = entry.getValue();
233            if (value.isEmpty()) {
234                iter.remove();
235            }
236        }
237    }
238
239    /**
240     * Creates a lazy property map which creates properties on lookup if they don'T exist.<p>
241     *
242     * @param properties the properties which should be initially put into the map
243     *
244     * @return the lazy property map
245     */
246    public static Map<String, CmsClientProperty> toLazyMap(Map<String, CmsClientProperty> properties) {
247
248        Map<String, CmsClientProperty> result = new CmsLazyPropertyMap(properties);
249        return result;
250    }
251
252    /**
253     * Returns the effective value of the property.<p>
254     *
255     * @return the effective value of the property
256     */
257    public String getEffectiveValue() {
258
259        return getPathValue().getValue();
260    }
261
262    /**
263     * Returns the name of the property.<p>
264     *
265     * @return the name of the property
266     */
267    public String getName() {
268
269        return m_name;
270    }
271
272    /**
273     * Gets the origin of the property (might return null).<p>
274     *
275     * @return the origin root path of the property, or null
276     */
277    public String getOrigin() {
278
279        return m_origin;
280    }
281
282    /**
283     * Returns the effective path value of the property.<p>
284     *
285     * @return the effective path value of the property
286     */
287    public CmsPathValue getPathValue() {
288
289        if (!CmsStringUtil.isEmpty(m_structureValue)) {
290            return new CmsPathValue(m_structureValue, PATH_STRUCTURE_VALUE);
291        } else if (!CmsStringUtil.isEmpty(m_resourceValue)) {
292            return new CmsPathValue(m_resourceValue, PATH_RESOURCE_VALUE);
293        } else {
294            return new CmsPathValue(null, PATH_STRUCTURE_VALUE);
295        }
296    }
297
298    /**
299     * Gets the path value for a specific access mode.<p>
300     * @param mode the access mode
301     *
302     * @return the path value for the access mode
303     */
304    public CmsPathValue getPathValue(Mode mode) {
305
306        switch (mode) {
307            case resource:
308                return new CmsPathValue(m_resourceValue, PATH_RESOURCE_VALUE);
309            case structure:
310                return new CmsPathValue(m_structureValue, PATH_STRUCTURE_VALUE);
311            case effective:
312            default:
313                return getPathValue();
314        }
315    }
316
317    /**
318     * Returns the resource value of the property.<p>
319     *
320     * @return the resource value
321     */
322    public String getResourceValue() {
323
324        return m_resourceValue;
325    }
326
327    /***
328     * Returns the structure value of the property.<p>
329     *
330     * @return  the structure value
331     */
332    public String getStructureValue() {
333
334        return m_structureValue;
335    }
336
337    /**
338     * Checks if both values of the property are empty.<p>
339     *
340     * @return true if both values of the property are empty
341     */
342    public boolean isEmpty() {
343
344        return CmsStringUtil.isEmpty(m_resourceValue) && CmsStringUtil.isEmpty(m_structureValue);
345
346    }
347
348    /**
349     * Sets the origin of the property.<p>
350     *
351     * @param origin the origin root path of the property
352     */
353    public void setOrigin(String origin) {
354
355        m_origin = origin;
356    }
357
358    /**
359     * Sets the resource value .<P>
360     *
361     * @param resourceValue the new resource value
362     */
363    public void setResourceValue(String resourceValue) {
364
365        m_resourceValue = resourceValue;
366    }
367
368    /**
369     * Sets the structure value.<p>
370     *
371     * @param structureValue the new structure value
372     */
373    public void setStructureValue(String structureValue) {
374
375        m_structureValue = structureValue;
376    }
377
378    /**
379     * Creates a copy of the property, but changes the origin in the copy.<p>
380     *
381     * @param origin the new origin
382     *
383     * @return the copy of the property
384     */
385    public CmsClientProperty withOrigin(String origin) {
386
387        CmsClientProperty property = new CmsClientProperty(this);
388        property.setOrigin(origin);
389        return property;
390    }
391
392}