Description
Provide a standalone implementation of a document builder service that can be registered as a hidden service, and injected into domain objects so that they are able to send build OpenXml documents. The input could be an XML-based notation (or perhaps JSON) along with a template .docx document.
The signature of the interface would be something like:
[Hidden]
public interface OpenXmlDocumentBuilder {
byte[] build(byte[] documentTemplate, org.w3c.Document xmlDoc);
}
eg where the XML format is something like:
<input>
<LetterDate type="date">2012-01-30</LetterDate>
<CustomerTitle type="rich">Dear Mrs. Jenkins</CustomerTitle>
<Blurb>As requested, here are the recent payments made from your account</Blurb>
<Payments type="rich-table">
<row>
<Date>2012-01-20</Date>
<Merchant>Walmart</Merchant>
<Amount>123.45</Date>
</row>
<row>
<Date>2012-01-21</Date>
<Merchant>Esso</Merchant>
<Amount>45.23</Date>
</row>
<row>
<Date>2012-01-22</Date>
<Merchant>Starbucks</Merchant>
<Amount>12.01</Date>
</row>
<row>
<Date>2012-01-22</Date>
<Merchant>Amazon</Merchant>
<Amount>89.99</Date>
</row>
</Payments>
</input>
so that the information is used to merge into fields within the OpenXml. (NB: if using MS Word, this would correspond to "Content Controls", as per the Developer tab).
~~~~~~~~~~~~~
In terms of how a domain object would use this service, one design is to have a CommunicationTemplate domain object, which holds the .docx (or .odf) (eg as a base 64 encoded string). The CommunicationTemplate acts as a factory for Communication objects, requiring that the appropriate XML be provided to it. The template then calls the DocumentBuilderService and gets back a mail-merged version; this is stored in the resultant Communication (eg again base 64 encoded).
The sequence diagram below shows how this service could be used by a CommunicationTemplate and Communication domain object:
~~~~~~~~~~~~
generated at http://www.websequencediagrams.com/ using the following script:
title create Communication
Customer->+CommunicationTemplateRepository: lookup(templateCode)
CommunicationTemplateRepository-->-Customer:
Customer->Customer: build xml
Customer->+CommunicationTemplate: create(xml)
CommunicationTemplate->+DocumentBuilderService: mailMerge(this.odfTemplate, xml)
DocumentBuilderService-->-CommunicationTemplate: mergedOdf
CommunicationTemplate->Communication: instantiate(mergedOdf)
CommunicationTemplate-->-Customer: