📄 cmsflexcache.java
字号:
/*
* File : $Source: /usr/local/cvs/opencms/src/org/opencms/flex/CmsFlexCache.java,v $
* Date : $Date: 2006/03/27 14:52:35 $
* Version: $Revision: 1.52 $
*
* This library is part of OpenCms -
* the Open Source Content Mananagement System
*
* Copyright (c) 2005 Alkacon Software GmbH (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 GmbH, 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.flex;
import org.opencms.cache.CmsLruCache;
import org.opencms.cache.I_CmsLruCacheObject;
import org.opencms.file.CmsObject;
import org.opencms.main.CmsLog;
import org.opencms.main.I_CmsEventListener;
import org.opencms.main.OpenCms;
import org.opencms.security.CmsRole;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsStringUtil;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.logging.Log;
/**
* This class implements the FlexCache.<p>
*
* The data structure used is a two-level hashtable.
* This is optimized for the structure of the keys that are used to describe the
* caching behaviour of the entries.
* The first hash-level is calculated from the resource name, i.e. the
* name of the resource as it is referred to in the VFS of OpenCms.
* The second hash-level is calculated from the cache-key of the resource,
* which also is a String representing the specifc variation of the cached entry.<p>
*
* A suffix [online] or [offline] is appended to te resource name
* to distinguish between the online and offline projects of OpenCms.
* Also, for support of JSP based workplace pages, a suffix [workplace]
* is appended. The same cached workplace pages are used both in the online and
* all offline projects.<p>
*
* Entries in the first level of the cache are of type CmsFlexCacheVariation,
* which is a sub-class of CmsFlexCache.
* This class is a simple data type that contains of a Map of CmsFlexCacheEntries,
* with variations - Strings as keys.<p>
*
* Here's a short summary of used terms:
* <ul>
* <li><b>key:</b>
* A combination of a resource name and a variation.
* The data structure used is CmsFlexCacheKey.
* <li><b>resource:</b>
* A String with the resource name and an appended [online] of [offline] suffix.
* <li><b>variation:</b>
* A String describing a variation of a cached entry in the CmsFlexCache language.
* <li><b>entry:</b>
* A CmsFlexCacheEntry data structure which is describes a cached OpenCms resource.
* For every entry a key is saved which contains the resource name and the variation.
* </ul>
*
* Cache clearing is handled using events.
* The cache is fully flushed if an event {@link I_CmsEventListener#EVENT_PUBLISH_PROJECT}
* or {@link I_CmsEventListener#EVENT_CLEAR_CACHES} is caught.<p>
*
* @author Alexander Kandzior
* @author Thomas Weckert
*
* @version $Revision: 1.52 $
*
* @since 6.0.0
*
* @see org.opencms.flex.CmsFlexCacheKey
* @see org.opencms.flex.CmsFlexCacheEntry
* @see org.opencms.cache.CmsLruCache
* @see org.opencms.cache.I_CmsLruCacheObject
*/
public class CmsFlexCache extends Object implements I_CmsEventListener {
/**
* A simple data container class for the FlexCache variations.<p>
*
* @author Alexander Kandzior
*/
public class CmsFlexCacheVariation extends Object {
/** The key belonging to the resource. */
public CmsFlexCacheKey m_key;
/** Maps variations to CmsFlexCacheEntries. */
public Map m_map;
/**
* Generates a new instance of CmsFlexCacheVariation.<p>
*
* @param theKey The (resource) key to contruct this variation list for
*/
public CmsFlexCacheVariation(CmsFlexCacheKey theKey) {
m_key = theKey;
m_map = new Hashtable(INITIAL_CAPACITY_VARIATIONS);
}
}
/**
* Extended LRUMap that handles the variations in case a key is removed.<p>
*
* @author Alexander Kandzior
*/
class CmsFlexKeyMap extends LRUMap {
/** Serial version UID required for safe serialization. */
private static final long serialVersionUID = 6931995916013396902L;
/**
* Initialize the map with the given size.<p>
*
* @param maxSize the maximum number of key to cache
*/
public CmsFlexKeyMap(int maxSize) {
super(maxSize);
}
/**
* Ensures that all variations that referenced by this key are released
* if the key is released.<p>
*/
protected boolean removeLRU(LinkEntry entry) {
CmsFlexCacheVariation v = (CmsFlexCacheVariation)entry.getValue();
if (v == null) {
return true;
}
Map m = v.m_map;
if ((m == null) || (m.size() == 0)) {
return true;
}
Object[] entries = m.values().toArray();
synchronized (m_variationCache) {
for (int i = 0, s = entries.length; i < s; i++) {
CmsFlexCacheEntry e = (CmsFlexCacheEntry)entries[i];
m_variationCache.remove(e);
}
v.m_map.clear();
v.m_map = null;
v.m_key = null;
}
return true;
}
}
/** Suffix to append to online cache entries. */
public static final String CACHE_OFFLINESUFFIX = " [offline]";
/** Suffix to append to online cache entries. */
public static final String CACHE_ONLINESUFFIX = " [online]";
/** Trigger for clearcache event: Clear complete cache. */
public static final int CLEAR_ALL = 0;
/** Trigger for clearcache event: Clear only entries. */
public static final int CLEAR_ENTRIES = 1;
/** Trigger for clearcache event: Clear complete offine cache. */
public static final int CLEAR_OFFLINE_ALL = 4;
/** Trigger for clearcache event: Clear only offline entries. */
public static final int CLEAR_OFFLINE_ENTRIES = 5;
/** Trigger for clearcache event: Clear complete online cache. */
public static final int CLEAR_ONLINE_ALL = 2;
/** Trigger for clearcache event: Clear only online entries. */
public static final int CLEAR_ONLINE_ENTRIES = 3;
/** Initial cache size, this should be a power of 2 because of the Java collections implementation. */
public static final int INITIAL_CAPACITY_CACHE = 512;
/** Initial size for variation lists, should be a power of 2. */
public static final int INITIAL_CAPACITY_VARIATIONS = 8;
/** Offline repository constant. */
public static final String REPOSITORY_OFFLINE = "offline";
/** Online repository constant. */
public static final String REPOSITORY_ONLINE = "online";
/** The log object for this class. */
private static final Log LOG = CmsLog.getLog(CmsFlexCache.class);
/** The LRU cache to organize the cached entries. */
protected CmsLruCache m_variationCache;
/** Indicates if offline resources should be cached or not. */
private boolean m_cacheOffline;
/** Indicates if the cache is enabled or not. */
private boolean m_enabled;
/** Hashmap to store the entries for fast lookup. */
private Map m_keyCache;
/** Counter for the size. */
private int m_size;
/**
* Constructor for class CmsFlexCache.<p>
*
* The parameter "enabled" is used to control if the cache is
* actually on or off. Even if you don't need the cache, you still
* have to create an instance of it with enabled=false.
* This is because you need some of the FlexCache data structures
* for JSP inclusion buffering.<p>
*
* @param configuration the flex cache configuration
*/
public CmsFlexCache(CmsFlexCacheConfiguration configuration) {
m_enabled = configuration.isCacheEnabled();
m_cacheOffline = configuration.isCacheOffline();
int maxCacheBytes = configuration.getMaxCacheBytes();
int avgCacheBytes = configuration.getAvgCacheBytes();
int maxEntryBytes = configuration.getMaxEntryBytes();
int maxKeys = configuration.getMaxKeys();
m_variationCache = new CmsLruCache(maxCacheBytes, avgCacheBytes, maxEntryBytes);
if (OpenCms.getMemoryMonitor().enabled()) {
OpenCms.getMemoryMonitor().register(getClass().getName() + ".m_entryLruCache", m_variationCache);
}
if (m_enabled) {
CmsFlexKeyMap flexKeyMap = new CmsFlexKeyMap(maxKeys);
m_keyCache = Collections.synchronizedMap(flexKeyMap);
if (OpenCms.getMemoryMonitor().enabled()) {
OpenCms.getMemoryMonitor().register(getClass().getName() + ".m_resourceMap", flexKeyMap);
}
OpenCms.addCmsEventListener(this, new int[] {
I_CmsEventListener.EVENT_PUBLISH_PROJECT,
I_CmsEventListener.EVENT_CLEAR_CACHES,
I_CmsEventListener.EVENT_FLEX_PURGE_JSP_REPOSITORY,
I_CmsEventListener.EVENT_FLEX_CACHE_CLEAR});
}
if (LOG.isInfoEnabled()) {
LOG.info(Messages.get().getBundle().key(
Messages.INIT_FLEXCACHE_CREATED_2,
new Boolean(m_enabled),
new Boolean(m_cacheOffline)));
}
}
/**
* Indicates if offline project resources are cached.<p>
*
* @return true if offline projects are cached, false if not
*/
public boolean cacheOffline() {
return m_cacheOffline;
}
/**
* Implements the CmsEvent interface,
* the FlexCache uses the events to clear itself in case a project is published.<p>
*
* @param event CmsEvent that has occurred
*/
public void cmsEvent(org.opencms.main.CmsEvent event) {
if (!isEnabled()) {
return;
}
switch (event.getType()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -