1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.jetspeed.cache.impl;
19
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.StringTokenizer;
25
26 import net.sf.ehcache.Cache;
27 import net.sf.ehcache.Ehcache;
28 import net.sf.ehcache.Element;
29
30 import org.apache.jetspeed.cache.CacheElement;
31 import org.apache.jetspeed.cache.ContentCacheElement;
32 import org.apache.jetspeed.cache.ContentCacheKey;
33 import org.apache.jetspeed.cache.ContentCacheKeyGenerator;
34 import org.apache.jetspeed.cache.JetspeedCache;
35 import org.apache.jetspeed.cache.JetspeedCacheEventListener;
36 import org.apache.jetspeed.cache.JetspeedContentCache;
37 import org.apache.jetspeed.decoration.Theme;
38 import org.apache.jetspeed.om.page.ContentPage;
39 import org.apache.jetspeed.request.RequestContext;
40
41 /***
42 * Wrapper around actual cache implementation
43 *
44 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
45 * @version $Id: $
46 */
47 public class EhDecorationContentCacheImpl extends EhCacheImpl implements JetspeedContentCache, JetspeedCacheEventListener
48 {
49
50 JetspeedCache preferenceCache = null;
51 ContentCacheKeyGenerator keyGenerator = null;
52
53 public EhDecorationContentCacheImpl(Ehcache ehcache, JetspeedCache preferenceCache, ContentCacheKeyGenerator keyGenerator)
54 {
55 this(ehcache);
56 this.preferenceCache = preferenceCache;
57 this.keyGenerator = keyGenerator;
58 preferenceCache.addEventListener(this,false);
59 }
60
61 public EhDecorationContentCacheImpl(Ehcache ehcache, JetspeedCache preferenceCache)
62 {
63 this(ehcache);
64 this.preferenceCache = preferenceCache;
65 preferenceCache.addEventListener(this,false);
66 }
67
68 public EhDecorationContentCacheImpl(Ehcache ehcache)
69 {
70 super(ehcache);
71 }
72
73 public EhDecorationContentCacheImpl(Cache ehcache, ContentCacheKeyGenerator keyGenerator)
74 {
75 this(ehcache);
76 this.keyGenerator = keyGenerator;
77 }
78
79
80 public void notifyElementAdded(JetspeedCache cache, boolean local, Object key, Object element)
81 {
82 }
83
84 public void notifyElementChanged(JetspeedCache cache, boolean local, Object key, Object element)
85 {
86 }
87
88 public void notifyElementEvicted(JetspeedCache cache, boolean local, Object key, Object element)
89 {
90 }
91
92 public void notifyElementExpired(JetspeedCache cache, boolean local, Object key, Object element)
93 {
94 notifyElementRemoved(cache,local,key,element);
95 }
96
97
98 public static final String KEY_THEME_KEY =
99 EhDecorationContentCacheElementImpl.KEY_SEPARATOR + "theme" + EhDecorationContentCacheElementImpl.KEY_SEPARATOR ;
100 public static final int KEY_THEME_KEY_LENGTH = KEY_THEME_KEY.length();
101
102 public void notifyElementRemoved(JetspeedCache cache, boolean local,
103 Object key, Object element)
104 {
105 if (local) return;
106
107
108
109 if (!(key instanceof String)) return;
110 String s = (String) key;
111 if (!(s.startsWith(KEY_THEME_KEY))) return;
112 StringTokenizer st = new StringTokenizer(s,
113 EhDecorationContentCacheElementImpl.KEY_SEPARATOR);
114 int count = 0;
115 String te = null;
116 String user = null;
117 while (st.hasMoreTokens())
118 {
119 String temp = st.nextToken();
120 switch (count)
121 {
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) break;
133 }
134 if (te != null)
135 {
136 removeUserEntry(user, "theme", te);
137 }
138 }
139
140 void removeUserEntry(String username, String pipeline, String windowId)
141 {
142 ContentCacheKey key = keyGenerator.createUserCacheKey(username, pipeline, windowId);
143 if (ehcache.remove(key.getKey()))
144 {
145 Element userElement = ehcache.get(username);
146
147 if (userElement != null)
148 {
149 Map map = (Map)userElement.getObjectValue();
150 if (map != null)
151 {
152 map.remove(windowId);
153 }
154 }
155 }
156 }
157
158 public CacheElement get(Object key)
159 {
160 ContentCacheKey cckey = (ContentCacheKey)key;
161 Element element = ehcache.get(cckey.getKey());
162 if (element == null)
163 return null;
164 return new EhDecorationContentCacheElementImpl(element, cckey);
165 }
166
167 public int getTimeToIdleSeconds()
168 {
169 return (int)ehcache.getTimeToIdleSeconds();
170 }
171
172 public int getTimeToLiveSeconds()
173 {
174 return (int)ehcache.getTimeToLiveSeconds();
175 }
176
177 public boolean isKeyInCache(Object key)
178 {
179 ContentCacheKey cckey = (ContentCacheKey)key;
180 return ehcache.isKeyInCache(cckey.getKey());
181 }
182
183 public void put(CacheElement element)
184 {
185 ContentCacheElement ccElement = (ContentCacheElement)element;
186 EhDecorationContentCacheElementImpl impl = (EhDecorationContentCacheElementImpl)element;
187 Element ehl = impl.getImplElement();
188 String userKey = ccElement.getContentCacheKey().getSessionId();
189 if (userKey == null)
190 {
191 userKey = ccElement.getContentCacheKey().getUsername();
192 }
193 String windowId = ccElement.getContentCacheKey().getWindowId();
194 try
195 {
196 ehcache.put(ehl);
197 }
198 catch (Exception e)
199 {
200 e.printStackTrace();
201 }
202 Element userElement = ehcache.get(userKey);
203 if (userElement == null)
204 {
205 Map map = Collections.synchronizedMap(new HashMap());
206 map.put(windowId, ccElement.getContentCacheKey());
207 userElement = new Element(userKey, map);
208 ehcache.put(userElement);
209 }
210 else
211 {
212 Map map = (Map)userElement.getObjectValue();
213 map.put(windowId, ccElement.getContentCacheKey());
214 }
215 }
216
217 public CacheElement createElement(Object key, Object content)
218 {
219 ContentCacheKey cckey = (ContentCacheKey)key;
220 Element cachedElement = new Element(cckey.getKey(), content);
221 return new EhDecorationContentCacheElementImpl(cachedElement, cckey);
222 }
223
224 public boolean remove(Object key)
225 {
226 CacheElement element = this.get(key);
227 boolean removed = false;
228 if (element == null)
229 return false;
230
231 ContentCacheElement ccElement = (ContentCacheElement)element;
232 EhDecorationContentCacheElementImpl impl = (EhDecorationContentCacheElementImpl)element;
233 Element ehl = impl.getImplElement();
234 String userKey = ccElement.getContentCacheKey().getSessionId();
235 if (userKey == null)
236 {
237 userKey = ccElement.getContentCacheKey().getUsername();
238 }
239 String windowId = ccElement.getContentCacheKey().getWindowId();
240 removed = ehcache.remove(ccElement.getContentCacheKey().getKey());
241 Element userElement = ehcache.get(userKey);
242 if (userElement != null)
243 {
244 Map map = (Map)userElement.getObjectValue();
245 if (map != null)
246 {
247 map.remove(windowId);
248 }
249 }
250 return removed;
251 }
252
253 public void evictContentForUser(String username)
254 {
255 Element userElement = saveGet(username);
256 if (userElement != null)
257 {
258 Map map = (Map)userElement.getObjectValue();
259 if (map != null)
260 {
261 Iterator entities = map.values().iterator();
262 while (entities.hasNext())
263 {
264 ContentCacheKey ccKey = (ContentCacheKey)entities.next();
265 ehcache.remove(ccKey.getKey());
266 }
267 }
268 ehcache.remove(username);
269 }
270 }
271
272 public void evictContentForSession(String session)
273 {
274 Element userElement = saveGet(session);
275 if (userElement != null)
276 {
277 Map map = (Map)userElement.getObjectValue();
278 if (map != null)
279 {
280 Iterator entities = map.values().iterator();
281 while (entities.hasNext())
282 {
283 ContentCacheKey ccKey = (ContentCacheKey)entities.next();
284 ehcache.remove(ccKey.getKey());
285 }
286 }
287 ehcache.remove(session);
288 }
289 }
290
291 public void clear()
292 {
293 ehcache.removeAll();
294 }
295
296 public ContentCacheKey createCacheKey(RequestContext context, String windowId)
297 {
298 return this.keyGenerator.createCacheKey(context, windowId);
299 }
300
301 protected Element saveGet(Object key)
302 {
303 try
304 {
305 return ehcache.get(key);
306 }
307 catch (IllegalStateException ise)
308 {
309
310 return null;
311 }
312 }
313
314 public String createSessionKey(RequestContext context)
315 {
316 boolean isAjaxRequest = (context == null);
317 String mode = isAjaxRequest ? "-d-" : "-p-";
318 String user = context.getRequest().getRemoteUser();
319 if (user == null)
320 user = "guest";
321 return user + mode + context.getPage().getId();
322 }
323
324 public void invalidate(RequestContext context)
325 {
326 ContentPage page = context.getPage();
327 ContentCacheKey themeContentCacheKey = createCacheKey(context, page.getId());
328 CacheElement themeCacheElem = get(themeContentCacheKey);
329
330 if (themeCacheElem != null)
331 {
332 Theme theme = (Theme) themeCacheElem.getContent();
333 theme.setInvalidated(true);
334 }
335 }
336 }