1 package com.ozacc.mail.impl;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.StringReader;
7 import java.io.StringWriter;
8 import java.util.List;
9
10 import org.apache.velocity.VelocityContext;
11 import org.apache.velocity.app.Velocity;
12 import org.apache.velocity.exception.MethodInvocationException;
13 import org.apache.velocity.exception.ParseErrorException;
14 import org.apache.velocity.exception.ResourceNotFoundException;
15 import org.apache.velocity.runtime.log.LogSystem;
16 import org.jdom.Document;
17 import org.jdom.Element;
18 import org.jdom.JDOMException;
19 import org.jdom.input.SAXBuilder;
20 import org.jdom.output.XMLOutputter;
21
22 import com.ozacc.mail.Mail;
23 import com.ozacc.mail.MailBuildException;
24 import com.ozacc.mail.VelocityMailBuilder;
25
26 /***
27 * <a href="http://www.jdom.org/">JDOM</a>を利用してXMLファイ�?からMailインスタンスを生成す�?クラス。
28 * <p>
29 * ソースXMLを読み�?む際に、DTDバ�?デーションが実行さ�?ますので妥当なXMLデータ(Valid XML Document)でなけ�?ばいけません。
30 *
31 * TODO: ソースXMLからDocument生成�?はコメントを�?�?しないようにす�?。
32 *
33 * @since 1.0
34 * @author Tomohiro Otsuka
35 * @version $Id: JDomXMLMailBuilder.java,v 1.9 2004/09/21 11:54:54 otsuka Exp $
36 */
37 public class JDomXMLMailBuilder implements VelocityMailBuilder {
38
39 private LogSystem velocityLogSystem = new VelocityLogSystem();
40
41 /***
42 * コンストラクタ。
43 */
44 public JDomXMLMailBuilder() {}
45
46 /***
47 * 指定さ�?たクラスパス上のXMLファイ�?からMailインスタンスを生成します。
48 *
49 * @param classPath メー�?内容を記述したXMLファイ�?のパス
50 * @return 生成さ�?たMailインスタンス
51 * @throws MailBuildException Mailインスタンスの生成に失敗した�?�?
52 */
53 public Mail buildMail(String classPath) throws MailBuildException {
54 Document doc = getDocumentFromClassPath(classPath);
55 return build(doc);
56 }
57
58 /***
59 * 指定さ�?たクラスパス上のXMLファイ�?からMailインスタンスを生成します。
60 * 指定さ�?たVelocityContextを使って、XMLファイ�?の内容を動的に生成できます。
61 *
62 * @param classPath メー�?内容を記述したXMLファイ�?のパス
63 * @param context VelocityContext
64 * @return 生成さ�?たMailインスタンス
65 * @throws MailBuildException Mailインスタンスの生成に失敗した�?�?
66 */
67 public Mail buildMail(String classPath, VelocityContext context) throws MailBuildException {
68 Document doc = getDocumentFromClassPath(classPath);
69 try {
70 return build(doc, context);
71 } catch (Exception e) {
72 throw new MailBuildException("メー�?の生成に失敗しました。", e);
73 }
74 }
75
76 /***
77 * 指定さ�?たXMLファイ�?からMailインスタンスを生成します。
78 *
79 * @param file メー�?内容を記述したXMLファイ�?
80 * @return 生成さ�?たMailインスタンス
81 * @throws MailBuildException Mailインスタンスの生成に失敗した�?�?
82 */
83 public Mail buildMail(File file) throws MailBuildException {
84 Document doc = getDocumentFromFile(file);
85 return build(doc);
86 }
87
88 /***
89 * 指定さ�?たXMLファイ�?からMailインスタンスを生成します。
90 * 指定さ�?たVelocityContextを使って、XMLファイ�?の内容を動的に生成できます。
91 *
92 * @param file メー�?内容を記述したXMLファイ�?
93 * @param context VelocityContext
94 * @return 生成さ�?たMailインスタンス
95 * @throws MailBuildException Mailインスタンスの生成に失敗した�?�?
96 */
97 public Mail buildMail(File file, VelocityContext context) throws MailBuildException {
98 Document doc = getDocumentFromFile(file);
99 try {
100 return build(doc, context);
101 } catch (Exception e) {
102 throw new MailBuildException("メー�?の生成に失敗しました。", e);
103 }
104 }
105
106 /***
107 * 指定さ�?たクラスパス上のファイ�?を読み�?んで、XMLドキュメントを生成します。
108 *
109 * @param classPath
110 * @return JDOM Document
111 */
112 private Document getDocumentFromClassPath(String classPath) throws MailBuildException {
113 InputStream is = getClass().getResourceAsStream(classPath);
114 SAXBuilder builder = new SAXBuilder(true);
115 builder.setEntityResolver(new DTDEntityResolver());
116 Document doc;
117 try {
118 doc = builder.build(is);
119 is.close();
120 } catch (JDOMException e) {
121 throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
122 } catch (IOException e) {
123 throw new MailBuildException("XMLファイ�?の読み�?みに失敗しました。", e);
124 }
125 return doc;
126 }
127
128 /***
129 * 指定さ�?たファイ�?を読み�?んで、XMLドキュメントを生成します。
130 *
131 * @param file
132 * @return JDOM Document
133 */
134 private Document getDocumentFromFile(File file) {
135 SAXBuilder builder = new SAXBuilder(true);
136 builder.setEntityResolver(new DTDEntityResolver());
137 Document doc;
138 try {
139 doc = builder.build(file);
140 } catch (JDOMException e) {
141 throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
142 } catch (IOException e) {
143 throw new MailBuildException("XMLファイ�?の読み�?みに失敗しました。", e);
144 }
145 return doc;
146 }
147
148 /***
149 * XMLドキュメントからMailインスタンスを生成します。
150 *
151 * @param doc
152 * @return Mail
153 */
154 private Mail build(Document doc) {
155 Element root = doc.getRootElement();
156
157 Mail mail = new Mail();
158 setFrom(root, mail);
159 setRecipients(root, mail);
160 setSubject(root, mail);
161 setBody(root, mail);
162 setReplyTo(root, mail);
163 setReturnPath(root, mail);
164
165 setHtml(root, mail);
166
167 return mail;
168 }
169
170 /***
171 * VelocityContextとXMLドキュメントをマージさせ、Mailインスタンスを生成します。
172 *
173 * @param context
174 * @param doc
175 * @return Mail
176 *
177 * @throws Exception
178 * @throws ParseErrorException
179 * @throws MethodInvocationException
180 * @throws ResourceNotFoundException
181 * @throws IOException
182 * @throws JDOMException
183 */
184 private Mail build(Document doc, VelocityContext context) throws Exception,
185 ParseErrorException,
186 MethodInvocationException,
187 ResourceNotFoundException,
188 IOException, JDOMException {
189 XMLOutputter output = new XMLOutputter();
190 String xmlContent = output.outputString(doc);
191
192 Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem);
193 Velocity.init();
194 StringWriter w = new StringWriter();
195 Velocity.evaluate(context, w, "XML Mail Data", xmlContent);
196 StringReader reader = new StringReader(w.toString());
197
198 SAXBuilder builder = new SAXBuilder(true);
199 Document doc2 = builder.build(reader);
200
201 return build(doc2);
202 }
203
204 /***
205 * @param root
206 * @param mail
207 */
208 private void setReturnPath(Element root, Mail mail) {
209 Element returnPathElem = root.getChild("returnPath");
210 if (returnPathElem != null && returnPathElem.getAttributeValue("email") != null) {
211 mail.setReturnPath(returnPathElem.getAttributeValue("email"));
212 }
213 }
214
215 /***
216 * @param root
217 * @param mail
218 */
219 private void setReplyTo(Element root, Mail mail) {
220 Element replyToElem = root.getChild("replyTo");
221 if (replyToElem != null && replyToElem.getAttributeValue("email") != null) {
222 mail.setReplyTo(replyToElem.getAttributeValue("email"));
223 }
224 }
225
226 /***
227 * @param root
228 * @param mail
229 */
230 private void setBody(Element root, Mail mail) {
231 Element bodyElem = root.getChild("body");
232 if (bodyElem != null) {
233 mail.setText(bodyElem.getTextTrim());
234 }
235 }
236
237 /***
238 * @param root
239 * @param mail
240 */
241 private void setHtml(Element root, Mail mail) {
242 Element htmlElem = root.getChild("html");
243 if (htmlElem != null) {
244 mail.setHtmlText(htmlElem.getTextTrim());
245 }
246 }
247
248 /***
249 * @param root
250 * @param mail
251 */
252 private void setSubject(Element root, Mail mail) {
253 Element subjectElem = root.getChild("subject");
254 if (subjectElem != null) {
255 mail.setSubject(subjectElem.getTextTrim());
256 }
257 }
258
259 /***
260 * @param root
261 * @param mail
262 */
263 private void setRecipients(Element root, Mail mail) {
264 Element recipientsElem = root.getChild("recipients");
265 if (recipientsElem == null) {
266 return;
267 }
268
269 List recipientElemList = recipientsElem.getChildren();
270 for (int i = 0, max = recipientElemList.size(); i < max; i++) {
271 Element e = (Element)recipientElemList.get(i);
272 if ("to".equals(e.getName())) {
273 if (e.getAttributeValue("email") != null) {
274 if (e.getAttributeValue("name") != null) {
275 mail.addTo(e.getAttributeValue("email"), e.getAttributeValue("name"));
276 } else {
277 mail.addTo(e.getAttributeValue("email"));
278 }
279 }
280 } else if ("cc".equals(e.getName())) {
281 if (e.getAttributeValue("email") != null) {
282 if (e.getAttributeValue("name") != null) {
283 mail.addCc(e.getAttributeValue("email"), e.getAttributeValue("name"));
284 } else {
285 mail.addCc(e.getAttributeValue("email"));
286 }
287 }
288 } else {
289 if (e.getAttributeValue("email") != null) {
290 mail.addBcc(e.getAttributeValue("email"));
291 }
292 }
293 }
294 }
295
296 /***
297 * @param root
298 * @param mail
299 */
300 private void setFrom(Element root, Mail mail) {
301 Element fromElem = root.getChild("from");
302 if (fromElem != null && fromElem.getAttributeValue("email") != null) {
303 if (fromElem.getAttributeValue("name") != null) {
304 mail.setFrom(fromElem.getAttributeValue("email"), fromElem
305 .getAttributeValue("name"));
306 } else {
307 mail.setFrom(fromElem.getAttributeValue("email"));
308 }
309 }
310 }
311
312 }