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.xml.content;
029
030import org.opencms.util.CmsStringUtil;
031
032import java.io.Serializable;
033
034/**
035 * Describes both VFS properties and Container Page Element settings, used by the GWT client.<p>
036 *
037 * Warning: This class is used by GWT client-side code (See GwtBase.gwt.xml for a list of
038 * classes used by GWT client-side code). If you change this class, either make sure that
039 * your changes are compatible with GWT, or write a separate client version of the class
040 * and put it into super_src.
041 *
042 * @since 8.0.0
043 */
044public class CmsXmlContentProperty implements Serializable {
045
046    /** Type constants. */
047    public enum PropType {
048    /** Type constant string. */
049    string,
050    /** Type constant VFS list. */
051    vfslist;
052
053        /**
054         * Checks if the given type is {@link #vfslist}.<p>
055         *
056         * @param type the type to check
057         *
058         * @return <code>true</code> if the given type is {@link #vfslist}
059         */
060        public static boolean isVfsList(String type) {
061
062            if (type == null) {
063                return false;
064            }
065            return valueOf(type.toLowerCase()) == vfslist;
066        }
067    }
068
069    /** The property visibility options. */
070    public enum Visibility {
071
072        /** Visible only on the element. */
073        element,
074
075        /** Visible in both element and list parent as an individual setting. */
076        elementAndParentIndividual,
077
078        /** Visible in both element and list parent as a shared setting. */
079        elementAndParentShared,
080
081        /** Visible only on list parent, as individual setting. */
082        parentIndividual,
083
084        /** Visible only on list parent, as shared setting. */
085        parentShared
086    }
087
088    /** XML node name constants. */
089    public enum XmlNode {
090
091        /** Value file list node name. */
092        FileList,
093        /** Container or property name node name. */
094        Name,
095        /** Element properties node name. */
096        Properties,
097        /** Value string node name. */
098        String,
099        /** File list URI node name. */
100        Uri,
101        /** Value node name. */
102        Value;
103    }
104
105    /** IDs separator constant. */
106    public static final String PROP_SEPARATOR = ",";
107
108    /** The serialization uid. */
109    private static final long serialVersionUID = -7718747702874213381L;
110
111    /** Default value. */
112    private String m_default;
113
114    /** The description. */
115    private String m_description;
116
117    /** The error message. */
118    private String m_error;
119
120    /** The include name. */
121    private String m_includeName;
122
123    /** The name of the property. */
124    private String m_name;
125
126    /** The nice name. */
127    private String m_niceName;
128
129    /** The "prefer folder" option. */
130    private String m_preferFolder;
131
132    /** The validation rule regex. */
133    private String m_ruleRegex;
134
135    /** The validation rule type. */
136    private String m_ruleType;
137
138    /** The value which indicates whether the user can influence how this property is going to be inherited. */
139    private String m_selectInherit;
140
141    /** The property type. */
142    private String m_type;
143
144    /** The property visibility. */
145    private Visibility m_visibility;
146
147    /** The widget to use in the editor. */
148    private String m_widget;
149
150    /** The widget configuration. */
151    private String m_widgetConfiguration;
152
153    /**
154     * Public constructor.<p>
155     *
156     * @param name the property name
157     * @param type the property type (string|uri)
158     * @param widget the widget
159     * @param widgetConfiguration the widget configuration
160     * @param ruleRegex the validation rule regex
161     * @param ruleType the validation rule type
162     * @param default1 the default value
163     * @param niceName the nice-name
164     * @param description  the description
165     * @param error the error message
166     * @param preferFolder the "prefer folder" option
167     */
168    public CmsXmlContentProperty(
169        String name,
170        String type,
171        String widget,
172        String widgetConfiguration,
173        String ruleRegex,
174        String ruleType,
175        String default1,
176        String niceName,
177        String description,
178        String error,
179        String preferFolder
180
181    ) {
182
183        this(
184            name,
185            type,
186            null, // visibility
187            widget,
188            widgetConfiguration,
189            ruleRegex,
190            ruleType,
191            default1,
192            niceName,
193            description,
194            error,
195            preferFolder);
196    }
197
198    /**
199     * Public constructor.<p>
200     *
201     * @param name the property name
202     * @param type the property type (string|uri)
203     * @param visibility the visibility of the property, used in the container page element context
204     * @param widget the widget
205     * @param widgetConfiguration the widget configuration
206     * @param ruleRegex the validation rule regex
207     * @param ruleType the validation rule type
208     * @param default1 the default value
209     * @param niceName the nice-name
210     * @param description  the description
211     * @param error the error message
212     * @param preferFolder the "prefer folder" option
213     */
214    public CmsXmlContentProperty(
215        String name,
216        String type,
217        Visibility visibility,
218        String widget,
219        String widgetConfiguration,
220        String ruleRegex,
221        String ruleType,
222        String default1,
223        String niceName,
224        String description,
225        String error,
226        String preferFolder
227
228    ) {
229
230        super();
231        m_name = name;
232        m_type = type;
233        m_visibility = visibility;
234        m_widget = widget;
235        m_widgetConfiguration = widgetConfiguration;
236        m_ruleRegex = ruleRegex;
237        m_ruleType = ruleType;
238        m_default = default1;
239        m_niceName = niceName;
240        m_description = description;
241        m_error = error;
242        m_preferFolder = preferFolder;
243    }
244
245    /**
246     * Serialization constructor.<p>
247     */
248    protected CmsXmlContentProperty() {
249
250        // empty
251    }
252
253    /**
254     * Gets the fist non-null value.<p>
255     *
256     * @param o1 the first value
257     * @param o2 the second value
258     *
259     * @return the first non-null value
260     */
261    private static <T> T firstNotNull(T o1, T o2) {
262
263        if (o1 != null) {
264            return o1;
265        }
266        return o2;
267    }
268
269    /**
270     * Copies this property definition.<p>
271     *
272     * @return a new copy of the current property definition
273     */
274    public CmsXmlContentProperty copy() {
275
276        return new CmsXmlContentProperty(
277            m_name,
278            m_type,
279            m_visibility,
280            m_widget,
281            m_widgetConfiguration,
282            m_ruleRegex,
283            m_ruleType,
284            m_default,
285            m_niceName,
286            m_description,
287            m_error,
288            m_preferFolder);
289    }
290
291    /**
292     * Gets the configured visibility, without using a default value.
293     *
294     * @return the configured visibility
295     */
296    public Visibility getConfiguredVisibility() {
297
298        return m_visibility;
299    }
300
301    /**
302     * Gets the configured widget, without using a default if it is null.<p>
303     *
304     * @return the configured widget
305     */
306    public String getConfiguredWidget() {
307
308        return m_widget;
309    }
310
311    /**
312     * Returns the default.<p>
313     *
314     * @return the default
315     */
316    public String getDefault() {
317
318        return m_default;
319    }
320
321    /**
322     * Returns the description.<p>
323     *
324     * @return the description
325     */
326    public String getDescription() {
327
328        return m_description;
329    }
330
331    /**
332     * Returns the error.<p>
333     *
334     * @return the error
335     */
336    public String getError() {
337
338        return m_error;
339    }
340
341    /**
342     * Gets the include name.<p>
343     *
344     * This is only used for element settings in formatters, where defaults from setting configuration files
345     * can be imported. The returned value is used to look up the setting name to look up for such an import in the
346     * setting configuration file.
347     *
348     * @param defaultValue the value that should be returned if no include name is configured
349     * @return the include name
350     */
351    public String getIncludeName(String defaultValue) {
352
353        if (m_includeName != null) {
354            return m_includeName;
355        }
356        return defaultValue;
357    }
358
359    /**
360     * Returns the property name.<p>
361     *
362     * @return the property name
363     */
364    public String getName() {
365
366        return m_name;
367    }
368
369    /**
370     * Returns the niceName.<p>
371     *
372     * @return the niceName
373     */
374    public String getNiceName() {
375
376        return m_niceName;
377    }
378
379    /**
380     * Returns the ruleRegex.<p>
381     *
382     * @return the ruleRegex
383     */
384    public String getRuleRegex() {
385
386        return m_ruleRegex;
387    }
388
389    /**
390     * Returns the rule type.<p>
391     *
392     * @return the rule type
393     */
394    public String getRuleType() {
395
396        return m_ruleType;
397    }
398
399    /**
400     * Returns a value which indicates whether the user can control the inheritance of this property.<p>
401     *
402     * @return the "select-inherit" property
403     */
404    public String getSelectInherit() {
405
406        return m_selectInherit;
407    }
408
409    /**
410     * Returns the property type.<p>
411     *
412     * @return the property type
413     */
414    public String getType() {
415
416        return m_type;
417    }
418
419    /**
420     * Returns the visibility of the property, used in the container page element context.<p>
421     *
422     * @param defaultValue the default value to return if the visibility is not set
423     *
424     * @return the visibility of the property
425     */
426    public Visibility getVisibility(Visibility defaultValue) {
427
428        if (m_visibility == null) {
429            return defaultValue;
430        }
431        return m_visibility;
432    }
433
434    /**
435     * Returns the widget.<p>
436     *
437     * @return the widget
438     */
439    public String getWidget() {
440
441        if (m_widget == null) {
442            return "string";
443        }
444        return m_widget;
445    }
446
447    /**
448     * Returns the widgetConfiguration.<p>
449     *
450     * @return the widgetConfiguration
451     */
452    public String getWidgetConfiguration() {
453
454        return m_widgetConfiguration;
455    }
456
457    /**
458     * Returns the value of the "prefer folder" option.<p>
459     *
460     * This flag determines whether a property entered in the sitemap entry editor should be stored by default at the folder
461     * or at the default file of a sitemap entry. It only has an effect if the sitemap entry being edited doesn't already
462     * have a value for that property at either location.<p>
463     *
464     * @return the "prefer folder" flag
465     */
466    public boolean isPreferFolder() {
467
468        return (m_preferFolder == null) || Boolean.valueOf(m_preferFolder).booleanValue();
469
470    }
471
472    /**
473     * Merges this object with another one containing default values.<p>
474     *
475     * This method does not modify this object or the object passed as a parameter.
476     * The resulting object's fields will be filled with the values from the default if they're null in this object.
477     *
478     * @param defaults the object with the defaults
479     *
480     * @return the result of merging this object with the defaults
481     */
482    public CmsXmlContentProperty mergeDefaults(CmsXmlContentProperty defaults) {
483
484        return new CmsXmlContentProperty(
485            firstNotNull(m_name, defaults.m_name),
486            firstNotNull(m_type, defaults.m_type),
487            firstNotNull(m_visibility, defaults.m_visibility),
488            firstNotNull(m_widget, defaults.m_widget),
489            firstNotNull(m_widgetConfiguration, defaults.m_widgetConfiguration),
490            firstNotNull(m_ruleRegex, defaults.m_ruleRegex),
491            firstNotNull(m_ruleType, defaults.m_ruleType),
492            firstNotNull(m_default, defaults.m_default),
493            firstNotNull(m_niceName, defaults.m_niceName),
494            firstNotNull(m_description, defaults.m_description),
495            firstNotNull(m_error, defaults.m_error),
496            firstNotNull(m_preferFolder, defaults.m_preferFolder));
497    }
498
499    /**
500     * Returns a modified copy of this bean with a different widget configuration.<p>
501     *
502     * @param config the new widget configuration
503     * @return the copy with the modified widget configuration
504     */
505    public CmsXmlContentProperty withConfig(String config) {
506
507        return new CmsXmlContentProperty(
508            m_name,
509            m_type,
510            m_visibility,
511            m_widget,
512            config,
513            m_ruleRegex,
514            m_ruleType,
515            m_default,
516            m_niceName,
517            m_description,
518            m_error,
519            m_preferFolder);
520    }
521
522    /**
523     * Copies a property definition, but replaces an empty widget with a given widget.<p>
524     *
525     * @param defaultWidget the widget to use if the set widget is empty
526     *
527     * @return the copied property definition
528     */
529    public CmsXmlContentProperty withDefaultWidget(String defaultWidget) {
530
531        return new CmsXmlContentProperty(
532            m_name,
533            m_type,
534            m_visibility,
535            CmsStringUtil.isEmptyOrWhitespaceOnly(m_widget) ? defaultWidget : m_widget,
536            m_widgetConfiguration,
537            m_ruleRegex,
538            m_ruleType,
539            m_default,
540            m_niceName,
541            m_description,
542            m_error,
543            m_preferFolder);
544    }
545
546    /**
547     * Creates a copy of this object with its include name set to a specific value.<p>
548     *
549     * @param includeName the include name to use
550     *
551     * @return the copy with the include name set
552     */
553    public CmsXmlContentProperty withIncludeName(String includeName) {
554
555        CmsXmlContentProperty result = copy();
556        if (includeName != null) {
557            includeName = includeName.trim();
558        }
559        result.m_includeName = includeName;
560        return result;
561    }
562
563    /**
564     * Copies a property definition, but replaces the nice name attribute.<p>
565     *
566     * @param name the new nice name attribute
567     *
568     * @return the copied property definition
569     */
570    public CmsXmlContentProperty withName(String name) {
571
572        return new CmsXmlContentProperty(
573            name,
574            m_type,
575            m_visibility,
576            m_widget,
577            m_widgetConfiguration,
578            m_ruleRegex,
579            m_ruleType,
580            m_default,
581            m_niceName,
582            m_description,
583            m_error,
584            m_preferFolder);
585    }
586
587    /**
588     * Copies a property definition, but replaces the nice name attribute.<p>
589     *
590     * @param niceName the new nice name attribute
591     *
592     * @return the copied property definition
593     */
594    public CmsXmlContentProperty withNiceName(String niceName) {
595
596        return new CmsXmlContentProperty(
597            m_name,
598            m_type,
599            m_visibility,
600            m_widget,
601            m_widgetConfiguration,
602            m_ruleRegex,
603            m_ruleType,
604            m_default,
605            niceName,
606            m_description,
607            m_error,
608            m_preferFolder);
609    }
610
611}