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