OSDN Git Service

文字コードを UTF-8、改行コードをLFに統一
[spring-ext/ozacc-mail.git] / src / main / java / com / ozacc / mail / impl / XMLVelocityMailBuilderImpl.java
old mode 100755 (executable)
new mode 100644 (file)
index 81908ab..b86e4af
-package com.ozacc.mail.impl;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.StringReader;\r
-import java.io.StringWriter;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.Properties;\r
-\r
-import javax.xml.parsers.DocumentBuilder;\r
-import javax.xml.transform.OutputKeys;\r
-import javax.xml.transform.Transformer;\r
-import javax.xml.transform.TransformerConfigurationException;\r
-import javax.xml.transform.TransformerException;\r
-import javax.xml.transform.TransformerFactory;\r
-import javax.xml.transform.TransformerFactoryConfigurationError;\r
-import javax.xml.transform.dom.DOMSource;\r
-import javax.xml.transform.stream.StreamResult;\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.w3c.dom.Document;\r
-import org.w3c.dom.Element;\r
-import org.xml.sax.InputSource;\r
-import org.xml.sax.SAXException;\r
-\r
-import com.ozacc.mail.Mail;\r
-import com.ozacc.mail.MailBuildException;\r
-import com.ozacc.mail.VelocityMultipleMailBuilder;\r
-\r
-/**\r
- * XMLファイルを読み込み、Velocityと連携して動的にメールデータを生成し、そのデータからMailインスタンスを生成するクラス。\r
- * \r
- * @since 1.0.1\r
- * @author Tomohiro Otsuka\r
- * @version $Id: XMLVelocityMailBuilderImpl.java,v 1.4.2.4 2005/01/23 06:13:10 otsuka Exp $\r
- */\r
-public class XMLVelocityMailBuilderImpl extends XMLMailBuilderImpl implements\r
-               VelocityMultipleMailBuilder {\r
-\r
-       private static Log log = LogFactory.getLog(XMLVelocityMailBuilderImpl.class);\r
-\r
-       private static String CACHE_KEY_SEPARATOR = "#";\r
-\r
-       private static String DEFAULT_MAIL_ID = "DEFAULT";\r
-\r
-       protected String charset = "UTF-8";\r
-\r
-       protected LogSystem velocityLogSystem = new VelocityLogSystem();\r
-\r
-       protected Map templateCache = new HashMap();\r
-\r
-       private boolean cacheEnabled = false;\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.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
-       /**\r
-        * @see com.ozacc.mail.VelocityMailBuilder#buildMail(java.lang.String, org.apache.velocity.VelocityContext)\r
-        */\r
-       public Mail buildMail(String classPath, VelocityContext context) throws MailBuildException {\r
-               String cacheKey = classPath + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;\r
-\r
-               String templateXmlText;\r
-               if (!hasTemplateCache(cacheKey)) {\r
-                       Document doc;\r
-                       try {\r
-                               // Velocityマージ前のXMLではコメントを許可する\r
-                               doc = getDocumentFromClassPath(classPath, false);\r
-                       } catch (SAXException e) {\r
-                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
-                       } catch (IOException e) {\r
-                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
-                       }\r
-                       templateXmlText = convertDocumentIntoString(doc.getDocumentElement());\r
-                       putTemplateCache(cacheKey, templateXmlText);\r
-               } else {\r
-                       templateXmlText = getTemplateCache(cacheKey);\r
-               }\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.VelocityMailBuilder#buildMail(java.io.File, org.apache.velocity.VelocityContext)\r
-        */\r
-       public Mail buildMail(File file, VelocityContext context) throws MailBuildException {\r
-               String cacheKey = file.getAbsolutePath() + CACHE_KEY_SEPARATOR + DEFAULT_MAIL_ID;\r
-\r
-               String templateXmlText;\r
-               if (!hasTemplateCache(cacheKey)) {\r
-                       Document doc;\r
-                       try {\r
-                               // Velocityマージ前のXMLではコメントを許可する\r
-                               doc = getDocumentFromFile(file, false);\r
-                       } catch (SAXException e) {\r
-                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
-                       } catch (IOException e) {\r
-                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
-                       }\r
-                       templateXmlText = convertDocumentIntoString(doc.getDocumentElement());\r
-                       putTemplateCache(cacheKey, templateXmlText);\r
-               } else {\r
-                       templateXmlText = getTemplateCache(cacheKey);\r
-               }\r
-\r
-               try {\r
-                       return build(templateXmlText, context);\r
-               } catch (Exception e) {\r
-                       throw new MailBuildException("メールの生成に失敗しました。", e);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * メールデータをVelocityContextとマージして生成されたXMLからMailインスタンスを生成します。\r
-        * \r
-        * @param templateXmlText メールデータのテンプレート\r
-        * @param context テンプレートにマージする内容を格納したVelocityContext\r
-        * @return VelocityContextをテンプレートにマージして生成されたXMLから生成されたMailインスタンス\r
-        * @throws TransformerFactoryConfigurationError\r
-        * @throws Exception\r
-        * @throws ParseErrorException\r
-        * @throws MethodInvocationException\r
-        * @throws ResourceNotFoundException\r
-        * @throws IOException\r
-        */\r
-       protected synchronized Mail build(String templateXmlText, VelocityContext context)\r
-                                                                                                                                                       throws TransformerFactoryConfigurationError,\r
-                                                                                                                                                       Exception,\r
-                                                                                                                                                       ParseErrorException,\r
-                                                                                                                                                       MethodInvocationException,\r
-                                                                                                                                                       ResourceNotFoundException,\r
-                                                                                                                                                       IOException {\r
-               if (log.isDebugEnabled()) {\r
-                       log.debug("Source XML Mail Data\n" + templateXmlText);\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", templateXmlText);\r
-               StringReader reader = new StringReader(w.toString());\r
-\r
-               DocumentBuilder db = createDocumentBuilder();\r
-               InputSource source = new InputSource(reader);\r
-               Document newDoc = db.parse(source);\r
-\r
-               if (log.isDebugEnabled()) {\r
-                       String newXmlContent = convertDocumentIntoString(newDoc.getDocumentElement());\r
-                       log.debug("VelocityContext-merged XML Mail Data\n" + newXmlContent);\r
-               }\r
-\r
-               return buildMail(newDoc.getDocumentElement());\r
-       }\r
-\r
-       /**\r
-        * 指定されたDOM Documentを文字列に変換します。\r
-        * \r
-        * @param mailElement\r
-        * @return XMLドキュメントの文字列\r
-        * @throws TransformerFactoryConfigurationError \r
-        */\r
-       protected String convertDocumentIntoString(Element mailElement)\r
-                                                                                                                                       throws TransformerFactoryConfigurationError {\r
-               TransformerFactory tf = TransformerFactory.newInstance();\r
-               Transformer t;\r
-               try {\r
-                       t = tf.newTransformer();\r
-               } catch (TransformerConfigurationException e) {\r
-                       throw new MailBuildException(e.getMessage(), e);\r
-               }\r
-               t.setOutputProperties(getOutputProperties());\r
-\r
-               DOMSource source = new DOMSource(mailElement);\r
-               StringWriter w = new StringWriter();\r
-               StreamResult result = new StreamResult(w);\r
-               try {\r
-                       t.transform(source, result);\r
-               } catch (TransformerException e) {\r
-                       throw new MailBuildException(e.getMessage(), e);\r
-               }\r
-\r
-               return w.toString();\r
-       }\r
-\r
-       /**\r
-        * 出力プロパティを生成。\r
-        * @return 出力プロパティを設定したPropertiesインスタンス\r
-        */\r
-       protected Properties getOutputProperties() {\r
-               Properties p = new Properties();\r
-               p.put(OutputKeys.ENCODING, charset);\r
-               p.put(OutputKeys.DOCTYPE_PUBLIC, Mail.DOCTYPE_PUBLIC);\r
-               p.put(OutputKeys.DOCTYPE_SYSTEM, Mail.DOCTYPE_SYSTEM);\r
-               return p;\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
-\r
-               String templateXmlText;\r
-               if (!hasTemplateCache(cacheKey)) {\r
-                       Document doc;\r
-                       try {\r
-                               // Velocityマージ前のXMLではコメントを許可する\r
-                               doc = getDocumentFromClassPath(classPath, false);\r
-                       } catch (SAXException e) {\r
-                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
-                       } catch (IOException e) {\r
-                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
-                       }\r
-                       if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) {\r
-                               throw new MailBuildException("指定されたクラスパスのXMLはシングルメールテンプレートです。[classPath='"\r
-                                               + classPath + "']");\r
-                       }\r
-                       templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);\r
-               } else {\r
-                       templateXmlText = getTemplateCache(cacheKey);\r
-               }\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 TransformerFactoryConfigurationError {\r
-               Element mailElem = doc.getElementById(mailId);\r
-               if (mailElem == null) {\r
-                       throw new MailBuildException("指定されたID[" + mailId + "]のメールデータは見つかりませんでした。");\r
-               }\r
-               String templateXmlText = convertDocumentIntoString(mailElem);\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
-\r
-               String templateXmlText;\r
-               if (!hasTemplateCache(cacheKey)) {\r
-                       Document doc;\r
-                       try {\r
-                               // Velocityマージ前のXMLではコメントを許可する\r
-                               doc = getDocumentFromFile(file, false);\r
-                       } catch (SAXException e) {\r
-                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);\r
-                       } catch (IOException e) {\r
-                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);\r
-                       }\r
-                       if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) {\r
-                               throw new MailBuildException("指定されたファイルのXMLはシングルメールテンプレートです。[filePath='"\r
-                                               + file.getAbsolutePath() + "']");\r
-                       }\r
-                       templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);\r
-               } else {\r
-                       templateXmlText = getTemplateCache(cacheKey);\r
-               }\r
-\r
-               try {\r
-                       return build(templateXmlText, context);\r
-               } catch (Exception e) {\r
-                       throw new MailBuildException("メールの生成に失敗しました。", e);\r
-               }\r
-       }\r
-\r
+package com.ozacc.mail.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+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.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.ozacc.mail.Mail;
+import com.ozacc.mail.MailBuildException;
+import com.ozacc.mail.VelocityMultipleMailBuilder;
+
+/**
+ * XMLファイルを読み込み、Velocityと連携して動的にメールデータを生成し、そのデータからMailインスタンスを生成するクラス。
+ * 
+ * @since 1.0.1
+ * @author Tomohiro Otsuka
+ * @version $Id: XMLVelocityMailBuilderImpl.java,v 1.4.2.4 2005/01/23 06:13:10 otsuka Exp $
+ */
+public class XMLVelocityMailBuilderImpl extends XMLMailBuilderImpl implements
+               VelocityMultipleMailBuilder {
+
+       private static Log log = LogFactory.getLog(XMLVelocityMailBuilderImpl.class);
+
+       private static String CACHE_KEY_SEPARATOR = "#";
+
+       private static String DEFAULT_MAIL_ID = "DEFAULT";
+
+       protected String charset = "UTF-8";
+
+       protected LogSystem velocityLogSystem = new VelocityLogSystem();
+
+       protected Map templateCache = new HashMap();
+
+       private boolean cacheEnabled = false;
+
+       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.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;
+       }
+
+       /**
+        * @see com.ozacc.mail.VelocityMailBuilder#buildMail(java.lang.String, org.apache.velocity.VelocityContext)
+        */
+       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;
+                       try {
+                               // Velocityマージ前のXMLではコメントを許可する
+                               doc = getDocumentFromClassPath(classPath, false);
+                       } catch (SAXException e) {
+                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+                       } catch (IOException e) {
+                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+                       }
+                       templateXmlText = convertDocumentIntoString(doc.getDocumentElement());
+                       putTemplateCache(cacheKey, templateXmlText);
+               } else {
+                       templateXmlText = getTemplateCache(cacheKey);
+               }
+
+               try {
+                       return build(templateXmlText, context);
+               } catch (Exception e) {
+                       throw new MailBuildException("メールの生成に失敗しました。", e);
+               }
+       }
+
+       /**
+        * @see com.ozacc.mail.VelocityMailBuilder#buildMail(java.io.File, org.apache.velocity.VelocityContext)
+        */
+       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;
+                       try {
+                               // Velocityマージ前のXMLではコメントを許可する
+                               doc = getDocumentFromFile(file, false);
+                       } catch (SAXException e) {
+                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+                       } catch (IOException e) {
+                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+                       }
+                       templateXmlText = convertDocumentIntoString(doc.getDocumentElement());
+                       putTemplateCache(cacheKey, templateXmlText);
+               } else {
+                       templateXmlText = getTemplateCache(cacheKey);
+               }
+
+               try {
+                       return build(templateXmlText, context);
+               } catch (Exception e) {
+                       throw new MailBuildException("メールの生成に失敗しました。", e);
+               }
+       }
+
+       /**
+        * メールデータをVelocityContextとマージして生成されたXMLからMailインスタンスを生成します。
+        * 
+        * @param templateXmlText メールデータのテンプレート
+        * @param context テンプレートにマージする内容を格納したVelocityContext
+        * @return VelocityContextをテンプレートにマージして生成されたXMLから生成されたMailインスタンス
+        * @throws TransformerFactoryConfigurationError
+        * @throws Exception
+        * @throws ParseErrorException
+        * @throws MethodInvocationException
+        * @throws ResourceNotFoundException
+        * @throws IOException
+        */
+       protected synchronized Mail build(String templateXmlText, VelocityContext context)
+                                                                                                                                                       throws TransformerFactoryConfigurationError,
+                                                                                                                                                       Exception,
+                                                                                                                                                       ParseErrorException,
+                                                                                                                                                       MethodInvocationException,
+                                                                                                                                                       ResourceNotFoundException,
+                                                                                                                                                       IOException {
+               if (log.isDebugEnabled()) {
+                       log.debug("Source XML Mail Data\n" + templateXmlText);
+               }
+
+               Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, velocityLogSystem);
+               Velocity.init();
+               StringWriter w = new StringWriter();
+               Velocity.evaluate(context, w, "XML Mail Data", templateXmlText);
+               StringReader reader = new StringReader(w.toString());
+
+               DocumentBuilder db = createDocumentBuilder();
+               InputSource source = new InputSource(reader);
+               Document newDoc = db.parse(source);
+
+               if (log.isDebugEnabled()) {
+                       String newXmlContent = convertDocumentIntoString(newDoc.getDocumentElement());
+                       log.debug("VelocityContext-merged XML Mail Data\n" + newXmlContent);
+               }
+
+               return buildMail(newDoc.getDocumentElement());
+       }
+
+       /**
+        * 指定されたDOM Documentを文字列に変換します。
+        * 
+        * @param mailElement
+        * @return XMLドキュメントの文字列
+        * @throws TransformerFactoryConfigurationError 
+        */
+       protected String convertDocumentIntoString(Element mailElement)
+                                                                                                                                       throws TransformerFactoryConfigurationError {
+               TransformerFactory tf = TransformerFactory.newInstance();
+               Transformer t;
+               try {
+                       t = tf.newTransformer();
+               } catch (TransformerConfigurationException e) {
+                       throw new MailBuildException(e.getMessage(), e);
+               }
+               t.setOutputProperties(getOutputProperties());
+
+               DOMSource source = new DOMSource(mailElement);
+               StringWriter w = new StringWriter();
+               StreamResult result = new StreamResult(w);
+               try {
+                       t.transform(source, result);
+               } catch (TransformerException e) {
+                       throw new MailBuildException(e.getMessage(), e);
+               }
+
+               return w.toString();
+       }
+
+       /**
+        * 出力プロパティを生成。
+        * @return 出力プロパティを設定したPropertiesインスタンス
+        */
+       protected Properties getOutputProperties() {
+               Properties p = new Properties();
+               p.put(OutputKeys.ENCODING, charset);
+               p.put(OutputKeys.DOCTYPE_PUBLIC, Mail.DOCTYPE_PUBLIC);
+               p.put(OutputKeys.DOCTYPE_SYSTEM, Mail.DOCTYPE_SYSTEM);
+               return p;
+       }
+
+       /**
+        * @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;
+                       try {
+                               // Velocityマージ前のXMLではコメントを許可する
+                               doc = getDocumentFromClassPath(classPath, false);
+                       } catch (SAXException e) {
+                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+                       } catch (IOException e) {
+                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+                       }
+                       if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) {
+                               throw new MailBuildException("指定されたクラスパスのXMLはシングルメールテンプレートです。[classPath='"
+                                               + 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 TransformerFactoryConfigurationError {
+               Element mailElem = doc.getElementById(mailId);
+               if (mailElem == null) {
+                       throw new MailBuildException("指定されたID[" + mailId + "]のメールデータは見つかりませんでした。");
+               }
+               String templateXmlText = convertDocumentIntoString(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;
+                       try {
+                               // Velocityマージ前のXMLではコメントを許可する
+                               doc = getDocumentFromFile(file, false);
+                       } catch (SAXException e) {
+                               throw new MailBuildException("XMLのパースに失敗しました。" + e.getMessage(), e);
+                       } catch (IOException e) {
+                               throw new MailBuildException("XMLファイルの読み込みに失敗しました。", e);
+                       }
+                       if (Mail.DOCTYPE_PUBLIC.equals(doc.getDoctype().getPublicId())) {
+                               throw new MailBuildException("指定されたファイルのXMLはシングルメールテンプレートです。[filePath='"
+                                               + file.getAbsolutePath() + "']");
+                       }
+                       templateXmlText = getAndCacheTemplateText(doc, mailId, cacheKey);
+               } else {
+                       templateXmlText = getTemplateCache(cacheKey);
+               }
+
+               try {
+                       return build(templateXmlText, context);
+               } catch (Exception e) {
+                       throw new MailBuildException("メールの生成に失敗しました。", e);
+               }
+       }
+
 }
\ No newline at end of file