001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://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.ade.configuration;
029
030import org.opencms.ade.configuration.CmsConfigurationReader.DiscardPropertiesMode;
031import org.opencms.ade.configuration.formatters.CmsFormatterChangeSet;
032import org.opencms.ade.detailpage.CmsDetailPageInfo;
033import org.opencms.ade.galleries.CmsAddContentRestriction;
034import org.opencms.file.CmsObject;
035import org.opencms.file.CmsResource;
036import org.opencms.main.CmsLog;
037import org.opencms.util.CmsUUID;
038
039import java.util.ArrayList;
040import java.util.Collection;
041import java.util.Collections;
042import java.util.Comparator;
043import java.util.HashMap;
044import java.util.List;
045import java.util.Map;
046import java.util.Set;
047
048import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
049import org.apache.commons.lang3.builder.ToStringStyle;
050import org.apache.commons.logging.Log;
051
052import com.google.common.collect.ComparisonChain;
053import com.google.common.collect.Lists;
054
055/**
056 * Represents a parsed sitemap or module configuration.<p>
057 *
058 * This is the internal representation stored in the cache. The configuration class
059 * which is actually returned by CmsADEManager, and which contains most of the logic
060 * related to sitemap configurations, is CmsADEConfigData.
061 */
062public class CmsADEConfigDataInternal {
063
064    /**
065     * Represents the value of an attribute, with additional information about where the value originated from.
066     */
067    public static class AttributeValue {
068
069        /** The path of the configuration from which this attribute value originates. */
070        private String m_origin;
071
072        /** The value of the attribute. */
073        private String m_value;
074
075        /**
076         * Creates a new instance.
077         *
078         * @param value the attribute value
079         * @param origin the origin path
080         */
081        public AttributeValue(String value, String origin) {
082
083            super();
084            m_value = value;
085            m_origin = origin;
086        }
087
088        /**
089         * Gets the origin path.
090         *
091         * @return the origin path
092         */
093        public String getOrigin() {
094
095            return m_origin;
096        }
097
098        /**
099         * Gets the attribute string value.
100         *
101         * @return the attribute value
102         */
103        public String getValue() {
104
105            return m_value;
106        }
107
108        /**
109         * @see java.lang.Object#toString()
110         */
111        @Override
112        public String toString() {
113
114            return "[" + m_value + " (from: " + m_origin + ")]";
115        }
116    }
117
118    /**
119     * Represents a reference to a sitemap configuration with some associated metadata about that reference.
120     */
121    public static class ConfigReference {
122
123        /** The id of the referenced configuration. */
124        private CmsUUID m_config;
125
126        /** The metadata associated with the reference. */
127        private ConfigReferenceMeta m_meta = new ConfigReferenceMeta();
128
129        /**
130         * Creates a new instance.
131         *
132         * @param config the id of the target sitemap configuration
133         */
134        public ConfigReference(CmsUUID config) {
135
136            m_config = config;
137        }
138
139        /**
140         * Creates a new instance.
141         *
142         * @param config the id of the target sitemap configuration
143         * @param meta the metadata associated with the reference
144         */
145        public ConfigReference(CmsUUID config, ConfigReferenceMeta meta) {
146
147            m_config = config;
148            m_meta = meta;
149
150        }
151
152        /**
153         * Gets the id of the referenced sitemap configuration.
154         *
155         * @return the id of the referenced sitemap configuration
156         */
157        public CmsUUID getId() {
158
159            return m_config;
160
161        }
162
163        /**
164         * Gets the metadata for the configuration reference
165         *
166         * @return the metadata for the configuration reference
167         */
168        public ConfigReferenceMeta getMeta() {
169
170            return m_meta;
171        }
172    }
173
174    /**
175     * Contains a sitemap configuration bean together with some metadata about how it was referenced from other sitemap configurations.
176     */
177    public static class ConfigReferenceInstance {
178
179        /** The configuration object. */
180        private CmsADEConfigDataInternal m_config;
181
182        /** The metadata associated with the configuration reference. */
183        private ConfigReferenceMeta m_meta = new ConfigReferenceMeta();
184
185        /**
186         * Creates a new instance.
187         *
188         * @param config the configuration
189         */
190        public ConfigReferenceInstance(CmsADEConfigDataInternal config) {
191
192            m_config = config;
193        }
194
195        /**
196         * Creates a new instance.
197         *
198         * @param config the configuration
199         * @param meta the metadata associated with the reference to the configuration
200         */
201        public ConfigReferenceInstance(CmsADEConfigDataInternal config, ConfigReferenceMeta meta) {
202
203            m_config = config;
204            m_meta = meta;
205
206        }
207
208        /**
209         * Gets the configuration instance.
210         *
211         * @return the configuration
212         */
213        public CmsADEConfigDataInternal getConfig() {
214
215            return m_config;
216        }
217
218        /**
219         * Gets the metadata associated with the configuration reference.
220         *
221         * @return the reference metadata
222         */
223        public ConfigReferenceMeta getMeta() {
224
225            return m_meta;
226        }
227
228    }
229
230    /**
231     * Represents additional metadata from the query string of a master configuration link.
232     */
233    public static class ConfigReferenceMeta {
234
235        /** The 'template' parameter. */
236        public static final String PARAM_TEMPLATE = "template";
237
238        /** The template identifier. */
239        private String m_template;
240
241        /**
242         * Creates a new, empty instance.
243         */
244        public ConfigReferenceMeta() {
245            // do nothing
246
247        }
248
249        /**
250         * Creates a new instance from the parameters from a master configuration link.
251         *
252         * @param params the parameters for the metadata
253         */
254        public ConfigReferenceMeta(Map<String, String[]> params) {
255
256            String[] templateVals = params.get(PARAM_TEMPLATE);
257            if ((templateVals != null) && (templateVals.length > 0)) {
258                m_template = templateVals[0];
259            }
260        }
261
262        /**
263         * If this object is the metadata for a link to a master configuration M, and 'next' is the metadata
264         * for a link from M to some other master configuration N, combines the metadata into a single object and returns it.
265         *
266         * @param next the metadata to combine this object with
267         * @return the combined metadata
268         */
269        public ConfigReferenceMeta combine(ConfigReferenceMeta next) {
270
271            ConfigReferenceMeta result = new ConfigReferenceMeta();
272            result.m_template = m_template != null ? m_template : next.m_template;
273            return result;
274        }
275
276        /**
277         * Gets the template identifier.
278         *
279         * <p>The template identifier should be one of the template context keys provided by a template provider.
280         *
281         * @return the template identifier
282         */
283        public String getTemplate() {
284
285            return m_template;
286        }
287
288        /**
289         * Returns true if 'remove all' settings should be ignored in the referenced master configuration.
290         *
291         * @return if true, 'remove all' settings are ignored in the referenced master configuration
292         */
293        public boolean isSkipRemovals() {
294
295            return getTemplate() != null;
296        }
297
298        /**
299         * @see java.lang.Object#toString()
300         */
301        @Override
302        public String toString() {
303
304            return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
305        }
306
307    }
308
309    /** Logger instance for this class. */
310    private static final Log LOG = CmsLog.getLog(CmsADEConfigDataInternal.class);
311
312    /** The "create contents locally" flag. */
313    protected boolean m_createContentsLocally;
314
315    /** Should inherited model pages be discarded? */
316    protected boolean m_discardInheritedModelPages;
317
318    /** Should inherited types be discarded? */
319    protected boolean m_discardInheritedTypes;
320
321    /** The 'discard properties' mode. */
322    protected DiscardPropertiesMode m_discardPropertiesMode;
323
324    /** The configured formatter changes. */
325    protected CmsFormatterChangeSet m_formatterChangeSet = new CmsFormatterChangeSet();
326
327    /** True if subsite should be included in site selector. */
328    protected boolean m_includeInSiteSelector;
329
330    /** True if this is a module configuration, not a normal sitemap configuration. */
331    protected boolean m_isModuleConfig;
332
333    /** The master configuration structure ids. */
334    protected List<ConfigReference> m_masterConfigs;
335
336    /** Mode for using formatter keys / the new container page format. */
337    protected Boolean m_useFormatterKeys;
338
339    /** The restrictions for the 'add content' dialog. */
340    private CmsAddContentRestriction m_addContentRestriction = CmsAddContentRestriction.EMPTY;
341
342    /** The set of ids of site plugins to add. */
343    private Set<CmsUUID> m_addedPlugins;
344
345    /** Structure id of the sitemap attribute editor configuration file. */
346    private CmsUUID m_attributeEditorConfigId;
347
348    /** The map of attributes. */
349    private Map<String, AttributeValue> m_attributes = Collections.emptyMap();
350
351    /** The structure id of the base folder. */
352    private CmsUUID m_baseId;
353
354    /** The base path of this configuration. */
355    private String m_basePath;
356
357    /** The CMS context. */
358    private CmsObject m_cms;
359
360    /** The content folder configuration. */
361    private CmsContentFolderOption m_contentFolderOption;
362
363    /** the dynamic functions available. */
364    private Set<CmsUUID> m_dynamicFunctions;
365
366    /** True if detail contents outside the sitemap should not be used with detail pages in the sitemap. */
367    private boolean m_excludeExternalDetailContents;
368
369    /** The list of configured function references. */
370    private List<CmsFunctionReference> m_functionReferences = Lists.newArrayList();
371
372    /** The functions to remove. */
373    private Set<CmsUUID> m_functionsToRemove;
374
375    /** The mode determining how to deal with disabled functions. */
376    private CmsGalleryDisabledTypesMode m_galleryDisabledFunctionsMode;
377
378    /** The display mode for deactivated types in the gallery dialog. */
379    private CmsGalleryDisabledTypesMode m_galleryDisabledTypesMode;
380
381    /** The internal detail page configuration. */
382    private List<CmsDetailPageInfo> m_ownDetailPages = Lists.newArrayList();
383
384    /** The internal model page entries. */
385    private volatile List<CmsModelPageConfig> m_ownModelPageConfig = null;
386
387    /** Model page data with no resources. */
388    private List<CmsModelPageConfigWithoutResource> m_ownModelPageConfigRaw = new ArrayList<>();
389
390    /** The internal property configuration. */
391    private List<CmsPropertyConfig> m_ownPropertyConfigurations = Lists.newArrayList();
392
393    /** The internal resource type entries. */
394    private List<CmsResourceTypeConfig> m_ownResourceTypes = Lists.newArrayList();
395
396    /** True if detail pages from this sitemap should be preferred when linking to contents inside this sitemap. */
397    private boolean m_preferDetailPagesForLocalContents;
398
399    /** Flag indicating whether all functions should be removed. */
400    private boolean m_removeAllFunctions;
401
402    /** If true, all site plugins inherited from parent sitemaps should be removed. */
403    private boolean m_removeAllPlugins;
404
405    /** The set of ids of site plugins to remove. */
406    private Set<CmsUUID> m_removedPlugins;
407
408    /** True if inherited shared setting overrides should be removed. */
409    private boolean m_removeSharedSettingOverrides;
410
411    /** The resource from which the configuration data was read. */
412    private CmsResource m_resource;
413
414    /** Shared setting override ID, may be null. */
415    private CmsUUID m_sharedSettingOverride;
416
417    /** The type ordering mode. */
418    private CmsTypeOrderingMode m_typeOrderingMode;
419
420    /**
421     * Creates a new configuration data instance.<p>
422     *
423     * @param cms the CMS context
424     * @param resource the resource from which this configuration data was read
425     * @param isModuleConfig true if this is a module configuration
426     * @param basePath the base path
427     * @param baseId the structure id corresponding to the base path
428     * @param masterConfigs structure ids of master configuration files
429     * @param resourceTypeConfig the resource type configuration
430     * @param galleryDisabledTypesMode  the display mode deactivated types in the gallery dialog
431     * @param galleryDisabledFunctionsMode the mode controlling how to deal with disabled functions
432     * @param discardInheritedTypes the "discard inherited types" flag
433     * @param propertyConfig the property configuration
434     * @param discardPropertiesMode the "discard inherited properties" mode
435     * @param detailPageInfos the detail page configuration
436     * @param modelPages the model page configuration
437     * @param functionReferences the function reference configuration
438     * @param discardInheritedModelPages the "discard  inherited model pages" flag
439     * @param createContentsLocally the "create contents locally" flag
440     * @param contentFolderOption the content folder configuration
441     * @param preferDetailPagesForLocalContents the "preferDetailPagesForLocalContents" flag
442     * @param excludeExternalDetailContents the "excludeExternalDetailContents" flag
443     * @param includeInSiteSelector the "includeInSiteSelector" flag
444     * @param formatterChangeSet the formatter changes
445     * @param removeAllFunctions flag indicating whether all functions should be removed
446     * @param functionIds the dynamic functions available
447     * @param functionsToRemove the function ids to remove
448     * @param removeAllPlugins true all site plugins should be removed
449     * @param removedPlugins the ids of site plugins to remove
450     * @param addedPlugins the ids of site plugins to add
451     * @param useFormatterKeys mode for using formatter keys / the new container page format
452     * @param orderingMode the mode used to order the resource types
453     * @param restriction the restrictions for the 'Add content' dialog
454     * @param sharedSettingOverride shared setting override id, may be null
455     * @param removeSharedSettingOverrides true if inherited shared setting overrides should be removed
456     * @param attributeEditorConfigId the structure id of the attribute editor configuration file
457     * @param attributes the map of attributes
458     */
459    public CmsADEConfigDataInternal(
460        CmsObject cms,
461        CmsResource resource,
462        boolean isModuleConfig,
463        String basePath,
464        CmsUUID baseId,
465        List<ConfigReference> masterConfigs,
466        List<CmsResourceTypeConfig> resourceTypeConfig,
467        CmsGalleryDisabledTypesMode galleryDisabledTypesMode,
468        CmsGalleryDisabledTypesMode galleryDisabledFunctionsMode,
469        boolean discardInheritedTypes,
470        List<CmsPropertyConfig> propertyConfig,
471        DiscardPropertiesMode discardPropertiesMode,
472        List<CmsDetailPageInfo> detailPageInfos,
473        List<CmsModelPageConfigWithoutResource> modelPages,
474        List<CmsFunctionReference> functionReferences,
475        boolean discardInheritedModelPages,
476        boolean createContentsLocally,
477        CmsContentFolderOption contentFolderOption,
478        boolean preferDetailPagesForLocalContents,
479        boolean excludeExternalDetailContents,
480        boolean includeInSiteSelector,
481        CmsFormatterChangeSet formatterChangeSet,
482        boolean removeAllFunctions,
483        Set<CmsUUID> functionIds,
484        Set<CmsUUID> functionsToRemove,
485        boolean removeAllPlugins,
486        Set<CmsUUID> addedPlugins,
487        Set<CmsUUID> removedPlugins,
488        Boolean useFormatterKeys,
489        CmsTypeOrderingMode orderingMode,
490        CmsAddContentRestriction restriction,
491        CmsUUID sharedSettingOverride,
492        boolean removeSharedSettingOverrides,
493        CmsUUID attributeEditorConfigId,
494        Map<String, String> attributes) {
495
496        m_cms = cms;
497        m_resource = resource;
498        m_basePath = basePath;
499        m_baseId = baseId;
500        m_ownResourceTypes = resourceTypeConfig;
501        m_galleryDisabledTypesMode = galleryDisabledTypesMode;
502        m_galleryDisabledFunctionsMode = galleryDisabledFunctionsMode;
503        m_ownPropertyConfigurations = propertyConfig;
504        m_ownModelPageConfigRaw = modelPages;
505        m_ownDetailPages = detailPageInfos;
506        m_functionReferences = functionReferences;
507        m_contentFolderOption = contentFolderOption;
508        m_isModuleConfig = isModuleConfig;
509        m_masterConfigs = masterConfigs;
510        if (m_masterConfigs == null) {
511            m_masterConfigs = Collections.emptyList();
512        }
513
514        m_discardInheritedTypes = discardInheritedTypes;
515        m_discardPropertiesMode = discardPropertiesMode;
516        m_discardInheritedModelPages = discardInheritedModelPages;
517        m_createContentsLocally = createContentsLocally;
518        m_preferDetailPagesForLocalContents = preferDetailPagesForLocalContents;
519        m_formatterChangeSet = formatterChangeSet;
520        m_formatterChangeSet.setDebugPath(m_basePath);
521        m_dynamicFunctions = functionIds;
522        m_functionsToRemove = functionsToRemove;
523        m_removeAllFunctions = removeAllFunctions;
524        m_excludeExternalDetailContents = excludeExternalDetailContents;
525        m_includeInSiteSelector = includeInSiteSelector;
526        m_useFormatterKeys = useFormatterKeys;
527        m_removeAllPlugins = removeAllPlugins;
528        m_addedPlugins = Collections.unmodifiableSet(addedPlugins);
529        m_removedPlugins = Collections.unmodifiableSet(removedPlugins);
530        m_sharedSettingOverride = sharedSettingOverride;
531        m_removeSharedSettingOverrides = removeSharedSettingOverrides;
532        Map<String, AttributeValue> attributeObjects = new HashMap<>();
533        String attributeOrigin = basePath;
534        if (resource != null) {
535            attributeOrigin = resource.getRootPath();
536        }
537        for (Map.Entry<String, String> entry : attributes.entrySet()) {
538            attributeObjects.put(entry.getKey(), new AttributeValue(entry.getValue(), attributeOrigin));
539        }
540        m_attributes = Collections.unmodifiableMap(new HashMap<>(attributeObjects));
541
542        m_typeOrderingMode = orderingMode;
543        m_addContentRestriction = restriction;
544        m_attributeEditorConfigId = attributeEditorConfigId;
545    }
546
547    /**
548     * Creates an empty configuration data object with a given base path.<p>
549     *
550     * @param basePath the base path
551     */
552    public CmsADEConfigDataInternal(String basePath) {
553
554        m_basePath = basePath;
555    }
556
557    /**
558     * Creates a new configuration data instance.<p>
559    
560     * @param resource the resource from which this configuration data was read
561     * @param isModuleConfig true if this is a module configuration
562     * @param basePath the base path
563     * @param masterConfigs structure ids of master configuration files
564     * @param resourceTypeConfig the resource type configuration
565     * @param discardInheritedTypes the "discard inherited types" flag
566     * @param propertyConfig the property configuration
567     * @param discardPropertiesMode the "discard inherited properties" mode
568     * @param detailPageInfos the detail page configuration
569     * @param modelPages the model page configuration
570     * @param functionReferences the function reference configuration
571     * @param discardInheritedModelPages the "discard  inherited model pages" flag
572     * @param createContentsLocally the "create contents locally" flag
573     * @param preferDetailPagesForLocalContents the "preferDetailPagesForLocalContents" flag
574     * @param excludeExternalDetailContents the "excludeExternalDetailContents" flag
575     * @param includeInSiteSelector the "includeInSiteSelector" flag
576     * @param formatterChangeSet the formatter changes
577     * @param removeAllFunctions flag indicating whether all functions should be removed
578     * @param functionIds the dynamic functions available
579     */
580    protected CmsADEConfigDataInternal(
581        CmsResource resource,
582        boolean isModuleConfig,
583        String basePath,
584        List<ConfigReference> masterConfigs,
585        List<CmsResourceTypeConfig> resourceTypeConfig,
586        boolean discardInheritedTypes,
587        List<CmsPropertyConfig> propertyConfig,
588        DiscardPropertiesMode discardPropertiesMode,
589        List<CmsDetailPageInfo> detailPageInfos,
590        List<CmsModelPageConfig> modelPages,
591        List<CmsFunctionReference> functionReferences,
592        boolean discardInheritedModelPages,
593        boolean createContentsLocally,
594        boolean preferDetailPagesForLocalContents,
595        boolean excludeExternalDetailContents,
596        boolean includeInSiteSelector,
597        CmsFormatterChangeSet formatterChangeSet,
598        boolean removeAllFunctions,
599        Set<CmsUUID> functionIds) {
600
601        m_resource = resource;
602        m_basePath = basePath;
603        m_ownResourceTypes = resourceTypeConfig;
604        m_ownPropertyConfigurations = propertyConfig;
605        m_ownModelPageConfig = modelPages;
606        m_ownDetailPages = detailPageInfos;
607        m_functionReferences = functionReferences;
608        m_isModuleConfig = isModuleConfig;
609        m_masterConfigs = masterConfigs;
610        if (m_masterConfigs == null) {
611            m_masterConfigs = Collections.emptyList();
612        }
613
614        m_discardInheritedTypes = discardInheritedTypes;
615        m_discardPropertiesMode = discardPropertiesMode;
616        m_discardInheritedModelPages = discardInheritedModelPages;
617        m_createContentsLocally = createContentsLocally;
618        m_preferDetailPagesForLocalContents = preferDetailPagesForLocalContents;
619        m_formatterChangeSet = formatterChangeSet;
620        m_dynamicFunctions = functionIds;
621        m_removeAllFunctions = removeAllFunctions;
622        m_excludeExternalDetailContents = excludeExternalDetailContents;
623        m_includeInSiteSelector = includeInSiteSelector;
624    }
625
626    /**
627     * Creates an empty configuration for a given base path.<p>
628     *
629     * @param basePath the base path
630     *
631     * @return the empty configuration object
632     */
633    public static CmsADEConfigDataInternal emptyConfiguration(String basePath) {
634
635        return new CmsADEConfigDataInternal(basePath);
636    }
637
638    /**
639     * Gets the restrictions for the 'Add content' dialog.
640     *
641     * @return the restrictions for the 'Add content' dialog
642     */
643    public CmsAddContentRestriction getAddContentRestriction() {
644
645        return m_addContentRestriction;
646    }
647
648    /**
649     * Gets the set of ids of added site plugins.
650     *
651     * @return the set of ids of added site plugins
652     */
653    public Set<CmsUUID> getAddedPlugins() {
654
655        return m_addedPlugins;
656    }
657
658    /**
659     * Gets the structure id of the sitemap attribute editor configuration
660     * @return the structure id of the sitemap attribute editor configuration
661     */
662    public CmsUUID getAttributeEditorConfigId() {
663
664        return m_attributeEditorConfigId;
665    }
666
667    /**
668     * Gets the map of attributes for this sitemap configuration.
669     *
670     * @return the map of attributes
671     */
672    public Map<String, AttributeValue> getAttributes() {
673
674        return m_attributes;
675    }
676
677    /**
678     * Gets the structure id of the base folder, or null if there is no base folder.
679     *
680     * @return the structure id of the base folder
681     */
682    public CmsUUID getBaseId() {
683
684        return m_baseId;
685    }
686
687    /**
688     * Gets the base path.<p>
689     *
690     * @return the base path
691     */
692    public String getBasePath() {
693
694        return m_basePath;
695    }
696
697    /**
698     * Gets the content folder configuration.
699     * 
700     * @return the content folder configuration
701     */
702    public CmsContentFolderOption getContentFolderOption() {
703
704        return m_contentFolderOption;
705    }
706
707    /**
708     * Gets the display mode for deactivated types in the sitemap dialog.
709     *
710     * @return the display mode for deactivated types
711     */
712    public CmsGalleryDisabledTypesMode getDisabledTypeMode() {
713
714        return m_galleryDisabledTypesMode;
715    }
716
717    /**
718     * Gets the 'discard properties' mode.
719     *
720     * @return the discard properties mode
721     */
722    public DiscardPropertiesMode getDiscardPropertiesMode() {
723
724        return m_discardPropertiesMode;
725    }
726
727    /**
728     * Returns the set of configured dynamic functions, regardless of whether the 'remove all formatters' option is enabled.
729     *
730     * @return the dynamic functions
731     */
732    public Collection<CmsUUID> getDynamicFunctions() {
733
734        if (m_dynamicFunctions == null) {
735            return Collections.emptySet();
736        }
737        return Collections.unmodifiableSet(m_dynamicFunctions);
738    }
739
740    /**
741     * Gets the formatter change set.<p>
742     *
743     * @return the formatter change set.<p>
744     */
745    public CmsFormatterChangeSet getFormatterChangeSet() {
746
747        return m_formatterChangeSet;
748
749    }
750
751    /**
752     * Gets the dynamic function references.<p>
753     *
754     * @return the dynamic function references
755     */
756    public List<CmsFunctionReference> getFunctionReferences() {
757
758        return m_functionReferences;
759    }
760
761    /**
762     * Gets the ids of dynamic functions to remove.
763     *
764     * @return the ids of dynamic functions to remove
765     */
766    public Collection<CmsUUID> getFunctionsToRemove() {
767
768        return m_functionsToRemove;
769    }
770
771    /**
772     * Gets the mode for how disabled functions should be handled.
773     *
774     * @return the mode for disabled functions
775     */
776    public CmsGalleryDisabledTypesMode getGalleryDisabledFunctionsMode() {
777
778        return m_galleryDisabledFunctionsMode;
779    }
780
781    /**
782     * Gets the structure ids of the master configuration files.
783     *
784     * @return the structure ids of the master configurations
785     */
786    public List<ConfigReference> getMasterConfigs() {
787
788        return Collections.unmodifiableList(m_masterConfigs);
789    }
790
791    /**
792     * Returns the ownDetailPages.<p>
793     *
794     * @return the ownDetailPages
795     */
796    public List<CmsDetailPageInfo> getOwnDetailPages() {
797
798        return m_ownDetailPages;
799    }
800
801    /**
802     * Returns the ownModelPageConfig.<p>
803     *
804     * @return the ownModelPageConfig
805     */
806    public List<CmsModelPageConfig> getOwnModelPageConfig() {
807
808        if (m_ownModelPageConfig == null) {
809            List<CmsModelPageConfig> result = new ArrayList<>();
810            for (CmsModelPageConfigWithoutResource modelPage : m_ownModelPageConfigRaw) {
811                try {
812                    CmsResource resource = m_cms.readResource(modelPage.getStructureId());
813                    result.add(new CmsModelPageConfig(resource, modelPage.isDefault(), modelPage.isDisabled()));
814                } catch (Exception e) {
815                    LOG.warn("can't read model page for base path " + m_basePath + ": " + e.getLocalizedMessage(), e);
816                }
817            }
818            m_ownModelPageConfig = result;
819            return result;
820        } else {
821            return m_ownModelPageConfig;
822        }
823    }
824
825    /**
826     * Returns the ownPropertyConfigurations.<p>
827     *
828     * @return the ownPropertyConfigurations
829     */
830    public List<CmsPropertyConfig> getOwnPropertyConfigurations() {
831
832        return m_ownPropertyConfigurations;
833    }
834
835    /**
836     * Gets the resource types defined in this configuration.<p>
837     *
838     * @return the resource type configurations
839     */
840    public List<CmsResourceTypeConfig> getOwnResourceTypes() {
841
842        return m_ownResourceTypes;
843    }
844
845    /**
846     * Gets the set of ids of removed site plugins.
847     *
848     * @return the set of ids of removed site plugins
849     */
850    public Set<CmsUUID> getRemovedPlugins() {
851
852        return m_removedPlugins;
853    }
854
855    /**
856     * Returns the resource.<p>
857     *
858     * @return the resource
859     */
860    public CmsResource getResource() {
861
862        return m_resource;
863    }
864
865    /**
866     * Gets the shared setting override ID (may be null).
867     *
868     * @return the shared setting override ID
869     */
870    public CmsUUID getSharedSettingOverride() {
871
872        return m_sharedSettingOverride;
873    }
874
875    /**
876     * Gets the type ordering mode.
877     *
878     * @return the type ordering mode
879     */
880    public CmsTypeOrderingMode getTypeOrderingMode() {
881
882        return m_typeOrderingMode;
883    }
884
885    /**
886     * Gets the 'use formatter keys' mode.<p>
887     *
888     * If true, container pages will be written in the new format, including using formatter keys when possible.
889     *
890     * @return the 'use formatter keys' mode
891     */
892    public Boolean getUseFormatterKeys() {
893
894        return m_useFormatterKeys;
895    }
896
897    /**
898     * Returns true if contents should be created in the sub-sitemap.<p>
899     *
900     * @return true if contents should be created in the sub-sitemap
901     */
902    public boolean isCreateContentsLocally() {
903
904        return m_createContentsLocally;
905    }
906
907    /**
908     * Returns true if inherited model pages should be discarded.<p>
909     *
910     * @return true if inherited model pages should be discarded.
911     */
912    public boolean isDiscardInheritedModelPages() {
913
914        return m_discardInheritedModelPages;
915    }
916
917    /**
918     * Returns true if inherited properties should be discarded.<p>
919     *
920     * @return true if inherited property configurations should be discardded.<p>
921     */
922    public boolean isDiscardInheritedProperties() {
923
924        return m_discardPropertiesMode != DiscardPropertiesMode.keep;
925    }
926
927    /**
928     * Returns true if inherited types should be discarded.<p>
929     *
930     * @return true if inherited types should be discarded
931     */
932    public boolean isDiscardInheritedTypes() {
933
934        return m_discardInheritedTypes;
935    }
936
937    /**
938     * Returns true if detail pages inside this subsite (and descendant subsites) should not be used for contents outside the subsite (and descendant subsites).<p>
939     *
940     * @return true if external detail contents should be excluded
941     */
942    public boolean isExcludeExternalDetailContents() {
943
944        return m_excludeExternalDetailContents;
945    }
946
947    /**
948     * Returns true if the subsite should be included in the site selector.
949     *
950     * @return true if the subsite should be included in the site selector
951     */
952    public boolean isIncludeInSiteSelector() {
953
954        return m_includeInSiteSelector;
955    }
956
957    /**
958     * Returns the isModuleConfig.<p>
959     *
960     * @return the isModuleConfig
961     */
962    public boolean isModuleConfig() {
963
964        return m_isModuleConfig;
965    }
966
967    /**
968     * Returns true if detail pages from this sitemap should be preferred for creating links to detail contents located inside this sitemap.<p>
969     *
970     * @return true if detail pages from this sitemap should be preferred
971     */
972    public boolean isPreferDetailPagesForLocalContents() {
973
974        return m_preferDetailPagesForLocalContents;
975    }
976
977    /**
978     * True if all functions should be removed by this sitemap configuration.
979     *
980     * @return true if all functions should be removed
981     */
982    public boolean isRemoveAllFunctions() {
983
984        return m_removeAllFunctions;
985    }
986
987    /**
988     * Returns true if all site plugins inherited from parent sitemaps should be removed.
989     *
990     * @return true if all site plugins should be removed
991     */
992    public boolean isRemoveAllPlugins() {
993
994        return m_removeAllPlugins;
995    }
996
997    /**
998     * Returns true if shared setting overrides inherited from other sitemap configurations should be discarded.
999     *
1000     * @return true if inherited shared setting overrides should be discarded
1001     */
1002    public boolean isRemoveSharedSettingOverrides() {
1003
1004        return m_removeSharedSettingOverrides;
1005    }
1006
1007    /**
1008     * @see java.lang.Object#toString()
1009     */
1010    @Override
1011    public String toString() {
1012
1013        if (getBasePath() != null) {
1014            return "[" + getBasePath() + "]";
1015        } else {
1016            return super.toString();
1017        }
1018
1019    }
1020
1021    /**
1022     * Merges the parent's data into this object.<p>
1023     *
1024     * @param parent the parent configuration data
1025     */
1026    protected void mergeParent(CmsADEConfigDataInternal parent) {
1027
1028        List<CmsResourceTypeConfig> parentTypes = null;
1029        if (parent != null) {
1030            parentTypes = parent.m_ownResourceTypes;
1031        } else {
1032            parentTypes = Collections.emptyList();
1033        }
1034
1035        List<CmsPropertyConfig> parentProperties = null;
1036        if (parent != null) {
1037            parentProperties = parent.m_ownPropertyConfigurations;
1038        } else {
1039            parentProperties = Collections.emptyList();
1040        }
1041
1042        List<CmsModelPageConfig> parentModelPages = null;
1043        if (parent != null) {
1044            parentModelPages = parent.m_ownModelPageConfig;
1045        } else {
1046            parentModelPages = Collections.emptyList();
1047        }
1048
1049        List<CmsFunctionReference> parentFunctionRefs = null;
1050        if (parent != null) {
1051            parentFunctionRefs = parent.m_functionReferences;
1052        } else {
1053            parentFunctionRefs = Collections.emptyList();
1054        }
1055
1056        m_ownResourceTypes = CmsADEConfigData.combineConfigurationElements(parentTypes, m_ownResourceTypes, false);
1057        m_ownPropertyConfigurations = CmsADEConfigData.combineConfigurationElements(
1058            parentProperties,
1059            m_ownPropertyConfigurations,
1060            false);
1061        m_ownModelPageConfig = CmsADEConfigData.combineConfigurationElements(
1062            parentModelPages,
1063            m_ownModelPageConfig,
1064            false);
1065        m_functionReferences = CmsADEConfigData.combineConfigurationElements(
1066            parentFunctionRefs,
1067            m_functionReferences,
1068            false);
1069
1070        // dynamic functions are not used in module configurations, so we do not need to merge them here
1071    }
1072
1073    /**
1074     * Handle the ordering from the module configurations.<p>
1075     */
1076    protected void processModuleOrdering() {
1077
1078        Collections.sort(m_ownResourceTypes, new Comparator<CmsResourceTypeConfig>() {
1079
1080            public int compare(CmsResourceTypeConfig a, CmsResourceTypeConfig b) {
1081
1082                return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(
1083                    a.getTypeName(),
1084                    b.getTypeName()).result();
1085            }
1086        });
1087
1088        Collections.sort(m_ownPropertyConfigurations, new Comparator<CmsPropertyConfig>() {
1089
1090            public int compare(CmsPropertyConfig a, CmsPropertyConfig b) {
1091
1092                return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(
1093                    a.getName(),
1094                    b.getName()).result();
1095            }
1096        });
1097
1098        Collections.sort(m_functionReferences, new Comparator<CmsFunctionReference>() {
1099
1100            public int compare(CmsFunctionReference a, CmsFunctionReference b) {
1101
1102                return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(
1103                    a.getName(),
1104                    b.getName()).result();
1105            }
1106        });
1107    }
1108
1109}