1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.tapfx.components.cache;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.io.UnsupportedEncodingException;
25
26 import net.sf.ehcache.CacheException;
27 import net.sf.ehcache.CacheManager;
28 import net.sf.ehcache.Element;
29
30 import org.apache.tapestry.AbstractComponent;
31 import org.apache.tapestry.IMarkupWriter;
32 import org.apache.tapestry.IRequestCycle;
33
34 /***
35 * A Tapestry component that caches web content.<BR>
36 * Surround the html content that should be cached with this component,
37 * and specify the cache name and (an optional) cache key.
38 * Ehcache is used to implement the caching, and so
39 * eache cache's properties are configured in the ehcache.xml file.
40 * This class also contains static utility methods for interacting
41 * with a cache from code, such as: get, put, remove, clear.
42 * @author andyhot
43 */
44 public abstract class Cache extends AbstractComponent
45 {
46 private static final Log log = LogFactory.getLog(Cache.class);
47
48 public abstract String getName();
49 public abstract Object getKey();
50
51 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
52 {
53 if (cycle.isRewinding())
54 {
55 return;
56 }
57 net.sf.ehcache.Cache cache = getCache(getName());
58 if (cache == null)
59 {
60 log.info("Cache not found: " + getName());
61 }
62 else
63 {
64 log.debug("HitCount: " + cache.getHitCount()
65 + " Size: " + cache.getMemoryStoreSize());
66
67 String cachedHtml = (String) Cache.get( cache, getKey());
68 if (cachedHtml != null)
69 {
70 writer.printRaw(cachedHtml);
71 writer.comment("Cache hit");
72 return;
73 }
74
75 }
76 if (log.isDebugEnabled())
77 {
78 log.debug("Generating cache content for cache: " + getName() + " and key: " + getKey());
79 }
80
81
82
83 ByteArrayOutputStream stream = new ByteArrayOutputStream();
84 IMarkupWriter nested = getPage().getResponseWriter(stream);
85 renderBody(nested, cycle);
86 nested.close();
87
88 String bodyHtml = "";
89 try
90 {
91 String ct = nested.getContentType();
92 if (ct != null)
93 {
94 int pos = ct.lastIndexOf("=");
95 if (pos >= 0)
96 {
97 ct = ct.substring(pos+1);
98 }
99 bodyHtml = stream.toString(ct);
100 }
101 }
102 catch (UnsupportedEncodingException e)
103 {
104 e.printStackTrace();
105 bodyHtml = stream.toString();
106 }
107 writer.printRaw(bodyHtml);
108 put(cache, getKey(), bodyHtml);
109 }
110
111 private static net.sf.ehcache.Cache getCache(String name)
112 {
113 net.sf.ehcache.Cache cache = null;
114 try
115 {
116 CacheManager manager = CacheManager.getInstance();
117 cache = manager.getCache(name);
118 if (cache == null)
119 {
120 log.warn("Could not find configuration for " + name
121 + ". Configuring using the defaultCache settings.");
122 manager.addCache(name);
123 cache = manager.getCache(name);
124 }
125 }
126 catch (net.sf.ehcache.CacheException e)
127 {
128 }
129 return cache;
130 }
131
132 public static Object get(String cacheName, Object key)
133 {
134 net.sf.ehcache.Cache cache = getCache(cacheName);
135 return get(cache, key);
136 }
137
138 public static void put(String cacheName, Object key, Object value)
139 {
140 net.sf.ehcache.Cache cache = getCache(cacheName);
141 put(cache, key, value);
142 }
143
144 public static void remove(String cacheName, Object key)
145 {
146 net.sf.ehcache.Cache cache = getCache(cacheName);
147 if (cache != null)
148 {
149 cache.remove((Serializable) key);
150 }
151 }
152
153 public static void clear(String cacheName)
154 {
155 net.sf.ehcache.Cache cache = getCache(cacheName);
156 if (cache != null)
157 {
158 try
159 {
160 cache.removeAll();
161 }
162 catch (IOException ignore)
163 {
164 }
165 }
166 }
167
168 private static void put(net.sf.ehcache.Cache cache, Object key, Object value)
169 {
170 if (cache != null)
171 {
172 Element element = new Element((Serializable) key, (Serializable) value);
173 cache.put(element);
174 }
175 }
176
177 private static Object get(net.sf.ehcache.Cache cache, Object key)
178 {
179 Object obj = null;
180 if (cache != null)
181 {
182 try
183 {
184 Element element = cache.get((Serializable) key);
185 if (element !=null)
186 {
187 obj = element.getValue();
188 }
189 }
190 catch (CacheException ignore)
191 {
192 }
193 }
194 return obj;
195 }
196 }