1 10 package org.mmbase.cache.xslt; 11 12 import org.mmbase.cache.Cache; 13 import javax.xml.transform.Templates ; 14 import javax.xml.transform.Source ; 15 import javax.xml.transform.stream.StreamSource ; 16 import org.mmbase.util.ResourceLoader; 17 import org.mmbase.util.ResourceWatcher; 18 19 import java.util.Map ; 20 import java.util.Iterator ; 21 import javax.xml.transform.URIResolver ; 22 23 import org.mmbase.util.logging.Logger; 24 import org.mmbase.util.logging.Logging; 25 26 39 public class TemplateCache extends Cache { 40 41 private static final Logger log = Logging.getLoggerInstance(TemplateCache.class); 42 43 private static int cacheSize = 50; 44 private static TemplateCache cache; 45 46 50 private static ResourceWatcher templateWatcher = new ResourceWatcher(ResourceLoader.getWebRoot()) { 51 public void onChange(String file) { 52 if (log.isDebugEnabled()) log.debug("Removing " + file.toString() + " from cache"); 54 synchronized(cache) { 55 int removed = cache.remove(file); 56 if (removed == 0) { 57 log.error("Could not remove " + file.toString() + " Template(s) from cache!"); 58 } else { 59 if (log.isDebugEnabled()) log.debug("Removed " + removed + " entries from cache"); 60 } 61 } 62 this.remove(file); } 64 }; 65 66 69 public static TemplateCache getCache() { 70 return cache; 71 } 72 73 static { 74 cache = new TemplateCache(cacheSize); 75 putCache(cache); 76 templateWatcher.setDelay(10 * 1000); templateWatcher.start(); 78 79 } 80 81 public String getName() { 82 return "XSLTemplates"; 83 } 84 public String getDescription() { 85 return "XSL Templates"; 86 } 87 88 91 private TemplateCache(int size) { 92 super(size); 93 } 94 95 100 private class Key { 101 private String src; 102 private URIResolver uri; 103 Key(Source src, URIResolver uri) { 104 this.src = src.getSystemId(); 105 this.uri = uri; 106 } 107 public boolean equals(Object o) { 108 if (o instanceof Key) { 109 Key k = (Key) o; 110 return (src == null ? k.src == null : src.equals(k.src)) && 111 (uri == null ? k.uri == null : uri.equals(k.uri)); 112 } 113 return false; 114 } 115 public int hashCode() { 116 return 32 * (src == null ? 0 : src.hashCode()) + (uri == null ? 0 : uri.hashCode()); 117 } 118 121 String getURL() { 122 if (src == null) return null; 123 try { 124 return src; 125 } catch (Exception e) { 126 return null; 127 } 128 } 129 public String toString() { 130 return "" + src + "/" + uri; 131 } 132 133 } 134 135 141 142 private int remove(String file) { 143 int removed = 0; 144 Iterator i = entrySet().iterator(); 145 if (log.isDebugEnabled()) log.debug("trying to remove keys containing " + file); 146 while (i.hasNext()) { 147 Key mapKey = (Key) ((Map.Entry ) i.next()).getKey(); 148 if (mapKey.getURL().equals(file)) { 149 if(remove(mapKey) != null) { 150 removed++; 151 } else { 152 log.warn("Could not remove " + mapKey); 153 } 154 } 155 } 156 return removed; 157 } 158 159 160 public Templates getTemplates(Source src) { 161 return getTemplates(src, null); 162 } 163 public Templates getTemplates(Source src, URIResolver uri) { 164 Key key = new Key(src, uri); 165 if (log.isDebugEnabled()) log.debug("Getting from cache " + key); 166 return (Templates ) get(key); 167 } 168 169 172 173 public synchronized Object remove(Object key) { 174 if (log.isDebugEnabled()) log.debug("Removing " + key); 175 Object result = super.remove(key); 176 String url = ((Key) key).getURL(); 177 remove(url); 178 templateWatcher.remove(url); 179 return result; 180 } 181 182 187 188 public Object put(Object key, Object value) { 189 throw new RuntimeException ("wrong types in cache"); 190 } 191 public Object put(Source src, Templates value) { 192 return put(src, value, null); 193 } 194 public Object put(Source src, Templates value, URIResolver uri) { 195 if (! isActive()) { 196 if (log.isDebugEnabled()) { 197 log.debug("XSLT Cache is not active"); 198 } 199 return null; 200 } 201 Key key = new Key(src, uri); 202 Object res = super.put(key, value); 203 log.service("Put xslt in cache with key " + key); 204 templateWatcher.add(key.getURL()); 205 if (log.isDebugEnabled()) { 206 log.debug("have set watch on " + key.getURL()); 207 log.trace("currently watching: " + templateWatcher); 208 } 209 return res; 210 } 211 212 213 216 public static void main(String [] argv) { 217 log.setLevel(org.mmbase.util.logging.Level.DEBUG); 218 try { 219 java.io.File xslFile = java.io.File.createTempFile("templatecachetest", ".xsl"); 220 log.info("using file " + xslFile); 221 java.io.FileWriter fw = new java.io.FileWriter (xslFile); 222 fw.write("<xsl:stylesheet version = \"1.1\" xmlns:xsl =\"http://www.w3.org/1999/XSL/Transform\"></xsl:stylesheet>"); 223 fw.close(); 224 for (int i =0; i<10; i++) { 225 TemplateCache cache = TemplateCache.getCache(); 226 Source xsl = new StreamSource (xslFile); 227 org.mmbase.util.xml.URIResolver uri = new org.mmbase.util.xml.URIResolver(xslFile.getParentFile()); 228 Templates cachedXslt = cache.getTemplates(xsl, uri); 229 log.info("template cache size " + cache.size() + " entries: " + cache.entrySet()); 230 if (cachedXslt == null) { 231 cachedXslt = FactoryCache.getCache().getFactory(uri).newTemplates(xsl); 232 cache.put(xsl, cachedXslt, uri); 233 } else { 234 if (log.isDebugEnabled()) log.debug("Used xslt from cache with " + xsl.getSystemId()); 235 } 236 } 237 xslFile.delete(); 238 } catch (Exception e) { 239 System.err.println("hmm?" + e); 240 } 241 242 243 } 244 245 } 246 | Popular Tags |