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 + -
显示快捷键?