/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (C) Alkacon Software (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.ade.configuration;
import org.opencms.ade.detailpage.CmsDetailPageInfo;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.types.CmsResourceTypeFolder;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.loader.CmsLoaderException;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;
import org.opencms.xml.CmsXmlContentDefinition;
import org.opencms.xml.containerpage.CmsFormatterConfiguration;
import org.opencms.xml.content.CmsXmlContentProperty;
import org.opencms.xml.content.I_CmsXmlContentHandler;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* A class which represents the accessible configuration data at a given point in a sitemap.<p>
*/
public class CmsADEConfigData {
/** The content folder name. */
public static final String CONTENT_FOLDER_NAME = ".content";
/** The log instance for this class. */
private static final Log LOG = CmsLog.getLog(CmsADEConfigData.class);
/** The "create contents locally" flag. */
protected boolean m_createContentsLocally;
/** Should inherited model pages be discarded? */
protected boolean m_discardInheritedModelPages;
/** Should inherited properties be discard? */
protected boolean m_discardInheritedProperties;
/** Should inherited types be discarded? */
protected boolean m_discardInheritedTypes;
/** The base path of this configuration. */
private String m_basePath;
/** The cms context used for reading the configuration data. */
private CmsObject m_cms;
/** The list of configured function references. */
private List<CmsFunctionReference> m_functionReferences = new ArrayList<CmsFunctionReference>();
/** A flag which keeps track of whether this instance has already been initialized. */
private boolean m_initialized;
/** True if this is a module configuration, not a normal sitemap configuration. */
private boolean m_isModuleConfig;
/** The internal detail page configuration. */
private List<CmsDetailPageInfo> m_ownDetailPages = new ArrayList<CmsDetailPageInfo>();
/** The internal model page entries. */
private List<CmsModelPageConfig> m_ownModelPageConfig = new ArrayList<CmsModelPageConfig>();
/** The internal property configuration. */
private List<CmsPropertyConfig> m_ownPropertyConfigurations = new ArrayList<CmsPropertyConfig>();
/** The internal resource type entries. */
private List<CmsResourceTypeConfig> m_ownResourceTypes = new ArrayList<CmsResourceTypeConfig>();
/** The resource from which the configuration data was read. */
private CmsResource m_resource;
/**
* Default constructor to create an empty configuration.<p>
*/
public CmsADEConfigData() {
// do nothing
}
/**
* Creates an empty configuration data object with a given base path.<p>
*
* @param basePath the base path
*/
public CmsADEConfigData(String basePath) {
m_basePath = basePath;
}
/**
* Creates a new configuration data instance.<p>
*
* @param basePath the base path
* @param resourceTypeConfig the resource type configuration
* @param discardInheritedTypes the "discard inherited types" flag
* @param propertyConfig the property configuration
* @param discardInheritedProperties the "discard inherited properties" flag
* @param detailPageInfos the detail page configuration
* @param modelPages the model page configuration
* @param functionReferences the function reference configuration
* @param discardInheritedModelPages the "discard inherited model pages" flag
* @param createContentsLocally the "create contents locally" flag
*/
public CmsADEConfigData(
String basePath,
List<CmsResourceTypeConfig> resourceTypeConfig,
boolean discardInheritedTypes,
List<CmsPropertyConfig> propertyConfig,
boolean discardInheritedProperties,
List<CmsDetailPageInfo> detailPageInfos,
List<CmsModelPageConfig> modelPages,
List<CmsFunctionReference> functionReferences,
boolean discardInheritedModelPages,
boolean createContentsLocally) {
m_basePath = basePath;
m_ownResourceTypes = resourceTypeConfig;
m_ownPropertyConfigurations = propertyConfig;
m_ownModelPageConfig = modelPages;
m_ownDetailPages = detailPageInfos;
m_functionReferences = functionReferences;
m_discardInheritedTypes = discardInheritedTypes;
m_discardInheritedProperties = discardInheritedProperties;
m_discardInheritedModelPages = discardInheritedModelPages;
m_createContentsLocally = createContentsLocally;
}
/**
* Creates an empty configuration for a given base path.<p>
*
* @param basePath the base path
*
* @return the empty configuration object
*/
public static CmsADEConfigData emptyConfiguration(String basePath) {
return new CmsADEConfigData(basePath);
}
/**
* Generic method to merge lists of named configuration objects.<p>
*
* The lists are merged such that the configuration objects from the child list rise to the front of the result list,
* and two configuration objects will be merged themselves if they share the same name.<p>
*
* For example, if we have two lists of configuration objects:<p>
*
* parent: A1, B1, C1<p>
* child: D2, B2<p>
*
* then the resulting list will look like:<p>
*
* D2, B3, A1, C1<p>
*
* where B3 is the result of merging B1 and B2.<p>
*
* @param <C> the type of configuration object
* @param parentConfigs the parent configurations
* @param childConfigs the child configurations
* @return the merged configuration object list
*/
protected static <C extends I_CmsConfigurationObject<C>> List<C> combineConfigurationElements(
List<C> parentConfigs,
List<C> childConfigs) {
List<C> result = new ArrayList<C>();
Map<String, C> map = new LinkedHashMap<String, C>();
if (parentConfigs != null) {
for (C parent : Lists.reverse(parentConfigs)) {
map.put(parent.getKey(), parent);
}
}
if (childConfigs == null) {
childConfigs = Collections.emptyList();
}
for (C child : Lists.reverse(childConfigs)) {
String childKey = child.getKey();
if (child.isDisabled()) {
map.remove(childKey);
} else {
C parent = map.get(childKey);
map.remove(childKey);
C newValue;
if (parent != null) {
newValue = parent.merge(child);
} else {
newValue = child;
}
map.put(childKey, newValue);
}
}
result = new ArrayList<C>(map.values());
Collections.reverse(result);
// those multiple "reverse" calls may a bit confusing. They are there because on the one hand we want to keep the
// configuration items from one configuration in the same order as they are defined, on the other hand we want
// configuration items from a child configuration to rise to the top of the configuration items.
// so for example, if the parent configuration has items with the keys A,B,C,E
// and the child configuration has items with the keys C,B,D
// we want the items of the combined configuration in the order C,B,D,A,E
return result;
}
/**
* Gets the list of all detail pages.<p>
*
* @return the list of all detail pages
*/
public List<CmsDetailPageInfo> getAllDetailPages() {
return getAllDetailPages(true);
}
/**
* Gets a list of all detail pages.<p>
*
* @param update if true, this method will try to correct the root paths in the returned objects if the corresponding resources have been moved
*
* @return the list of all detail pages
*/
public List<CmsDetailPageInfo> getAllDetailPages(boolean update) {
checkInitialized();
CmsADEConfigData parentData = parent();
List<CmsDetailPageInfo> parentDetailPages;
if (parentData != null) {
parentDetailPages = parentData.getAllDetailPages(false);
} else {
parentDetailPages = Collections.emptyList();
}
List<CmsDetailPageInfo> result = mergeDetailPages(parentDetailPages, m_ownDetailPages);
if (update) {
result = updateUris(result);
}
return result;
}
/**
* Gets the configuration base path.<p>
*
* For example, if the configuration file is located at /sites/default/.content/.config, the base path is /sites/default.<p>
*
* @return the base path of the configuration
*/
public String getBasePath() {
checkInitialized();
return m_basePath;
}
/**
* Gets the content folder path.<p>
*
* For example, if the configuration file is located at /sites/default/.content/.config, the content folder path is /sites/default/.content
*
* @return the content folder path
*/
public String getContentFolderPath() {
return CmsStringUtil.joinPaths(m_basePath, CONTENT_FOLDER_NAME);
}
/**
* Returns a list of the creatable resource types.<p>
*
* @param cms the CMS context used to check whether the resource types are creatable
* @return the list of creatable resource type
*
* @throws CmsException if something goes wrong
*/
public List<CmsResourceTypeConfig> getCreatableTypes(CmsObject cms) throws CmsException {
checkInitialized();
List<CmsResourceTypeConfig> result = new ArrayList<CmsResourceTypeConfig>();
for (CmsResourceTypeConfig typeConfig : getResourceTypes()) {
if (typeConfig.checkCreatable(cms)) {
result.add(typeConfig);
}
}
return result;
}
/**
* Returns the default model page.<p>
*
* @return the default model page
*/
public CmsModelPageConfig getDefaultModelPage() {
checkInitialized();
List<CmsModelPageConfig> modelPages = getModelPages();
for (CmsModelPageConfig modelPageConfig : getModelPages()) {
if (modelPageConfig.isDefault()) {
return modelPageConfig;
}
}
if (modelPages.isEmpty()) {
return null;
}
return modelPages.get(0);
}
/**
* Gets the detail pages for a specific type.<p>
*
* @param type the type name
*
* @return the list of detail pages for that type
*/
public List<CmsDetailPageInfo> getDetailPagesForType(String type) {
List<CmsDetailPageInfo> result = new ArrayList<CmsDetailPageInfo>();
for (CmsDetailPageInfo detailpage : getAllDetailPages(true)) {
if (detailpage.getType().equals(type)) {
result.add(detailpage);
}
}
return result;
}
/**
* Gets the formatter configuration for a resource.<p>
*
* @param cms the current CMS context
* @param res the resource for which the formatter configuration should be retrieved
*
* @return the configuration of formatters for the resource
*/
public CmsFormatterConfiguration getFormatters(CmsObject cms, CmsResource res) {
int resTypeId = res.getTypeId();
try {
I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(resTypeId);
String typeName = resType.getTypeName();
CmsResourceTypeConfig typeConfig = getResourceType(typeName);
if ((typeConfig != null)
&& (typeConfig.getFormatterConfiguration() != null)
&& !typeConfig.getFormatterConfiguration().getAllFormatters().isEmpty()) {
return typeConfig.getFormatterConfiguration();
}
return getFormattersFromSchema(cms, res);
} catch (CmsLoaderException e) {
LOG.warn(e.getLocalizedMessage(), e);
return null;
}
}
/**
* Gets a named function reference.<p>
*
* @param name the name of the function reference
*
* @return the function reference for the given name
*/
public CmsFunctionReference getFunctionReference(String name) {
List<CmsFunctionReference> functionReferences = getFunctionReferences();
for (CmsFunctionReference functionRef : functionReferences) {
if (functionRef.getName().equals(name)) {
return functionRef;
}
}
return null;
}
/**
* Gets the list of configured function references.<p>
*
* @return the list of configured function references
*/
public List<CmsFunctionReference> getFunctionReferences() {
return internalGetFunctionReferences();
}
/**
* Gets the main detail page for a specific type.<p>
*
* @param type the type name
*
* @return the main detail page for that type
*/
public CmsDetailPageInfo getMainDetailPage(String type) {
List<CmsDetailPageInfo> detailPages = getDetailPagesForType(type);
if ((detailPages == null) || detailPages.isEmpty()) {
return null;
}
return detailPages.get(0);
}
/**
* Gets the list of available model pages.<p>
*
* @return the list of available model pages
*/
public List<CmsModelPageConfig> getModelPages() {
CmsADEConfigData parentData = parent();
List<CmsModelPageConfig> parentModelPages;
if ((parentData != null) && !m_discardInheritedModelPages) {
parentModelPages = parentData.getModelPages();
} else {
parentModelPages = Collections.emptyList();
}
List<CmsModelPageConfig> result = combineConfigurationElements(parentModelPages, m_ownModelPageConfig);
return result;
}
/**
* Gets the configuration for the available properties.<p>
*
* @return the configuration for the available properties
*/
public List<CmsPropertyConfig> getPropertyConfiguration() {
CmsADEConfigData parentData = parent();
List<CmsPropertyConfig> parentProperties;
if ((parentData != null) && !m_discardInheritedProperties) {
parentProperties = parentData.getPropertyConfiguration();
} else {
parentProperties = Collections.emptyList();
}
List<CmsPropertyConfig> result = combineConfigurationElements(parentProperties, m_ownPropertyConfigurations);
return result;
}
/**
* Gets the property configuration as a map of CmsXmlContentProperty instances.<p>
*
* @return the map of property configurations
*/
public Map<String, CmsXmlContentProperty> getPropertyConfigurationAsMap() {
Map<String, CmsXmlContentProperty> result = new LinkedHashMap<String, CmsXmlContentProperty>();
for (CmsPropertyConfig propConf : getPropertyConfiguration()) {
result.put(propConf.getName(), propConf.getPropertyData());
}
return result;
}
/**
* Returns the resource from which this configuration was read.<p>
*
* @return the resource from which this configuration was read
*/
public CmsResource getResource() {
return m_resource;
}
/**
* Returns the configuration for a specific resource type.<p>
*
* @param typeName the name of the type
*
* @return the resource type configuration for that type
*/
public CmsResourceTypeConfig getResourceType(String typeName) {
checkInitialized();
for (CmsResourceTypeConfig type : getResourceTypes()) {
if (typeName.equals(type.getTypeName())) {
return type;
}
}
return null;
}
/**
* Gets a list of all available resource type configurations.<p>
*
* @return the available resource type configurations
*/
public List<CmsResourceTypeConfig> getResourceTypes() {
List<CmsResourceTypeConfig> result = internalGetResourceTypes();
for (CmsResourceTypeConfig config : result) {
config.initialize(m_cms);
}
return result;
}
/**
* Gets the searchable resource type configurations.<p>
*
* @param cms the current CMS context
* @return the searchable resource type configurations
*/
public Collection<CmsResourceTypeConfig> getSearchableTypes(CmsObject cms) {
return getResourceTypes();
}
/**
* Initializes the configuration object.<p>
*
* @param cms the CMS context to be used for VFS operations
*/
public void initialize(CmsObject cms) {
m_cms = cms;
m_initialized = true;
}
/**
* Returns the value of the "create contents locally" flag.<p>
*
* If this flag is set, contents of types configured in a super-sitemap will be created in the sub-sitemap (if the user
* creates them from the sub-sitemap).
*
* @return the "create contents locally" flag
*/
public boolean isCreateContentsLocally() {
return m_createContentsLocally;
}
/**
* Returns the value of the "discard inherited model pages" flag.<p>
*
* If this flag is set, inherited model pages will be discarded for this sitemap.<p>
*
* @return the "discard inherited model pages" flag
*/
public boolean isDiscardInheritedModelPages() {
return m_discardInheritedModelPages;
}
/**
* Returns the value of the "discard inherited properties" flag.<p>
*
* If this is flag is set, inherited property definitions will be discarded for this sitemap.<p>
*
* @return the "discard inherited properties" flag.<p>
*/
public boolean isDiscardInheritedProperties() {
return m_discardInheritedProperties;
}
/**
* Returns the value of the "discard inherited types" flag.<p>
*
* If this flag is set, inherited resource types from a super-sitemap will be discarded for this sitemap.<p>
*
* @return the "discard inherited types" flag
*/
public boolean isDiscardInheritedTypes() {
return m_discardInheritedTypes;
}
/**
* Returns true if this is a module configuration instead of a normal sitemap configuration.<p>
*
* @return true if this is a module configuration
*/
public boolean isModuleConfiguration() {
return m_isModuleConfig;
}
/**
* Fetches the parent configuration of this configuration.<p>
*
* If this configuration is a sitemap configuration with no direct parent configuration,
* the module configuration will be returned. If this configuration already is a module configuration,
* null will be returned.<p>
*
* @return the parent configuration
*/
public CmsADEConfigData parent() {
if (m_basePath == null) {
return null;
}
String parentPath = CmsResource.getParentFolder(m_basePath);
if (OpenCms.getADEManager() == null) {
return null;
}
CmsADEConfigData result = OpenCms.getADEManager().internalLookupConfiguration(m_cms, parentPath);
return result;
}
/**
* Sets the "module configuration" flag.<p>
*
* @param isModuleConfig true if this configuration should be marked as a module configuration
*/
public void setIsModuleConfig(boolean isModuleConfig) {
checkNotInitialized();
m_isModuleConfig = isModuleConfig;
}
/**
* Sets the configuration file resource.<p>
*
* @param resource the configuration file resource
*/
public void setResource(CmsResource resource) {
checkNotInitialized();
m_resource = resource;
}
/**
* Checks whether the configuration is initialized and throws an error otherwise.<p>
*/
protected void checkInitialized() {
if (!m_initialized) {
throw new IllegalStateException();
}
}
/**
* Checks whether the configuration is *NOT* initialized and throws an error otherwise.<p>
*/
protected void checkNotInitialized() {
if (m_initialized) {
throw new IllegalStateException();
}
}
/**
* Creates the content directory for this configuration node if possible.<p>
*
* @throws CmsException if something goes wrong
*/
protected void createContentDirectory() throws CmsException {
if (!isModuleConfiguration()) {
String contentFolder = getContentFolderPath();
if (!m_cms.existsResource(contentFolder)) {
m_cms.createResource(
contentFolder,
OpenCms.getResourceManager().getResourceType(CmsResourceTypeFolder.getStaticTypeName()).getTypeId());
}
}
}
/**
* Gets the CMS object used for VFS operations.<p>
*
* @return the CMS object
*/
protected CmsObject getCmsObject() {
return m_cms;
}
/**
* Helper method to converts a list of detail pages to a map from type names to lists of detail pages for each type.<p>
*
* @param detailPages the list of detail pages
*
* @return the map of detail pages
*/
protected Map<String, List<CmsDetailPageInfo>> getDetailPagesMap(List<CmsDetailPageInfo> detailPages) {
Map<String, List<CmsDetailPageInfo>> result = Maps.newHashMap();
for (CmsDetailPageInfo detailpage : detailPages) {
String type = detailpage.getType();
if (!result.containsKey(type)) {
result.put(type, new ArrayList<CmsDetailPageInfo>());
}
result.get(type).add(detailpage);
}
return result;
}
/**
* Collects the folder types in a map.<p>
*
* @return the map of folder types
*
* @throws CmsException if something goes wrong
*/
protected Map<String, String> getFolderTypes() throws CmsException {
Map<String, String> result = new HashMap<String, String>();
CmsObject cms = OpenCms.initCmsObject(m_cms);
if (m_isModuleConfig) {
Set<String> siteRoots = OpenCms.getSiteManager().getSiteRoots();
for (String siteRoot : siteRoots) {
cms.getRequestContext().setSiteRoot(siteRoot);
for (CmsResourceTypeConfig config : getResourceTypes()) {
String typeName = config.getTypeName();
String folderPath = config.getFolderPath(cms);
result.put(CmsStringUtil.joinPaths(folderPath, "/"), typeName);
}
}
} else {
for (CmsResourceTypeConfig config : getResourceTypes()) {
String typeName = config.getTypeName();
String folderPath = config.getFolderPath(m_cms);
result.put(CmsStringUtil.joinPaths(folderPath, "/"), typeName);
}
}
return result;
}
/**
* Gets the formatter configuration for a given type.<p>
*
* @param type the type for which to get the formatters
*
* @return the formatter configuration for that type
*/
protected CmsFormatterConfiguration getFormatters(String type) {
CmsResourceTypeConfig typeConfig = getResourceType(type);
if ((typeConfig == null)
|| (typeConfig.getFormatterConfiguration() == null)
|| (typeConfig.getFormatterConfiguration().getAllFormatters().isEmpty())) {
try {
CmsXmlContentDefinition contentDefinition = CmsXmlContentDefinition.getContentDefinitionForType(
m_cms,
type);
if (contentDefinition == null) {
return null;
}
return contentDefinition.getContentHandler().getFormatterConfiguration(m_cms, null);
} catch (CmsException e) {
LOG.error(e.getLocalizedMessage(), e);
return null;
}
}
return typeConfig.getFormatterConfiguration();
}
/**
* Gets the formatters from the schema.<p>
*
* @param cms the current CMS context
* @param res the resource for which the formatters should be retrieved
*
* @return the formatters from the schema
*/
protected CmsFormatterConfiguration getFormattersFromSchema(CmsObject cms, CmsResource res) {
try {
I_CmsXmlContentHandler contentHandler = CmsXmlContentDefinition.getContentHandlerForResource(m_cms, res);
return contentHandler.getFormatterConfiguration(cms, res);
} catch (CmsException e) {
LOG.warn(e.getLocalizedMessage(), e);
return CmsFormatterConfiguration.EMPTY_CONFIGURATION;
}
}
/**
* Internal method for getting the function references.<p>
*
* @return the function references
*/
protected List<CmsFunctionReference> internalGetFunctionReferences() {
checkInitialized();
CmsADEConfigData parentData = parent();
if ((parentData == null)) {
if (m_isModuleConfig) {
return Collections.unmodifiableList(m_functionReferences);
} else {
return Lists.newArrayList();
}
} else {
return parentData.internalGetFunctionReferences();
}
}
/**
* Helper method for getting the list of resource types.<p>
*
* @return the list of resource types
*/
protected List<CmsResourceTypeConfig> internalGetResourceTypes() {
checkInitialized();
CmsADEConfigData parentData = parent();
List<CmsResourceTypeConfig> parentResourceTypes = null;
if ((parentData == null) || m_discardInheritedTypes) {
parentResourceTypes = Lists.newArrayList();
} else {
parentResourceTypes = Lists.newArrayList();
for (CmsResourceTypeConfig typeConfig : parentData.internalGetResourceTypes()) {
parentResourceTypes.add(typeConfig.copy());
}
}
List<CmsResourceTypeConfig> result = combineConfigurationElements(parentResourceTypes, m_ownResourceTypes);
if (m_createContentsLocally) {
for (CmsResourceTypeConfig typeConfig : result) {
typeConfig.updateBasePath(CmsStringUtil.joinPaths(m_basePath, ".content"));
}
}
return result;
}
/**
* Merges two lists of detail pages, one from a parent configuration and one from a child configuration.<p>
*
* @param parentDetailPages the parent's detail pages
* @param ownDetailPages the child's detail pages
*
* @return the merged detail pages
*/
protected List<CmsDetailPageInfo> mergeDetailPages(
List<CmsDetailPageInfo> parentDetailPages,
List<CmsDetailPageInfo> ownDetailPages) {
List<CmsDetailPageInfo> result = new ArrayList<CmsDetailPageInfo>();
Map<String, List<CmsDetailPageInfo>> resultDetailPageMap = Maps.newHashMap();
resultDetailPageMap.putAll(getDetailPagesMap(parentDetailPages));
resultDetailPageMap.putAll(getDetailPagesMap(ownDetailPages));
result = new ArrayList<CmsDetailPageInfo>();
for (List<CmsDetailPageInfo> pages : resultDetailPageMap.values()) {
result.addAll(pages);
}
return result;
}
/**
* Merges the parent's data into this object.<p>
*
* @param parent the parent configuration data
*/
protected void mergeParent(CmsADEConfigData parent) {
List<CmsResourceTypeConfig> parentTypes = null;
if (parent != null) {
parentTypes = parent.m_ownResourceTypes;
} else {
parentTypes = Collections.emptyList();
}
List<CmsPropertyConfig> parentProperties = null;
if (parent != null) {
parentProperties = parent.m_ownPropertyConfigurations;
} else {
parentProperties = Collections.emptyList();
}
List<CmsModelPageConfig> parentModelPages = null;
if (parent != null) {
parentModelPages = parent.m_ownModelPageConfig;
} else {
parentModelPages = Collections.emptyList();
}
List<CmsFunctionReference> parentFunctionRefs = null;
if (parent != null) {
parentFunctionRefs = parent.m_functionReferences;
} else {
parentFunctionRefs = Collections.emptyList();
}
m_ownResourceTypes = combineConfigurationElements(parentTypes, m_ownResourceTypes);
m_ownPropertyConfigurations = combineConfigurationElements(parentProperties, m_ownPropertyConfigurations);
m_ownModelPageConfig = combineConfigurationElements(parentModelPages, m_ownModelPageConfig);
m_functionReferences = combineConfigurationElements(parentFunctionRefs, m_functionReferences);
}
/**
* Handle the ordering from the module configurations.<p>
*/
protected void processModuleOrdering() {
Collections.sort(m_ownResourceTypes, new Comparator<CmsResourceTypeConfig>() {
public int compare(CmsResourceTypeConfig a, CmsResourceTypeConfig b) {
return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(
a.getTypeName(),
b.getTypeName()).result();
}
});
Collections.sort(m_ownPropertyConfigurations, new Comparator<CmsPropertyConfig>() {
public int compare(CmsPropertyConfig a, CmsPropertyConfig b) {
return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(a.getName(), b.getName()).result();
}
});
Collections.sort(m_functionReferences, new Comparator<CmsFunctionReference>() {
public int compare(CmsFunctionReference a, CmsFunctionReference b) {
return ComparisonChain.start().compare(a.getOrder(), b.getOrder()).compare(a.getName(), b.getName()).result();
}
});
}
/**
* Helper method to correct paths in detail page beans if the corresponding resources have been moved.<p>
*
* @param detailPages the original list of detail pages
*
* @return the corrected list of detail pages
*/
protected List<CmsDetailPageInfo> updateUris(List<CmsDetailPageInfo> detailPages) {
List<CmsDetailPageInfo> result = new ArrayList<CmsDetailPageInfo>();
for (CmsDetailPageInfo page : detailPages) {
CmsUUID structureId = page.getId();
try {
String rootPath = OpenCms.getADEManager().getRootPath(
structureId,
m_cms.getRequestContext().getCurrentProject().isOnlineProject());
CmsDetailPageInfo correctedPage = new CmsDetailPageInfo(structureId, rootPath, page.getType());
result.add(correctedPage);
} catch (CmsException e) {
LOG.warn(e.getLocalizedMessage(), e);
}
}
return result;
}
}