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.8 2004/09/17 23:07:16 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 Document doc;
116 try {
117 doc = builder.build(is);
118 is.close();
119 } catch (JDOMException e) {
120 throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
121 } catch (IOException e) {
122 throw new MailBuildException("XMLファイ�?の読み�?みに失敗しました。", e);
123 }
124 return doc;
125 }
126
127 /***
128 * 指定さ�?たファイ�?を読み�?んで、XMLドキュメントを生成します。
129 *
130 * @param file
131 * @return JDOM Document
132 */
133 private Document getDocumentFromFile(File file) {
134 SAXBuilder builder = new SAXBuilder(true);
135 Document doc;
136 try {
137 doc = builder.build(file);
138 } catch (JDOMException e) {
139 throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
140 } catch (IOException e) {
141 throw new MailBuildException("XMLファイ�?の読み�?みに失敗しました。", e);
142 }
143 return doc;
144 }
145
146 /***
147 * XMLドキュメントからMailインスタンスを生成します。
148 *
149 * @param doc
150 * @return Mail
151 */
152 private Mail build(Document doc) {
153 Element root = doc.getRootElement();
154
155 Mail mail = new Mail();
156 setFrom(root, mail);
157 setRecipients(root, mail);
158 setSubject(root, mail);
159 setBody(root, mail);
160 setReplyTo(root, mail);
161 setReturnPath(root, mail);
162
163 setHtml(root, mail);
164
165 return mail;
166 }
167
168 /***
169 * VelocityContextとXMLドキュメントをマージさせ、Mailインスタンスを生成します。
170 *
171 * @param context
172 * @param doc
173 * @return Mail
174 *
175 * @throws Exception
176 * @throws ParseErrorException
177 * @throws MethodInvocationException
178 * @throws ResourceNotFoundException
179 * @throws IOException
180 * @throws JDOMException
181 */
182 private Mail build(Document doc, VelocityContext context) throws Exception,
183 ParseErrorException,
184 MethodInvocationException,
185 ResourceNotFoundException,
186 IOException, JDOMException {
187 XMLOutputter output = new XMLOutputter();
188 String xmlContent = output.outputString(doc);
189
190 Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem);
191 Velocity.init();
192 StringWriter w = new StringWriter();
193 Velocity.evaluate(context, w, "XML Mail Data", xmlContent);
194 StringReader reader = new StringReader(w.toString());
195
196 SAXBuilder builder = new SAXBuilder(true);
197 Document doc2 = builder.build(reader);
198
199 return build(doc2);
200 }
201
202 /***
203 * @param root
204 * @param mail
205 */
206 private void setReturnPath(Element root, Mail mail) {
207 Element returnPathElem = root.getChild("returnPath");
208 if (returnPathElem != null && returnPathElem.getAttributeValue("email") != null) {
209 mail.setReturnPath(returnPathElem.getAttributeValue("email"));
210 }
211 }
212
213 /***
214 * @param root
215 * @param mail
216 */
217 private void setReplyTo(Element root, Mail mail) {
218 Element replyToElem = root.getChild("replyTo");
219 if (replyToElem != null && replyToElem.getAttributeValue("email") != null) {
220 mail.setReplyTo(replyToElem.getAttributeValue("email"));
221 }
222 }
223
224 /***
225 * @param root
226 * @param mail
227 */
228 private void setBody(Element root, Mail mail) {
229 Element bodyElem = root.getChild("body");
230 if (bodyElem != null) {
231 mail.setText(bodyElem.getTextTrim());
232 }
233 }
234
235 /***
236 * @param root
237 * @param mail
238 */
239 private void setHtml(Element root, Mail mail) {
240 Element htmlElem = root.getChild("html");
241 if (htmlElem != null) {
242 mail.setHtmlText(htmlElem.getTextTrim());
243 }
244 }
245
246 /***
247 * @param root
248 * @param mail
249 */
250 private void setSubject(Element root, Mail mail) {
251 Element subjectElem = root.getChild("subject");
252 if (subjectElem != null) {
253 mail.setSubject(subjectElem.getTextTrim());
254 }
255 }
256
257 /***
258 * @param root
259 * @param mail
260 */
261 private void setRecipients(Element root, Mail mail) {
262 Element recipientsElem = root.getChild("recipients");
263 if (recipientsElem == null) {
264 return;
265 }
266
267 List recipientElemList = recipientsElem.getChildren();
268 for (int i = 0, max = recipientElemList.size(); i < max; i++) {
269 Element e = (Element)recipientElemList.get(i);
270 if ("to".equals(e.getName())) {
271 if (e.getAttributeValue("email") != null) {
272 if (e.getAttributeValue("name") != null) {
273 mail.addTo(e.getAttributeValue("email"), e.getAttributeValue("name"));
274 } else {
275 mail.addTo(e.getAttributeValue("email"));
276 }
277 }
278 } else if ("cc".equals(e.getName())) {
279 if (e.getAttributeValue("email") != null) {
280 if (e.getAttributeValue("name") != null) {
281 mail.addCc(e.getAttributeValue("email"), e.getAttributeValue("name"));
282 } else {
283 mail.addCc(e.getAttributeValue("email"));
284 }
285 }
286 } else {
287 if (e.getAttributeValue("email") != null) {
288 mail.addBcc(e.getAttributeValue("email"));
289 }
290 }
291 }
292 }
293
294 /***
295 * @param root
296 * @param mail
297 */
298 private void setFrom(Element root, Mail mail) {
299 Element fromElem = root.getChild("from");
300 if (fromElem != null && fromElem.getAttributeValue("email") != null) {
301 if (fromElem.getAttributeValue("name") != null) {
302 mail.setFrom(fromElem.getAttributeValue("email"), fromElem
303 .getAttributeValue("name"));
304 } else {
305 mail.setFrom(fromElem.getAttributeValue("email"));
306 }
307 }
308 }
309
310 }