001: package freemarker.debug.impl;
002:
003: import java.rmi.RemoteException;
004: import java.util.ArrayList;
005: import java.util.Arrays;
006: import java.util.Collection;
007: import java.util.Collections;
008: import java.util.Iterator;
009: import java.util.List;
010:
011: import freemarker.cache.CacheStorage;
012: import freemarker.cache.SoftCacheStorage;
013: import freemarker.core.Configurable;
014: import freemarker.core.Environment;
015: import freemarker.debug.DebugModel;
016: import freemarker.debug.DebuggedEnvironment;
017: import freemarker.ext.util.IdentityHashMap;
018: import freemarker.template.Configuration;
019: import freemarker.template.SimpleCollection;
020: import freemarker.template.SimpleScalar;
021: import freemarker.template.Template;
022: import freemarker.template.TemplateCollectionModel;
023: import freemarker.template.TemplateHashModelEx;
024: import freemarker.template.TemplateModel;
025: import freemarker.template.TemplateModelException;
026: import freemarker.template.utility.UndeclaredThrowableException;
027:
028: /**
029: * @author Attila Szegedi
030: * @version $Id: RmiDebuggedEnvironmentImpl.java,v 1.3.2.2 2006/11/27 07:55:17 szegedia Exp $
031: */
032: class RmiDebuggedEnvironmentImpl extends RmiDebugModelImpl implements
033: DebuggedEnvironment {
034: private static final long serialVersionUID = 1L;
035:
036: private static final CacheStorage storage = new SoftCacheStorage(
037: new IdentityHashMap());
038: private static final Object idLock = new Object();
039: private static long nextId = 1;
040:
041: private boolean stopped = false;
042: private final long id;
043:
044: private RmiDebuggedEnvironmentImpl(Environment env)
045: throws RemoteException {
046: super (new DebugEnvironmentModel(env),
047: DebugModel.TYPE_ENVIRONMENT);
048: synchronized (idLock) {
049: id = nextId++;
050: }
051: }
052:
053: static synchronized Object getCachedWrapperFor(Object key)
054: throws RemoteException {
055: Object value = storage.get(key);
056: if (value == null) {
057: if (key instanceof TemplateModel) {
058: int extraTypes;
059: if (key instanceof DebugConfigurationModel) {
060: extraTypes = DebugModel.TYPE_CONFIGURATION;
061: } else if (key instanceof DebugTemplateModel) {
062: extraTypes = DebugModel.TYPE_TEMPLATE;
063: } else {
064: extraTypes = 0;
065: }
066: value = new RmiDebugModelImpl((TemplateModel) key,
067: extraTypes);
068: } else if (key instanceof Environment) {
069: value = new RmiDebuggedEnvironmentImpl(
070: (Environment) key);
071: } else if (key instanceof Template) {
072: value = new DebugTemplateModel((Template) key);
073: } else if (key instanceof Configuration) {
074: value = new DebugConfigurationModel((Configuration) key);
075: }
076: }
077: return value;
078: }
079:
080: public void resume() {
081: synchronized (this ) {
082: notify();
083: }
084: }
085:
086: public void stop() {
087: stopped = true;
088: resume();
089: }
090:
091: public long getId() {
092: return id;
093: }
094:
095: boolean isStopped() {
096: return stopped;
097: }
098:
099: private abstract static class DebugMapModel implements
100: TemplateHashModelEx {
101: public int size() {
102: return keySet().size();
103: }
104:
105: public TemplateCollectionModel keys() {
106: return new SimpleCollection(keySet());
107: }
108:
109: public TemplateCollectionModel values()
110: throws TemplateModelException {
111: Collection keys = keySet();
112: List list = new ArrayList(keys.size());
113:
114: for (Iterator it = keys.iterator(); it.hasNext();) {
115: list.add(get((String) it.next()));
116: }
117: return new SimpleCollection(list);
118: }
119:
120: public boolean isEmpty() {
121: return size() == 0;
122: }
123:
124: abstract Collection keySet();
125:
126: static List composeList(Collection c1, Collection c2) {
127: List list = new ArrayList(c1);
128: list.addAll(c2);
129: Collections.sort(list);
130: return list;
131: }
132: }
133:
134: private static class DebugConfigurableModel extends DebugMapModel {
135: static final List KEYS = Arrays.asList(new String[] {
136: Configurable.ARITHMETIC_ENGINE_KEY,
137: Configurable.BOOLEAN_FORMAT_KEY,
138: Configurable.CLASSIC_COMPATIBLE_KEY,
139: Configurable.LOCALE_KEY,
140: Configurable.NUMBER_FORMAT_KEY,
141: Configurable.OBJECT_WRAPPER_KEY,
142: Configurable.TEMPLATE_EXCEPTION_HANDLER_KEY });
143:
144: final Configurable configurable;
145:
146: DebugConfigurableModel(Configurable configurable) {
147: this .configurable = configurable;
148: }
149:
150: Collection keySet() {
151: return KEYS;
152: }
153:
154: public TemplateModel get(String key)
155: throws TemplateModelException {
156: String s = configurable.getSetting(key);
157: return s == null ? null : new SimpleScalar(s);
158: }
159:
160: }
161:
162: private static class DebugConfigurationModel extends
163: DebugConfigurableModel {
164: private static final List KEYS = composeList(
165: DebugConfigurableModel.KEYS, Collections
166: .singleton("sharedVariables"));
167:
168: private TemplateModel sharedVariables = new DebugMapModel() {
169: Collection keySet() {
170: return ((Configuration) configurable)
171: .getSharedVariableNames();
172: }
173:
174: public TemplateModel get(String key) {
175: return ((Configuration) configurable)
176: .getSharedVariable(key);
177: }
178: };
179:
180: DebugConfigurationModel(Configuration config) {
181: super (config);
182: }
183:
184: Collection keySet() {
185: return KEYS;
186: }
187:
188: public TemplateModel get(String key)
189: throws TemplateModelException {
190: if ("sharedVariables".equals(key)) {
191: return sharedVariables;
192: } else {
193: return super .get(key);
194: }
195: }
196: }
197:
198: private static class DebugTemplateModel extends
199: DebugConfigurableModel {
200: private static final List KEYS = composeList(
201: DebugConfigurableModel.KEYS,
202: Arrays
203: .asList(new String[] { "configuration", "name", }));
204:
205: private final SimpleScalar name;
206:
207: DebugTemplateModel(Template template) {
208: super (template);
209: this .name = new SimpleScalar(template.getName());
210: }
211:
212: Collection keySet() {
213: return KEYS;
214: }
215:
216: public TemplateModel get(String key)
217: throws TemplateModelException {
218: if ("configuration".equals(key)) {
219: try {
220: return (TemplateModel) getCachedWrapperFor(((Template) configurable)
221: .getConfiguration());
222: } catch (RemoteException e) {
223: throw new TemplateModelException(e);
224: }
225: }
226: if ("name".equals(key)) {
227: return name;
228: }
229: return super .get(key);
230: }
231: }
232:
233: private static class DebugEnvironmentModel extends
234: DebugConfigurableModel {
235: private static final List KEYS = composeList(
236: DebugConfigurableModel.KEYS, Arrays
237: .asList(new String[] { "currentNamespace",
238: "dataModel", "globalNamespace",
239: "knownVariables", "mainNamespace",
240: "template", }));
241:
242: private TemplateModel knownVariables = new DebugMapModel() {
243: Collection keySet() {
244: try {
245: return ((Environment) configurable)
246: .getKnownVariableNames();
247: } catch (TemplateModelException e) {
248: throw new UndeclaredThrowableException(e);
249: }
250: }
251:
252: public TemplateModel get(String key)
253: throws TemplateModelException {
254: return ((Environment) configurable).getVariable(key);
255: }
256: };
257:
258: DebugEnvironmentModel(Environment env) {
259: super (env);
260: }
261:
262: Collection keySet() {
263: return KEYS;
264: }
265:
266: public TemplateModel get(String key)
267: throws TemplateModelException {
268: if ("currentNamespace".equals(key)) {
269: return ((Environment) configurable)
270: .getCurrentNamespace();
271: }
272: if ("dataModel".equals(key)) {
273: return ((Environment) configurable).getDataModel();
274: }
275: if ("globalNamespace".equals(key)) {
276: return ((Environment) configurable)
277: .getGlobalNamespace();
278: }
279: if ("knownVariables".equals(key)) {
280: return knownVariables;
281: }
282: if ("mainNamespace".equals(key)) {
283: return ((Environment) configurable).getMainNamespace();
284: }
285: if ("template".equals(key)) {
286: try {
287: return (TemplateModel) getCachedWrapperFor(((Environment) configurable)
288: .getTemplate());
289: } catch (RemoteException e) {
290: throw new TemplateModelException(e);
291: }
292: }
293: return super.get(key);
294: }
295: }
296: }
|