001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.jetspeed.cache.impl;
019:
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Map;
024: import java.util.StringTokenizer;
025:
026: import net.sf.ehcache.Cache;
027: import net.sf.ehcache.Ehcache;
028: import net.sf.ehcache.Element;
029:
030: import org.apache.jetspeed.cache.CacheElement;
031: import org.apache.jetspeed.cache.ContentCacheElement;
032: import org.apache.jetspeed.cache.ContentCacheKey;
033: import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
034: import org.apache.jetspeed.cache.JetspeedCache;
035: import org.apache.jetspeed.cache.JetspeedCacheEventListener;
036: import org.apache.jetspeed.cache.JetspeedContentCache;
037: import org.apache.jetspeed.decoration.Theme;
038: import org.apache.jetspeed.om.page.ContentPage;
039: import org.apache.jetspeed.request.RequestContext;
040:
041: /**
042: * Wrapper around actual cache implementation
043: *
044: * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
045: * @version $Id: $
046: */
047: public class EhDecorationContentCacheImpl extends EhCacheImpl implements
048: JetspeedContentCache, JetspeedCacheEventListener {
049:
050: JetspeedCache preferenceCache = null;
051: ContentCacheKeyGenerator keyGenerator = null;
052:
053: public EhDecorationContentCacheImpl(Ehcache ehcache,
054: JetspeedCache preferenceCache,
055: ContentCacheKeyGenerator keyGenerator) {
056: this (ehcache);
057: this .preferenceCache = preferenceCache;
058: this .keyGenerator = keyGenerator;
059: preferenceCache.addEventListener(this , false); //only listen to remote events
060: }
061:
062: public EhDecorationContentCacheImpl(Ehcache ehcache,
063: JetspeedCache preferenceCache) {
064: this (ehcache);
065: this .preferenceCache = preferenceCache;
066: preferenceCache.addEventListener(this , false); //only listen to remote events
067: }
068:
069: public EhDecorationContentCacheImpl(Ehcache ehcache) {
070: super (ehcache);
071: }
072:
073: public EhDecorationContentCacheImpl(Cache ehcache,
074: ContentCacheKeyGenerator keyGenerator) {
075: this (ehcache);
076: this .keyGenerator = keyGenerator;
077: }
078:
079: public void notifyElementAdded(JetspeedCache cache, boolean local,
080: Object key, Object element) {
081: }
082:
083: public void notifyElementChanged(JetspeedCache cache,
084: boolean local, Object key, Object element) {
085: }
086:
087: public void notifyElementEvicted(JetspeedCache cache,
088: boolean local, Object key, Object element) {
089: }
090:
091: public void notifyElementExpired(JetspeedCache cache,
092: boolean local, Object key, Object element) {
093: notifyElementRemoved(cache, local, key, element);
094: }
095:
096: public static final String KEY_THEME_KEY = EhDecorationContentCacheElementImpl.KEY_SEPARATOR
097: + "theme"
098: + EhDecorationContentCacheElementImpl.KEY_SEPARATOR;
099: public static final int KEY_THEME_KEY_LENGTH = KEY_THEME_KEY
100: .length();
101:
102: public void notifyElementRemoved(JetspeedCache cache,
103: boolean local, Object key, Object element) {
104: if (local)
105: return; // not interested in local changes
106:
107: // System.out.println("notifying DecorationContent that element " +
108: // key.toString() + " has been removed");
109: if (!(key instanceof String))
110: return;
111: String s = (String) key;
112: if (!(s.startsWith(KEY_THEME_KEY)))
113: return;
114: StringTokenizer st = new StringTokenizer(s,
115: EhDecorationContentCacheElementImpl.KEY_SEPARATOR);
116: int count = 0;
117: String te = null;
118: String user = null;
119: while (st.hasMoreTokens()) {
120: String temp = st.nextToken();
121: switch (count) {
122: case 0:
123: break;
124: case 1:
125: te = temp;
126: break;
127: case 2:
128: user = temp;
129: break;
130: }
131: count++;
132: if (count > 2)
133: break;
134: }
135: if (te != null) {
136: removeUserEntry(user, "theme", te);
137: }
138: }
139:
140: void removeUserEntry(String username, String pipeline,
141: String windowId) {
142: ContentCacheKey key = keyGenerator.createUserCacheKey(username,
143: pipeline, windowId);
144: if (ehcache.remove(key.getKey())) {
145: Element userElement = ehcache.get(username);
146:
147: if (userElement != null) {
148: Map map = (Map) userElement.getObjectValue();
149: if (map != null) {
150: map.remove(windowId);
151: }
152: }
153: }
154: }
155:
156: public CacheElement get(Object key) {
157: ContentCacheKey cckey = (ContentCacheKey) key;
158: Element element = ehcache.get(cckey.getKey());
159: if (element == null)
160: return null;
161: return new EhDecorationContentCacheElementImpl(element, cckey);
162: }
163:
164: public int getTimeToIdleSeconds() {
165: return (int) ehcache.getTimeToIdleSeconds();
166: }
167:
168: public int getTimeToLiveSeconds() {
169: return (int) ehcache.getTimeToLiveSeconds();
170: }
171:
172: public boolean isKeyInCache(Object key) {
173: ContentCacheKey cckey = (ContentCacheKey) key;
174: return ehcache.isKeyInCache(cckey.getKey());
175: }
176:
177: public void put(CacheElement element) {
178: ContentCacheElement ccElement = (ContentCacheElement) element;
179: EhDecorationContentCacheElementImpl impl = (EhDecorationContentCacheElementImpl) element;
180: Element ehl = impl.getImplElement();
181: String userKey = ccElement.getContentCacheKey().getSessionId();
182: if (userKey == null) {
183: userKey = ccElement.getContentCacheKey().getUsername();
184: }
185: String windowId = ccElement.getContentCacheKey().getWindowId();
186: try {
187: ehcache.put(ehl);
188: } catch (Exception e) {
189: e.printStackTrace();
190: }
191: Element userElement = ehcache.get(userKey);
192: if (userElement == null) {
193: Map map = Collections.synchronizedMap(new HashMap());
194: map.put(windowId, ccElement.getContentCacheKey());
195: userElement = new Element(userKey, map);
196: ehcache.put(userElement);
197: } else {
198: Map map = (Map) userElement.getObjectValue();
199: map.put(windowId, ccElement.getContentCacheKey());
200: }
201: }
202:
203: public CacheElement createElement(Object key, Object content) {
204: ContentCacheKey cckey = (ContentCacheKey) key;
205: Element cachedElement = new Element(cckey.getKey(), content);
206: return new EhDecorationContentCacheElementImpl(cachedElement,
207: cckey);
208: }
209:
210: public boolean remove(Object key) {
211: CacheElement element = this .get(key);
212: boolean removed = false;
213: if (element == null)
214: return false;
215:
216: ContentCacheElement ccElement = (ContentCacheElement) element;
217: EhDecorationContentCacheElementImpl impl = (EhDecorationContentCacheElementImpl) element;
218: Element ehl = impl.getImplElement();
219: String userKey = ccElement.getContentCacheKey().getSessionId();
220: if (userKey == null) {
221: userKey = ccElement.getContentCacheKey().getUsername();
222: }
223: String windowId = ccElement.getContentCacheKey().getWindowId();
224: removed = ehcache.remove(ccElement.getContentCacheKey()
225: .getKey());
226: Element userElement = ehcache.get(userKey);
227: if (userElement != null) {
228: Map map = (Map) userElement.getObjectValue();
229: if (map != null) {
230: map.remove(windowId);
231: }
232: }
233: return removed;
234: }
235:
236: public void evictContentForUser(String username) {
237: Element userElement = saveGet(username);
238: if (userElement != null) {
239: Map map = (Map) userElement.getObjectValue();
240: if (map != null) {
241: Iterator entities = map.values().iterator();
242: while (entities.hasNext()) {
243: ContentCacheKey ccKey = (ContentCacheKey) entities
244: .next();
245: ehcache.remove(ccKey.getKey());
246: }
247: }
248: ehcache.remove(username);
249: }
250: }
251:
252: public void evictContentForSession(String session) {
253: Element userElement = saveGet(session);
254: if (userElement != null) {
255: Map map = (Map) userElement.getObjectValue();
256: if (map != null) {
257: Iterator entities = map.values().iterator();
258: while (entities.hasNext()) {
259: ContentCacheKey ccKey = (ContentCacheKey) entities
260: .next();
261: ehcache.remove(ccKey.getKey());
262: }
263: }
264: ehcache.remove(session);
265: }
266: }
267:
268: public void clear() {
269: ehcache.removeAll();
270: }
271:
272: public ContentCacheKey createCacheKey(RequestContext context,
273: String windowId) {
274: return this .keyGenerator.createCacheKey(context, windowId);
275: }
276:
277: protected Element saveGet(Object key) {
278: try {
279: return ehcache.get(key);
280: } catch (IllegalStateException ise) {
281: // can be thrown during shutdown for instance
282: return null;
283: }
284: }
285:
286: public String createSessionKey(RequestContext context) {
287: boolean isAjaxRequest = (context == null);
288: String mode = isAjaxRequest ? "-d-" : "-p-";
289: String user = context.getRequest().getRemoteUser();
290: if (user == null)
291: user = "guest";
292: return user + mode + context.getPage().getId();
293: }
294:
295: public void invalidate(RequestContext context) {
296: ContentPage page = context.getPage();
297: ContentCacheKey themeContentCacheKey = createCacheKey(context,
298: page.getId());
299: CacheElement themeCacheElem = get(themeContentCacheKey);
300:
301: if (themeCacheElem != null) {
302: Theme theme = (Theme) themeCacheElem.getContent();
303: theme.setInvalidated(true);
304: }
305: }
306: }
|