1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package org.melati.template;
47
48 import java.util.Hashtable;
49
50 import org.melati.poem.FieldAttributes;
51 import org.melati.util.MelatiBugMelatiException;
52
53
54
55
56 public final class ClassNameTempletLoader implements TempletLoader {
57
58
59 private static ClassNameTempletLoader it = null;
60
61
62 private static Hashtable<String,Template> templetForClassCache = new Hashtable<String,Template>();
63
64 private static final Integer FOUND = new Integer(1);
65 private static final Integer NOT_FOUND = new Integer(0);
66 private static Hashtable<String,Integer> lookedupTemplateNames = new Hashtable<String,Integer>();
67
68
69 private ClassNameTempletLoader() {}
70
71
72
73
74 public static ClassNameTempletLoader getInstance() {
75 if (it == null)
76 it = new ClassNameTempletLoader();
77 return it;
78 }
79 protected static String templetsPath(TemplateEngine templateEngine,
80 MarkupLanguage markupLanguage) {
81
82
83
84
85
86
87
88
89
90 return "org/melati/templets/" +
91 markupLanguage.getName() + "/";
92
93 }
94
95
96
97
98 protected static String templetsTempletPath(TemplateEngine templateEngine,
99 MarkupLanguage markupLanguage,
100 String purpose, String name) {
101 if (purpose == null)
102 return
103 templetsPath(templateEngine, markupLanguage) +
104 name +
105 templateEngine.templateExtension();
106 return
107 templetsPath(templateEngine, markupLanguage) +
108 purpose + "/" +
109 name +
110 templateEngine.templateExtension();
111 }
112
113 protected static String classpathTempletPath(Class<?> clazz, TemplateEngine templateEngine) {
114 return clazz.getName().replace('.', '/') + templateEngine.templateExtension();
115 }
116
117
118
119
120
121
122 public Template templet(TemplateEngine templateEngine,
123 MarkupLanguage markupLanguage, String purpose,
124 String name) throws NotFoundException {
125 return templateEngine.template(templetsTempletPath(templateEngine, markupLanguage,
126 purpose, name));
127 }
128
129
130
131
132
133
134
135 public Template templet(TemplateEngine templateEngine,
136 MarkupLanguage markupLanguage, String name)
137 throws NotFoundException {
138 return templet(templateEngine, markupLanguage, null, name);
139 }
140
141
142
143
144
145
146
147
148
149 public Template templet(TemplateEngine templateEngine,
150 MarkupLanguage markupLanguage, String purpose,
151 Class<?> clazz)
152 throws TemplateEngineException {
153 Class<?> lookupClass = clazz;
154 Template templet = null;
155 Template fromCache = null;
156 String originalCacheKey = cacheKey(templateEngine, markupLanguage, purpose, lookupClass);
157 String lookupCacheKey = originalCacheKey;
158 String lookupPurpose = purpose;
159 while (true) {
160 fromCache = (Template)templetForClassCache.get(lookupCacheKey);
161 if (fromCache != null) {
162 templet = fromCache;
163 break;
164 }
165
166
167
168
169
170 String templetPath = templetsTempletPath(templateEngine, markupLanguage,
171 lookupPurpose, lookupClass.getName());
172 templet = getTemplate(templateEngine, templetPath);
173 if (templet != null)
174 break;
175
176 templetPath = classpathTempletPath(lookupClass, templateEngine);
177 templet = getTemplate(templateEngine, templetPath);
178 if (templet != null)
179 break;
180
181 if (lookupPurpose != null)
182 lookupPurpose = null;
183 else {
184 lookupClass = lookupClass.getSuperclass();
185 lookupPurpose = purpose;
186 }
187 lookupCacheKey = cacheKey(templateEngine, markupLanguage, lookupPurpose, lookupClass);
188 }
189
190
191
192 System.err.println(lookupCacheKey);
193 if (fromCache == null)
194 templetForClassCache.put(originalCacheKey, templet);
195 if (!lookupCacheKey.equals(originalCacheKey)) {
196 if (templetForClassCache.get(lookupCacheKey) == null)
197 templetForClassCache.put(lookupCacheKey, templet);
198 }
199 return templet;
200 }
201
202 private String cacheKey(TemplateEngine templateEngine,
203 MarkupLanguage markupLanguage,
204 String purpose,
205 Class<?> lookupClass) {
206 return purpose == null ? cacheKey(templateEngine, markupLanguage, lookupClass)
207 : lookupClass + "/" +
208 purpose + "/" +
209 markupLanguage + "/" +
210 templateEngine.getName();
211 }
212
213 private String cacheKey(TemplateEngine templateEngine,
214 MarkupLanguage markupLanguage,
215 Class<?> lookupClass) {
216 return lookupClass +
217 "/" + markupLanguage +
218 "/" + templateEngine.getName();
219 }
220
221 private Template getTemplate(TemplateEngine templateEngine, String templetPath) {
222 Template templet = null;
223 try {
224 Object triedAlready = lookedupTemplateNames.get(templetPath);
225 if (triedAlready != NOT_FOUND) {
226 templet = templateEngine.template(templetPath);
227 lookedupTemplateNames.put(templetPath, FOUND);
228 }
229 } catch (NotFoundException e) {
230 lookedupTemplateNames.put(templetPath, NOT_FOUND);
231 }
232 return templet;
233 }
234
235
236
237
238
239
240
241 public Template templet(TemplateEngine templateEngine,
242 MarkupLanguage markupLanguage, Class<?> clazz) {
243 return templet(templateEngine, markupLanguage, null, clazz);
244 }
245
246
247
248
249
250
251
252
253 public Template templet(TemplateEngine templateEngine,
254 MarkupLanguage markupLanguage,
255 FieldAttributes attributes) {
256 if (attributes.getRenderInfo() != null) {
257 String templetName = attributes.getType().getClass().getName()
258 + "-"
259 + attributes.getRenderInfo();
260 try {
261 return templet(templateEngine, markupLanguage,
262 templetName);
263 } catch (NotFoundException e) {
264 throw new MelatiBugMelatiException(
265 "Templet " + templetName + " not found", e);
266 }
267 } else {
268 return templet(templateEngine, markupLanguage,
269 attributes.getType().getClass());
270 }
271 }
272 }
273
274
275
276
277
278
279
280
281
282