All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ozacc.mail.impl.JDomXMLMailBuilder Maven / Gradle / Ivy

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;

/**
 * JDOMを利用してXMLファイルからMailインスタンスを生成するクラス。
 * 

* ソース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 = "\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(); // 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 + "]のメールデータは見つかりませんでした。"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy