com.agilejava.docbkx.maven.AbstractTransformerMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docbkx-maven-base Show documentation
Show all versions of docbkx-maven-base Show documentation
A number of base classes, providing the basic behaviour
of objects / plugins transforming DocBook XML sources into some
other format.
package com.agilejava.docbkx.maven;
/*
* Copyright 2006 Wilfred Springer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
import com.icl.saxon.Controller;
import com.icl.saxon.TransformerFactoryImpl;
import nu.xom.Builder;
import nu.xom.ParsingException;
import nu.xom.Serializer;
import nu.xom.ValidityException;
import nu.xom.xinclude.XIncludeException;
import nu.xom.xinclude.XIncluder;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.antrun.AntPropertyHelper;
import org.apache.maven.project.MavenProject;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.PropertyHelper;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.types.Path;
import org.apache.xerces.jaxp.SAXParserFactoryImpl;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.StringUtils;
import org.jaxen.JaxenException;
import org.jaxen.XPath;
import org.jaxen.dom.DOMXPath;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.VariableResolver;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.util.*;
/**
* The abstract Mojo base for concrete Mojos that generate some kind of output format from DocBook. This Mojo will
* search documents in the directory returned by {@link #getTargetDirectory()}, and apply the stylesheets on these
* documents. This Mojo will be subclassed by Mojo's that generate a particular type of output.
*
* @author Wilfred Springer
*/
public abstract class AbstractTransformerMojo extends AbstractMojo {
protected String[] catalogs = { "catalog.xml", "docbook/catalog.xml" };
/**
* Builds the actual output document.
*/
public void execute() throws MojoExecutionException, MojoFailureException {
preProcess();
final File targetDirectory = getTargetDirectory();
final File sourceDirectory = getSourceDirectory();
if (!sourceDirectory.exists()) {
return; // No sources, so there is nothing to render.
}
if (!targetDirectory.exists()) {
org.codehaus.plexus.util.FileUtils.mkdir(targetDirectory.getAbsolutePath());
}
final String[] included = scanIncludedFiles();
// configure a resolver for catalog files
final CatalogManager catalogManager = createCatalogManager();
final CatalogResolver catalogResolver = new CatalogResolver(catalogManager);
// configure a resolver for urn:dockbx:stylesheet
final URIResolver uriResolver = createStyleSheetResolver(catalogResolver);
// configure a resolver for xml entities
final InjectingEntityResolver injectingResolver = createEntityResolver(catalogResolver);
EntityResolver resolver = catalogResolver;
if (injectingResolver != null) {
resolver = injectingResolver;
}
// configure the builder for XSL Transforms
final TransformerBuilder builder = createTransformerBuilder(uriResolver);
// configure the XML parser
SAXParserFactory factory = createParserFactory();
// iterate over included source files
for (int i = included.length - 1; i >= 0; i--) {
try {
if (injectingResolver != null) {
injectingResolver.forceInjection();
}
final String inputFilename = included[i];
// targetFilename is inputFilename - ".xml" + targetFile extension
String baseTargetFile = inputFilename.substring(0, inputFilename.length() - 4);
final String targetFilename = baseTargetFile + "." + getTargetFileExtension();
final File sourceFile = new File(sourceDirectory, inputFilename);
getLog().debug("SourceFile: " + sourceFile.toString());
File targetFile = null;
if (isUseStandardOutput()) {
targetFile = new File(targetDirectory, targetFilename);
getLog().debug("TargetFile: " + targetFile.toString());
} else {
String name = new File(baseTargetFile).getName();
String dir = new File(baseTargetFile).getParent();
if (dir == null) { // file is located on root of targetDirectory
targetFile = targetDirectory;
} else { // else append the relative directory to targetDirectory
targetFile = new File(targetDirectory, dir);
}
targetFile = new File(targetFile, name);
targetFile = new File(targetFile, name + "." + getTargetFileExtension());
getLog().debug("TargetDirectory: " + targetDirectory.getAbsolutePath());
}
if (!targetFile.exists() || (targetFile.exists() && FileUtils.isFileNewer(sourceFile, targetFile))) {
getLog().info("Processing input file: " + inputFilename);
final XMLReader reader = factory.newSAXParser().getXMLReader();
// configure XML reader
reader.setEntityResolver(resolver);
// eval PI
final PreprocessingFilter filter = createPIHandler(resolver, reader);
// configure SAXSource for XInclude
final SAXSource xmlSource = createSAXSource(inputFilename, sourceFile, filter);
// XSL Transformation
final Transformer transformer = builder.build();
adjustTransformer(transformer, sourceFile.getAbsolutePath(), targetFile);
final Result result = new StreamResult(targetFile.getAbsolutePath());
if (isUseStandardOutput()) {
transformer.transform(xmlSource, result);
} else {
transformer.transform(xmlSource, new StreamResult(System.out));
}
postProcessResult(targetFile);
if (isUseStandardOutput()) {
getLog().info(targetFile + " has been generated.");
} else {
getLog().info("See " + targetFile.getParentFile().getAbsolutePath() + " for generated file(s)");
}
} else {
getLog().info(targetFile + " is up to date.");
}
} catch (SAXException saxe) {
throw new MojoExecutionException("Failed to parse " + included[i] + ".", saxe);
} catch (TransformerException te) {
throw new MojoExecutionException("Failed to transform " + included[i] + ".", te);
} catch (ParserConfigurationException pce) {
throw new MojoExecutionException("Failed to construct parser.", pce);
}
}
postProcess();
}
/**
* Creates a SAXSource configured with the desired XInclude mode. XOM library is used for advanced XInclude else
* Xerces XInclude is used.
*
* @param inputFilename Is used for temp file generation (XOM)
* @param sourceFile The docbook source file.
* @param filter The XML PI filter.
* @return An XInclude configured SAXSource
* @throws MojoExecutionException
*/
private SAXSource createSAXSource(String inputFilename, File sourceFile, PreprocessingFilter filter)
throws MojoExecutionException {
// if both properties are set, XOM is used for a better XInclude support.
if (getXIncludeSupported() && getGeneratedSourceDirectory() != null) {
getLog().debug("Advanced XInclude mode entered");
final Builder xomBuilder = new Builder();
try {
final nu.xom.Document doc = xomBuilder.build(sourceFile);
XIncluder.resolveInPlace(doc);
// TODO also dump PIs computed and Entities included
final File dump = dumpResolvedXML(inputFilename, doc);
return new SAXSource(filter, new InputSource(dump.getAbsolutePath()));
} catch (ValidityException e) {
throw new MojoExecutionException("Failed to validate source", e);
} catch (ParsingException e) {
throw new MojoExecutionException("Failed to parse source", e);
} catch (IOException e) {
throw new MojoExecutionException("Failed to read source", e);
} catch (XIncludeException e) {
throw new MojoExecutionException("Failed to process XInclude", e);
}
} else { // else fallback on Xerces XInclude support.
getLog().debug("Xerces XInclude mode entered");
final InputSource inputSource = new InputSource(sourceFile.getAbsolutePath());
return new SAXSource(filter, inputSource);
}
}
/**
* Creates an XML Processing handler for the built-in docbkx <?eval?>
PI. This PI resolves maven
* properties and basic math formula.
*
* @param resolver The initial resolver to use.
* @param reader The source XML reader.
* @return The XML PI filter.
*/
private PreprocessingFilter createPIHandler(EntityResolver resolver, XMLReader reader) {
PreprocessingFilter filter = new PreprocessingFilter(reader);
ProcessingInstructionHandler resolvingHandler = new ExpressionHandler(new VariableResolver() {
public Object resolveVariable(String name) throws ELException {
if ("date".equals(name)) {
return DateFormat.getDateInstance(DateFormat.LONG).format(new Date());
} else if ("project".equals(name)) {
return getMavenProject();
} else {
return getMavenProject().getProperties().get(name);
}
}
}, getLog());
filter.setHandlers(Arrays.asList(new Object[] { resolvingHandler }));
filter.setEntityResolver(resolver);
return filter;
}
/**
* Creates an XML entity resolver.
*
* @param resolver The initial resolver to use.
* @return The new XML entity resolver or null if there is no entities to resolve.
* @see com.agilejava.docbkx.maven.InjectingEntityResolver
*/
private InjectingEntityResolver createEntityResolver(EntityResolver resolver) {
if (getEntities() != null) {
return new InjectingEntityResolver(getEntities(), resolver, getType(), getLog());
} else {
return null;
}
}
/**
* Creates an URI resolver to handle urn:docbkx:stylesheet(/)
as a special URI. This URI points to the
* default docbook stylesheet location
*
* @param catalogResolver The initial resolver to use
* @return The Stylesheet resolver.
* @throws MojoExecutionException If an error occurs while reading the stylesheet
*/
private URIResolver createStyleSheetResolver(CatalogResolver catalogResolver) throws MojoExecutionException {
URIResolver uriResolver;
try {
URL url = getNonDefaultStylesheetURL() == null ? getDefaultStylesheetURL() : getNonDefaultStylesheetURL();
getLog().debug("Using stylesheet: " + url.toExternalForm());
uriResolver = new StylesheetResolver("urn:docbkx:stylesheet", new StreamSource(url.openStream(), url
.toExternalForm()), catalogResolver);
} catch (IOException ioe) {
throw new MojoExecutionException("Failed to read stylesheet.", ioe);
}
return uriResolver;
}
/**
* Returns the list of docbook files to include.
*/
private String[] scanIncludedFiles() {
final DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir(getSourceDirectory());
scanner.setIncludes(getIncludes());
scanner.scan();
return scanner.getIncludedFiles();
}
/**
* Saves the Docbook XML file with all XInclude resolved.
*
* @param initialFilename Filename of the root docbook source file.
* @param doc XOM Document resolved.
* @return The new file generated.
* @throws MojoExecutionException
*/
protected File dumpResolvedXML(String initialFilename, nu.xom.Document doc) throws MojoExecutionException {
final File file = new File(initialFilename);
final String parent = file.getParent();
File resolvedXML = null;
if (parent != null) {
resolvedXML = new File(getGeneratedSourceDirectory(), parent);
resolvedXML.mkdirs();
resolvedXML = new File(resolvedXML, "(gen)" + file.getName());
} else {
getGeneratedSourceDirectory().mkdirs();
resolvedXML = new File(getGeneratedSourceDirectory(), "(gen)" + initialFilename);
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(resolvedXML);
} catch (FileNotFoundException e) {
throw new MojoExecutionException("Failed to open dump file", e);
}
if (fos != null) {
getLog().info("Dumping to " + resolvedXML.getAbsolutePath());
final BufferedOutputStream bos = new BufferedOutputStream(fos);
final Serializer serializer = new Serializer(bos);
try {
serializer.write(doc);
bos.flush();
bos.close();
fos.close();
return resolvedXML;
} catch (IOException e) {
throw new MojoExecutionException("Failed to write to dump file", e);
} finally {
IOUtils.closeQuietly(bos);
IOUtils.closeQuietly(fos);
}
}
throw new MojoExecutionException("Failed to open dump file");
}
/**
* Returns the SAXParserFactory used for constructing parsers.
*/
private SAXParserFactory createParserFactory() {
SAXParserFactory factory = new SAXParserFactoryImpl();
factory.setXIncludeAware(getXIncludeSupported());
return factory;
}
/**
* Returns a boolean indicating if XInclude should be supported.
*
* @return A boolean indicating if XInclude should be supported.
*/
protected abstract boolean getXIncludeSupported();
/**
* Returns the directory to use to save the resolved docbook XML before it is given to the Transformer.
*
* @return
*/
protected abstract File getGeneratedSourceDirectory();
/**
* The stylesheet location override by a class in the mojo hierarchy.
*
* @return The location of the stylesheet set by one of the superclasses, or null
.
*/
protected String getNonDefaultStylesheetLocation() {
return null;
}
/**
* Returns false if the stylesheet is responsible to create the output file(s) using its own naming scheme.
*
* @return If using the standard output.
*/
abstract protected boolean isUseStandardOutput();
abstract void setUseStandardOutput(boolean useStandardOutput);
/**
* The operation to override when it is required to make some adjustments to the {@link Transformer} right before it is
* applied to a certain source file. The two parameters provide some context, allowing implementers to respond to
* specific conditions for specific files.
*
* @param transformer The Transformer
that must be adjusted.
* @param sourceFilename The name of the source file that is being transformed.
* @param targetFile The target File.
*/
public void adjustTransformer(Transformer transformer, String sourceFilename, File targetFile) {
// To be implemented by subclasses.
}
/**
* Allows subclasses to add their own specific pre-processing logic.
*
* @throws MojoExecutionException If the Mojo fails to pre-process the results.
*/
public void preProcess() throws MojoExecutionException {
// save system properties
originalSystemProperties = (Properties) System.getProperties().clone();
// set the new properties
if (getSystemProperties() != null) {
final Enumeration props = getSystemProperties().keys();
while (props.hasMoreElements()) {
final String key = (String) props.nextElement();
System.setProperty(key, getSystemProperties().getProperty(key));
}
}
if (getPreProcess() != null) {
executeTasks(getPreProcess(), getMavenProject());
}
}
/**
* Allows classes to add their own specific post-processing logic.
*
* @throws MojoExecutionException If the Mojo fails to post-process the results.
*/
public void postProcess() throws MojoExecutionException {
if (getPostProcess() != null) {
executeTasks(getPostProcess(), getMavenProject());
}
// restore system properties
if (originalSystemProperties != null) {
System.setProperties(originalSystemProperties);
}
}
/**
* Post-processes the file. (Might be changed in the future to except an XML representation instead of a file, in order
* to prevent the file from being parsed.)
*
* @param result An individual result.
*/
public void postProcessResult(File result) throws MojoExecutionException {
}
/**
* Creates a CatalogManager
, used to resolve DTDs and other entities.
*
* @return A CatalogManager
to be used for resolving DTDs and other entities.
*/
protected CatalogManager createCatalogManager() {
CatalogManager manager = new CatalogManager();
manager.setIgnoreMissingProperties(true);
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
StringBuffer builder = new StringBuffer();
boolean first = true;
for (int i = 0; i < catalogs.length; i++) {
final String catalog = catalogs[i];
try {
Enumeration enumeration = classLoader.getResources(catalog);
while (enumeration.hasMoreElements()) {
if (!first) {
builder.append(';');
} else {
first = false;
}
URL resource = (URL) enumeration.nextElement();
builder.append(resource.toExternalForm());
}
} catch (IOException ioe) {
getLog().warn("Failed to search for catalog files: " + catalog);
// Let's be a little tolerant here.
}
}
String catalogFiles = builder.toString();
if (catalogFiles.length() == 0) {
getLog().warn("Failed to find catalog files.");
} else {
if (getLog().isDebugEnabled()) {
getLog().debug("Catalogs to load: " + catalogFiles);
}
manager.setCatalogFiles(catalogFiles);
}
return manager;
}
/**
* Creates a DocumentBuilder
to be used to parse DocBook XML documents.
*
* @return A DocumentBuilder
instance.
* @throws MojoExecutionException If we cannot create an instance of the DocumentBuilder
.
*/
protected DocumentBuilder createDocumentBuilder() throws MojoExecutionException {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder;
} catch (ParserConfigurationException pce) {
throw new MojoExecutionException("Failed to construct parser.", pce);
}
}
/**
* Creates an instance of an XPath expression for picking the title from a document.
*
* @return An XPath expression to pick the title from a document.
* @throws MojoExecutionException If the XPath expression cannot be parsed.
*/
protected XPath createTitleXPath() throws MojoExecutionException {
try {
StringBuffer builder = new StringBuffer();
builder.append("(article/title|article/articleinfo/title|book/title|book/bookinfo/title)[position()=1]");
return new DOMXPath(builder.toString());
} catch (JaxenException je) {
throw new MojoExecutionException("Failed to parse XPath.", je);
}
}
/**
* Constructs the default {@link TransformerBuilder}.
*/
protected TransformerBuilder createTransformerBuilder(URIResolver resolver) {
return new CachingTransformerBuilder(new DefaultTransformerBuilder(resolver));
}
/**
* Returns the title of the document.
*
* @param document The document from which we want the title.
* @return The title of the document, or null
if we can't find the title.
*/
private String getTitle(Document document) throws MojoExecutionException {
try {
XPath titleXPath = createTitleXPath();
Node titleNode = (Node) titleXPath.selectSingleNode(document);
if (titleNode != null) {
return titleNode.getNodeValue();
} else {
return null;
}
} catch (JaxenException je) {
getLog().debug("Failed to find title of document.");
return null;
}
}
protected void executeTasks(Target antTasks, MavenProject mavenProject) throws MojoExecutionException {
try {
ExpressionEvaluator exprEvaluator = (ExpressionEvaluator) antTasks.getProject().getReference(
"maven.expressionEvaluator");
Project antProject = antTasks.getProject();
PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(antProject);
propertyHelper.setNext(new AntPropertyHelper(exprEvaluator, getLog()));
DefaultLogger antLogger = new DefaultLogger();
antLogger.setOutputPrintStream(System.out);
antLogger.setErrorPrintStream(System.err);
antLogger.setMessageOutputLevel(2);
antProject.addBuildListener(antLogger);
antProject.setBaseDir(mavenProject.getBasedir());
Path p = new Path(antProject);
p.setPath(StringUtils.join(mavenProject.getArtifacts().iterator(), File.pathSeparator));
antProject.addReference("maven.dependency.classpath", p);
p = new Path(antProject);
p.setPath(StringUtils.join(mavenProject.getCompileClasspathElements().iterator(), File.pathSeparator));
antProject.addReference("maven.compile.classpath", p);
p = new Path(antProject);
p.setPath(StringUtils.join(mavenProject.getRuntimeClasspathElements().iterator(), File.pathSeparator));
antProject.addReference("maven.runtime.classpath", p);
p = new Path(antProject);
p.setPath(StringUtils.join(mavenProject.getTestClasspathElements().iterator(), File.pathSeparator));
antProject.addReference("maven.test.classpath", p);
List artifacts = getArtifacts();
List list = new ArrayList(artifacts.size());
File file;
for (Iterator i = artifacts.iterator(); i.hasNext(); list.add(file.getPath())) {
Artifact a = (Artifact) i.next();
file = a.getFile();
if (file == null)
throw new DependencyResolutionRequiredException(a);
}
p = new Path(antProject);
p.setPath(StringUtils.join(list.iterator(), File.pathSeparator));
antProject.addReference("maven.plugin.classpath", p);
getLog().info("Executing tasks");
antTasks.execute();
getLog().info("Executed tasks");
} catch (Exception e) {
throw new MojoExecutionException("Error executing ant tasks", e);
}
}
/**
* The default policy for constructing Transformers.
*/
private class DefaultTransformerBuilder implements TransformerBuilder {
/**
* The standard {@link URIResolver}.
*/
private URIResolver resolver;
public DefaultTransformerBuilder(URIResolver resolver) {
this.resolver = resolver;
}
public Transformer build() throws TransformerBuilderException {
Transformer transformer = createTransformer(resolver);
transformer.setURIResolver(resolver);
return transformer;
}
/**
* Returns a Transformer
capable of rendering a particular type of output from DocBook input.
*
* @param uriResolver
* @return A Transformer
capable of rendering a particular type of output from DocBook input.
* @throws MojoExecutionException If the operation fails to create a Transformer
.
*/
protected Transformer createTransformer(URIResolver uriResolver) throws TransformerBuilderException {
URL url = getStylesheetURL();
try {
TransformerFactory transformerFactory = new TransformerFactoryImpl();
transformerFactory.setURIResolver(uriResolver);
Source source = new StreamSource(url.openStream(), url.toExternalForm());
Transformer transformer = transformerFactory.newTransformer(source);
if (!getLog().isDebugEnabled()) {
Controller controller = (Controller) transformer;
try {
controller.makeMessageEmitter();
controller.getMessageEmitter().setWriter(new NullWriter());
} catch (TransformerException te) {
getLog().error("Failed to redirect xsl:message output.", te);
}
}
if (getCustomizationParameters() != null) {
getLog().info("Applying customization parameters");
final Iterator iterator = getCustomizationParameters().iterator();
while (iterator.hasNext()) {
Parameter param = (Parameter) iterator.next();
if (param.getName() != null) // who knows
{
transformer.setParameter(param.getName(), param.getValue());
}
}
}
configure(transformer);
return transformer;
} catch (IOException ioe) {
throw new TransformerBuilderException("Failed to read stylesheet from " + url.toExternalForm(), ioe);
} catch (TransformerConfigurationException tce) {
throw new TransformerBuilderException("Failed to build Transformer from " + url.toExternalForm(), tce);
}
}
}
/**
* Configure the Transformer by passing in some parameters.
*
* @param transformer The Transformer that needs to be configured.
*/
protected abstract void configure(Transformer transformer);
/**
* Returns the target directory in which all results should be placed.
*
* @return The target directory in which all results should be placed.
*/
protected abstract File getTargetDirectory();
/**
* Returns the source directory containing the source XML files.
*
* @return The source directory containing the source XML files.
*/
protected abstract File getSourceDirectory();
/**
* Returns the include patterns, as a comma-seperate collection of patterns.
*/
protected abstract String[] getIncludes();
/**
* Returns the URL of the stylesheet. You can override this operation to return a URL pointing to a stylesheet residing
* on a location that can be adressed by a URL. By default, it will return a stylesheet that will be loaded from the
* classpath, using the resource name returned by {@link #getStylesheetLocation()}.
*
* @return The URL of the stylesheet.
*/
protected URL getStylesheetURL() {
URL url = this.getClass().getClassLoader().getResource(getStylesheetLocation());
if (url == null) {
try {
if (getStylesheetLocation().startsWith("http://")) {
return new URL(getStylesheetLocation());
}
return new File(getStylesheetLocation()).toURL();
} catch (MalformedURLException mue) {
return null;
}
} else {
return url;
}
}
/**
* Returns the URL of the default stylesheet.
*
* @return The URL of the stylesheet.
*/
protected URL getNonDefaultStylesheetURL() {
if (getNonDefaultStylesheetLocation() != null) {
URL url = this.getClass().getClassLoader().getResource(getNonDefaultStylesheetLocation());
return url;
} else {
return null;
}
}
/**
* Returns the URL of the default stylesheet.
*
* @return The URL of the stylesheet.
*/
protected URL getDefaultStylesheetURL() {
URL url = this.getClass().getClassLoader().getResource(getDefaultStylesheetLocation());
return url;
}
/**
* Returns the default stylesheet location within the root of the stylesheet distribution.
*
* @return The location of the directory containing the stylesheets.
*/
protected abstract String getDefaultStylesheetLocation();
/**
* Returns the actual stylesheet location.
*
* @return The actual stylesheet location.
*/
protected abstract String getStylesheetLocation();
/**
* Returns the extension of the target files, e.g. "html" for HTML files, etc.
*
* @return The extension of the target files.
*/
protected abstract String getTargetFileExtension();
/**
* Sets the file extension, this can be usefull to override this value especially
* for multiple transformations plugins (like XML to FO to PDF).
*
* @param extension The file extension to set
*/
protected abstract void setTargetFileExtension(String extension);
/**
* Returns a list of {@link Entity Entities}
*/
protected abstract List getEntities();
/**
* A list of additional XSL parameters to give to the XSLT engine. These parameters overrides regular docbook ones as
* they are last configured.
For regular docbook parameters prefer the use of this plugin facilities offering
* named paramters.
These parameters feet well for custom properties you may have defined within your
* customization layer.
*
* {@link Parameter customizationParameters}
*/
protected abstract List getCustomizationParameters();
/**
* A copy of JVM system properties before plugin process.
*/
private Properties originalSystemProperties;
/**
* Returns the additional System Properties. JVM System Properties are copied back if no problem have occurred
* during the plugin process.
*
* @return The current forked System Properties.
*/
protected abstract Properties getSystemProperties();
/**
* Returns the tasks that should be executed before the transformation.
*
* @return The tasks that should be executed before the transformation.
*/
protected abstract Target getPreProcess();
/**
* Returns the tasks that should be executed after the transformation.
*
* @return The tasks that should be executed after the transformation.
*/
protected abstract Target getPostProcess();
/**
* Returns a reference to the current project.
*
* @return A reference to the current project.
*/
protected abstract MavenProject getMavenProject();
/**
* Returns the plugin dependencies.
*
* @return The plugin dependencies.
*/
protected abstract List getArtifacts();
/**
* Returns the type of conversion.
*/
protected abstract String getType();
/**
* Converts a String parameter to the type expected by the XSLT processor.
*/
protected Object convertStringToXsltParam(String value) {
return value;
}
/**
* Converts a Boolean parameter to the type expected by the XSLT processor.
*/
protected Object convertBooleanToXsltParam(String value) {
String trimmed = value.trim();
if ("false".equals(trimmed) || "0".equals(trimmed)) {
return "0";
} else {
return "1";
}
}
/**
* Sets the value of a property of this object using introspection.
*
* @param propertyname The field name
* @param value The value
*/
protected void setProperty(String propertyname, String value) {
try {
final Field f = this.getClass().getDeclaredField(propertyname);
if (f.getType().equals(Boolean.class)) {
f.set(this, convertBooleanToXsltParam(value));
} else {
f.set(this, value);
}
} catch (NoSuchFieldException e) {
getLog().warn("Property not found in " + this.getClass().getName(), e);
} catch (IllegalAccessException e) {
getLog().warn("Unable to set " + propertyname + " value", e);
}
}
/**
* Returns the value of a property of this object using introspection.
*
* @param propertyname The filed name
* @return The value
*/
protected String getProperty(String propertyname) {
try {
final Field f = this.getClass().getDeclaredField(propertyname);
Object o = f.get(this);
if (o == null) {
return null;
} else {
return o.toString();
}
} catch (NoSuchFieldException e) {
getLog().warn("Property not found in " + this.getClass().getName(), e);
} catch (IllegalAccessException e) {
getLog().warn("Unable to get " + propertyname + " value", e);
}
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy