All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.ade.containerpage.inherited.CmsContainerConfigurationCache Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * File   : $Source$
 * Date   : $Date$
 * Version: $Revision$
 *
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (C) 2002 - 2011 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.containerpage.inherited;

import org.opencms.ade.configuration.CmsSynchronizedUpdateSet;
import org.opencms.ade.configuration.I_CmsGlobalConfigurationCache;
import org.opencms.db.CmsPublishedResource;
import org.opencms.db.CmsResourceState;
import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsUUID;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;

import com.google.common.collect.Maps;

/**
 * A cache class for storing inherited container configurations.

*/ public class CmsContainerConfigurationCache implements I_CmsGlobalConfigurationCache { /** Interval used to check for changes. */ public static final long UPDATE_INTERVAL_MILLIS = 500; /** The standard file name for inherited container configurations. */ public static final String INHERITANCE_CONFIG_FILE_NAME = ".inherited"; /** UUID used to signal a cache clear. */ public static final CmsUUID UPDATE_ALL = CmsUUID.getNullUUID(); /** The logger instance for this class. */ public static final Log LOG = CmsLog.getLog(CmsContainerConfigurationCache.class); /** A flag which indicates whether this cache is initialized. */ protected boolean m_initialized; /** The CMS context used for this cache's VFS operations. */ private CmsObject m_cms; /** The name of this cache, used for testing/debugging purposes. */ private String m_name; /** The current cache state. */ private volatile CmsContainerConfigurationCacheState m_state = new CmsContainerConfigurationCacheState( new ArrayList()); /** Future used to cancel an already scheduled task if initialize() is called again. */ private ScheduledFuture m_taskFuture; /** The set of IDs to update. */ private CmsSynchronizedUpdateSet m_updateSet = new CmsSynchronizedUpdateSet(); /** * Creates a new cache instance for inherited containers.

* * @param cms the CMS context to use for VFS operations. * @param name the name of the cache, for debugging/testing purposes * * @throws CmsException if something goes wrong */ public CmsContainerConfigurationCache(CmsObject cms, String name) throws CmsException { m_cms = OpenCms.initCmsObject(cms); m_name = name; } /** * @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#clear() */ public synchronized void clear() { m_updateSet.add(UPDATE_ALL); } /** * Processes all enqueued inheritance container updates.

*/ public synchronized void flushUpdates() { Set updateIds = m_updateSet.removeAll(); if (!updateIds.isEmpty()) { if (updateIds.contains(UPDATE_ALL)) { initialize(); } else { Map groups = loadFromIds(updateIds); CmsContainerConfigurationCacheState state = m_state.updateWithChangedGroups(groups); m_state = state; } } } /** * Gets the current cache contents.

* * @return the cache contents */ public CmsContainerConfigurationCacheState getState() { return m_state; } /** * Initializes the cache.

*/ public synchronized void initialize() { LOG.info("Initializing inheritance group cache: " + m_name); if (m_taskFuture != null) { // in case initialize has been called before on this object, cancel the existing task m_taskFuture.cancel(false); m_taskFuture = null; } try { List resources = m_cms.readResources( "/", CmsResourceFilter.IGNORE_EXPIRATION.addRequireType( OpenCms.getResourceManager().getResourceType( CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_CONFIG_TYPE_NAME)), true); m_state = new CmsContainerConfigurationCacheState(load(resources).values()); } catch (Exception e) { LOG.error(e.getLocalizedMessage(), e); } Runnable updateAction = new Runnable() { public void run() { try { flushUpdates(); } catch (Throwable e) { LOG.error(e.getLocalizedMessage(), e); } } }; m_taskFuture = OpenCms.getExecutor().scheduleWithFixedDelay( updateAction, UPDATE_INTERVAL_MILLIS, UPDATE_INTERVAL_MILLIS, TimeUnit.MILLISECONDS); } /** * @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#remove(org.opencms.db.CmsPublishedResource) */ public void remove(CmsPublishedResource resource) { remove(resource.getStructureId(), resource.getRootPath(), resource.getType()); } /** * @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#remove(org.opencms.file.CmsResource) */ public void remove(CmsResource resource) { remove(resource.getStructureId(), resource.getRootPath(), resource.getTypeId()); } /** * @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#update(org.opencms.db.CmsPublishedResource) */ public void update(CmsPublishedResource resource) { update(resource.getStructureId(), resource.getRootPath(), resource.getType(), resource.getState()); } /** * @see org.opencms.ade.configuration.I_CmsGlobalConfigurationCache#update(org.opencms.file.CmsResource) */ public void update(CmsResource resource) { update(resource.getStructureId(), resource.getRootPath(), resource.getTypeId(), resource.getState()); } /** * Returns the base path for a given configuration file. * * E.g. the result for the input '/sites/default/.container-config' will be '/sites/default'.

* * @param rootPath the root path of the configuration file * * @return the base path for the configuration file */ protected String getBasePath(String rootPath) { if (rootPath.endsWith(INHERITANCE_CONFIG_FILE_NAME)) { return rootPath.substring(0, rootPath.length() - INHERITANCE_CONFIG_FILE_NAME.length()); } return rootPath; } /** * Gets the cache key for a given base path.

* * @param basePath the base path * * @return the cache key for the base path */ protected String getCacheKey(String basePath) { assert !basePath.endsWith(INHERITANCE_CONFIG_FILE_NAME); return CmsFileUtil.addTrailingSeparator(basePath); } /** * Checks whether a given combination of path and resource type belongs to an inherited container configuration file.

* * @param rootPath the root path of the resource * @param type the type id of the resource * * @return true if the given root path / type combination matches an inherited container configuration file */ protected boolean isContainerConfiguration(String rootPath, int type) { return OpenCms.getResourceManager().matchResourceType( CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_CONFIG_TYPE_NAME, type) && !CmsResource.isTemporaryFileName(rootPath) && rootPath.endsWith("/" + INHERITANCE_CONFIG_FILE_NAME); } /** * Loads the inheritance groups from a list of resources.

* * If the configuration for a given resource can't be read, the corresponding map entry will be null in the result. * * @param resources the resources * @return the inheritance group configurations, with structure ids of the corresponding resources as keys */ protected Map load(Collection resources) { Map result = Maps.newHashMap(); for (CmsResource resource : resources) { CmsContainerConfigurationGroup parsedGroup = null; try { CmsFile file = m_cms.readFile(resource); CmsContainerConfigurationParser parser = new CmsContainerConfigurationParser(m_cms); parser.parse(file); parsedGroup = new CmsContainerConfigurationGroup(parser.getParsedResults()); parsedGroup.setResource(resource); } catch (CmsVfsResourceNotFoundException e) { LOG.debug(e.getLocalizedMessage(), e); } catch (Throwable e) { LOG.error(e.getLocalizedMessage(), e); } // if the group couldn't be read or parsed for some reason, the map value is null result.put(resource.getStructureId(), parsedGroup); } return result; } /** * Loads the inheritance groups from the resources with structure ids from the given list.

* * If the configuration for a given id can't be read, the corresponding map entry will be null in the result. * * @param structureIds the structure ids * @return the inheritance group configurations, with structure ids of the corresponding resources as keys */ protected Map loadFromIds(Collection structureIds) { Map result = Maps.newHashMap(); for (CmsUUID id : structureIds) { CmsContainerConfigurationGroup parsedGroup = null; try { CmsResource resource = m_cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); CmsFile file = m_cms.readFile(resource); CmsContainerConfigurationParser parser = new CmsContainerConfigurationParser(m_cms); parser.parse(file); parsedGroup = new CmsContainerConfigurationGroup(parser.getParsedResults()); parsedGroup.setResource(resource); } catch (CmsVfsResourceNotFoundException e) { LOG.debug(e.getLocalizedMessage(), e); } catch (Throwable e) { LOG.error(e.getLocalizedMessage(), e); } // if the group couldn't be read or parsed for some reason, the map value is null result.put(id, parsedGroup); } return result; } /** * Removes a resource from the cache.

* * @param structureId the structure id of the resource * @param rootPath the root path of the resource * * @param type the resource type */ protected void remove(CmsUUID structureId, String rootPath, int type) { if (!isContainerConfiguration(rootPath, type)) { return; } m_updateSet.add(structureId); } /** * Updates a resource in the cache.

* * @param structureId the structure id of the resource * @param rootPath the root path of the resource * @param type the resource type * @param state the resource state */ protected void update(CmsUUID structureId, String rootPath, int type, CmsResourceState state) { if (!isContainerConfiguration(rootPath, type)) { return; } m_updateSet.add(structureId); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy