servletcacheadministrator.java
来自「oscache-2.4.1-full」· Java 代码 · 共 807 行 · 第 1/2 页
JAVA
807 行
Cache cache = getCache(request, scope);
key = this.generateEntryKey(key, request, scope);
return cache.getFromCache(key, refreshPeriod);
}
/**
* Checks if the given scope was flushed more recently than the CacheEntry provided.
* Used to determine whether to refresh the particular CacheEntry.
*
* @param cacheEntry The cache entry which we're seeing whether to refresh
* @param scope The scope we're checking
*
* @return Whether or not the scope has been flushed more recently than this cache entry was updated.
*/
public boolean isScopeFlushed(CacheEntry cacheEntry, int scope) {
Date flushDateTime = getFlushTime(scope);
if (flushDateTime != null) {
long lastUpdate = cacheEntry.getLastUpdate();
return (flushDateTime.getTime() >= lastUpdate);
} else {
return false;
}
}
/**
* Register a listener for Cache Map events.
*
* @param listener The object that listens to events.
*/
public void addScopeEventListener(ScopeEventListener listener) {
listenerList.add(ScopeEventListener.class, listener);
}
/**
* Cancels a pending cache update. This should only be called by a thread
* that received a {@link NeedsRefreshException} and was unable to generate
* some new cache content.
*
* @param scope The cache scope
* @param request The servlet request
* @param key The cache entry key to cancel the update of.
*/
public void cancelUpdate(int scope, HttpServletRequest request, String key) {
Cache cache = getCache(request, scope);
key = this.generateEntryKey(key, request, scope);
cache.cancelUpdate(key);
}
/**
* Flush all scopes at a particular time
*
* @param date The time to flush the scope
*/
public void flushAll(Date date) {
synchronized (flushTimes) {
setFlushTime(date, PageContext.APPLICATION_SCOPE);
setFlushTime(date, PageContext.SESSION_SCOPE);
setFlushTime(date, PageContext.REQUEST_SCOPE);
setFlushTime(date, PageContext.PAGE_SCOPE);
}
// Trigger a flushAll event
dispatchScopeEvent(ScopeEventType.ALL_SCOPES_FLUSHED, -1, date, null);
}
/**
* Flush all scopes instantly.
*/
public void flushAll() {
flushAll(new Date());
}
/**
* Generates a cache entry key.
*
* If the string key is not specified, the HTTP request URI and QueryString is used.
* Operating systems that have a filename limitation less than 255 or have
* filenames that are case insensitive may have issues with key generation where
* two distinct pages map to the same key.
* <p>
* POST Requests (which have no distinguishing
* query string) may also generate identical keys for what is actually different pages.
* In these cases, specify an explicit key attribute for the CacheTag.
*
* @param key The key entered by the user
* @param request The current request
* @param scope The scope this cache entry is under
* @return The generated cache key
*/
public String generateEntryKey(String key, HttpServletRequest request, int scope) {
return generateEntryKey(key, request, scope, null, null);
}
/**
* Generates a cache entry key.
*
* If the string key is not specified, the HTTP request URI and QueryString is used.
* Operating systems that have a filename limitation less than 255 or have
* filenames that are case insensitive may have issues with key generation where
* two distinct pages map to the same key.
* <p>
* POST Requests (which have no distinguishing
* query string) may also generate identical keys for what is actually different pages.
* In these cases, specify an explicit key attribute for the CacheTag.
*
* @param key The key entered by the user
* @param request The current request
* @param scope The scope this cache entry is under
* @param language The ISO-639 language code to distinguish different pages in application scope
* @return The generated cache key
*/
public String generateEntryKey(String key, HttpServletRequest request, int scope, String language) {
return generateEntryKey(key, request, scope, language, null);
}
/**
* Generates a cache entry key.
* <p>
* If the string key is not specified, the HTTP request URI and QueryString is used.
* Operating systems that have a filename limitation less than 255 or have
* filenames that are case insensitive may have issues with key generation where
* two distinct pages map to the same key.
* <p>
* POST Requests (which have no distinguishing
* query string) may also generate identical keys for what is actually different pages.
* In these cases, specify an explicit key attribute for the CacheTag.
*
* @param key The key entered by the user
* @param request The current request
* @param scope The scope this cache entry is under
* @param language The ISO-639 language code to distinguish different pages in application scope
* @param suffix The ability to put a suffix at the end of the key
* @return The generated cache key
*/
public String generateEntryKey(String key, HttpServletRequest request, int scope, String language, String suffix) {
/**
* Used for generating cache entry keys.
*/
StringBuffer cBuffer = new StringBuffer(AVERAGE_KEY_LENGTH);
// Append the language if available
if (language != null) {
cBuffer.append(FILE_SEPARATOR).append(language);
}
// Servers for multiple host domains need this distinction in the key
if (useHostDomainInKey) {
cBuffer.append(FILE_SEPARATOR).append(request.getServerName());
}
if (key != null) {
cBuffer.append(FILE_SEPARATOR).append(key);
} else {
String generatedKey = request.getRequestURI();
if (generatedKey.charAt(0) != FILE_SEPARATOR_CHAR) {
cBuffer.append(FILE_SEPARATOR_CHAR);
}
cBuffer.append(generatedKey);
cBuffer.append("_").append(request.getMethod()).append("_");
generatedKey = getSortedQueryString(request);
if (generatedKey != null) {
try {
java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
byte[] b = digest.digest(generatedKey.getBytes());
cBuffer.append('_');
// Base64 encoding allows for unwanted slash characters.
cBuffer.append(toBase64(b).replace('/', '_'));
} catch (Exception e) {
// Ignore query string
}
}
}
// Do we want a suffix
if ((suffix != null) && (suffix.length() > 0)) {
cBuffer.append(suffix);
}
return cBuffer.toString();
}
/**
* Creates a string that contains all of the request parameters and their
* values in a single string. This is very similar to
* <code>HttpServletRequest.getQueryString()</code> except the parameters are
* sorted by name, and if there is a <code>jsessionid</code> parameter it is
* filtered out.<p>
* If the request has no parameters, this method returns <code>null</code>.
*/
protected String getSortedQueryString(HttpServletRequest request) {
Map paramMap = request.getParameterMap();
if (paramMap.isEmpty()) {
return null;
}
Set paramSet = new TreeMap(paramMap).entrySet();
StringBuffer buf = new StringBuffer();
boolean first = true;
for (Iterator it = paramSet.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String[] values = (String[]) entry.getValue();
for (int i = 0; i < values.length; i++) {
String key = (String) entry.getKey();
if ((key.length() != 10) || !"jsessionid".equals(key)) {
if (first) {
first = false;
} else {
buf.append('&');
}
buf.append(key).append('=').append(values[i]);
}
}
}
// We get a 0 length buffer if the only parameter was a jsessionid
if (buf.length() == 0) {
return null;
} else {
return buf.toString();
}
}
/**
* Log error messages to commons logging.
*
* @param message Message to log.
*/
public void logError(String message) {
log.error("[oscache]: " + message);
}
/**
* Put an object in the cache. This should only be called by a thread
* that received a {@link NeedsRefreshException}. Using session scope
* the thread has to insure that the session wasn't invalidated in
* the meantime. CacheTag and CacheFilter guarantee that the same
* cache is used in cancelUpdate and getFromCache.
*
* @param scope The cache scope
* @param request The servlet request
* @param key The object key
* @param content The object to add
*/
public void putInCache(int scope, HttpServletRequest request, String key, Object content) {
putInCache(scope, request, key, content, null);
}
/**
* Put an object in the cache. This should only be called by a thread
* that received a {@link NeedsRefreshException}. Using session scope
* the thread has to insure that the session wasn't invalidated in
* the meantime. CacheTag and CacheFilter guarantee that the same
* cache is used in cancelUpdate and getFromCache.
*
* @param scope The cache scope
* @param request The servlet request
* @param key The object key
* @param content The object to add
* @param policy The refresh policy
*/
public void putInCache(int scope, HttpServletRequest request, String key, Object content, EntryRefreshPolicy policy) {
Cache cache = getCache(request, scope);
key = this.generateEntryKey(key, request, scope);
cache.putInCache(key, content, policy);
}
/**
* Sets the cache capacity (number of items). If the cache contains
* more than <code>capacity</code> items then items will be removed
* to bring the cache back down to the new size.
*
* @param scope The cache scope
* @param request The servlet request
* @param capacity The new capacity
*/
public void setCacheCapacity(int scope, HttpServletRequest request, int capacity) {
setCacheCapacity(capacity);
getCache(request, scope).setCapacity(capacity);
}
/**
* Unregister a listener for Cache Map events.
*
* @param listener The object that currently listens to events.
*/
public void removeScopeEventListener(ScopeEventListener listener) {
listenerList.remove(ScopeEventListener.class, listener);
}
/**
* Finalizes all the listeners that are associated with the given cache object
*/
protected void finalizeListeners(Cache cache) {
super.finalizeListeners(cache);
}
/**
* Convert a byte array into a Base64 string (as used in mime formats)
*/
private static String toBase64(byte[] aValue) {
int byte1;
int byte2;
int byte3;
int iByteLen = aValue.length;
StringBuffer tt = new StringBuffer();
for (int i = 0; i < iByteLen; i += 3) {
boolean bByte2 = (i + 1) < iByteLen;
boolean bByte3 = (i + 2) < iByteLen;
byte1 = aValue[i] & 0xFF;
byte2 = (bByte2) ? (aValue[i + 1] & 0xFF) : 0;
byte3 = (bByte3) ? (aValue[i + 2] & 0xFF) : 0;
tt.append(m_strBase64Chars.charAt(byte1 / 4));
tt.append(m_strBase64Chars.charAt((byte2 / 16) + ((byte1 & 0x3) * 16)));
tt.append(((bByte2) ? m_strBase64Chars.charAt((byte3 / 64) + ((byte2 & 0xF) * 4)) : '='));
tt.append(((bByte3) ? m_strBase64Chars.charAt(byte3 & 0x3F) : '='));
}
return tt.toString();
}
/**
* Create a cache
*
* @param scope The cache scope
* @param sessionId The sessionId for with the cache will be created
* @return A new cache
*/
private ServletCache createCache(int scope, String sessionId) {
ServletCache newCache = new ServletCache(this, algorithmClass, cacheCapacity, scope);
// TODO - Fix me please!
// Hack! This is nasty - if two sessions are created within a short
// space of time it is possible they will end up with duplicate
// session IDs being passed to the DiskPersistenceListener!...
config.set(HASH_KEY_SCOPE, "" + scope);
config.set(HASH_KEY_SESSION_ID, sessionId);
newCache = (ServletCache) configureStandardListeners(newCache);
if (config.getProperty(CACHE_ENTRY_EVENT_LISTENERS_KEY) != null) {
// Add any event listeners that have been specified in the configuration
CacheEventListener[] listeners = getCacheEventListeners();
for (int i = 0; i < listeners.length; i++) {
if (listeners[i] instanceof ScopeEventListener) {
newCache.addCacheEventListener(listeners[i]);
}
}
}
return newCache;
}
/**
* Dispatch a scope event to all registered listeners.
*
* @param eventType The type of event
* @param scope Scope that was flushed (Does not apply for FLUSH_ALL event)
* @param date Date of flushing
* @param origin The origin of the event
*/
private void dispatchScopeEvent(ScopeEventType eventType, int scope, Date date, String origin) {
// Create the event
ScopeEvent event = new ScopeEvent(eventType, scope, date, origin);
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i+1] instanceof ScopeEventListener) {
((ScopeEventListener) listeners[i + 1]).scopeFlushed(event);
}
}
}
/**
* Set property cache.use.host.domain.in.key=true to add domain information to key
* generation for hosting multiple sites
*/
private void initHostDomainInKey() {
String propStr = getProperty(CACHE_USE_HOST_DOMAIN_KEY);
useHostDomainInKey = "true".equalsIgnoreCase(propStr);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?