1 52 53 package freemarker.ext.util; 54 55 import java.lang.ref.ReferenceQueue ; 56 import java.lang.ref.SoftReference ; 57 import java.util.Map ; 58 59 import freemarker.template.ObjectWrapper; 60 import freemarker.template.TemplateModel; 61 62 68 public class ModelCache 69 { 70 private boolean useCache = false; 71 private Map modelCache = null; 72 private ReferenceQueue refQueue = null; 73 private final ObjectWrapper wrapper; 74 75 public ModelCache(ObjectWrapper wrapper) 76 { 77 this.wrapper = wrapper; 78 } 79 80 85 public synchronized void setUseCache(boolean useCache) 86 { 87 this.useCache = useCache; 88 if(useCache) 89 { 90 modelCache = new IdentityHashMap(); 91 refQueue = new ReferenceQueue (); 92 } 93 else 94 { 95 modelCache = null; 96 refQueue = null; 97 } 98 } 99 100 public TemplateModel getInstance(Object object, ModelFactory factory) 101 { 102 if(useCache) 103 { 104 TemplateModel model = lookup(object); 105 if(model == null) 106 { 107 model = factory.create(object, wrapper); 108 register(model, object); 109 } 110 return model; 111 } 112 113 return factory.create(object, wrapper); 114 } 115 116 public void clearCache() 117 { 118 if(modelCache != null) 119 { 120 synchronized(modelCache) 121 { 122 modelCache.clear(); 123 } 124 } 125 } 126 127 private final TemplateModel lookup(Object object) 128 { 129 ModelReference ref = null; 130 synchronized (modelCache) 134 { 135 ref = (ModelReference) modelCache.get(object); 136 } 137 138 if (ref != null) 139 return ref.getModel(); 140 141 return null; 142 } 143 144 private final void register(TemplateModel model, Object object) 145 { 146 synchronized (modelCache) 147 { 148 for (;;) 150 { 151 ModelReference queuedRef = (ModelReference) refQueue.poll(); 152 if (queuedRef == null) 153 break; 154 modelCache.remove(queuedRef.object); 155 } 156 modelCache.put(object, new ModelReference(model, object, refQueue)); 158 } 159 } 160 161 166 private static final class ModelReference extends SoftReference 167 { 168 Object object; 169 170 ModelReference(TemplateModel ref, Object object, ReferenceQueue refQueue) 171 { 172 super(ref); 173 this.object = object; 174 } 175 176 TemplateModel getModel() 177 { 178 return (TemplateModel) this.get(); 179 } 180 } 181 182 } 183 | Popular Tags |