org.milyn.templating.stringtemplate.StringTemplateContentHandlerFactory Maven / Gradle / Ivy
The newest version!
/*
Milyn - Copyright (C) 2006 - 2010
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (version 2.1) as published by the Free Software
Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details:
http://www.gnu.org/licenses/lgpl.txt
*/
package org.milyn.templating.stringtemplate;
import java.util.Map;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.milyn.cdr.SmooksConfigurationException;
import org.milyn.cdr.SmooksResourceConfiguration;
import org.milyn.cdr.annotation.AppContext;
import org.milyn.cdr.annotation.Configurator;
import org.milyn.container.ApplicationContext;
import org.milyn.container.ExecutionContext;
import org.milyn.delivery.ContentHandler;
import org.milyn.delivery.ContentHandlerFactory;
import org.milyn.delivery.ordering.Consumer;
import org.milyn.delivery.annotation.Resource;
import org.milyn.delivery.dom.serialize.ContextObjectSerializationUnit;
import org.milyn.delivery.dom.serialize.TextSerializationUnit;
import org.milyn.event.report.annotation.VisitAfterReport;
import org.milyn.event.report.annotation.VisitBeforeReport;
import org.milyn.templating.AbstractTemplateProcessor;
import org.milyn.xml.DomUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* StringTemplate {@link org.milyn.delivery.dom.DOMElementVisitor} Creator class.
*
* Creates {@link org.milyn.delivery.dom.DOMElementVisitor} instances for applying
* StringTemplate transformations (i.e. ".st" files).
*
* This templating solution relies on the Smooks JavaBean Cartridge
* to perform the JavaBean population that's required by StringTemplate.
*
* Targeting ".st" Files for Transformation
*
* <resource-config selector="target-element">
* <!-- See {@link org.milyn.resource.URIResourceLocator} -->
* <resource>/com/acme/AcmeStringTemplate.st</resource>
*
* <!-- (Optional) The action to be applied on the template content. Should the content
* generated by the template:
* 1. replace ("replace") the target element, or
* 2. be added to ("addto") the target element, or
* 3. be inserted before ("insertbefore") the target element, or
* 4. be inserted after ("insertafter") the target element.
* 5. be bound to ("bindto") a {@link BeanContext} variable named by the "bindId" param.
* Default "replace".-->
* <param name="action">replace/addto/insertbefore/insertafter</param>
*
* <!-- (Optional) Should the template be applied before (true) or
* after (false) Smooks visits the child elements of the target element.
* Default "false".-->
* <param name="applyTemplateBefore">true/false</param>
*
* <!-- (Optional) The name of the {@link org.milyn.io.AbstractOutputStreamResource OutputStreamResource}
* to which the result should be written. If set, the "action" param is ignored. -->
* <param name="outputStreamResource">xyzResource</param>
*
* <!-- (Optional) Template encoding.
* Default "UTF-8".-->
* <param name="encoding">encoding</param>
*
* <!-- (Optional) bindId when "action" is "bindto".
* <param name="bindId">xxxx</param>
*
* </resource-config>
*
*
* @author tfennelly
*/
@Resource(type="st")
public class StringTemplateContentHandlerFactory implements ContentHandlerFactory {
@AppContext
private ApplicationContext applicationContext;
/**
* Create a StringTemplate based ContentHandler.
* @param resourceConfig The SmooksResourceConfiguration for the StringTemplate.
* @return The StringTemplate {@link org.milyn.delivery.ContentHandler} instance.
*/
public synchronized ContentHandler create(SmooksResourceConfiguration resourceConfig) throws SmooksConfigurationException, InstantiationException {
try {
return Configurator.configure(new StringTemplateTemplateProcessor(), resourceConfig, applicationContext);
} catch (SmooksConfigurationException e) {
throw e;
} catch (Exception e) {
InstantiationException instanceException = new InstantiationException("StringTemplate ProcessingUnit resource [" + resourceConfig.getResource() + "] not loadable. StringTemplate resource invalid.");
instanceException.initCause(e);
throw instanceException;
}
}
/**
* StringTemplate template application ProcessingUnit.
* @author tfennelly
*/
@VisitBeforeReport(condition = "false")
@VisitAfterReport(summary = "Applied StringTemplate Template.", detailTemplate = "reporting/StringTemplateTemplateProcessor_After.html")
private static class StringTemplateTemplateProcessor extends AbstractTemplateProcessor implements Consumer {
private StringTemplate template;
@Override
protected void loadTemplate(SmooksResourceConfiguration config) {
String path = config.getResource();
if(path.charAt(0) == '/') {
path = path.substring(1);
}
if(path.endsWith(".st")) {
path = path.substring(0, path.length() - 3);
}
StringTemplateGroup templateGroup = new StringTemplateGroup(path);
templateGroup.setFileCharEncoding(getEncoding().displayName());
template = templateGroup.getInstanceOf(path);
}
@Override
protected void visit(Element element, ExecutionContext executionContext) {
// First thing we do is clone the template for this transformation...
StringTemplate thisTransTemplate = template.getInstanceOf();
Map beans = executionContext.getBeanContext().getBeanMap();
String templatingResult;
Node resultNode;
// Set the document data beans on the template and apply it...
thisTransTemplate.setAttributes(beans);
templatingResult = thisTransTemplate.toString();
resultNode = TextSerializationUnit.createTextElement(element, templatingResult);
// Process the templating action, supplying the templating result...
processTemplateAction(element, resultNode, executionContext);
}
public boolean consumes(Object object) {
if(template.getTemplate().indexOf(object.toString()) != -1) {
return true;
}
return false;
}
}
}