View Javadoc

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