001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.rendering.util.cache;
020:
021: import java.util.Date;
022: import java.util.Enumeration;
023: import java.util.HashMap;
024: import java.util.Map;
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.apache.roller.RollerException;
028: import org.apache.roller.config.RollerConfig;
029: import org.apache.roller.business.RollerFactory;
030: import org.apache.roller.ui.rendering.util.PlanetRequest;
031: import org.apache.roller.util.cache.Cache;
032: import org.apache.roller.util.cache.CacheManager;
033: import org.apache.roller.util.cache.ExpiringCacheEntry;
034:
035: /**
036: * Cache for planet content.
037: */
038: public class PlanetCache {
039:
040: private static Log log = LogFactory.getLog(PlanetCache.class);
041:
042: // a unique identifier for this cache, this is used as the prefix for
043: // roller config properties that apply to this cache
044: public static final String CACHE_ID = "cache.planet";
045:
046: // keep cached content
047: private boolean cacheEnabled = true;
048: private Cache contentCache = null;
049:
050: // keep a cached version of last expired time
051: private ExpiringCacheEntry lastUpdateTime = null;
052: private long timeout = 15 * 60 * 1000;
053:
054: // reference to our singleton instance
055: private static PlanetCache singletonInstance = new PlanetCache();
056:
057: private PlanetCache() {
058:
059: cacheEnabled = RollerConfig.getBooleanProperty(CACHE_ID
060: + ".enabled");
061:
062: Map cacheProps = new HashMap();
063: cacheProps.put("id", CACHE_ID);
064: Enumeration allProps = RollerConfig.keys();
065: String prop = null;
066: while (allProps.hasMoreElements()) {
067: prop = (String) allProps.nextElement();
068:
069: // we are only interested in props for this cache
070: if (prop.startsWith(CACHE_ID + ".")) {
071: cacheProps.put(prop.substring(CACHE_ID.length() + 1),
072: RollerConfig.getProperty(prop));
073: }
074: }
075:
076: log.info("Planet cache = " + cacheProps);
077:
078: if (cacheEnabled) {
079: contentCache = CacheManager
080: .constructCache(null, cacheProps);
081: } else {
082: log.warn("Caching has been DISABLED");
083: }
084:
085: // lookup our timeout value
086: String timeoutString = RollerConfig
087: .getProperty("cache.planet.timeout");
088: try {
089: long timeoutSecs = Long.parseLong(timeoutString);
090: this .timeout = timeoutSecs * 1000;
091: } catch (Exception e) {
092: // ignored ... illegal value
093: }
094: }
095:
096: public static PlanetCache getInstance() {
097: return singletonInstance;
098: }
099:
100: public Object get(String key) {
101:
102: if (!cacheEnabled)
103: return null;
104:
105: Object entry = contentCache.get(key);
106:
107: if (entry == null) {
108: log.debug("MISS " + key);
109: } else {
110: log.debug("HIT " + key);
111: }
112:
113: return entry;
114: }
115:
116: public void put(String key, Object value) {
117:
118: if (!cacheEnabled)
119: return;
120:
121: contentCache.put(key, value);
122: log.debug("PUT " + key);
123: }
124:
125: public void remove(String key) {
126:
127: if (!cacheEnabled)
128: return;
129:
130: contentCache.remove(key);
131: log.debug("REMOVE " + key);
132: }
133:
134: public void clear() {
135:
136: if (!cacheEnabled)
137: return;
138:
139: contentCache.clear();
140: this .lastUpdateTime = null;
141: log.debug("CLEAR");
142: }
143:
144: public Date getLastModified() {
145:
146: Date lastModified = null;
147:
148: // first try our cached version
149: if (this .lastUpdateTime != null) {
150: lastModified = (Date) this .lastUpdateTime.getValue();
151: }
152:
153: // still null, we need to get a fresh value
154: if (lastModified == null) {
155:
156: try {
157: lastModified = RollerFactory.getRoller()
158: .getPlanetManager().getLastUpdated();
159: } catch (RollerException ex) {
160: log.error("Error getting planet manager", ex);
161: }
162:
163: if (lastModified == null) {
164: lastModified = new Date();
165: log
166: .warn("Can't get lastUpdate time, using current time instead");
167: }
168:
169: this .lastUpdateTime = new ExpiringCacheEntry(lastModified,
170: this .timeout);
171: }
172:
173: return lastModified;
174: }
175:
176: /**
177: * Generate a cache key from a parsed planet request.
178: * This generates a key of the form ...
179: *
180: * <context>/<type>/<language>[/user]
181: * or
182: * <context>/<type>[/flavor]/<language>[/excerpts]
183: *
184: *
185: * examples ...
186: *
187: * planet/page/en
188: * planet/feed/rss/en/excerpts
189: *
190: */
191: public String generateKey(PlanetRequest planetRequest) {
192:
193: StringBuffer key = new StringBuffer();
194:
195: key.append(this .CACHE_ID).append(":");
196: key.append(planetRequest.getContext());
197: key.append("/");
198: key.append(planetRequest.getType());
199:
200: if (planetRequest.getFlavor() != null) {
201: key.append("/").append(planetRequest.getFlavor());
202: }
203:
204: // add language
205: key.append("/").append(planetRequest.getLanguage());
206:
207: if (planetRequest.getFlavor() != null) {
208: // add excerpts
209: if (planetRequest.isExcerpts()) {
210: key.append("/excerpts");
211: }
212: } else {
213: // add login state
214: if (planetRequest.getAuthenticUser() != null) {
215: key.append("/user=").append(
216: planetRequest.getAuthenticUser());
217: }
218: }
219:
220: return key.toString();
221: }
222:
223: }
|