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.IOException;
22  import java.io.PrintWriter;
23  import java.io.Serializable;
24  import java.io.StringWriter;
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  import org.apache.tapestry.util.ContentType;
34  
35  /***
36   * A Tapestry component that caches web content.<BR>
37   * Surround the html content that should be cached with this component,
38   * and specify the cache name and (an optional) cache key.
39   * Ehcache is used to implement the caching, and so
40   * each cache's properties are configured in the ehcache.xml file.
41   * This class also contains static utility methods for interacting
42   * with a cache from code, such as: get, put, remove, clear.
43   * @author andyhot
44   * @version $Id: Cache.java,v 1.2 2005/11/04 23:32:15 andyhot Exp $
45   */
46  public abstract class Cache extends AbstractComponent
47  {
48      private static final Log log = LogFactory.getLog(Cache.class);
49  
50      public abstract String getName();
51      public abstract Object getKey();
52  
53      protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
54      {
55          if (cycle.isRewinding())
56          {
57              return;
58          }
59          net.sf.ehcache.Cache cache = getCache(getName());
60          if (cache == null)
61          {
62              log.info("Cache not found: " + getName());
63          }
64          else
65          {
66              log.debug("HitCount: " + cache.getHitCount()
67                      + " Size: " + cache.getMemoryStoreSize());
68  
69              String cachedHtml = (String) Cache.get( cache, getKey());
70              if (cachedHtml != null)
71              {
72                  writer.printRaw(cachedHtml);
73                  writer.comment("Cache hit");
74                  return;
75              }
76  
77          }
78          if (log.isDebugEnabled())
79          {
80              log.debug("Generating cache content for cache: " + getName() + " and key: " + getKey());
81          }
82          // first, render the body in a byte array
83          // in 4.0 we can use the nested writer, because it publishes
84          // a getBuffer() method to get its contents. In 3.0 this does not exit!
85          //ByteArrayOutputStream stream = new ByteArrayOutputStream();
86          //IMarkupWriter nested = getPage().getResponseWriter(stream);
87          StringWriter sWriter = new StringWriter();
88          IMarkupWriter nested = cycle.getInfrastructure().getMarkupWriterSource().newMarkupWriter(new PrintWriter(sWriter),
89                  new ContentType(writer.getContentType()));        
90          renderBody(nested, cycle);
91          nested.close();
92          // now, we have to use the char encoding to turn the byte array into string
93          //String bodyHtml = "";
94          String bodyHtml = sWriter.toString();
95          /*try
96          {
97              String ct = nested.getContentType();
98              if (ct != null)
99              {
100 	            int pos = ct.lastIndexOf("=");
101 	            if (pos >= 0)
102 	            {
103 	                ct = ct.substring(pos+1);
104 	            }
105 	            bodyHtml = stream.toString(ct);
106             }
107         }
108         catch (UnsupportedEncodingException e)
109         {
110             e.printStackTrace();
111             bodyHtml = stream.toString();
112         }*/
113         writer.printRaw(bodyHtml);
114         put(cache, getKey(), bodyHtml);
115     }
116 
117     private static net.sf.ehcache.Cache getCache(String name)
118     {
119         net.sf.ehcache.Cache cache = null;
120         try
121         {
122             CacheManager manager = CacheManager.getInstance();
123             cache = manager.getCache(name);
124             if (cache == null)
125             {
126                 log.warn("Could not find configuration for " + name
127                         + ". Configuring using the defaultCache settings.");
128                 manager.addCache(name);
129                 cache = manager.getCache(name);
130             }
131         }
132         catch (net.sf.ehcache.CacheException e)
133         {
134         }
135         return cache;
136     }
137 
138     public static Object get(String cacheName, Object key)
139     {
140         net.sf.ehcache.Cache cache = getCache(cacheName);
141         return get(cache, key);
142     }
143 
144     public static void put(String cacheName, Object key, Object value)
145     {
146         net.sf.ehcache.Cache cache = getCache(cacheName);
147         put(cache, key, value);
148     }
149 
150     public static void remove(String cacheName, Object key)
151     {
152         net.sf.ehcache.Cache cache = getCache(cacheName);
153         if (cache != null)
154         {
155             cache.remove((Serializable) key);
156         }
157     }
158 
159     public static void clear(String cacheName)
160     {
161         net.sf.ehcache.Cache cache = getCache(cacheName);
162         if (cache != null)
163         {
164             try
165             {
166                 cache.removeAll();
167             }
168             catch (IOException ignore)
169             {
170             }
171         }
172     }
173 
174     private static void put(net.sf.ehcache.Cache cache, Object key, Object value)
175     {
176         if (cache != null)
177         {
178             Element element = new Element((Serializable) key, (Serializable) value);
179             cache.put(element);
180         }
181     }
182 
183     private static Object get(net.sf.ehcache.Cache cache, Object key)
184     {
185         Object obj = null;
186         if (cache != null)
187         {
188             try
189             {
190                 Element element = cache.get((Serializable) key);
191                 if (element !=null)
192                 {
193                     obj = element.getValue();
194                 }
195             }
196             catch (CacheException ignore)
197             {
198             }
199         }
200         return obj;
201     }
202 }