1 package com.ozacc.mail.xml.impl;
2
3 import java.io.File;
4 import java.util.Properties;
5
6 import javax.mail.internet.InternetAddress;
7 import javax.xml.parsers.DocumentBuilder;
8 import javax.xml.parsers.DocumentBuilderFactory;
9 import javax.xml.parsers.ParserConfigurationException;
10 import javax.xml.transform.OutputKeys;
11 import javax.xml.transform.Transformer;
12 import javax.xml.transform.TransformerException;
13 import javax.xml.transform.TransformerFactory;
14 import javax.xml.transform.dom.DOMSource;
15 import javax.xml.transform.stream.StreamResult;
16
17 import org.w3c.dom.DOMImplementation;
18 import org.w3c.dom.Document;
19 import org.w3c.dom.DocumentType;
20 import org.w3c.dom.Element;
21
22 import com.ozacc.mail.Mail;
23 import com.ozacc.mail.xml.XMLBuildException;
24 import com.ozacc.mail.xml.XMLBuilder;
25
26 /***
27 * JDK 1.4以降の標準XMLライブラリを使用して実装さ�?たXMLBuilder。
28 *
29 * @author Tomohiro Otsuka
30 * @version $Id: XMLBuilderImpl.java,v 1.2 2004/09/10 07:35:22 otsuka Exp $
31 */
32 public class XMLBuilderImpl implements XMLBuilder {
33
34 public static final String DOCTYPE_PUBLIC = "-//OZACC//DTD MAIL//EN";
35
36 public static final String DOCTYPE_SYSTEM = "http://www.ozacc.com/library/dtd/ozacc-mail.dtd";
37
38 private String charset = "UTF-8";
39
40 /***
41 * コンストラクタ。
42 */
43 public XMLBuilderImpl() {}
44
45 /***
46 * コンストラクタ。
47 * 出力XMLファイ�?の文字コードを指定します。デフォ�?トはUTF-8。
48 *
49 * @param charset 出力XMLファイ�?の文字コード
50 */
51 public XMLBuilderImpl(String charset) {
52 super();
53 this.charset = charset;
54 }
55
56 /***
57 * 出力XMLファイ�?の文字コードを返します。
58 *
59 * @return 出力XMLファイ�?の文字コード
60 */
61 public String getCharset() {
62 return charset;
63 }
64
65 /***
66 * 出力XMLファイ�?の文字コードを指定します。デフォ�?トはUTF-8。
67 *
68 * @param charset 出力XMLファイ�?の文字コード
69 */
70 public void setCharset(String charset) {
71 this.charset = charset;
72 }
73
74 /***
75 * @see com.ozacc.mail.xml.XMLBuilder#buildDocument(com.ozacc.mail.Mail)
76 */
77 public Document buildDocument(Mail mail) throws XMLBuildException {
78 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
79 DocumentBuilder db;
80 try {
81 db = dbf.newDocumentBuilder();
82 } catch (ParserConfigurationException e) {
83
84 throw new XMLBuildException(e.getMessage());
85 }
86 Document doc = db.newDocument();
87
88 DOMImplementation domImpl = doc.getImplementation();
89 DocumentType docType = domImpl.createDocumentType("mail", DOCTYPE_PUBLIC, DOCTYPE_SYSTEM);
90 doc.appendChild(docType);
91
92 Element mailElem = doc.createElement("mail");
93
94
95 if (mail.getReturnPath() != null) {
96 InternetAddress returnPath = mail.getReturnPath();
97 Element returnPathElem = convertInternetAddressIntoElement(returnPath, "returnPath",
98 doc);
99 mailElem.appendChild(returnPathElem);
100 }
101
102
103 if (mail.getFrom() != null) {
104 InternetAddress from = mail.getFrom();
105 Element fromElem = convertInternetAddressIntoElement(from, "from", doc);
106 mailElem.appendChild(fromElem);
107 }
108
109 if (mail.getTo().length > 0 || mail.getCc().length > 0 || mail.getBcc().length > 0) {
110 Element recipientsElem = doc.createElement("recipients");
111
112
113 if (mail.getTo().length > 0) {
114 for (int i = 0; i < mail.getTo().length; i++) {
115 InternetAddress to = mail.getTo()[i];
116 Element toElem = convertInternetAddressIntoElement(to, "to", doc);
117 recipientsElem.appendChild(toElem);
118 }
119 }
120
121 if (mail.getCc().length > 0) {
122 for (int i = 0; i < mail.getCc().length; i++) {
123 InternetAddress cc = mail.getCc()[i];
124 Element ccElem = convertInternetAddressIntoElement(cc, "cc", doc);
125 recipientsElem.appendChild(ccElem);
126 }
127 }
128
129 if (mail.getBcc().length > 0) {
130 for (int i = 0; i < mail.getBcc().length; i++) {
131 InternetAddress bcc = mail.getBcc()[i];
132 Element bccElem = convertInternetAddressIntoElement(bcc, "bcc", doc);
133 recipientsElem.appendChild(bccElem);
134 }
135 }
136 mailElem.appendChild(recipientsElem);
137 }
138
139
140 if (mail.getReplyTo() != null) {
141 InternetAddress replyTo = mail.getReplyTo();
142 Element replyToElem = convertInternetAddressIntoElement(replyTo, "replyTo", doc);
143 mailElem.appendChild(replyToElem);
144 }
145
146
147 if (mail.getSubject() != null) {
148 Element subjectElem = doc.createElement("subject");
149 subjectElem.appendChild(doc.createTextNode(mail.getSubject()));
150 mailElem.appendChild(subjectElem);
151 }
152
153
154 if (mail.getText() != null) {
155 Element bodyElem = doc.createElement("body");
156 bodyElem.appendChild(doc.createTextNode(mail.getText()));
157 mailElem.appendChild(bodyElem);
158 }
159
160 doc.appendChild(mailElem);
161
162 return doc;
163 }
164
165 private Element convertInternetAddressIntoElement(InternetAddress address, String elemName,
166 Document doc) {
167 Element element = doc.createElement(elemName);
168 element.setAttribute("email", address.getAddress());
169 if (address.getPersonal() != null) {
170 element.setAttribute("name", address.getPersonal());
171 }
172 return element;
173 }
174
175 /***
176 * 指定さ�?たMailインスタンスからXMLドキュメントを生成し、
177 * 指定さ�?たファイ�?に保存します。
178 *
179 * このメソッド内部で使用さ�?�?TransformerFactoryがス�?ッドセーフではないため、synchronzedメソッドになっています。
180 *
181 * @see com.ozacc.mail.xml.XMLBuilder#saveDocument(com.ozacc.mail.Mail, java.io.File)
182 * @see TransformerFactory
183 */
184 public synchronized void saveDocument(Mail mail, File destFile) throws XMLBuildException {
185 Document doc = buildDocument(mail);
186
187 Transformer t;
188 try {
189 t = TransformerFactory.newInstance().newTransformer();
190 } catch (Exception e) {
191
192 throw new XMLBuildException(e.getMessage());
193 }
194 t.setOutputProperties(getOutputProperties());
195
196 DOMSource source = new DOMSource(doc);
197 StreamResult result = new StreamResult(destFile);
198 try {
199 t.transform(source, result);
200 } catch (TransformerException e) {
201 throw new XMLBuildException("XMLファイ�?の保存に失敗しました。", e);
202 }
203 }
204
205 /***
206 * 出力プ��叢ティを生成。
207 * @return 出力プ��叢ティを設定したPropertiesインスタンス
208 */
209 private Properties getOutputProperties() {
210 Properties p = new Properties();
211 p.put(OutputKeys.ENCODING, charset);
212 p.put(OutputKeys.INDENT, "yes");
213 p.put(OutputKeys.DOCTYPE_PUBLIC, DOCTYPE_PUBLIC);
214 p.put(OutputKeys.DOCTYPE_SYSTEM, DOCTYPE_SYSTEM);
215 return p;
216 }
217
218 }