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