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 (http://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: http://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: http://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        for (CmsContainerConfigurationGroup group : groups) {
070            if (group != null) {
071                m_configurationsByPath.put(getBasePath(group.getRootPath()), group);
072                m_configurationsById.put(group.getStructureId(), group);
073            }
074        }
075    }
076
077    /**
078     * Gets the container configuration for a given root path, name and locale.<p>
079     *
080     * @param rootPath the root path
081     * @param name the configuration name
082     *
083     * @return the container configuration for the given combination of parameters
084     */
085    public synchronized CmsContainerConfiguration getContainerConfiguration(String rootPath, String name) {
086
087        String key = getCacheKey(rootPath);
088        if (m_configurationsByPath.containsKey(key)) {
089            CmsContainerConfigurationGroup group = m_configurationsByPath.get(key);
090            CmsContainerConfiguration result = group.getConfiguration(name);
091            return result;
092        }
093        return null;
094    }
095
096    /**
097     * Creates a new inheritance container cache state, which is based on this instance, but with some changed configurations.<p>
098     *
099     * @param updateGroups a map of the updated configurations, with the structure ids as keys
100     *
101     * @return the new cache state
102     */
103    public CmsContainerConfigurationCacheState updateWithChangedGroups(
104        Map<CmsUUID, CmsContainerConfigurationGroup> updateGroups) {
105
106        Map<CmsUUID, CmsContainerConfigurationGroup> newGroups = Maps.newHashMap(m_configurationsById);
107
108        for (Map.Entry<CmsUUID, CmsContainerConfigurationGroup> entry : updateGroups.entrySet()) {
109            CmsUUID key = entry.getKey();
110            CmsContainerConfigurationGroup group = entry.getValue();
111            if (group == null) {
112                newGroups.remove(key);
113            } else {
114                newGroups.put(key, group);
115            }
116        }
117        return new CmsContainerConfigurationCacheState(newGroups.values());
118    }
119
120    /**
121     * Returns the base path for a given configuration file.
122     *
123     * E.g. the result for the input '/sites/default/.container-config' will be '/sites/default'.<p>
124     *
125     * @param rootPath the root path of the configuration file
126     *
127     * @return the base path for the configuration file
128     */
129    protected String getBasePath(String rootPath) {
130
131        if (rootPath.endsWith(INHERITANCE_CONFIG_FILE_NAME)) {
132            return rootPath.substring(0, rootPath.length() - INHERITANCE_CONFIG_FILE_NAME.length());
133        }
134        return rootPath;
135    }
136
137    /**
138     * Gets the cache key for a given base path.<p>
139     *
140     * @param basePath the base path
141     *
142     * @return the cache key for the base path
143     */
144    protected String getCacheKey(String basePath) {
145
146        assert !basePath.endsWith(INHERITANCE_CONFIG_FILE_NAME);
147        return CmsFileUtil.addTrailingSeparator(basePath);
148    }
149
150}