1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.skife.jdbi.v2.unstable.stringtemplate;
17
18 import antlr.CharScanner;
19 import org.antlr.stringtemplate.StringTemplateErrorListener;
20 import org.antlr.stringtemplate.StringTemplateGroup;
21 import org.antlr.stringtemplate.StringTemplateGroupInterface;
22 import org.antlr.stringtemplate.StringTemplateGroupLoader;
23
24 import java.io.BufferedReader;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.UnsupportedEncodingException;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ConcurrentMap;
30
31
32
33
34
35
36
37
38 public class ClasspathGroupLoader implements StringTemplateGroupLoader
39 {
40
41
42
43
44
45 private String fileCharEncoding = System.getProperty("file.encoding");
46
47 private final ConcurrentMap<String, StringTemplateGroup> groupCache;
48 private final ConcurrentMap<String, StringTemplateGroupInterface> interfaceCache;
49 private final Class<? extends CharScanner> lexerClass;
50 private final StringTemplateErrorListener errors;
51 private final String[] dirs;
52
53
54
55
56
57
58
59
60
61 public ClasspathGroupLoader(Class<? extends CharScanner> lexerClass,
62 StringTemplateErrorListener errors,
63 String... roots)
64 {
65 groupCache = new ConcurrentHashMap<String, StringTemplateGroup>();
66 interfaceCache = new ConcurrentHashMap<String, StringTemplateGroupInterface>();
67 this.lexerClass = lexerClass;
68 this.errors = errors;
69 this.dirs = roots;
70 }
71
72
73
74
75
76
77
78
79 public ClasspathGroupLoader(StringTemplateErrorListener errors,
80 String... roots)
81 {
82 this(null, errors, roots);
83 }
84
85
86
87
88
89
90
91 public ClasspathGroupLoader(StringTemplateErrorListener errors)
92 {
93 this(errors, "/");
94 }
95
96
97
98
99
100
101
102
103 public ClasspathGroupLoader(String... roots)
104 {
105 this(new ExplodingStringTemplateErrorListener(), roots);
106 }
107
108
109
110
111
112
113
114
115
116 public ClasspathGroupLoader(Class<? extends CharScanner> lexerClass, String... roots)
117 {
118 this(lexerClass, new ExplodingStringTemplateErrorListener(), roots);
119 }
120
121
122
123
124
125
126 public ClasspathGroupLoader()
127 {
128 this("/");
129 }
130
131 private BufferedReader locate(String name)
132 {
133 for (String dir : dirs) {
134 final String fileName = dir + "/" + name;
135 ClassLoader loader = Thread.currentThread().getContextClassLoader();
136 InputStream stream = loader.getResourceAsStream(fileName);
137 if (stream == null) {
138 loader = this.getClass().getClassLoader();
139 stream = loader.getResourceAsStream(fileName);
140 }
141 if (stream != null) {
142 return new BufferedReader(getInputStreamReader(stream));
143 }
144 }
145 return null;
146 }
147
148
149
150
151
152 public StringTemplateGroup loadGroup(String groupName)
153 {
154 if (groupCache.containsKey(groupName)) {
155 return groupCache.get(groupName);
156 }
157 final BufferedReader br = locate(groupName + ".stg");
158 if (br == null) {
159 errors.error("no such group file " + groupName + ".stg", null);
160 return null;
161 }
162 final StringTemplateGroup group = new StringTemplateGroup(br, lexerClass, errors);
163 groupCache.putIfAbsent(groupName, group);
164
165 return group;
166 }
167
168
169
170
171
172
173 public StringTemplateGroup loadGroup(String groupName, StringTemplateGroup superGroup)
174 {
175 final String key = new StringBuilder(groupName).append("!@#$%^&*()").append(superGroup).toString();
176 if (groupCache.containsKey(key)) {
177 return groupCache.get(key);
178 }
179 final BufferedReader br = locate(groupName + ".stg");
180 if (br == null) {
181 errors.error("no such group file " + groupName + ".stg", null);
182 return null;
183 }
184 final StringTemplateGroup group = new StringTemplateGroup(br, lexerClass, errors, superGroup);
185 groupCache.putIfAbsent(key, group);
186
187 return group;
188 }
189
190
191
192
193
194 public StringTemplateGroupInterface loadInterface(String interfaceName)
195 {
196 if (interfaceCache.containsKey(interfaceName)) {
197 return interfaceCache.get(interfaceName);
198 }
199 final BufferedReader br = locate(interfaceName + ".sti");
200 if (br == null) {
201 errors.error("no such interface file " + interfaceName + ".sti", null);
202 return null;
203 }
204 final StringTemplateGroupInterface iface = new StringTemplateGroupInterface(br, errors);
205 interfaceCache.put(interfaceName, iface);
206
207 return iface;
208 }
209
210 private InputStreamReader getInputStreamReader(InputStream in)
211 {
212 InputStreamReader isr = null;
213 try {
214 isr = new InputStreamReader(in, fileCharEncoding);
215 }
216 catch (UnsupportedEncodingException uee) {
217 errors.error("Invalid file character encoding: " + fileCharEncoding, null);
218 }
219 return isr;
220 }
221
222 public void setFileCharEncoding(String fileCharEncoding)
223 {
224 this.fileCharEncoding = fileCharEncoding;
225 }
226
227 private static class ExplodingStringTemplateErrorListener implements StringTemplateErrorListener
228 {
229
230 public void error(String msg, Throwable e)
231 {
232 throw new IllegalStateException(msg, e);
233 }
234
235 public void warning(String msg)
236 {
237 throw new IllegalStateException(msg);
238 }
239 }
240 }