KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > cache > xslt > ResultCache


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.cache.xslt;
11
12 import org.mmbase.cache.Cache;
13
14 import javax.xml.transform.*;
15 import java.util.*;
16 import org.w3c.dom.*;
17
18 import org.mmbase.util.logging.Logger;
19 import org.mmbase.util.logging.Logging;
20
21 /**
22  * Caches the results of XSL transformations.
23  *
24  * @todo Cache entries must be invalidated if XSL template changes (now getSystemId is used as cache
25  * entry). See TemplatesCache (which uses a FileWatcher).
26  *
27  * @author Michiel Meeuwissen
28  * @version $Id: ResultCache.java,v 1.9 2005/01/30 16:46:38 nico Exp $
29  * @since MMBase-1.6
30  */

31 public class ResultCache extends Cache {
32
33     private static Logger log = Logging.getLoggerInstance(ResultCache.class);
34
35     private static int cacheSize = 50;
36     private static ResultCache cache;
37
38
39     protected int getDefaultMaxEntrySize() {
40         return 1500;
41     }
42
43     /**
44      * Returns the XSLT Result cache.
45      */

46     public static ResultCache getCache() {
47         return cache;
48     }
49
50     static {
51         cache = new ResultCache(cacheSize);
52         putCache(cache);
53     }
54
55     public String JavaDoc getName() {
56         return "XSLTResults";
57     }
58     public String JavaDoc getDescription() {
59         return "XSL Transformation Results";
60     }
61
62     /**
63      * Creates the XSL Result Cache.
64      */

65     private ResultCache(int size) {
66         super(size);
67     }
68
69     /**
70      * You can only put Source/Templates values in the cache, so this throws an Exception.
71      *
72      * @throws RuntimeException
73      **/

74     
75     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
76         throw new RuntimeException JavaDoc("wrong types in cache");
77     }
78
79
80     /**
81      * Generating a key for a document. Keep it simple...
82      *
83      * @todo Generate this key faster and smaller
84      */

85     private StringBuffer JavaDoc append(StringBuffer JavaDoc buf, Node node) {
86         switch(node.getNodeType()) {
87         case Node.ATTRIBUTE_NODE:
88             buf.append(node.getNodeName()).append(node.getNodeValue());
89             break;
90         case Node.ELEMENT_NODE: {
91             NodeList nl = node.getChildNodes();
92             for (int i = 0; i < nl.getLength(); i++) {
93                 append(buf, nl.item(i));
94             }
95         }
96         case Node.ENTITY_NODE:
97         case Node.ENTITY_REFERENCE_NODE:
98             buf.append(node.getNodeName());
99             break;
100         case Node.CDATA_SECTION_NODE:
101         case Node.TEXT_NODE:
102             buf.append(node.getNodeValue().hashCode());
103             break;
104         default:
105             log.debug("Unknown nodetype " + node.getNodeType());
106             break;
107         }
108         
109         return buf;
110     }
111     /**
112      * Generates the key which is to be used in the Cache Map.
113      *
114      * @todo Generate this key faster and smaller
115      */

116     private String JavaDoc getKey(Source xsl, Map params, Properties props, Document src) {
117         StringBuffer JavaDoc key = new StringBuffer JavaDoc(""+(xsl.getSystemId() + "/" + (params != null ? params.toString() : "") + "/" + (props != null ? props.toString() : "")+ "/"));
118         
119         return append(key, src.getDocumentElement()).toString();
120     }
121       
122     /**
123      * This is an intelligent get, which also does the put if it
124      * cannot find the requested result. So, it never returns null.
125      *
126      * @param temp The Templates from which the transformer must be created (if necessary)
127      * @param xsl The XSL Source. This only used to produce the key, because with the Templates it
128      * is difficult
129      * @param params Parameters for the XSL Transformation
130      * @param src The Document which must be transformed.
131      * @return The transformation result. It does not return null.
132      */

133     public String JavaDoc get(Templates temp, Source xsl, Map params, Properties props, Document src) {
134         String JavaDoc key = null;
135         String JavaDoc result = null;
136         if (isActive()) {
137             key = getKey(xsl, params, props, src);
138             if (log.isDebugEnabled()) {
139                 log.debug("Getting result of XSL transformation: " + key);
140             }
141             result = (String JavaDoc) get(key);
142         }
143         if (result == null) {
144             try {
145                 // do the transformation, and cache the result if cache is active:
146
Transformer transformer = temp.newTransformer();
147                 // add the params:
148
if (params != null) {
149                     Iterator i = params.entrySet().iterator();
150                     while (i.hasNext()) {
151                         Map.Entry entry = (Map.Entry) i.next();
152                         transformer.setParameter((String JavaDoc) entry.getKey(), entry.getValue());
153                     }
154                 }
155                 if (props != null) {
156                     transformer.setOutputProperties(props);
157                 }
158                 
159                 java.io.StringWriter JavaDoc res = new java.io.StringWriter JavaDoc();
160                 transformer.transform(new javax.xml.transform.dom.DOMSource JavaDoc(src),
161                                       new javax.xml.transform.stream.StreamResult JavaDoc(res));
162                 result = res.toString();
163             } catch (TransformerException e) {
164                 result = e.toString();
165             }
166             // if result is not too big, then it can be cached:
167
if (isActive()) {
168                 if (result.length() < getMaxEntrySize()) {
169                     if (log.isDebugEnabled()) {
170                         log.debug("Put xslt Result in cache with key " + key);
171                     }
172                     super.put(key, result);
173                 } else {
174                     if (log.isDebugEnabled()) {
175                         log.debug("xslt Result of key " + key.substring(100) + " is too big to put in cache. " + result.length() + " >= " + getMaxEntrySize());
176                     }
177                 }
178             }
179
180         }
181             
182         return result;
183         
184     }
185
186 }
187
Popular Tags