1 package freemarker.debug.impl; 2 3 import java.rmi.RemoteException ; 4 import java.util.ArrayList ; 5 import java.util.Arrays ; 6 import java.util.Collection ; 7 import java.util.Collections ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 11 import freemarker.cache.CacheStorage; 12 import freemarker.cache.SoftCacheStorage; 13 import freemarker.debug.DebuggedEnvironment; 14 import freemarker.ext.util.IdentityHashMap; 15 import freemarker.core.Configurable; 16 import freemarker.template.Configuration; 17 import freemarker.core.Environment; 18 import freemarker.template.SimpleCollection; 19 import freemarker.template.SimpleScalar; 20 import freemarker.template.Template; 21 import freemarker.template.TemplateCollectionModel; 22 import freemarker.template.TemplateHashModelEx; 23 import freemarker.template.TemplateModel; 24 import freemarker.template.TemplateModelException; 25 import freemarker.template.utility.UndeclaredThrowableException; 26 27 31 class RmiDebuggedEnvironmentImpl 32 extends 33 RmiDebugModelImpl 34 implements 35 DebuggedEnvironment 36 { 37 private static final CacheStorage storage = new SoftCacheStorage(new IdentityHashMap()); 38 private static final Object idLock = new Object (); 39 private static long nextId = 1; 40 41 private boolean stopped = false; 42 private final long id; 43 44 private RmiDebuggedEnvironmentImpl(Environment env) throws RemoteException 45 { 46 super(new DebugEnvironmentModel(env)); 47 synchronized(idLock) 48 { 49 id = nextId++; 50 } 51 } 52 53 static synchronized Object getCachedWrapperFor(Object key) 54 throws 55 RemoteException 56 { 57 Object value = storage.get(key); 58 if(value == null) 59 { 60 if(key instanceof TemplateModel) 61 { 62 value = new RmiDebugModelImpl((TemplateModel)key); 63 } 64 else if(key instanceof Environment) 65 { 66 value = new RmiDebuggedEnvironmentImpl((Environment)key); 67 } 68 else if(key instanceof Template) 69 { 70 value = new DebugTemplateModel((Template)key); 71 } 72 else if(key instanceof Configuration) 73 { 74 value = new DebugConfigurationModel((Configuration)key); 75 } 76 } 77 return value; 78 } 79 80 public void resume() 81 { 82 synchronized(this) 83 { 84 notify(); 85 } 86 } 87 88 public void stop() 89 { 90 stopped = true; 91 resume(); 92 } 93 94 public long getId() 95 { 96 return id; 97 } 98 99 boolean isStopped() 100 { 101 return stopped; 102 } 103 104 private abstract static class DebugMapModel implements TemplateHashModelEx 105 { 106 public int size() 107 { 108 return keySet().size(); 109 } 110 111 public TemplateCollectionModel keys() 112 { 113 return new SimpleCollection(keySet()); 114 } 115 116 public TemplateCollectionModel values() throws TemplateModelException 117 { 118 Collection keys = keySet(); 119 List list = new ArrayList (keys.size()); 120 121 for(Iterator it = keys.iterator(); it.hasNext();) 122 { 123 list.add(get((String )it.next())); 124 } 125 return new SimpleCollection(list); 126 } 127 128 public boolean isEmpty() 129 { 130 return size() == 0; 131 } 132 133 abstract Collection keySet(); 134 135 static List composeList(Collection c1, Collection c2) 136 { 137 List list = new ArrayList (c1); 138 list.addAll(c2); 139 Collections.sort(list); 140 return list; 141 } 142 } 143 144 private static class DebugConfigurableModel extends DebugMapModel 145 { 146 static final List KEYS = Arrays.asList(new String [] 147 { 148 Configurable.ARITHMETIC_ENGINE_KEY, 149 Configurable.BOOLEAN_FORMAT_KEY, 150 Configurable.CLASSIC_COMPATIBLE_KEY, 151 Configurable.LOCALE_KEY, 152 Configurable.NUMBER_FORMAT_KEY, 153 Configurable.OBJECT_WRAPPER_KEY, 154 Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY 155 }); 156 157 final Configurable configurable; 158 159 DebugConfigurableModel(Configurable configurable) 160 { 161 this.configurable = configurable; 162 } 163 164 Collection keySet() 165 { 166 return KEYS; 167 } 168 169 public TemplateModel get(String key) throws TemplateModelException 170 { 171 String s = configurable.getSetting(key); 172 return s == null ? null : new SimpleScalar(s); 173 } 174 175 } 176 177 private static class DebugConfigurationModel extends DebugConfigurableModel 178 { 179 private static final List KEYS = composeList(DebugConfigurableModel.KEYS, Collections.singleton("sharedVariables")); 180 181 private TemplateModel sharedVariables = new DebugMapModel() 182 { 183 Collection keySet() 184 { 185 return ((Configuration)configurable).getSharedVariableNames(); 186 } 187 188 public TemplateModel get(String key) 189 { 190 return ((Configuration)configurable).getSharedVariable(key); 191 } 192 }; 193 194 DebugConfigurationModel(Configuration config) 195 { 196 super(config); 197 } 198 199 Collection keySet() 200 { 201 return KEYS; 202 } 203 204 public TemplateModel get(String key) throws TemplateModelException 205 { 206 if("sharedVariables".equals(key)) 207 { 208 return sharedVariables; 209 } 210 else 211 { 212 return super.get(key); 213 } 214 } 215 } 216 217 private static class DebugTemplateModel extends DebugConfigurableModel 218 { 219 private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 220 Arrays.asList(new String [] { 221 "configuration", 222 "name", 223 })); 224 225 private final SimpleScalar name; 226 227 DebugTemplateModel(Template template) 228 { 229 super(template); 230 this.name = new SimpleScalar(template.getName()); 231 } 232 233 Collection keySet() 234 { 235 return KEYS; 236 } 237 238 public TemplateModel get(String key) throws TemplateModelException 239 { 240 if("configuration".equals(key)) 241 { 242 try 243 { 244 return (TemplateModel)getCachedWrapperFor(((Template)configurable).getConfiguration()); 245 } 246 catch (RemoteException e) 247 { 248 throw new TemplateModelException(e); 249 } 250 } 251 if("name".equals(key)) 252 { 253 return name; 254 } 255 return super.get(key); 256 } 257 } 258 259 private static class DebugEnvironmentModel extends DebugConfigurableModel 260 { 261 private static final List KEYS = composeList(DebugConfigurableModel.KEYS, 262 Arrays.asList(new String [] { 263 "currentNamespace", 264 "dataModel", 265 "globalNamespace", 266 "knownVariables", 267 "mainNamespace", 268 "template", 269 })); 270 271 private TemplateModel knownVariables = new DebugMapModel() 272 { 273 Collection keySet() 274 { 275 try 276 { 277 return ((Environment)configurable).getKnownVariableNames(); 278 } 279 catch (TemplateModelException e) 280 { 281 throw new UndeclaredThrowableException(e); 282 } 283 } 284 285 public TemplateModel get(String key) throws TemplateModelException 286 { 287 return ((Environment)configurable).getVariable(key); 288 } 289 }; 290 291 DebugEnvironmentModel(Environment env) 292 { 293 super(env); 294 } 295 296 Collection keySet() 297 { 298 return KEYS; 299 } 300 301 public TemplateModel get(String key) throws TemplateModelException 302 { 303 if("currentNamespace".equals(key)) 304 { 305 return ((Environment)configurable).getCurrentNamespace(); 306 } 307 if("dataModel".equals(key)) 308 { 309 return ((Environment)configurable).getDataModel(); 310 } 311 if("globalNamespace".equals(key)) 312 { 313 return ((Environment)configurable).getGlobalNamespace(); 314 } 315 if("knownVariables".equals(key)) 316 { 317 return knownVariables; 318 } 319 if("mainNamespace".equals(key)) 320 { 321 return ((Environment)configurable).getMainNamespace(); 322 } 323 if("template".equals(key)) 324 { 325 try 326 { 327 return (TemplateModel) getCachedWrapperFor(((Environment)configurable).getTemplate()); 328 } 329 catch (RemoteException e) 330 { 331 throw new TemplateModelException(e); 332 } 333 } 334 return super.get(key); 335 } 336 } 337 } 338 | Popular Tags |