001/*
002 * File   : $Source$
003 * Date   : $Date$
004 * Version: $Revision$
005 *
006 * This library is part of OpenCms -
007 * the Open Source Content Management System
008 *
009 * Copyright (C) 2002 - 2011 Alkacon Software (https://www.alkacon.com)
010 *
011 * This library is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Lesser General Public
013 * License as published by the Free Software Foundation; either
014 * version 2.1 of the License, or (at your option) any later version.
015 *
016 * This library is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 * Lesser General Public License for more details.
020 *
021 * For further information about Alkacon Software, please see the
022 * company website: https://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: https://www.opencms.org
026 *
027 * You should have received a copy of the GNU Lesser General Public
028 * License along with this library; if not, write to the Free Software
029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030 */
031
032package org.opencms.ade.containerpage.inherited;
033
034import org.opencms.main.CmsLog;
035import org.opencms.util.CmsFileUtil;
036import org.opencms.util.CmsUUID;
037
038import java.util.Collection;
039import java.util.HashMap;
040import java.util.Map;
041
042import org.apache.commons.logging.Log;
043
044import com.google.common.collect.Maps;
045
046/**
047 * A cache class for storing inherited container configurations.<p>
048 */
049public class CmsContainerConfigurationCacheState {
050
051    /** The standard file name for inherited container configurations. */
052    public static final String INHERITANCE_CONFIG_FILE_NAME = ".inherited";
053
054    /** The logger instance for this class. */
055    public static final Log LOG = CmsLog.getLog(CmsContainerConfigurationCacheState.class);
056
057    /** Inheritance configurations by structure id. */
058    private Map<CmsUUID, CmsContainerConfigurationGroup> m_configurationsById = new HashMap<CmsUUID, CmsContainerConfigurationGroup>();
059
060    /** The map of cached configurations, with the base paths as keys. */
061    private Map<String, CmsContainerConfigurationGroup> m_configurationsByPath = new HashMap<String, CmsContainerConfigurationGroup>();
062
063    /**
064     * Creates a new cache state.<p>
065     *
066     * @param groups the inheritance group configurations.<p>
067     */
068    public CmsContainerConfigurationCacheState(Collection<CmsContainerConfigurationGroup> groups) {
069
070        for (CmsContainerConfigurationGroup group : groups) {
071            if (group != null) {
072                m_configurationsByPath.put(getBasePath(group.getRootPath()), group);
073                m_configurationsById.put(group.getStructureId(), group);
074            }
075        }
076    }
077
078    /**
079     * Gets the container configuration for a given root path, name and locale.<p>
080     *
081     * @param rootPath the root path
082     * @param name the configuration name
083     *
084     * @return the container configuration for the given combination of parameters
085     */
086    public synchronized CmsContainerConfiguration getContainerConfiguration(String rootPath, String name) {
087
088        String key = getCacheKey(rootPath);
089        if (m_configurationsByPath.containsKey(key)) {
090            CmsContainerConfigurationGroup group = m_configurationsByPath.get(key);
091            CmsContainerConfiguration result = group.getConfiguration(name);
092            return result;
093        }
094        return null;
095    }
096
097    /**
098     * Creates a new inheritance container cache state, which is based on this instance, but with some changed configurations.<p>
099     *
100     * @param updateGroups a map of the updated configurations, with the structure ids as keys
101     *
102     * @return the new cache state
103     */
104    public CmsContainerConfigurationCacheState updateWithChangedGroups(
105        Map<CmsUUID, CmsContainerConfigurationGroup> updateGroups) {
106
107        Map<CmsUUID, CmsContainerConfigurationGroup> newGroups = Maps.newHashMap(m_configurationsById);
108
109        for (Map.Entry<CmsUUID, CmsContainerConfigurationGroup> entry : updateGroups.entrySet()) {
110            CmsUUID key = entry.getKey();
111            CmsContainerConfigurationGroup group = entry.getValue();
112            if (group == null) {
113                newGroups.remove(key);
114            } else {
115                newGroups.put(key, group);
116            }
117        }
118        return new CmsContainerConfigurationCacheState(newGroups.values());
119    }
120
121    /**
122     * Returns the base path for a given configuration file.
123     *
124     * E.g. the result for the input '/sites/default/.container-config' will be '/sites/default'.<p>
125     *
126     * @param rootPath the root path of the configuration file
127     *
128     * @return the base path for the configuration file
129     */
130    protected String getBasePath(String rootPath) {
131
132        if (rootPath.endsWith(INHERITANCE_CONFIG_FILE_NAME)) {
133            return rootPath.substring(0, rootPath.length() - INHERITANCE_CONFIG_FILE_NAME.length());
134        }
135        return rootPath;
136    }
137
138    /**
139     * Gets the cache key for a given base path.<p>
140     *
141     * @param basePath the base path
142     *
143     * @return the cache key for the base path
144     */
145    protected String getCacheKey(String basePath) {
146
147        assert !basePath.endsWith(INHERITANCE_CONFIG_FILE_NAME);
148        return CmsFileUtil.addTrailingSeparator(basePath);
149    }
150
151}