1 |
|
package com.ozacc.mail.impl; |
2 |
|
|
3 |
|
import java.io.File; |
4 |
|
import java.io.IOException; |
5 |
|
import java.io.StringReader; |
6 |
|
import java.io.StringWriter; |
7 |
|
import java.util.HashMap; |
8 |
|
import java.util.Map; |
9 |
|
import java.util.Properties; |
10 |
|
|
11 |
|
import javax.xml.parsers.DocumentBuilder; |
12 |
|
import javax.xml.transform.OutputKeys; |
13 |
|
import javax.xml.transform.Transformer; |
14 |
|
import javax.xml.transform.TransformerConfigurationException; |
15 |
|
import javax.xml.transform.TransformerException; |
16 |
|
import javax.xml.transform.TransformerFactory; |
17 |
|
import javax.xml.transform.TransformerFactoryConfigurationError; |
18 |
|
import javax.xml.transform.dom.DOMSource; |
19 |
|
import javax.xml.transform.stream.StreamResult; |
20 |
|
|
21 |
|
import org.apache.commons.logging.Log; |
22 |
|
import org.apache.commons.logging.LogFactory; |
23 |
|
import org.apache.velocity.VelocityContext; |
24 |
|
import org.apache.velocity.app.Velocity; |
25 |
|
import org.apache.velocity.exception.MethodInvocationException; |
26 |
|
import org.apache.velocity.exception.ParseErrorException; |
27 |
|
import org.apache.velocity.exception.ResourceNotFoundException; |
28 |
|
import org.apache.velocity.runtime.log.LogSystem; |
29 |
|
import org.w3c.dom.Document; |
30 |
|
import org.w3c.dom.Element; |
31 |
|
import org.xml.sax.InputSource; |
32 |
|
import org.xml.sax.SAXException; |
33 |
|
|
34 |
|
import com.ozacc.mail.Mail; |
35 |
|
import com.ozacc.mail.MailBuildException; |
36 |
|
import com.ozacc.mail.VelocityMultipleMailBuilder; |
37 |
|
|
38 |
|
|
39 |
|
|
40 |
|
|
41 |
|
|
42 |
|
|
43 |
|
|
44 |
|
|
45 |
7 |
public class XMLVelocityMailBuilderImpl extends XMLMailBuilderImpl implements |
46 |
|
VelocityMultipleMailBuilder { |
47 |
|
|
48 |
1 |
private static Log log = LogFactory.getLog(XMLVelocityMailBuilderImpl.class); |
49 |
|
|
50 |
1 |
private static String CACHE_KEY_SEPARATOR = "#"; |
51 |
|
|
52 |
1 |
private static String DEFAULT_MAIL_ID = "DEFAULT"; |
53 |
|
|
54 |
3 |
protected String charset = "UTF-8"; |
55 |
|
|
56 |
3 |
protected LogSystem velocityLogSystem = new VelocityLogSystem(); |
57 |
|
|
58 |
3 |
protected Map templateCache = new HashMap(); |
59 |
|
|
60 |
3 |
private boolean cacheEnabled = false; |
61 |
|
|
62 |
|
protected boolean hasTemplateCache(String key) { |
63 |
6 |
if (cacheEnabled) { |
64 |
4 |
return templateCache.containsKey(key); |
65 |
|
} |
66 |
2 |
return false; |
67 |
|
} |
68 |
|
|
69 |
|
protected void putTemplateCache(String key, String templateXmlText) { |
70 |
4 |
if (cacheEnabled) { |
71 |
2 |
log.debug("¥Æ¥ó¥×¥?¡¼¥È¤ò¥¥ã¥Ã¥·¥å¤·¤Þ¤¹¡£[key='" + key + "']"); |
72 |
2 |
templateCache.put(key, templateXmlText); |
73 |
|
} |
74 |
4 |
} |
75 |
|
|
76 |
|
protected String getTemplateCache(String key) { |
77 |
1 |
if (hasTemplateCache(key)) { |
78 |
1 |
log.debug("¥Æ¥ó¥×¥?¡¼¥È¥¥ã¥Ã¥·¥å¤òÊÖ¤·¤Þ¤¹¡£[key='" + key + "']"); |
79 |
1 |
return (String)templateCache.get(key); |
80 |
|
} |
81 |
0 |
return null; |
82 |
|
} |
83 |
|
|
84 |
|
|
85 |
|
|
86 |
|
|
87 |
|
public synchronized void clearCache() { |
88 |
1 |
log.debug("¥Æ¥ó¥×¥?¡¼¥È¥¥ã¥Ã¥·¥å¤ò¥¯¥?¥¢¤·¤Þ¤¹¡£"); |
89 |
1 |
templateCache.clear(); |
90 |
1 |
} |
91 |
|
|
92 |
|
|
93 |
|
|
94 |
|
|
95 |
|
public boolean isCacheEnabled() { |
96 |
0 |
return cacheEnabled; |
97 |
|
} |
98 |
|
|
99 |
|
|
100 |
|
|
101 |
|
|
102 |
|
public void setCacheEnabled(boolean cacheEnabled) { |
103 |
1 |
if (!cacheEnabled) { |
104 |
0 |
clearCache(); |
105 |
|
} |
106 |
1 |
this.cacheEnabled = cacheEnabled; |
107 |
1 |
} |
108 |
|
|
109 |
|
|
110 |
|
|
111 |
|
|
112 |
|
public Mail buildMail(String classPath, VelocityContext context) throws MailBuildException { |
113 |
4 |
String cacheKey = classPath + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID; |
114 |
|
|
115 |
|
String templateXmlText; |
116 |
4 |
if (!hasTemplateCache(cacheKey)) { |
117 |
|
Document doc; |
118 |
|
try { |
119 |
|
|
120 |
3 |
doc = getDocumentFromClassPath(classPath, false); |
121 |
0 |
} catch (SAXException e) { |
122 |
0 |
throw new MailBuildException("XML¤Î¥Ñ¡¼¥¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£" + e.getMessage(), e); |
123 |
0 |
} catch (IOException e) { |
124 |
0 |
throw new MailBuildException("XML¥Õ¥¡¥¤¥?¤ÎÆÉ¤ß¹?¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
125 |
|
} |
126 |
3 |
templateXmlText = convertDocumentIntoString(doc.getDocumentElement()); |
127 |
3 |
putTemplateCache(cacheKey, templateXmlText); |
128 |
|
} else { |
129 |
1 |
templateXmlText = getTemplateCache(cacheKey); |
130 |
|
} |
131 |
|
|
132 |
|
try { |
133 |
4 |
return build(templateXmlText, context); |
134 |
0 |
} catch (Exception e) { |
135 |
0 |
throw new MailBuildException("¥á¡¼¥?¤ÎÀ¸À®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
136 |
|
} |
137 |
|
} |
138 |
|
|
139 |
|
|
140 |
|
|
141 |
|
|
142 |
|
public Mail buildMail(File file, VelocityContext context) throws MailBuildException { |
143 |
1 |
String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID; |
144 |
|
|
145 |
|
String templateXmlText; |
146 |
1 |
if (!hasTemplateCache(cacheKey)) { |
147 |
|
Document doc; |
148 |
|
try { |
149 |
|
|
150 |
1 |
doc = getDocumentFromFile(file, false); |
151 |
0 |
} catch (SAXException e) { |
152 |
0 |
throw new MailBuildException("XML¤Î¥Ñ¡¼¥¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£" + e.getMessage(), e); |
153 |
0 |
} catch (IOException e) { |
154 |
0 |
throw new MailBuildException("XML¥Õ¥¡¥¤¥?¤ÎÆÉ¤ß¹?¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
155 |
|
} |
156 |
1 |
templateXmlText = convertDocumentIntoString(doc.getDocumentElement()); |
157 |
1 |
putTemplateCache(cacheKey, templateXmlText); |
158 |
|
} else { |
159 |
0 |
templateXmlText = getTemplateCache(cacheKey); |
160 |
|
} |
161 |
|
|
162 |
|
try { |
163 |
1 |
return build(templateXmlText, context); |
164 |
0 |
} catch (Exception e) { |
165 |
0 |
throw new MailBuildException("¥á¡¼¥?¤ÎÀ¸À®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
166 |
|
} |
167 |
|
} |
168 |
|
|
169 |
|
|
170 |
|
|
171 |
|
|
172 |
|
|
173 |
|
|
174 |
|
|
175 |
|
|
176 |
|
|
177 |
|
|
178 |
|
|
179 |
|
|
180 |
|
|
181 |
|
|
182 |
|
protected Mail build(String templateXmlText, VelocityContext context) |
183 |
|
throws TransformerFactoryConfigurationError, |
184 |
|
Exception, |
185 |
|
ParseErrorException, |
186 |
|
MethodInvocationException, |
187 |
|
ResourceNotFoundException, |
188 |
|
IOException { |
189 |
5 |
if (log.isDebugEnabled()) { |
190 |
4 |
log.debug("Source XML Mail Data\n" + templateXmlText); |
191 |
|
} |
192 |
|
|
193 |
5 |
Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem); |
194 |
5 |
Velocity.init(); |
195 |
5 |
StringWriter w = new StringWriter(); |
196 |
5 |
Velocity.evaluate(context, w, "XML Mail Data", templateXmlText); |
197 |
5 |
StringReader reader = new StringReader(w.toString()); |
198 |
|
|
199 |
5 |
DocumentBuilder db = createDocumentBuilder(); |
200 |
5 |
InputSource source = new InputSource(reader); |
201 |
5 |
Document newDoc = db.parse(source); |
202 |
|
|
203 |
5 |
if (log.isDebugEnabled()) { |
204 |
4 |
String newXmlContent = convertDocumentIntoString(newDoc.getDocumentElement()); |
205 |
4 |
log.debug("VelocityContext-merged XML Mail Data\n" + newXmlContent); |
206 |
|
} |
207 |
|
|
208 |
5 |
return buildMail(newDoc.getDocumentElement()); |
209 |
|
} |
210 |
|
|
211 |
|
|
212 |
|
|
213 |
|
|
214 |
|
|
215 |
|
|
216 |
|
|
217 |
|
|
218 |
|
protected String convertDocumentIntoString(Element mailElement) |
219 |
|
throws TransformerFactoryConfigurationError { |
220 |
8 |
TransformerFactory tf = TransformerFactory.newInstance(); |
221 |
|
Transformer t; |
222 |
|
try { |
223 |
8 |
t = tf.newTransformer(); |
224 |
0 |
} catch (TransformerConfigurationException e) { |
225 |
0 |
throw new MailBuildException(e.getMessage(), e); |
226 |
|
} |
227 |
8 |
t.setOutputProperties(getOutputProperties()); |
228 |
|
|
229 |
8 |
DOMSource source = new DOMSource(mailElement); |
230 |
8 |
StringWriter w = new StringWriter(); |
231 |
8 |
StreamResult result = new StreamResult(w); |
232 |
|
try { |
233 |
8 |
t.transform(source, result); |
234 |
0 |
} catch (TransformerException e) { |
235 |
0 |
throw new MailBuildException(e.getMessage(), e); |
236 |
|
} |
237 |
|
|
238 |
8 |
return w.toString(); |
239 |
|
} |
240 |
|
|
241 |
|
|
242 |
|
|
243 |
|
|
244 |
|
|
245 |
|
protected Properties getOutputProperties() { |
246 |
8 |
Properties p = new Properties(); |
247 |
8 |
p.put(OutputKeys.ENCODING, charset); |
248 |
8 |
p.put(OutputKeys.DOCTYPE_PUBLIC, Mail.DOCTYPE_PUBLIC); |
249 |
8 |
p.put(OutputKeys.DOCTYPE_SYSTEM, Mail.DOCTYPE_SYSTEM); |
250 |
8 |
return p; |
251 |
|
} |
252 |
|
|
253 |
|
|
254 |
|
|
255 |
|
|
256 |
|
public Mail buildMail(String classPath, VelocityContext context, String mailId) |
257 |
|
throws MailBuildException { |
258 |
0 |
if (mailId == null || "".equals(mailId)) { |
259 |
0 |
throw new IllegalArgumentException("¥á¡¼¥?ID¤¬»ØÄꤵ¤?¤Æ¤¤¤Þ¤»¤ó¡£"); |
260 |
|
} |
261 |
|
|
262 |
0 |
String cacheKey = classPath + CACHE_KEY_SEPARATOR + mailId; |
263 |
|
|
264 |
|
String templateXmlText; |
265 |
0 |
if (!hasTemplateCache(cacheKey)) { |
266 |
|
Document doc; |
267 |
|
try { |
268 |
|
|
269 |
0 |
doc = getDocumentFromClassPath(classPath, false); |
270 |
0 |
} catch (SAXException e) { |
271 |
0 |
throw new MailBuildException("XML¤Î¥Ñ¡¼¥¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£" + e.getMessage(), e); |
272 |
0 |
} catch (IOException e) { |
273 |
0 |
throw new MailBuildException("XML¥Õ¥¡¥¤¥?¤ÎÆÉ¤ß¹?¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
274 |
|
} |
275 |
0 |
if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) { |
276 |
0 |
throw new MailBuildException("»ØÄꤵ¤?¤¿¥¯¥é¥¹¥Ñ¥¹¤ÎXML¤Ï¥·¥ó¥°¥?¥á¡¼¥?¥Æ¥ó¥×¥?¡¼¥È¤Ç¤¹¡£[classPath='" |
277 |
0 |
+ classPath + "']"); |
278 |
|
} |
279 |
0 |
templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey); |
280 |
|
} else { |
281 |
0 |
templateXmlText = getTemplateCache(cacheKey); |
282 |
|
} |
283 |
|
|
284 |
|
try { |
285 |
0 |
return build(templateXmlText, context); |
286 |
0 |
} catch (Exception e) { |
287 |
0 |
throw new MailBuildException("¥á¡¼¥?¤ÎÀ¸À®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
288 |
|
} |
289 |
|
} |
290 |
|
|
291 |
|
private String getAndCacheTemplateText(Document doc, String mailId, String cacheKey) |
292 |
|
throws TransformerFactoryConfigurationError { |
293 |
0 |
Element mailElem = doc.getElementById(mailId); |
294 |
0 |
if (mailElem == null) { |
295 |
0 |
throw new MailBuildException("»ØÄꤵ¤?¤¿ID[" + mailId + "]¤Î¥á¡¼¥?¥Ç¡¼¥¿¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿¡£"); |
296 |
|
} |
297 |
0 |
String templateXmlText = templateXmlText = convertDocumentIntoString(mailElem); |
298 |
0 |
putTemplateCache(cacheKey, templateXmlText); |
299 |
0 |
return templateXmlText; |
300 |
|
} |
301 |
|
|
302 |
|
|
303 |
|
|
304 |
|
|
305 |
|
public Mail buildMail(File file, VelocityContext context, String mailId) |
306 |
|
throws MailBuildException { |
307 |
0 |
if (mailId == null || "".equals(mailId)) { |
308 |
0 |
throw new IllegalArgumentException("¥á¡¼¥?ID¤¬»ØÄꤵ¤?¤Æ¤¤¤Þ¤»¤ó¡£"); |
309 |
|
} |
310 |
|
|
311 |
0 |
String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + mailId; |
312 |
|
|
313 |
|
String templateXmlText; |
314 |
0 |
if (!hasTemplateCache(cacheKey)) { |
315 |
|
Document doc; |
316 |
|
try { |
317 |
|
|
318 |
0 |
doc = getDocumentFromFile(file, false); |
319 |
0 |
} catch (SAXException e) { |
320 |
0 |
throw new MailBuildException("XML¤Î¥Ñ¡¼¥¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£" + e.getMessage(), e); |
321 |
0 |
} catch (IOException e) { |
322 |
0 |
throw new MailBuildException("XML¥Õ¥¡¥¤¥?¤ÎÆÉ¤ß¹?¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
323 |
|
} |
324 |
0 |
if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) { |
325 |
0 |
throw new MailBuildException("»ØÄꤵ¤?¤¿¥Õ¥¡¥¤¥?¤ÎXML¤Ï¥·¥ó¥°¥?¥á¡¼¥?¥Æ¥ó¥×¥?¡¼¥È¤Ç¤¹¡£[filePath='" |
326 |
0 |
+ file.getAbsolutePath() + "']"); |
327 |
|
} |
328 |
0 |
templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey); |
329 |
|
} else { |
330 |
0 |
templateXmlText = getTemplateCache(cacheKey); |
331 |
|
} |
332 |
|
|
333 |
|
try { |
334 |
0 |
return build(templateXmlText, context); |
335 |
0 |
} catch (Exception e) { |
336 |
0 |
throw new MailBuildException("¥á¡¼¥?¤ÎÀ¸À®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£", e); |
337 |
|
} |
338 |
|
} |
339 |
|
|
340 |
|
} |