Problem statement:
What is the Adobe recommended way to create TransformerFactory?
Requirement:
Create the Transformer to rewrites the output with powerful mechanisms
Introduction:
The TransformerFactory is a service which creates Transformers on demand. The created transformers form the middle part of the rewriter pipeline. The factories itself are not chained but the resulting transformers are. On each pipeline call new instances are created. The factory is referenced using a service property named ‘pipeline.type’. Each factory should have a unique value for this property. With the optional property ‘pipeline.mode’ set to the value ‘global’ the transformer is used for each and every pipeline regardless of the actual configuration for this pipeline. All available global transformers with a service ranking below zero are chained right after the generator. All available global transformers with a service ranking higher or equal to zero are chained right before the serializer. Therefore the property “service.ranking” should be used for the factory in combination with ‘pipeline.mode’. To be compatible with possible future uses of the ‘pipeline.mode’ property, it should only be used with the value ‘global’.
This is a powerful mechanism that rewrites the output (typically html markup) generated by the Sling rendering process. It is part of the Apache Sling Rewriter module, which uses SAX event based pipelines as shown here.
Every pipeline consists of three components, and each component has a corresponding Java interface and factory:
Create Component Service with TransformerFactory class and implement TransformerFactory class
Provide pipeline for the action
Override createTransformer method
package com.mysite.core.filters;
import org.apache.sling.rewriter.Transformer;
import org.apache.sling.rewriter.TransformerFactory;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link TransformerFactory} defined to create new {@link ContentVariableTransformer} objects and pass in the reference to
* the service used to aggregate properties.
*/
@Component(service = TransformerFactory.class, property = {
"pipeline.type=ccvar-transformer"
})
public class ContentVariableTransformerFactory implements TransformerFactory {
private static final Logger LOG = LoggerFactory.getLogger(ContentVariableTransformerFactory.class);
@Override
public Transformer createTransformer() {
LOG.trace("Content Variable Transformer");
return new ContentVariableTransformer();
}
}
Create the transformer implementation and override init() method
package com.mysite.core.filters;
import java.io.IOException;
import java.util.Map;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.rewriter.ProcessingComponentConfiguration;
import org.apache.sling.rewriter.ProcessingContext;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.adobe.acs.commons.rewriter.ContentHandlerBasedTransformer;
/**
* {@link org.apache.sling.rewriter.Transformer} used to process HTML requests and replace content tokens found in the
* rendered HTML.
*/
public class ContentVariableTransformer extends ContentHandlerBasedTransformer {
private Map<String, Object> contentVariableReplacements;
public ContentVariableTransformer() {
}
@Override
public void init(ProcessingContext processingContext, ProcessingComponentConfiguration processingComponentConfiguration) throws IOException {
SlingHttpServletRequest request = processingContext.getRequest();
}
public void startElement(String uri, String localName, String quaName, Attributes atts) throws SAXException {
}
public void characters(char[] ch, int start, int length) throws SAXException {
}
}