View Javadoc

1   /*
2    * Copyright 2004-2005 Andreas Andreou
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *  http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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          // first, render the body in a byte array
81          // in 4.0 we can use the nested writer, because it publishes
82          // a getBuffer() method to get its contents. In 3.0 this does not exit!
83          ByteArrayOutputStream stream = new ByteArrayOutputStream();
84          IMarkupWriter nested = getPage().getResponseWriter(stream);
85          renderBody(nested, cycle);
86          nested.close();
87          // now, we have to use the char encoding to turn the byte array into string
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 }