-package com.ozacc.mail.impl;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.StringReader;\r
-import java.io.StringWriter;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.apache.commons.logging.Log;\r
-import org.apache.commons.logging.LogFactory;\r
-import org.apache.velocity.VelocityContext;\r
-import org.apache.velocity.app.Velocity;\r
-import org.apache.velocity.exception.MethodInvocationException;\r
-import org.apache.velocity.exception.ParseErrorException;\r
-import org.apache.velocity.exception.ResourceNotFoundException;\r
-import org.apache.velocity.runtime.log.LogSystem;\r
-import org.jdom.Document;\r
-import org.jdom.Element;\r
-import org.jdom.JDOMException;\r
-import org.jdom.input.SAXBuilder;\r
-import org.jdom.output.XMLOutputter;\r
-\r
-import com.ozacc.mail.Mail;\r
-import com.ozacc.mail.MailBuildException;\r
-import com.ozacc.mail.MultipleMailBuilder;\r
-import com.ozacc.mail.VelocityMultipleMailBuilder;\r
-\r
-/**\r
- * <a href="http://www.jdom.org/">JDOM</a>を利用してXMLファイルからMailインスタンスを生成するクラス。\r
- * <p>\r
- * ソースXMLを読み込む際に、DTDバリデーションが実行されますので妥当なXMLデータ(Valid XML Document)でなければいけません。\r
- * \r
- * @since 1.0\r
- * \r
- * @author Tomohiro Otsuka\r
- * @version $Id: JDomXMLMailBuilder.java,v 1.10.2.5 2005/02/01 20:37:49 otsuka Exp $\r
- */\r
-public class JDomXMLMailBuilder implements MultipleMailBuilder, VelocityMultipleMailBuilder {\r
-\r
- private static Log log = LogFactory.getLog(JDomXMLMailBuilder.class);\r
-\r
- private static String CACHE_KEY_SEPARATOR = "#";\r
-\r
- private static String DEFAULT_MAIL_ID = "DEFAULT";\r
-\r
- protected LogSystem velocityLogSystem = new VelocityLogSystem();\r
-\r
- private boolean cacheEnabled = false;\r
-\r
- protected Map templateCache = new HashMap();\r
-\r
- /**\r
- * コンストラクタ。\r
- */\r
- public JDomXMLMailBuilder() {}\r
-\r
- /**\r
- * 指定されたクラスパス上のXMLファイルからMailインスタンスを生成します。\r
- * \r
- * @param classPath メール内容を記述したXMLファイルのパス\r
- * @return 生成されたMailインスタンス\r
- * @throws MailBuildException Mailインスタンスの生成に失敗した場合\r
- */\r
- public Mail buildMail(String classPath) throws MailBuildException {\r
- Document doc = getDocumentFromClassPath(classPath);\r
- return build(doc.getRootElement());\r
- }\r
-\r
- /**\r
- * 指定されたクラスパス上のXMLファイルからMailインスタンスを生成します。\r
- * 指定されたVelocityContextを使って、XMLファイルの内容を動的に生成できます。\r
- * \r
- * @param classPath メール内容を記述したXMLファイルのパス\r
- * @param context VelocityContext\r
- * @return 生成されたMailインスタンス\r
- * @throws MailBuildException Mailインスタンスの生成に失敗した場合\r
- */\r
- public Mail buildMail(String classPath, VelocityContext context) throws MailBuildException {\r
- String cacheKey = classPath + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;\r
- String templateXmlText;\r
- if (!hasTemplateCache(cacheKey)) {\r
- Document doc = getDocumentFromClassPath(classPath);\r
- templateXmlText = cacheTemplateText(doc, cacheKey);\r
- } else {\r
- templateXmlText = getTemplateCache(cacheKey);\r
- }\r
- try {\r
- return build(templateXmlText, context);\r
- } catch (Exception e) {\r
- throw new MailBuildException("メールの生成に失敗しました。", e);\r
- }\r
- }\r
-\r
- /**\r
- * 指定されたXMLファイルからMailインスタンスを生成します。\r
- * \r
- * @param file メール内容を記述したXMLファイル\r
- * @return 生成されたMailインスタンス\r
- * @throws MailBuildException Mailインスタンスの生成に失敗した場合\r
- */\r
- public Mail buildMail(File file) throws MailBuildException {\r
- Document doc = getDocumentFromFile(file);\r
- return build(doc.getRootElement());\r
- }\r
-\r
- /**\r
- * 指定されたXMLファイルからMailインスタンスを生成します。\r
- * 指定されたVelocityContextを使って、XMLファイルの内容を動的に生成できます。\r
- * \r
- * @param file メール内容を記述したXMLファイル\r
- * @param context VelocityContext\r
- * @return 生成されたMailインスタンス\r
- * @throws MailBuildException Mailインスタンスの生成に失敗した場合\r
- */\r
- public Mail buildMail(File file, VelocityContext context) throws MailBuildException {\r
- String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;\r
- String templateXmlText;\r
- if (!hasTemplateCache(cacheKey)) {\r
- Document doc = getDocumentFromFile(file);\r
- templateXmlText = cacheTemplateText(doc, cacheKey);\r
- } else {\r
- templateXmlText = getTemplateCache(cacheKey);\r
- }\r
- try {\r
- return build(templateXmlText, context);\r
- } catch (Exception e) {\r
- throw new MailBuildException("メールの生成に失敗しました。", e);\r
- }\r
- }\r
-\r
- private String cacheTemplateText(Document doc, String cacheKey) {\r
- XMLOutputter output = new XMLOutputter();\r
- String templateXmlText = "<!DOCTYPE mail PUBLIC \"" + Mail.DOCTYPE_PUBLIC + "\" \""\r
- + Mail.DOCTYPE_SYSTEM + "\">\n" + output.outputString(doc.getRootElement());\r
- log.debug("以下のXMLデータをキャッシュします。\n" + templateXmlText);\r
- putTemplateCache(cacheKey, templateXmlText);\r
- return templateXmlText;\r
- }\r
-\r
- /**\r
- * 指定されたクラスパス上のファイルを読み込んで、XMLドキュメントを生成します。\r
- * \r
- * @param classPath\r
- * @return JDOM Document\r
- */\r
- protected Document getDocumentFromClassPath(String classPath) throws MailBuildException {\r
- InputStream is = getClass().getResourceAsStream(classPath);\r
- SAXBuilder builder = new SAXBuilder(true);\r
- builder.setEntityResolver(new DTDEntityResolver());\r
- Document doc;\r
- try {\r
- doc = builder.build(is);\r
- } catch (JDOMException e) {\r
- throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
- } catch (IOException e) {\r
- throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
- } finally {\r
- if (is != null) {\r
- try {\r
- is.close();\r
- } catch (IOException e) {\r
- // ignore\r
- }\r
- }\r
- }\r
- return doc;\r
- }\r
-\r
- /**\r
- * 指定されたファイルを読み込んで、XMLドキュメントを生成します。\r
- * \r
- * @param file\r
- * @return JDOM Document\r
- */\r
- protected Document getDocumentFromFile(File file) {\r
- SAXBuilder builder = new SAXBuilder(true);\r
- builder.setEntityResolver(new DTDEntityResolver());\r
- Document doc;\r
- try {\r
- doc = builder.build(file);\r
- } catch (JDOMException e) {\r
- throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
- } catch (IOException e) {\r
- throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
- }\r
- return doc;\r
- }\r
-\r
- /**\r
- * XMLのmailルートエレメントからMailインスタンスを生成します。\r
- * \r
- * @param mailElement mail要素を示すElementインスタンス\r
- * @return Mail 生成されたMail\r
- */\r
- protected Mail build(Element mailElement) {\r
- Mail mail = new Mail();\r
- setFrom(mailElement, mail);\r
- setRecipients(mailElement, mail);\r
- setSubject(mailElement, mail);\r
- setBody(mailElement, mail);\r
- setReplyTo(mailElement, mail);\r
- setReturnPath(mailElement, mail);\r
-\r
- setHtml(mailElement, mail);\r
-\r
- return mail;\r
- }\r
-\r
- /**\r
- * VelocityContextとXMLテンプレートをマージさせ、Mailインスタンスを生成します。\r
- * \r
- * @param templateText マージするXMLテンプレートの文字列\r
- * @param context マージするVelocityContext\r
- * @return Mail\r
- * \r
- * @throws Exception\r
- * @throws ParseErrorException\r
- * @throws MethodInvocationException\r
- * @throws ResourceNotFoundException\r
- * @throws IOException\r
- * @throws JDOMException \r
- */\r
- protected Mail build(String templateText, VelocityContext context) throws Exception,\r
- ParseErrorException,\r
- MethodInvocationException,\r
- ResourceNotFoundException,\r
- IOException, JDOMException {\r
- if (log.isDebugEnabled()) {\r
- log.debug("ソースXMLデータ\n" + templateText);\r
- }\r
-\r
- Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem);\r
- Velocity.init();\r
- StringWriter w = new StringWriter();\r
- Velocity.evaluate(context, w, "XML Mail Data", templateText);\r
-\r
- if (log.isDebugEnabled()) {\r
- log.debug("VelocityContextとマージ後のXMLデータ\n" + w.toString());\r
- }\r
-\r
- StringReader reader = new StringReader(w.toString());\r
- SAXBuilder builder = new SAXBuilder(true);\r
- builder.setEntityResolver(new DTDEntityResolver());\r
- Document mergedDoc = builder.build(reader);\r
-\r
- return build(mergedDoc.getRootElement());\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setReturnPath(Element root, Mail mail) {\r
- Element returnPathElem = root.getChild("returnPath");\r
- if (returnPathElem != null && returnPathElem.getAttributeValue("email") != null) {\r
- mail.setReturnPath(returnPathElem.getAttributeValue("email"));\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setReplyTo(Element root, Mail mail) {\r
- Element replyToElem = root.getChild("replyTo");\r
- if (replyToElem != null && replyToElem.getAttributeValue("email") != null) {\r
- mail.setReplyTo(replyToElem.getAttributeValue("email"));\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setBody(Element root, Mail mail) {\r
- Element bodyElem = root.getChild("body");\r
- if (bodyElem != null) {\r
- mail.setText(bodyElem.getTextTrim());\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail\r
- */\r
- protected void setHtml(Element root, Mail mail) {\r
- Element htmlElem = root.getChild("html");\r
- if (htmlElem != null) {\r
- mail.setHtmlText(htmlElem.getTextTrim());\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setSubject(Element root, Mail mail) {\r
- Element subjectElem = root.getChild("subject");\r
- if (subjectElem != null) {\r
- mail.setSubject(subjectElem.getTextTrim());\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setRecipients(Element root, Mail mail) {\r
- Element recipientsElem = root.getChild("recipients");\r
- if (recipientsElem == null) {\r
- return;\r
- }\r
-\r
- List recipientElemList = recipientsElem.getChildren();\r
- for (int i = 0, max = recipientElemList.size(); i < max; i++) {\r
- Element e = (Element)recipientElemList.get(i);\r
- if ("to".equals(e.getName())) { // to\r
- if (e.getAttributeValue("email") != null) {\r
- if (e.getAttributeValue("name") != null) {\r
- mail.addTo(e.getAttributeValue("email"), e.getAttributeValue("name"));\r
- } else {\r
- mail.addTo(e.getAttributeValue("email"));\r
- }\r
- }\r
- } else if ("cc".equals(e.getName())) { // cc\r
- if (e.getAttributeValue("email") != null) {\r
- if (e.getAttributeValue("name") != null) {\r
- mail.addCc(e.getAttributeValue("email"), e.getAttributeValue("name"));\r
- } else {\r
- mail.addCc(e.getAttributeValue("email"));\r
- }\r
- }\r
- } else {\r
- if (e.getAttributeValue("email") != null) { // bcc\r
- mail.addBcc(e.getAttributeValue("email"));\r
- }\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * @param root\r
- * @param mail \r
- */\r
- protected void setFrom(Element root, Mail mail) {\r
- Element fromElem = root.getChild("from");\r
- if (fromElem != null && fromElem.getAttributeValue("email") != null) {\r
- if (fromElem.getAttributeValue("name") != null) {\r
- mail.setFrom(fromElem.getAttributeValue("email"), fromElem\r
- .getAttributeValue("name"));\r
- } else {\r
- mail.setFrom(fromElem.getAttributeValue("email"));\r
- }\r
- }\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.VelocityMailBuilder#clearCache()\r
- */\r
- public synchronized void clearCache() {\r
- log.debug("テンプレートキャッシュをクリアします。");\r
- templateCache.clear();\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.VelocityMailBuilder#isCacheEnabled()\r
- */\r
- public boolean isCacheEnabled() {\r
- return cacheEnabled;\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.VelocityMailBuilder#setCacheEnabled(boolean)\r
- */\r
- public void setCacheEnabled(boolean cacheEnabled) {\r
- if (!cacheEnabled) {\r
- clearCache();\r
- }\r
- this.cacheEnabled = cacheEnabled;\r
- }\r
-\r
- protected boolean hasTemplateCache(String key) {\r
- if (cacheEnabled) {\r
- return templateCache.containsKey(key);\r
- }\r
- return false;\r
- }\r
-\r
- protected void putTemplateCache(String key, String templateXmlText) {\r
- if (cacheEnabled) {\r
- log.debug("テンプレートをキャッシュします。[key='" + key + "']");\r
- templateCache.put(key, templateXmlText);\r
- }\r
- }\r
-\r
- protected String getTemplateCache(String key) {\r
- if (hasTemplateCache(key)) {\r
- log.debug("テンプレートキャッシュを返します。[key='" + key + "']");\r
- return (String)templateCache.get(key);\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.VelocityMultipleMailBuilder#buildMail(java.lang.String, org.apache.velocity.VelocityContext, java.lang.String)\r
- */\r
- public Mail buildMail(String classPath, VelocityContext context, String mailId)\r
- throws MailBuildException {\r
- if (mailId == null || "".equals(mailId)) {\r
- throw new IllegalArgumentException("メールIDが指定されていません。");\r
- }\r
-\r
- String cacheKey = classPath + CACHE_KEY_SEPARATOR + mailId;\r
- String templateXmlText;\r
- if (!hasTemplateCache(cacheKey)) {\r
- Document doc = getDocumentFromClassPath(classPath);\r
- templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);\r
- } else {\r
- templateXmlText = getTemplateCache(cacheKey);\r
- }\r
- try {\r
- return build(templateXmlText, context);\r
- } catch (Exception e) {\r
- throw new MailBuildException("メールの生成に失敗しました。", e);\r
- }\r
- }\r
-\r
- private String getAndCacheTemplateText(Document doc, String mailId, String cacheKey)\r
- throws MailBuildException {\r
- Element mailElem = getElementById(doc, mailId);\r
- XMLOutputter output = new XMLOutputter();\r
- String templateXmlText = output.outputString(mailElem);\r
-\r
- putTemplateCache(cacheKey, templateXmlText);\r
- return templateXmlText;\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.VelocityMultipleMailBuilder#buildMail(java.io.File, org.apache.velocity.VelocityContext, java.lang.String)\r
- */\r
- public Mail buildMail(File file, VelocityContext context, String mailId)\r
- throws MailBuildException {\r
- if (mailId == null || "".equals(mailId)) {\r
- throw new IllegalArgumentException("メールIDが指定されていません。");\r
- }\r
-\r
- String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + mailId;\r
- String templateXmlText;\r
- if (!hasTemplateCache(cacheKey)) {\r
- Document doc = getDocumentFromFile(file);\r
- templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);\r
- } else {\r
- templateXmlText = getTemplateCache(cacheKey);\r
- }\r
- try {\r
- return build(templateXmlText, context);\r
- } catch (Exception e) {\r
- throw new MailBuildException("メールの生成に失敗しました。", e);\r
- }\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.MultipleMailBuilder#buildMail(java.lang.String, java.lang.String)\r
- */\r
- public Mail buildMail(String classPath, String mailId) throws MailBuildException {\r
- Document doc = getDocumentFromClassPath(classPath);\r
- Element mailElem = getElementById(doc, mailId);\r
- return build(mailElem);\r
- }\r
-\r
- /**\r
- * @see com.ozacc.mail.MultipleMailBuilder#buildMail(java.io.File, java.lang.String)\r
- */\r
- public Mail buildMail(File file, String mailId) throws MailBuildException {\r
- Document doc = getDocumentFromFile(file);\r
- Element mailElem = getElementById(doc, mailId);\r
- return build(mailElem);\r
- }\r
-\r
- /**\r
- * 指定されたXMLドキュメントの中から、指定されたid属性がセットされている要素を取得します。\r
- * \r
- * @param doc XMLドキュメント\r
- * @param id 抽出する要素のid属性値\r
- * @return XMLドキュメントで見つかったid属性を持つ要素\r
- */\r
- private Element getElementById(Document doc, String id) {\r
- Element mailsElem = doc.getRootElement(); // <mails>\r
- List mailElemList = mailsElem.getChildren("mail");\r
- for (Iterator itr = mailElemList.iterator(); itr.hasNext();) {\r
- Element mailElem = (Element)itr.next();\r
- String mailId = mailElem.getAttributeValue("id");\r
- if (mailId.equals(id)) {\r
- return mailElem;\r
- }\r
- }\r
- throw new MailBuildException("指定されたID[" + id + "]のメールデータは見つかりませんでした。");\r
- }\r
-\r
+package com.ozacc.mail.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.log.LogSystem;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+import com.ozacc.mail.Mail;
+import com.ozacc.mail.MailBuildException;
+import com.ozacc.mail.MultipleMailBuilder;
+import com.ozacc.mail.VelocityMultipleMailBuilder;
+
+/**
+ * <a href="http://www.jdom.org/">JDOM</a>を利用してXMLファイルからMailインスタンスを生成するクラス。
+ * <p>
+ * ソースXMLを読み込む際に、DTDバリデーションが実行されますので妥当なXMLデータ(Valid XML Document)でなければいけません。
+ *
+ * @since 1.0
+ *
+ * @author Tomohiro Otsuka
+ * @version $Id: JDomXMLMailBuilder.java,v 1.10.2.5 2005/02/01 20:37:49 otsuka Exp $
+ */
+public class JDomXMLMailBuilder implements MultipleMailBuilder, VelocityMultipleMailBuilder {
+
+ private static Log log = LogFactory.getLog(JDomXMLMailBuilder.class);
+
+ private static String CACHE_KEY_SEPARATOR = "#";
+
+ private static String DEFAULT_MAIL_ID = "DEFAULT";
+
+ protected LogSystem velocityLogSystem = new VelocityLogSystem();
+
+ private boolean cacheEnabled = false;
+
+ protected Map templateCache = new HashMap();
+
+ /**
+ * コンストラクタ。
+ */
+ public JDomXMLMailBuilder() {}
+
+ /**
+ * 指定されたクラスパス上のXMLファイルからMailインスタンスを生成します。
+ *
+ * @param classPath メール内容を記述したXMLファイルのパス
+ * @return 生成されたMailインスタンス
+ * @throws MailBuildException Mailインスタンスの生成に失敗した場合
+ */
+ public Mail buildMail(String classPath) throws MailBuildException {
+ Document doc = getDocumentFromClassPath(classPath);
+ return build(doc.getRootElement());
+ }
+
+ /**
+ * 指定されたクラスパス上のXMLファイルからMailインスタンスを生成します。
+ * 指定されたVelocityContextを使って、XMLファイルの内容を動的に生成できます。
+ *
+ * @param classPath メール内容を記述したXMLファイルのパス
+ * @param context VelocityContext
+ * @return 生成されたMailインスタンス
+ * @throws MailBuildException Mailインスタンスの生成に失敗した場合
+ */
+ public Mail buildMail(String classPath, VelocityContext context) throws MailBuildException {
+ String cacheKey = classPath + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;
+ String templateXmlText;
+ if (!hasTemplateCache(cacheKey)) {
+ Document doc = getDocumentFromClassPath(classPath);
+ templateXmlText = cacheTemplateText(doc, cacheKey);
+ } else {
+ templateXmlText = getTemplateCache(cacheKey);
+ }
+ try {
+ return build(templateXmlText, context);
+ } catch (Exception e) {
+ throw new MailBuildException("メールの生成に失敗しました。", e);
+ }
+ }
+
+ /**
+ * 指定されたXMLファイルからMailインスタンスを生成します。
+ *
+ * @param file メール内容を記述したXMLファイル
+ * @return 生成されたMailインスタンス
+ * @throws MailBuildException Mailインスタンスの生成に失敗した場合
+ */
+ public Mail buildMail(File file) throws MailBuildException {
+ Document doc = getDocumentFromFile(file);
+ return build(doc.getRootElement());
+ }
+
+ /**
+ * 指定されたXMLファイルからMailインスタンスを生成します。
+ * 指定されたVelocityContextを使って、XMLファイルの内容を動的に生成できます。
+ *
+ * @param file メール内容を記述したXMLファイル
+ * @param context VelocityContext
+ * @return 生成されたMailインスタンス
+ * @throws MailBuildException Mailインスタンスの生成に失敗した場合
+ */
+ public Mail buildMail(File file, VelocityContext context) throws MailBuildException {
+ String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;
+ String templateXmlText;
+ if (!hasTemplateCache(cacheKey)) {
+ Document doc = getDocumentFromFile(file);
+ templateXmlText = cacheTemplateText(doc, cacheKey);
+ } else {
+ templateXmlText = getTemplateCache(cacheKey);
+ }
+ try {
+ return build(templateXmlText, context);
+ } catch (Exception e) {
+ throw new MailBuildException("メールの生成に失敗しました。", e);
+ }
+ }
+
+ private String cacheTemplateText(Document doc, String cacheKey) {
+ XMLOutputter output = new XMLOutputter();
+ String templateXmlText = "<!DOCTYPE mail PUBLIC \"" + Mail.DOCTYPE_PUBLIC + "\" \""
+ + Mail.DOCTYPE_SYSTEM + "\">\n" + output.outputString(doc.getRootElement());
+ log.debug("以下のXMLデータをキャッシュします。\n" + templateXmlText);
+ putTemplateCache(cacheKey, templateXmlText);
+ return templateXmlText;
+ }
+
+ /**
+ * 指定されたクラスパス上のファイルを読み込んで、XMLドキュメントを生成します。
+ *
+ * @param classPath
+ * @return JDOM Document
+ */
+ protected Document getDocumentFromClassPath(String classPath) throws MailBuildException {
+ InputStream is = getClass().getResourceAsStream(classPath);
+ SAXBuilder builder = new SAXBuilder(true);
+ builder.setEntityResolver(new DTDEntityResolver());
+ Document doc;
+ try {
+ doc = builder.build(is);
+ } catch (JDOMException e) {
+ throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return doc;
+ }
+
+ /**
+ * 指定されたファイルを読み込んで、XMLドキュメントを生成します。
+ *
+ * @param file
+ * @return JDOM Document
+ */
+ protected Document getDocumentFromFile(File file) {
+ SAXBuilder builder = new SAXBuilder(true);
+ builder.setEntityResolver(new DTDEntityResolver());
+ Document doc;
+ try {
+ doc = builder.build(file);
+ } catch (JDOMException e) {
+ throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+ }
+ return doc;
+ }
+
+ /**
+ * XMLのmailルートエレメントからMailインスタンスを生成します。
+ *
+ * @param mailElement mail要素を示すElementインスタンス
+ * @return Mail 生成されたMail
+ */
+ protected Mail build(Element mailElement) {
+ Mail mail = new Mail();
+ setFrom(mailElement, mail);
+ setRecipients(mailElement, mail);
+ setSubject(mailElement, mail);
+ setBody(mailElement, mail);
+ setReplyTo(mailElement, mail);
+ setReturnPath(mailElement, mail);
+
+ setHtml(mailElement, mail);
+
+ return mail;
+ }
+
+ /**
+ * VelocityContextとXMLテンプレートをマージさせ、Mailインスタンスを生成します。
+ *
+ * @param templateText マージするXMLテンプレートの文字列
+ * @param context マージするVelocityContext
+ * @return Mail
+ *
+ * @throws Exception
+ * @throws ParseErrorException
+ * @throws MethodInvocationException
+ * @throws ResourceNotFoundException
+ * @throws IOException
+ * @throws JDOMException
+ */
+ protected Mail build(String templateText, VelocityContext context) throws Exception,
+ ParseErrorException,
+ MethodInvocationException,
+ ResourceNotFoundException,
+ IOException, JDOMException {
+ if (log.isDebugEnabled()) {
+ log.debug("ソースXMLデータ\n" + templateText);
+ }
+
+ Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem);
+ Velocity.init();
+ StringWriter w = new StringWriter();
+ Velocity.evaluate(context, w, "XML Mail Data", templateText);
+
+ if (log.isDebugEnabled()) {
+ log.debug("VelocityContextとマージ後のXMLデータ\n" + w.toString());
+ }
+
+ StringReader reader = new StringReader(w.toString());
+ SAXBuilder builder = new SAXBuilder(true);
+ builder.setEntityResolver(new DTDEntityResolver());
+ Document mergedDoc = builder.build(reader);
+
+ return build(mergedDoc.getRootElement());
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setReturnPath(Element root, Mail mail) {
+ Element returnPathElem = root.getChild("returnPath");
+ if (returnPathElem != null && returnPathElem.getAttributeValue("email") != null) {
+ mail.setReturnPath(returnPathElem.getAttributeValue("email"));
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setReplyTo(Element root, Mail mail) {
+ Element replyToElem = root.getChild("replyTo");
+ if (replyToElem != null && replyToElem.getAttributeValue("email") != null) {
+ mail.setReplyTo(replyToElem.getAttributeValue("email"));
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setBody(Element root, Mail mail) {
+ Element bodyElem = root.getChild("body");
+ if (bodyElem != null) {
+ mail.setText(bodyElem.getTextTrim());
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setHtml(Element root, Mail mail) {
+ Element htmlElem = root.getChild("html");
+ if (htmlElem != null) {
+ mail.setHtmlText(htmlElem.getTextTrim());
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setSubject(Element root, Mail mail) {
+ Element subjectElem = root.getChild("subject");
+ if (subjectElem != null) {
+ mail.setSubject(subjectElem.getTextTrim());
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setRecipients(Element root, Mail mail) {
+ Element recipientsElem = root.getChild("recipients");
+ if (recipientsElem == null) {
+ return;
+ }
+
+ List recipientElemList = recipientsElem.getChildren();
+ for (int i = 0, max = recipientElemList.size(); i < max; i++) {
+ Element e = (Element)recipientElemList.get(i);
+ if ("to".equals(e.getName())) { // to
+ if (e.getAttributeValue("email") != null) {
+ if (e.getAttributeValue("name") != null) {
+ mail.addTo(e.getAttributeValue("email"), e.getAttributeValue("name"));
+ } else {
+ mail.addTo(e.getAttributeValue("email"));
+ }
+ }
+ } else if ("cc".equals(e.getName())) { // cc
+ if (e.getAttributeValue("email") != null) {
+ if (e.getAttributeValue("name") != null) {
+ mail.addCc(e.getAttributeValue("email"), e.getAttributeValue("name"));
+ } else {
+ mail.addCc(e.getAttributeValue("email"));
+ }
+ }
+ } else {
+ if (e.getAttributeValue("email") != null) { // bcc
+ mail.addBcc(e.getAttributeValue("email"));
+ }
+ }
+ }
+ }
+
+ /**
+ * @param root
+ * @param mail
+ */
+ protected void setFrom(Element root, Mail mail) {
+ Element fromElem = root.getChild("from");
+ if (fromElem != null && fromElem.getAttributeValue("email") != null) {
+ if (fromElem.getAttributeValue("name") != null) {
+ mail.setFrom(fromElem.getAttributeValue("email"), fromElem
+ .getAttributeValue("name"));
+ } else {
+ mail.setFrom(fromElem.getAttributeValue("email"));
+ }
+ }
+ }
+
+ /**
+ * @see com.ozacc.mail.VelocityMailBuilder#clearCache()
+ */
+ public synchronized void clearCache() {
+ log.debug("テンプレートキャッシュをクリアします。");
+ templateCache.clear();
+ }
+
+ /**
+ * @see com.ozacc.mail.VelocityMailBuilder#isCacheEnabled()
+ */
+ public boolean isCacheEnabled() {
+ return cacheEnabled;
+ }
+
+ /**
+ * @see com.ozacc.mail.VelocityMailBuilder#setCacheEnabled(boolean)
+ */
+ public void setCacheEnabled(boolean cacheEnabled) {
+ if (!cacheEnabled) {
+ clearCache();
+ }
+ this.cacheEnabled = cacheEnabled;
+ }
+
+ protected boolean hasTemplateCache(String key) {
+ if (cacheEnabled) {
+ return templateCache.containsKey(key);
+ }
+ return false;
+ }
+
+ protected void putTemplateCache(String key, String templateXmlText) {
+ if (cacheEnabled) {
+ log.debug("テンプレートをキャッシュします。[key='" + key + "']");
+ templateCache.put(key, templateXmlText);
+ }
+ }
+
+ protected String getTemplateCache(String key) {
+ if (hasTemplateCache(key)) {
+ log.debug("テンプレートキャッシュを返します。[key='" + key + "']");
+ return (String)templateCache.get(key);
+ }
+ return null;
+ }
+
+ /**
+ * @see com.ozacc.mail.VelocityMultipleMailBuilder#buildMail(java.lang.String, org.apache.velocity.VelocityContext, java.lang.String)
+ */
+ public Mail buildMail(String classPath, VelocityContext context, String mailId)
+ throws MailBuildException {
+ if (mailId == null || "".equals(mailId)) {
+ throw new IllegalArgumentException("メールIDが指定されていません。");
+ }
+
+ String cacheKey = classPath + CACHE_KEY_SEPARATOR + mailId;
+ String templateXmlText;
+ if (!hasTemplateCache(cacheKey)) {
+ Document doc = getDocumentFromClassPath(classPath);
+ templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);
+ } else {
+ templateXmlText = getTemplateCache(cacheKey);
+ }
+ try {
+ return build(templateXmlText, context);
+ } catch (Exception e) {
+ throw new MailBuildException("メールの生成に失敗しました。", e);
+ }
+ }
+
+ private String getAndCacheTemplateText(Document doc, String mailId, String cacheKey)
+ throws MailBuildException {
+ Element mailElem = getElementById(doc, mailId);
+ XMLOutputter output = new XMLOutputter();
+ String templateXmlText = output.outputString(mailElem);
+
+ putTemplateCache(cacheKey, templateXmlText);
+ return templateXmlText;
+ }
+
+ /**
+ * @see com.ozacc.mail.VelocityMultipleMailBuilder#buildMail(java.io.File, org.apache.velocity.VelocityContext, java.lang.String)
+ */
+ public Mail buildMail(File file, VelocityContext context, String mailId)
+ throws MailBuildException {
+ if (mailId == null || "".equals(mailId)) {
+ throw new IllegalArgumentException("メールIDが指定されていません。");
+ }
+
+ String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + mailId;
+ String templateXmlText;
+ if (!hasTemplateCache(cacheKey)) {
+ Document doc = getDocumentFromFile(file);
+ templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);
+ } else {
+ templateXmlText = getTemplateCache(cacheKey);
+ }
+ try {
+ return build(templateXmlText, context);
+ } catch (Exception e) {
+ throw new MailBuildException("メールの生成に失敗しました。", e);
+ }
+ }
+
+ /**
+ * @see com.ozacc.mail.MultipleMailBuilder#buildMail(java.lang.String, java.lang.String)
+ */
+ public Mail buildMail(String classPath, String mailId) throws MailBuildException {
+ Document doc = getDocumentFromClassPath(classPath);
+ Element mailElem = getElementById(doc, mailId);
+ return build(mailElem);
+ }
+
+ /**
+ * @see com.ozacc.mail.MultipleMailBuilder#buildMail(java.io.File, java.lang.String)
+ */
+ public Mail buildMail(File file, String mailId) throws MailBuildException {
+ Document doc = getDocumentFromFile(file);
+ Element mailElem = getElementById(doc, mailId);
+ return build(mailElem);
+ }
+
+ /**
+ * 指定されたXMLドキュメントの中から、指定されたid属性がセットされている要素を取得します。
+ *
+ * @param doc XMLドキュメント
+ * @param id 抽出する要素のid属性値
+ * @return XMLドキュメントで見つかったid属性を持つ要素
+ */
+ private Element getElementById(Document doc, String id) {
+ Element mailsElem = doc.getRootElement(); // <mails>
+ List mailElemList = mailsElem.getChildren("mail");
+ for (Iterator itr = mailElemList.iterator(); itr.hasNext();) {
+ Element mailElem = (Element)itr.next();
+ String mailId = mailElem.getAttributeValue("id");
+ if (mailId.equals(id)) {
+ return mailElem;
+ }
+ }
+ throw new MailBuildException("指定されたID[" + id + "]のメールデータは見つかりませんでした。");
+ }
+
}
\ No newline at end of file