servletcacheadministrator.java
来自「一个不错的cache」· Java 代码 · 共 744 行 · 第 1/2 页
JAVA
744 行
} /** * 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 * * @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 * * @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], ScopeEventListener.class); } } } 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] == ScopeEventListener.class) { ((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 + -
显示快捷键?