Esta sección de la Especificación de Requerimientos Software
Index: src/main/java/org/codehaus/mojo/docbook/DocumentTransformer.java
===================================================================
--- src/main/java/org/codehaus/mojo/docbook/DocumentTransformer.java (revision 3044)
+++ src/main/java/org/codehaus/mojo/docbook/DocumentTransformer.java (working copy)
@@ -23,8 +23,11 @@
*/
package org.codehaus.mojo.docbook;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
@@ -29,7 +32,9 @@
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import javax.xml.transform.Result;
@@ -35,12 +40,17 @@
import javax.xml.transform.Result;
import javax.xml.transform.Source;
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.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.Fop;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.MimeConstants;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
import org.codehaus.plexus.compiler.util.scan.StaleSourceScanner;
@@ -49,10 +59,15 @@
import org.codehaus.plexus.util.FileUtils;
/**
+ * A helper class for transforming DocBook documents into different output
+ * formats.
+ *
* @author jgonzalez
+ * @author Lars Trieloff
*/
-public class DocumentTransformer
-{
+public class DocumentTransformer {
+ private Set sourcePatterns;
+
protected Log log;
protected File sourceDirectory;
@@ -65,6 +80,16 @@
protected URI stylesheetLocation;
+ private boolean generateHtml;
+
+ private boolean generatePdf;
+
+ private MojoURIResolver mojoResolver;
+
+ private String xslfoCustomization;
+
+ private String xhtmlCustomization;
+
/**
* @param log
* @param sourceDirectory
@@ -69,19 +94,35 @@
* @param log
* @param sourceDirectory
* @param outputDirectory
+ * @param customizations
*/
- public DocumentTransformer( Log log, File sourceDirectory, File resourceDirectory, File databaseDirectory,
- File outputDirectory, URI stylesheetLocation )
- {
- this.log = log;
- this.sourceDirectory = sourceDirectory;
- this.resourceDirectory = resourceDirectory;
- this.databaseDirectory = databaseDirectory;
- this.outputDirectory = outputDirectory;
- this.stylesheetLocation = stylesheetLocation;
+ public DocumentTransformer(Log log, File sourceDirectory,
+ File resourceDirectory, File databaseDirectory,
+ File outputDirectory, URI stylesheetLocation, Map customizations) {
+ this.log = log;
+ this.sourceDirectory = sourceDirectory;
+ this.resourceDirectory = resourceDirectory;
+ this.databaseDirectory = databaseDirectory;
+ this.outputDirectory = outputDirectory;
+ this.stylesheetLocation = stylesheetLocation;
+ this.mojoResolver = new MojoURIResolver();
+
+ this.xslfoCustomization = (String) customizations.get("pdf");
+ this.xhtmlCustomization = (String) customizations.get("xhtml");
+
+ this.sourcePatterns = new HashSet(2);
+ this.sourcePatterns.add("*.xml");
+ this.sourcePatterns.add("**/*xml");
+ }
+
+ public void transform() throws TransformerFactoryConfigurationError,
+ TransformerException, IOException, URISyntaxException,
+ InclusionScanException {
+ this.transform(null);
}
/**
+ * @param transformProfile
* @throws TransformerException
* @throws TransformerFactoryConfigurationError
* @throws URISyntaxException
@@ -88,32 +129,54 @@
* @throws IOException
* @throws InclusionScanException
*/
- public void transform()
- throws TransformerFactoryConfigurationError, TransformerException, IOException, URISyntaxException,
- InclusionScanException
- {
- StaleSourceScanner scanner = new StaleSourceScanner( 0, Collections.singleton( "**/*.xml" ),
- Collections.EMPTY_SET );
- scanner.addSourceMapping( new SuffixMapping( ".xml", ".html" ) );
- Set staleDocbookFiles = scanner.getIncludedSources( this.sourceDirectory, this.outputDirectory );
+ public void transform(TransformProfile transformProfile)
+ throws TransformerFactoryConfigurationError, TransformerException,
+ IOException, URISyntaxException, InclusionScanException {
+ StaleSourceScanner scanner = new StaleSourceScanner(0,
+ this.sourcePatterns, Collections.EMPTY_SET);
+ String profile = getFileExtension(transformProfile);
+ if (generateHtml) {
+ scanner
+ .addSourceMapping(new SuffixMapping(".xml", profile
+ + "html"));
+ }
+ if (generatePdf) {
+ scanner
+ .addSourceMapping(new SuffixMapping(".xml", profile + "pdf"));
+ }
+ Set staleDocbookFiles = scanner.getIncludedSources(
+ this.sourceDirectory, this.outputDirectory);
+
+ if (staleDocbookFiles.size() > 0) {
+ DirectoryScanner docbookScanner = new DirectoryScanner();
+ docbookScanner.setBasedir(this.sourceDirectory);
+ docbookScanner.setFollowSymlinks(true);
+ docbookScanner.setIncludes(new String[] { "**/*.xml", "*.xml" });
+ docbookScanner.scan();
+ String[] docbookFiles = docbookScanner.getIncludedFiles();
- if ( staleDocbookFiles.size() > 0 )
- {
- DirectoryScanner docbookScanner = new DirectoryScanner();
- docbookScanner.setBasedir( this.sourceDirectory );
- docbookScanner.setFollowSymlinks( true );
- docbookScanner.setIncludes( new String[] { "**/*.xml" } );
- docbookScanner.scan();
- String[] docbookFiles = docbookScanner.getIncludedFiles();
+ this.prepareFileSystem(docbookFiles);
+ this.transformDocuments(staleDocbookFiles, transformProfile);
+ } else {
+ this.log.info("Generated docbook files up to date");
+ }
+ if (this.resourceDirectory.exists()) {
+ FileUtils.copyDirectoryStructure(this.resourceDirectory,
+ this.outputDirectory);
+ } else {
+ this.outputDirectory.mkdirs();
+ this.log.warn("Specified resource directory does not exist: "
+ + this.resourceDirectory.toString());
+ }
+ }
- this.prepareFileSystem( docbookFiles );
- this.transformDocuments( staleDocbookFiles );
- }
- else
- {
- this.log.info( "Generated docbook files up to date" );
- }
- FileUtils.copyDirectoryStructure( this.resourceDirectory, this.outputDirectory );
+ private String getFileExtension(TransformProfile transformProfile) {
+ StringBuffer profile = new StringBuffer(".");
+ if (transformProfile != null) {
+ profile.append(transformProfile.getId());
+ profile.append(".");
+ }
+ return profile.toString();
}
/**
@@ -119,67 +182,211 @@
/**
* @param docbookFiles
*/
- protected void prepareFileSystem( String[] docbookFiles )
- {
- this.log.debug( "Creating output directories for the following files - "
- + Arrays.asList( docbookFiles ).toString() );
- // TODO: This should be a bit smarter also, shouldn't it?
- for ( int fileIndex = 0; fileIndex < docbookFiles.length; fileIndex++ )
- {
- String docbookFile = docbookFiles[fileIndex];
- int lastFileSeparator = docbookFile.lastIndexOf( File.separator );
- if ( lastFileSeparator > 0 )
- {
- File directory = new File( this.outputDirectory, docbookFile.substring( 0, lastFileSeparator ) );
- directory.mkdirs();
- }
- }
+ protected void prepareFileSystem(String[] docbookFiles) {
+ this.log.debug("Creating output directories for the following files - "
+ + Arrays.asList(docbookFiles).toString());
+ this.outputDirectory.mkdirs();
+ // TODO: This should be a bit smarter also, shouldn't it?
+ for (int fileIndex = 0; fileIndex < docbookFiles.length; fileIndex++) {
+ String docbookFile = docbookFiles[fileIndex];
+ int lastFileSeparator = docbookFile.lastIndexOf(File.separator);
+ if (lastFileSeparator > 0) {
+ File directory = new File(this.outputDirectory, docbookFile
+ .substring(0, lastFileSeparator));
+ directory.mkdirs();
+ }
+ }
+ }
+
+ protected void transformDocuments(Set docbookFiles,
+ TransformProfile transformProfile) throws TransformerException,
+ URISyntaxException {
+ this.log.info("Transforming " + docbookFiles.size()
+ + " Docbook stale file(s)");
+ Transformer xhtmlTransformer = null;
+ Transformer xslfoTransformer = null;
+ FopFactory fopFactory = null;
+ URI olinkDBURI = new File(this.databaseDirectory + File.separator
+ + "olinkdb.xml").toURI();
+
+ if (generateHtml) {
+ xhtmlTransformer = createXHTMLTransformer(olinkDBURI,
+ transformProfile);
+ }
+ if (generatePdf) {
+ xslfoTransformer = createXSLFOTransformer(olinkDBURI,
+ transformProfile);
+ fopFactory = FopFactory.newInstance();
+ fopFactory.setURIResolver(this.mojoResolver);
+ }
+ Iterator filesIterator = docbookFiles.iterator();
+ while (filesIterator.hasNext()) {
+ File docbookFile = (File) filesIterator.next();
+ if (generateHtml) {
+ transformXhtml(xhtmlTransformer, docbookFile, transformProfile);
+ }
+ if (generatePdf) {
+ transformPdf(xslfoTransformer, docbookFile, fopFactory,
+ transformProfile);
+ }
+ }
}
- protected void transformDocuments( Set docbookFiles )
- throws TransformerException, URISyntaxException
- {
- this.log.info( "Transforming " + docbookFiles.size() + " Docbook stale file(s)" );
- Source docbookStyleSheetSource = new StreamSource( this.stylesheetLocation.resolve( "xhtml/docbook.xsl" )
- .toString() );
- Transformer documentTransformer = TransformerFactory.newInstance().newTransformer( docbookStyleSheetSource );
- URI olinkDBURI = new File( this.databaseDirectory + File.separator + "olinkdb.xml" ).toURI();
- documentTransformer.setParameter( "target.database.document", olinkDBURI.toString() );
- documentTransformer.setParameter( "generate.toc", "" );
- this.log.debug( "Style sheet loaded." );
+ private Transformer createXSLFOTransformer(URI olinkDBURI,
+ TransformProfile transformProfile)
+ throws TransformerFactoryConfigurationError, TransformerException,
+ TransformerConfigurationException {
+ Transformer xslfoTransformer;
+ TransformerFactory xslfoTf = TransformerFactory.newInstance();
+ xslfoTf.setURIResolver(this.mojoResolver);
+ Source docbookStyleSheetSource;
+ if ((this.xslfoCustomization == null) && (transformProfile == null)) {
+ docbookStyleSheetSource = this.mojoResolver.resolve("docbook.xsl",
+ this.stylesheetLocation.toASCIIString() + "fo/");
+ } else if ((this.xslfoCustomization == null)
+ && (transformProfile != null)) {
+ docbookStyleSheetSource = this.mojoResolver.resolve(
+ "profile-docbook.xsl", this.stylesheetLocation
+ .toASCIIString()
+ + "fo/");
+ } else {
+ docbookStyleSheetSource = this.mojoResolver.resolve(
+ this.xslfoCustomization, this.sourceDirectory.toURI()
+ .toString());
+ }
+ xslfoTransformer = xslfoTf.newTransformer(docbookStyleSheetSource);
+ xslfoTransformer.setParameter("target.database.document", olinkDBURI
+ .toString());
- Iterator filesIterator = docbookFiles.iterator();
- while ( filesIterator.hasNext() )
- {
- File docbookFile = (File) filesIterator.next();
- this.log.debug( "Processing " + this.sourceDirectory + File.separator + docbookFile );
- Source source = new StreamSource( docbookFile );
- String relativePath = docbookFile.getAbsolutePath().substring(
- (int) this.sourceDirectory.getAbsolutePath()
- .length() );
- File resultFile = new File( this.outputDirectory, relativePath
- .substring( 0, relativePath.lastIndexOf( '.' ) )
- + ".html" );
- Result result = new StreamResult( resultFile.getAbsolutePath() );
+ if (transformProfile != null) {
+ transformProfile.setParameters(xslfoTransformer);
+ }
- documentTransformer.setParameter( "current.docid", OLinkDBUpdater.computeFileID( relativePath ) );
- // TODO: Parametrize this !!!!
- documentTransformer
- .setParameter( "html.stylesheet", this.pathToResources( relativePath ) + "css/xhtml.css" );
- documentTransformer.transform( source, result );
- this.log.debug( "Generated " + this.databaseDirectory + File.separator + docbookFile );
- }
+ this.log.debug("XSL:FO Style sheet loaded.");
+ return xslfoTransformer;
}
- protected String pathToResources( String relativePath )
- {
- StringBuffer pathToResources = new StringBuffer();
- int separatorIndex = relativePath.indexOf( File.separator, 1 );
- while ( separatorIndex != -1 )
- {
- pathToResources.append( "../" );
- separatorIndex = relativePath.indexOf( File.separator, separatorIndex + 1 );
- }
- return pathToResources.toString();
+ private Transformer createXHTMLTransformer(URI olinkDBURI,
+ TransformProfile transformProfile)
+ throws TransformerFactoryConfigurationError, TransformerException,
+ TransformerConfigurationException {
+ Transformer xhtmlTransformer;
+ TransformerFactory xhtmlTf = TransformerFactory.newInstance();
+ xhtmlTf.setURIResolver(this.mojoResolver);
+ Source docbookStyleSheetSource;
+ if ((this.xslfoCustomization == null) && (transformProfile == null)) {
+ docbookStyleSheetSource = this.mojoResolver.resolve("docbook.xsl",
+ this.stylesheetLocation.toASCIIString() + "xhtml/");
+ } else if ((this.xslfoCustomization == null)
+ && (transformProfile != null)) {
+ docbookStyleSheetSource = this.mojoResolver.resolve(
+ "profile-docbook.xsl", this.stylesheetLocation
+ .toASCIIString()
+ + "xhtml/");
+ } else {
+ docbookStyleSheetSource = this.mojoResolver.resolve(
+ this.xhtmlCustomization, this.sourceDirectory.toURI()
+ .toString());
+ }
+ xhtmlTransformer = xhtmlTf.newTransformer(docbookStyleSheetSource);
+ xhtmlTransformer.setParameter("target.database.document", olinkDBURI
+ .toString());
+ xhtmlTransformer.setParameter("generate.toc", "");
+
+ if (transformProfile != null) {
+ transformProfile.setParameters(xhtmlTransformer);
+ }
+
+ this.log.debug("XHTML Style sheet loaded.");
+ return xhtmlTransformer;
+ }
+
+ private void transformXhtml(Transformer documentTransformer,
+ File docbookFile, TransformProfile transformProfile)
+ throws TransformerException {
+ this.log.debug("Processing " + this.sourceDirectory + File.separator
+ + docbookFile);
+ Source source = this.mojoResolver.resolve(docbookFile.toURI()
+ .toString(), null);
+ String relativePath = docbookFile.getAbsolutePath().substring(
+ (int) this.sourceDirectory.getAbsolutePath().length());
+
+ File resultFile = new File(this.outputDirectory, relativePath
+ .substring(0, relativePath.lastIndexOf('.'))
+ + getFileExtension(transformProfile) + "html");
+ Result result = new StreamResult(resultFile.getAbsolutePath());
+
+ documentTransformer.setParameter("current.docid", OLinkDBUpdater
+ .computeFileID(relativePath));
+ // TODO: Parametrize this !!!!
+ documentTransformer.setParameter("html.stylesheet", this
+ .pathToResources(relativePath)
+ + "css/xhtml.css");
+ documentTransformer.transform(source, result);
+ this.log.debug("Generated " + this.databaseDirectory + File.separator
+ + docbookFile);
+ }
+
+ private void transformPdf(Transformer documentTransformer,
+ File docbookFile, FopFactory fopFactory,
+ TransformProfile transformProfile) throws TransformerException {
+ this.log.debug("Processing " + this.sourceDirectory + File.separator
+ + docbookFile);
+ Source source = this.mojoResolver.resolve(docbookFile.toURI()
+ .toString(), null);
+ String relativePath = docbookFile.getAbsolutePath().substring(
+ (int) this.sourceDirectory.getAbsolutePath().length());
+ File resultFile = new File(this.outputDirectory, relativePath
+ .substring(0, relativePath.lastIndexOf('.'))
+ + getFileExtension(transformProfile) + "pdf");
+ this.mojoResolver.setDocumentUri(docbookFile.toURI());
+ documentTransformer.setParameter("current.docid", OLinkDBUpdater
+ .computeFileID(relativePath));
+ try {
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(
+ resultFile.getAbsolutePath()));
+ try {
+ Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
+ Result intermediate = new SAXResult(fop.getDefaultHandler());
+
+ documentTransformer.transform(source, intermediate);
+ } catch (FOPException e) {
+ this.log.error(e);
+ } finally {
+ out.close();
+ }
+ } catch (Exception e) {
+ this.log.error(e);
+ }
+ this.log.debug("Generated " + this.databaseDirectory + File.separator
+ + docbookFile);
+ }
+
+ protected String pathToResources(String relativePath) {
+ StringBuffer pathToResources = new StringBuffer();
+ int separatorIndex = relativePath.indexOf(File.separator, 1);
+ while (separatorIndex != -1) {
+ pathToResources.append("../");
+ separatorIndex = relativePath.indexOf(File.separator,
+ separatorIndex + 1);
+ }
+ return pathToResources.toString();
+ }
+
+ /**
+ * Enables a specified output format.
+ *
+ * @param format
+ * the format
+ */
+ public void enableOutputFormat(String format) {
+ if ("xhtml".equalsIgnoreCase(format)) {
+ generateHtml = true;
+ }
+ if ("pdf".equalsIgnoreCase(format)) {
+ generatePdf = true;
+ }
+
}
+
}
Index: src/main/java/org/codehaus/mojo/docbook/MojoURIResolver.java
===================================================================
--- src/main/java/org/codehaus/mojo/docbook/MojoURIResolver.java (revision 0)
+++ src/main/java/org/codehaus/mojo/docbook/MojoURIResolver.java (revision 0)
@@ -0,0 +1,95 @@
+package org.codehaus.mojo.docbook;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xml.resolver.tools.CatalogResolver;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+public class MojoURIResolver extends CatalogResolver implements URIResolver, EntityResolver {
+ private URI documentUri = null;
+
+ public InputSource resolveEntity(final String href, final String base) {
+ InputSource result;
+ String fullUri = makeFullUri(href, base);
+ if (fullUri.startsWith("resource://")) {
+ result = new InputSource(getResourceAsStream(fullUri));
+ } else {
+ result = super.resolveEntity(href, base);
+ }
+ if (result==null) {
+ result = new InputSource(fullUri);
+ }
+ if (result==null) {
+ System.out.println("can't handle this");
+ }
+ result.setSystemId(fullUri);
+ return result;
+ }
+
+ public Source resolve(final String href, final String base) throws TransformerException {
+ Source result;
+ String fullUri = makeFullUri(href, base);
+ try {
+ XMLReader reader;
+ // get a SAXParserFactory instance
+ SAXParserFactory SAXpf = SAXParserFactory.newInstance();
+ // enabling the namespaces processing
+ SAXpf.setNamespaceAware(true);
+ // get a SAXParser object
+ SAXParser SAXparser = SAXpf.newSAXParser();
+ // get the XMLReader
+ reader = SAXparser.getXMLReader();
+ reader.setEntityResolver(this);
+ // creating the SAXSource
+ InputSource insrc = this.resolveEntity(href, base);
+ result = new SAXSource(reader, insrc);
+ } catch (javax.xml.parsers.ParserConfigurationException e) {
+ result = new StreamSource(getResourceAsStream(fullUri));
+ } catch (org.xml.sax.SAXException e) {
+ result = new StreamSource(getResourceAsStream(fullUri));
+ }
+ result.setSystemId(fullUri);
+ return result;
+ }
+
+ private InputStream getResourceAsStream(String fullUri) {
+ return MojoURIResolver.class.getResourceAsStream(fullUri.substring(10));
+ }
+
+ private String makeFullUri(final String href, final String base) {
+ String fullUri = href;
+ //if it is no absolute url starting with scheme:/
+ if ((href!=null)&&(base!=null)) {
+ try {
+ fullUri = URI.create(base).resolve(href).toString();
+ } catch (IllegalArgumentException use) {
+ fullUri = base;
+ }
+ } else if ((href!=null)&&(href.indexOf(":/")!=-1)) {
+ fullUri = href;
+ } else if (base!=null) {
+ fullUri = base;
+ } else if (this.documentUri!=null) {
+ fullUri = documentUri.resolve(href).toString();
+ } else {
+ fullUri = href;
+ }
+ return fullUri;
+ }
+
+ public void setDocumentUri(URI documentUri) {
+ this.documentUri = documentUri;
+ }
+
+}
Index: src/main/java/org/codehaus/mojo/docbook/OLinkDBUpdater.java
===================================================================
--- src/main/java/org/codehaus/mojo/docbook/OLinkDBUpdater.java (revision 3044)
+++ src/main/java/org/codehaus/mojo/docbook/OLinkDBUpdater.java (working copy)
@@ -43,6 +43,8 @@
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
@@ -142,9 +144,16 @@
throws TransformerFactoryConfigurationError, TransformerException
{
this.log.info( "Loading olink database generation stylesheet" );
- Source docbookStyleSheetSource = new StreamSource( this.stylesheetLocation.resolve( "xhtml/docbook.xsl" )
- .toString() );
- Transformer olinkDBGenerator = TransformerFactory.newInstance().newTransformer( docbookStyleSheetSource );
+ TransformerFactory tf = TransformerFactory.newInstance();
+ MojoURIResolver resolver = new MojoURIResolver();
+ Source docbookStyleSheetSource = resolver.resolve( "docbook.xsl", this.stylesheetLocation.toASCIIString() + "xhtml/" );
+ tf.setURIResolver(resolver);
+ if (tf.getFeature(SAXSource.FEATURE)) {
+ SAXTransformerFactory stf =
+ ((SAXTransformerFactory) tf);
+
+ }
+ Transformer olinkDBGenerator = tf.newTransformer( docbookStyleSheetSource );
olinkDBGenerator.setParameter( "collect.xref.targets", "only" );
olinkDBGenerator.setParameter( "generate.toc", "" );
Index: src/main/java/org/codehaus/mojo/docbook/TransformMojo.java
===================================================================
--- src/main/java/org/codehaus/mojo/docbook/TransformMojo.java (revision 3044)
+++ src/main/java/org/codehaus/mojo/docbook/TransformMojo.java (working copy)
@@ -27,6 +27,8 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;
@@ -40,17 +42,14 @@
import org.codehaus.plexus.compiler.util.scan.InclusionScanException;
/**
- * Transforms a set of Docbook files into XHTML output. Currently there is only support for
- * XHTML output, though is planned to add all kind of outputs available in the standard
- * stylesheets.
+ * Transforms a set of Docbook files into XHTML and PDF output.
*
* @author jgonzalez
+ * @author Lars Trieloff
* @goal transform
* @description Transform Docbook files into XHTML output
*/
-public class TransformMojo
- extends AbstractMojo
-{
+public class TransformMojo extends AbstractMojo {
private static String XERCES_PARSER_CONFIG = "org.apache.xerces.xni.parser.XMLParserConfiguration";
private static String XERCES_XINCLUDE_PARSER = "org.apache.xerces.parsers.XIncludeParserConfiguration";
@@ -55,9 +54,13 @@
private static String XERCES_XINCLUDE_PARSER = "org.apache.xerces.parsers.XIncludeParserConfiguration";
+ private static String XERCES_RESOLVER_CONFIG = "org.apache.xerces.xni.parser.XMLEntityResolver";
+
+ private static String DOCBOOK_MOJO_RESOVER = "org.codehaus.mojo.docbook.MojoURIResolver";
+
/**
* Directory where the source Docbook files are located.
- *
+ *
* @parameter expression="${basedir}/src/docbook"
* @required
*/
@@ -65,7 +68,7 @@
/**
* Directory where the resource files are located.
- *
+ *
* @parameter expression="${basedir}/src/docbook/resources"
* @required
*/
@@ -95,10 +98,107 @@
private String outputEncoding;
/**
- * Specifies the stylesheet location, useful if you want to use a local copy or a
- * specific version instead of the current release from the Internet.
+ * Specifies the list of desired output formats. Example:
+ * <outputFormats> <param>xhtml</param>
+ * <param>pdf</param> </outputFormats>
+ *
+ * @parameter
+ */
+ private String[] outputFormats = new String[] { "xhtml", "pdf" };
+ /**
+ *
+ * Specifies a list of customization stylesheets for the specified output
+ * formats. The default value is to use no customizations, but you can point
+ * this configuration parameter to your own stylesheets that set parameters
+ * or override templates.
+ *
+ *
+ * An example configuration that changes the pdf stylesheet:
+ *
*
- * @parameter expression="${stylesheetLocation}" default-value="http://docbook.sourceforge.net/release/xsl/current/"
+ *
+ * <customizations>
+ * <pdf>src/main/resources/docbook2pdf.xsl</pdf>
+ * </customizations>
+ *
+ *
+ *
+ * All relative URLs are resolved against resourcePath
+ *
+ *
+ * @parameter
+ */
+ private Map customizations = new HashMap();
+
+ /**
+ *
+ * Specifies a list of transformation profiles, e.g.
+ *
+ *
+ *
+ * <profiles>
+ * <transformProfile>
+ * <id>linux</id>
+ * <os>linux</os>
+ * </transformProfile>
+ * <transformProfile>
+ * <id>windows</id>
+ * <os>windows</os>
+ * </transformProfile>
+ * <transformProfile>
+ * <id>nonlinux</id>
+ * <operatingsystems>
+ * <os>windows</os>
+ * <os>macosx</os>
+ * </operatingsystems>
+ * </transformProfile>
+ * </profiles>
+ *
+ *
+ *
+ * This examples creates three profiles: one containing only content marked
+ * for linux, one containing only content marked for windows and a third
+ * with content marked for either windows or mac os x. The id element is
+ * required for each profile, as the resulting files will have the pattern
+ * $filename.$profile.$ext. You can combine profile conditions e.g. having
+ * an os element and an arch element in place and you can profile for
+ * multiple values as shown in the nonlinux profile.
+ *
+ *
+ * All available filtering elements are:
+ *
+ *
+ * - arch/architectures
+ * - condition/conditions
+ * - conformance/conformances
+ * - lang/languages
+ * - os/operatingsystems
+ * - revision/revisions
+ * - security/securities
+ * - userlevel/userlevels
+ * - vendor/vendors
+ *
+ *
+ * Additionally there is support for attribute-based filtering, which
+ * requires the use of attribute and value elements. For more information
+ * about DocBook profiling, see Chapter 25.
+ * Profiling (conditional text) in Bob Stayton's DocBook XSL: The
+ * Complete Guide.
+ *
+ *
+ * @parameter
+ */
+ private TransformProfile[] profiles = new TransformProfile[] {};
+
+ /**
+ * Specifies the stylesheet location, useful if you want to use a local copy
+ * or a specific version instead of the current release from the maven
+ * repository.
+ *
+ * @parameter expression="${stylesheetLocation}"
+ * default-value="resource://net/sourceforge/docbook/"
*/
private String stylesheetLocation;
@@ -114,84 +214,85 @@
*
* @see org.apache.maven.plugin.Mojo#execute()
*/
- public void execute()
- throws MojoExecutionException, MojoFailureException
- {
- Log log = this.getLog();
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ Log log = this.getLog();
- Proxy activeProxy = this.settings.getActiveProxy();
- String httpProxyHost = System.getProperty( "http.proxyHost" );
- String httpProxyPort = System.getProperty( "http.proxyPort" );
- String httpNonProxyHosts = System.getProperty( "http.nonProxyHosts" );
- if ( activeProxy != null )
- {
- System.setProperty( "http.proxyHost", activeProxy.getHost() );
- System.setProperty( "http.proxyPort", new Integer( activeProxy.getPort() ).toString() );
- System.setProperty( "http.nonProxyHosts", activeProxy.getNonProxyHosts() );
- }
+ Proxy activeProxy = this.settings.getActiveProxy();
+ String httpProxyHost = System.getProperty("http.proxyHost");
+ String httpProxyPort = System.getProperty("http.proxyPort");
+ String httpNonProxyHosts = System.getProperty("http.nonProxyHosts");
+ if (activeProxy != null) {
+ System.setProperty("http.proxyHost", activeProxy.getHost());
+ System.setProperty("http.proxyPort", new Integer(activeProxy
+ .getPort()).toString());
+ System.setProperty("http.nonProxyHosts", activeProxy
+ .getNonProxyHosts());
+ }
- // Set XInclude Xerces parser so we're able to process master olink database file
- String xercesParser = System.getProperty( TransformMojo.XERCES_PARSER_CONFIG );
- System.setProperty( TransformMojo.XERCES_PARSER_CONFIG, TransformMojo.XERCES_XINCLUDE_PARSER );
+ // Set XInclude Xerces parser so we're able to process master olink
+ // database file
+ String xercesParser = System
+ .getProperty(TransformMojo.XERCES_PARSER_CONFIG);
+ System.setProperty(TransformMojo.XERCES_PARSER_CONFIG,
+ TransformMojo.XERCES_XINCLUDE_PARSER);
+ String entityResolver = System
+ .getProperty(TransformMojo.XERCES_RESOLVER_CONFIG);
+ System.setProperty(TransformMojo.XERCES_RESOLVER_CONFIG,
+ TransformMojo.DOCBOOK_MOJO_RESOVER);
- try
- {
- URI stylesheetLocationURI = new URI( this.stylesheetLocation );
- OLinkDBUpdater olinkDBUpdater = new OLinkDBUpdater( log, this.sourceDirectory, this.databaseDirectory,
- stylesheetLocationURI );
- DocumentTransformer documentTransformer = new DocumentTransformer( log, this.sourceDirectory,
- this.resourceDirectory,
- this.databaseDirectory,
- this.outputDirectory,
- stylesheetLocationURI );
- olinkDBUpdater.update();
- documentTransformer.transform();
- }
- catch ( TransformerFactoryConfigurationError exc )
- {
- throw new MojoExecutionException( exc.getLocalizedMessage(), exc );
- }
- catch ( TransformerException exc )
- {
- throw new MojoFailureException( exc.getLocalizedMessage() );
- }
- catch ( URISyntaxException exc )
- {
- throw new MojoExecutionException( exc.getLocalizedMessage(), exc );
- }
- catch ( IOException exc )
- {
- throw new MojoExecutionException( exc.getLocalizedMessage(), exc );
- }
- catch ( InclusionScanException exc )
- {
- throw new MojoExecutionException( exc.getLocalizedMessage(), exc );
- }
- finally
- {
- // Reset XInclude Xerces parser to previous value
- if ( xercesParser != null )
- {
- System.setProperty( TransformMojo.XERCES_PARSER_CONFIG, xercesParser );
- }
- else
- {
- // In 1.4 there's no clear property method... is this correct?
- System.setProperty( TransformMojo.XERCES_PARSER_CONFIG, "" );
- }
+ try {
+ if (this.sourceDirectory.exists()) {
+ URI stylesheetLocationURI = new URI(this.stylesheetLocation);
+ OLinkDBUpdater olinkDBUpdater = new OLinkDBUpdater(log,
+ this.sourceDirectory, this.databaseDirectory,
+ stylesheetLocationURI);
+ DocumentTransformer documentTransformer = new DocumentTransformer(
+ log, this.sourceDirectory, this.resourceDirectory,
+ this.databaseDirectory, this.outputDirectory,
+ stylesheetLocationURI, this.customizations);
+ for (int i = 0; i < outputFormats.length; i++) {
+ documentTransformer.enableOutputFormat(outputFormats[i]);
+ }
+ olinkDBUpdater.update();
+ documentTransformer.transform();
+ if (this.profiles.length != 0) {
+ for (int i = 0; i < profiles.length; i++) {
+ documentTransformer.transform(this.profiles[i]);
+ }
+ }
+ }
+ } catch (TransformerFactoryConfigurationError exc) {
+ throw new MojoExecutionException(exc.getLocalizedMessage(), exc);
+ } catch (TransformerException exc) {
+ throw new MojoExecutionException(exc.getLocalizedMessage(), exc);
+ } catch (URISyntaxException exc) {
+ throw new MojoExecutionException(exc.getLocalizedMessage(), exc);
+ } catch (IOException exc) {
+ throw new MojoExecutionException(exc.getLocalizedMessage(), exc);
+ } catch (InclusionScanException exc) {
+ throw new MojoExecutionException(exc.getLocalizedMessage(), exc);
+ } finally {
+ // Reset XInclude Xerces parser to previous value
+ if (xercesParser != null) {
+ System.setProperty(TransformMojo.XERCES_PARSER_CONFIG,
+ xercesParser);
+ System.setProperty(TransformMojo.XERCES_RESOLVER_CONFIG,
+ entityResolver);
+ } else {
+ // In 1.4 there's no clear property method... is this correct?
+ System.setProperty(TransformMojo.XERCES_PARSER_CONFIG, "");
+ System.setProperty(TransformMojo.XERCES_RESOLVER_CONFIG, "");
+ }
- if ( httpProxyHost != null )
- {
- System.setProperty( "http.proxyHost", httpProxyHost );
- System.setProperty( "http.proxyPort", httpProxyPort );
- System.setProperty( "http.nonProxyHosts", httpNonProxyHosts );
- }
- else
- {
- System.setProperty( "http.proxyHost", "" );
- System.setProperty( "http.proxyPort", "" );
- System.setProperty( "http.nonProxyHosts", "" );
- }
- }
+ if (httpProxyHost != null) {
+ System.setProperty("http.proxyHost", httpProxyHost);
+ System.setProperty("http.proxyPort", httpProxyPort);
+ System.setProperty("http.nonProxyHosts", httpNonProxyHosts);
+ } else {
+ System.setProperty("http.proxyHost", "");
+ System.setProperty("http.proxyPort", "");
+ System.setProperty("http.nonProxyHosts", "");
+ }
+ }
}
}
Index: src/main/java/org/codehaus/mojo/docbook/TransformProfile.java
===================================================================
--- src/main/java/org/codehaus/mojo/docbook/TransformProfile.java (revision 0)
+++ src/main/java/org/codehaus/mojo/docbook/TransformProfile.java (revision 0)
@@ -0,0 +1,388 @@
+package org.codehaus.mojo.docbook;
+
+import javax.xml.transform.Transformer;
+
+/**
+ * A holder of profiling information, like operating system, architecture or
+ * vendor.
+ *
+ * @author Lars Trieloff
+ */
+public class TransformProfile {
+ /**
+ * A unique id for the profile
+ */
+ private String id;
+
+ /**
+ * The attribute to profile for (attribute-based profiling)
+ */
+ private String attribute;
+ /**
+ * The attribute's value to profile for (for attribute-based profiling)
+ */
+ private String value;
+
+ /**
+ * For profiling for a single hardware architecture
+ */
+ private String arch;
+ /**
+ * For profiling for multiple hardware architectures
+ */
+ private String[] archictectures;
+ /**
+ * For profiling for a single condition
+ */
+ private String condition;
+ /**
+ * For profiling for multiple conditions
+ */
+ private String[] conditions;
+ /**
+ * For profiling for a single conformance
+ */
+ private String conformance;
+ /**
+ * For profiling for multiple conformances
+ */
+ private String[] conformances;
+ /**
+ * For profiling for a single language
+ */
+ private String lang;
+ /**
+ * For profiling for multiple languages
+ */
+ private String[] languages;
+ /**
+ * For profiling for a single operating system
+ */
+ private String os;
+ /**
+ * For profiling for multiple operating systems
+ */
+ private String[] operatingsystems;
+ /**
+ * For profiling for a single revision
+ */
+ private String revision;
+ /**
+ * For profiling for multiple revisions
+ */
+ private String[] revisions;
+ /**
+ * For profiling for a single role
+ */
+ private String role;
+ /**
+ * For profiling for multiple roles
+ */
+ private String[] roles;
+ /**
+ * For profiling for a single security level
+ */
+ private String security;
+ /**
+ * For profiling for multiple profiling levels
+ */
+ private String[] securities;
+ /**
+ * For profiling for a single user level
+ */
+ private String userlevel;
+ /**
+ * For profiling for multiple user levels
+ */
+ private String[] userlevels;
+ /**
+ * For profiling for a single vendor
+ */
+ private String vendor;
+ /**
+ * For profiling for multiple vendors
+ */
+ private String vendors[];
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAttribute() {
+ return attribute;
+ }
+
+ public void setAttribute(String attribute) {
+ this.attribute = attribute;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getArch() {
+ return arch;
+ }
+
+ public void setArch(String arch) {
+ this.arch = arch;
+ }
+
+ public String[] getArchictectures() {
+ return archictectures;
+ }
+
+ public void setArchictectures(String[] archictectures) {
+ this.archictectures = archictectures;
+ }
+
+ public String getCondition() {
+ return condition;
+ }
+
+ public void setCondition(String condition) {
+ this.condition = condition;
+ }
+
+ public String[] getConditions() {
+ return conditions;
+ }
+
+ public void setConditions(String[] conditions) {
+ this.conditions = conditions;
+ }
+
+ public String getConformance() {
+ return conformance;
+ }
+
+ public void setConformance(String conformance) {
+ this.conformance = conformance;
+ }
+
+ public String[] getConformances() {
+ return conformances;
+ }
+
+ public void setConformances(String[] conformances) {
+ this.conformances = conformances;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+
+ public void setLang(String lang) {
+ this.lang = lang;
+ }
+
+ public String[] getLanguages() {
+ return languages;
+ }
+
+ public void setLanguages(String[] languages) {
+ this.languages = languages;
+ }
+
+ public String getOs() {
+ return os;
+ }
+
+ public void setOs(String os) {
+ this.os = os;
+ }
+
+ public String[] getOperatingsystems() {
+ return operatingsystems;
+ }
+
+ public void setOperatingsystems(String[] operatingsystems) {
+ this.operatingsystems = operatingsystems;
+ }
+
+ public String getRevision() {
+ return revision;
+ }
+
+ public void setRevision(String revision) {
+ this.revision = revision;
+ }
+
+ public String[] getRevisions() {
+ return revisions;
+ }
+
+ public void setRevisions(String[] revisions) {
+ this.revisions = revisions;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String[] getRoles() {
+ return roles;
+ }
+
+ public void setRoles(String[] roles) {
+ this.roles = roles;
+ }
+
+ public String getSecurity() {
+ return security;
+ }
+
+ public void setSecurity(String security) {
+ this.security = security;
+ }
+
+ public String[] getSecurities() {
+ return securities;
+ }
+
+ public void setSecurities(String[] securities) {
+ this.securities = securities;
+ }
+
+ public String getUserlevel() {
+ return userlevel;
+ }
+
+ public void setUserlevel(String userlevel) {
+ this.userlevel = userlevel;
+ }
+
+ public String[] getUserlevels() {
+ return userlevels;
+ }
+
+ public void setUserlevels(String[] userlevels) {
+ this.userlevels = userlevels;
+ }
+
+ public String getVendor() {
+ return vendor;
+ }
+
+ public void setVendor(String vendor) {
+ this.vendor = vendor;
+ }
+
+ public String[] getVendors() {
+ return vendors;
+ }
+
+ public void setVendors(String[] vendors) {
+ this.vendors = vendors;
+ }
+
+ /**
+ * Concatenates all profile values.
+ *
+ * @return concatenated string conatining all profile values;
+ */
+ private String concatenateValues() {
+ StringBuffer buf = new StringBuffer();
+ append(buf, this.arch);
+ append(buf, this.archictectures);
+ append(buf, this.attribute);
+ append(buf, this.condition);
+ append(buf, this.conditions);
+ append(buf, this.conformance);
+ append(buf, this.conformances);
+ append(buf, this.lang);
+ append(buf, this.languages);
+ append(buf, this.operatingsystems);
+ append(buf, this.os);
+ append(buf, this.revision);
+ append(buf, this.revisions);
+ append(buf, this.role);
+ append(buf, this.roles);
+ append(buf, this.securities);
+ append(buf, this.security);
+ append(buf, this.userlevel);
+ append(buf, this.userlevels);
+ append(buf, this.vendor);
+ append(buf, this.vendors);
+ return buf.toString();
+ }
+
+ private void append(StringBuffer buf, String string) {
+ if (string == null) {
+ return;
+ }
+ buf.append(string);
+ }
+
+ private void append(StringBuffer buf, String[] strings) {
+ if (strings == null) {
+ return;
+ }
+ for (int i = 0; i < strings.length; i++) {
+ buf.append(strings[i]);
+ }
+ }
+
+ public String getSeparator() {
+ int startchar = 33;
+ String values = this.concatenateValues();
+ while (values.indexOf(startchar) != -1) {
+ startchar++;
+ }
+ return new String(new byte[] { (byte) startchar });
+ }
+
+ public void setParameters(Transformer t) {
+ String s = this.getSeparator();
+ t.setParameter("profile.separator", s);
+ setParameter(t, "profile.arch", arch, archictectures, s);
+ setParameter(t, "profile.condition", condition, conditions, s);
+ setParameter(t, "profile.conformance", conformance, conformances, s);
+ setParameter(t, "profile.lang", lang, languages, s);
+ setParameter(t, "profile.os", os, operatingsystems, s);
+ setParameter(t, "profile.revision", revision, revisions, s);
+ setParameter(t, "profile.role", role, roles, s);
+ setParameter(t, "profile.security", security, securities, s);
+ setParameter(t, "profile.userlevel", userlevel, userlevels, s);
+ setParameter(t, "profile.vendor", vendor, vendors, s);
+
+ if (attribute != null && attribute.length() != 0 && value != null
+ && value.length() != 0) {
+ t.setParameter("profile.attribute", attribute);
+ t.setParameter("profile.value", value);
+ }
+ }
+
+ public static void setParameter(Transformer transformer, String parameter,
+ String singlevalue, String[] multivalue, String separator) {
+ if ((multivalue == null || multivalue.length == 0)
+ && (singlevalue != null) && (!"".equals(singlevalue))) {
+ transformer.setParameter(parameter, singlevalue);
+ } else if (multivalue != null && multivalue.length != 0) {
+ transformer.setParameter(parameter, join(multivalue, separator));
+ }
+ }
+
+ private static String join(String[] strings, String separator) {
+ StringBuffer joined = new StringBuffer();
+ for (int i = 0; i < strings.length; i++) {
+ if (i != 0) {
+ joined.append(separator);
+ }
+ joined.append(strings[i]);
+ }
+ return joined.toString();
+ }
+}
Index: src/test/java/org/codehas/mojo/docbook/TransformProfileTest.java
===================================================================
--- src/test/java/org/codehas/mojo/docbook/TransformProfileTest.java (revision 0)
+++ src/test/java/org/codehas/mojo/docbook/TransformProfileTest.java (revision 0)
@@ -0,0 +1,18 @@
+package org.codehas.mojo.docbook;
+
+import org.codehaus.mojo.docbook.TransformProfile;
+
+import junit.framework.TestCase;
+
+public class TransformProfileTest extends TestCase {
+
+ public void testGetSeparator() {
+ TransformProfile profile = new TransformProfile();
+
+ profile.setOs("linux!");
+ profile.setArch("\"");
+
+ System.out.println(profile.getSeparator());
+ }
+
+}