cachetag.java
来自「一个不错的cache」· Java 代码 · 共 797 行 · 第 1/2 页
JAVA
797 行
/* * Copyright (c) 2002-2003 by OpenSymphony * All rights reserved. */package com.opensymphony.oscache.web.tag;import com.opensymphony.oscache.base.Cache;import com.opensymphony.oscache.base.NeedsRefreshException;import com.opensymphony.oscache.util.StringUtil;import com.opensymphony.oscache.web.ServletCacheAdministrator;import com.opensymphony.oscache.web.WebEntryRefreshPolicy;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.jsp.JspTagException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.BodyTagSupport;import javax.servlet.jsp.tagext.TryCatchFinally;/** * CacheTag is a tag that allows for server-side caching of post-processed JSP content.<p> * * It also gives great programatic control over refreshing, flushing and updating the cache.<p> * * Usage Example: * <pre><code> * <%@ taglib uri="oscache" prefix="cache" %> * <cache:cache key="mycache" * scope="application" * refresh="false" * time="30"> * jsp content here... refreshed every 30 seconds * </cache:cache> * </code></pre> * * @author <a href="mailto:mike@atlassian.com">Mike Cannon-Brookes</a> * @author <a href="mailto:tgochenour@peregrine.com">Todd Gochenour</a> * @author <a href="mailto:fbeauregard@pyxis-tech.com">Francois Beauregard</a> * @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a> * @version $Revision: 1.6 $ */public class CacheTag extends BodyTagSupport implements TryCatchFinally { /** * Constants for time computation */ private final static int SECOND = 1; private final static int MINUTE = 60 * SECOND; private final static int HOUR = 60 * MINUTE; private final static int DAY = 24 * HOUR; private final static int WEEK = 7 * DAY; private final static int MONTH = 30 * DAY; private final static int YEAR = 365 * DAY; /** * The key under which the tag counter will be stored in the request */ private final static String CACHE_TAG_COUNTER_KEY = "__oscache_tag_counter"; /** * Constants for refresh time */ final static private int ONE_MINUTE = 60; final static private int ONE_HOUR = 60 * ONE_MINUTE; final static private int DEFAULT_TIMEOUT = ONE_HOUR; private static transient Log log = LogFactory.getLog(CacheTag.class); /** * Cache modes */ final static private int SILENT_MODE = 1; /** * A flag to indicate whether a NeedsRefreshException was thrown and * the update needs to be cancelled */ boolean cancelUpdateRequired = false; private Cache cache = null; /** * If no groups are specified, the cached content does not get put into any groups */ private List groups = null; private ServletCacheAdministrator admin = null; /** * The actual key to use. This is generated based on the supplied key, scope etc. */ private String actualKey = null; /** * The content that was retrieved from cache */ private String content = null; /** * The cron expression that is used to expire cache entries at specific dates and/or times. */ private String cron = null; /** * if cache key is null, the request URI is used */ private String key = null; /** * The ISO-639 language code to distinguish different pages in application scope */ private String language = null; /** * Class used to handle the refresh policy logic */ private String refreshPolicyClass = null; /** * Parameters that will be passed to the init method of the * refresh policy instance. */ private String refreshPolicyParam = null; /** * Whether the cache should be refreshed instantly */ private boolean refresh = false; /** * used for subtags to tell this tag that we should use the cached version */ private boolean useBody = true; /** * The cache mode. Valid values are SILENT_MODE */ private int mode = 0; /** * The cache scope to use */ private int scope = PageContext.APPLICATION_SCOPE; /** * time (in seconds) before cache should be refreshed */ private int time = DEFAULT_TIMEOUT; /** * Set the time this cache entry will be cached for. A date and/or time in * either ISO-8601 format or a simple format can be specified. The acceptable * syntax for the simple format can be any one of the following: * * <ul> * <li>0 (seconds) * <li>0s (seconds) * <li>0m (minutes) * <li>0h (hours) * <li>0d (days) * <li>0w (weeks) * </ul> * * @param duration The duration to cache this content (using either the simple * or the ISO-8601 format). Passing in a duration of zero will turn off the * caching, while a negative value will result in the cached content never * expiring (ie, the cached content will always be served as long as it is * present). */ public void setDuration(String duration) { try { // Try Simple Date Format Duration first because it's faster this.time = parseDuration(duration); } catch (Exception ex) { if (log.isDebugEnabled()) { log.debug("Failed parsing simple duration format '" + duration + "' (" + ex.getMessage() + "). Trying ISO-8601 format..."); } try { // Try ISO-8601 Duration this.time = parseISO_8601_Duration(duration); } catch (Exception ex1) { // An invalid duration entered, not much impact. // The default timeout will be used log.warn("The requested cache duration '" + duration + "' is invalid (" + ex1.getMessage() + "). Reverting to the default timeout"); this.time = DEFAULT_TIMEOUT; } } } /** * Sets the cron expression that should be used to expire content at specific * dates and/or times. */ public void setCron(String cron) { this.cron = cron; } /** * Sets the groups for this cache entry. Any existing groups will * be replaced. * * @param groups A comma-delimited list of groups that the cache entry belongs to. */ public void setGroups(String groups) { this.groups = StringUtil.split(groups, ','); } /** * Adds to the groups for this cache entry. * * @param group A group to which the cache entry should belong. */ void addGroup(String group) { if (groups == null) { groups = new ArrayList(); } groups.add(group); } /** * Set the key for this cache entry. * * @param key The key for this cache entry. */ public void setKey(String key) { this.key = key; } /** * Set the ISO-639 language code to distinguish different pages in application scope * * @param language The language code for this cache entry. */ public void setLanguage(String language) { this.language = language; } /** * This method allows the user to programatically decide whether the cached * content should be refreshed immediately. * * @param refresh Whether or not to refresh this cache entry immediately. */ public void setRefresh(boolean refresh) { this.refresh = refresh; } /** * Setting this to <code>true</code> prevents the cache from writing any output * to the response, however the JSP content is still cached as normal. * @param mode The cache mode to use. */ public void setMode(String mode) { if ("silent".equalsIgnoreCase(mode)) { this.mode = SILENT_MODE; } else { this.mode = 0; } } /** * Class used to handle the refresh policy logic */ public void setRefreshpolicyclass(String refreshPolicyClass) { this.refreshPolicyClass = refreshPolicyClass; } /** * Parameters that will be passed to the init method of the * refresh policy instance. */ public void setRefreshpolicyparam(String refreshPolicyParam) { this.refreshPolicyParam = refreshPolicyParam; } // ----------- setMethods ------------------------------------------------------ /** * Set the scope of this cache. * <p> * @param scope The scope of this cache. Either "application" (default) or "session". */ public void setScope(String scope) { if (scope.equalsIgnoreCase(ServletCacheAdministrator.SESSION_SCOPE_NAME)) { this.scope = PageContext.SESSION_SCOPE; } else { this.scope = PageContext.APPLICATION_SCOPE; } } /** * Set the time this cache entry will be cached for (in seconds) * * @param time The time to cache this content (in seconds). Passing in * a time of zero will turn off the caching. A negative value for the * time will result in the cached content never expiring (ie, the cached * content will always be served if it is present) */ public void setTime(int time) { this.time = time; } /** * This controls whether or not the body of the tag is evaluated or used.<p> * * It is most often called by the <UseCached /> tag to tell this tag to * use the cached content. * * @see UseCachedTag * @param useBody Whether or not to use the cached content. */ public void setUseBody(boolean useBody) { if (log.isDebugEnabled()) { log.debug("<cache>: Set useBody to " + useBody); } this.useBody = useBody; } /** * After the cache body, either update the cache, serve new cached content or * indicate an error. * * @throws JspTagException The standard exception thrown. * @return The standard BodyTag return. */ public int doAfterBody() throws JspTagException { String body = null; try { // if we have a body, and we have not been told to use the cached version if ((bodyContent != null) && (useBody || (time == 0)) && ((body = bodyContent.getString()) != null)) { if ((time != 0) || (refreshPolicyClass != null)) { // Instantiate custom refresh policy if needed WebEntryRefreshPolicy policy = null; if (refreshPolicyClass != null) { try { policy = (WebEntryRefreshPolicy) Class.forName(refreshPolicyClass).newInstance(); policy.init(actualKey, refreshPolicyParam); } catch (Exception e) { if (log.isInfoEnabled()) { log.info("<cache>: Problem instantiating or initializing refresh policy : " + refreshPolicyClass); } } } if (log.isDebugEnabled()) { log.debug("<cache>: Updating cache entry with new content : " + actualKey); } cancelUpdateRequired = false; if ((groups == null) || groups.isEmpty()) { cache.putInCache(actualKey, body, policy); } else { String[] groupArray = new String[groups.size()]; groups.toArray(groupArray); cache.putInCache(actualKey, body, groupArray, policy, null); } } } // otherwise if we have been told to use the cached content and we have cached content else { if (!useBody && (content != null)) { if (log.isInfoEnabled()) { log.info("<cache>: Using cached version as instructed, useBody = false : " + actualKey); } body = content; } // either the cached entry is blank and a subtag has said don't useBody, or body is null else { if (log.isInfoEnabled()) { log.info("<cache>: Missing cached content : " + actualKey); } body = "Missing cached content"; } } // Only display anything if we're not running in silent mode if (mode != SILENT_MODE) { bodyContent.clearBody(); bodyContent.write(body); bodyContent.writeOut(bodyContent.getEnclosingWriter()); } } catch (java.io.IOException e) { throw new JspTagException("IO Error: " + e.getMessage()); } return SKIP_BODY; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?