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