Index: pom.xml =================================================================== --- pom.xml (revision 3044) +++ pom.xml (working copy) @@ -9,7 +9,7 @@ docbook-maven-plugin maven-plugin Maven Docbook plugin - 1.0.0-alpha-1-SNAPSHOT + 1.0.0-alpha-1-Mindquarry This plugin adds support for Docbook transformations to Maven. http://mojo.codehaus.org/maven-docbook-plugin @@ -20,6 +20,13 @@ http://www.openinput.com/ +1 + + Lars Trieloff + lars.trieloff@mindquarry.com + Mindquarry GmbH + http://www.mindquarry.com/ + +1 + @@ -52,6 +59,17 @@ test + org.docbook + docbook-xsl + 1.71.1 + runtime + + + xml-resolver + xml-resolver + 1.2 + + org.apache.maven maven-plugin-api 2.0 @@ -80,7 +98,17 @@ xerces xercesImpl - 2.6.2 + 2.7.1 + + + org.apache.xmlgraphics + fop + 0.92beta + + + commons-logging + commons-logging + 1.1 runtime Index: src/docbook/nested/UCS3.xml =================================================================== --- src/docbook/nested/UCS3.xml (revision 3044) +++ src/docbook/nested/UCS3.xml (working copy) @@ -1,6 +1,6 @@ - +
Nombre del proyecto - Cliente 3 Index: src/docbook/other/pass/UCS2.xml =================================================================== --- src/docbook/other/pass/UCS2.xml (revision 3044) +++ src/docbook/other/pass/UCS2.xml (working copy) @@ -1,6 +1,6 @@ - +
Nombre del proyecto - Cliente 2 Index: src/docbook/other/UCS1.xml =================================================================== --- src/docbook/other/UCS1.xml (revision 3044) +++ src/docbook/other/UCS1.xml (working copy) @@ -1,6 +1,6 @@ - +
Nombre del proyecto - Cliente 1 Index: src/docbook/SRS.xml =================================================================== --- src/docbook/SRS.xml (revision 3044) +++ src/docbook/SRS.xml (working copy) @@ -1,6 +1,6 @@ - +
Nombre del proyecto - Cliente 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,18 @@ 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; @@ -50,10 +61,13 @@ /** * @author jgonzalez + * @author Lars Trieloff */ public class DocumentTransformer { - protected Log log; + private Set sourcePatterns; + + protected Log log; protected File sourceDirectory; @@ -65,6 +79,16 @@ protected URI stylesheetLocation; + private boolean generateHtml; + + private boolean generatePdf; + + private MojoURIResolver mojoResolver; + + private String xslfoCustomization; + + private String xhtmlCustomization; + /** * @param log * @param sourceDirectory @@ -69,9 +93,10 @@ * @param log * @param sourceDirectory * @param outputDirectory + * @param customizations */ public DocumentTransformer( Log log, File sourceDirectory, File resourceDirectory, File databaseDirectory, - File outputDirectory, URI stylesheetLocation ) + File outputDirectory, URI stylesheetLocation, Map customizations ) { this.log = log; this.sourceDirectory = sourceDirectory; @@ -79,6 +104,14 @@ 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"); } /** @@ -92,9 +125,16 @@ throws TransformerFactoryConfigurationError, TransformerException, IOException, URISyntaxException, InclusionScanException { - StaleSourceScanner scanner = new StaleSourceScanner( 0, Collections.singleton( "**/*.xml" ), + StaleSourceScanner scanner = new StaleSourceScanner( 0, this.sourcePatterns, Collections.EMPTY_SET ); - scanner.addSourceMapping( new SuffixMapping( ".xml", ".html" ) ); + if (generateHtml) + { + scanner.addSourceMapping( new SuffixMapping( ".xml", ".html" ) ); + } + if ( generatePdf ) + { + scanner.addSourceMapping( new SuffixMapping( ".xml", ".pdf" ) ); + } Set staleDocbookFiles = scanner.getIncludedSources( this.sourceDirectory, this.outputDirectory ); if ( staleDocbookFiles.size() > 0 ) @@ -102,7 +142,7 @@ DirectoryScanner docbookScanner = new DirectoryScanner(); docbookScanner.setBasedir( this.sourceDirectory ); docbookScanner.setFollowSymlinks( true ); - docbookScanner.setIncludes( new String[] { "**/*.xml" } ); + docbookScanner.setIncludes( new String[] { "**/*.xml", "*.xml" } ); docbookScanner.scan(); String[] docbookFiles = docbookScanner.getIncludedFiles(); @@ -113,7 +153,12 @@ { this.log.info( "Generated docbook files up to date" ); } - FileUtils.copyDirectoryStructure( this.resourceDirectory, this.outputDirectory ); + 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() ); + } } /** @@ -123,6 +168,7 @@ { 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++ ) { @@ -140,14 +186,22 @@ 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 ); + Transformer xhtmlTransformer = null; + Transformer xslfoTransformer = null; + FopFactory fopFactory = null; 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." ); - + + + if ( generateHtml ) + { + xhtmlTransformer = createXHTMLTransformer(olinkDBURI); + } + if ( generatePdf ) + { + xslfoTransformer = createXSLFOTransformer(olinkDBURI); + fopFactory = FopFactory.newInstance(); + fopFactory.setURIResolver(this.mojoResolver); + } Iterator filesIterator = docbookFiles.iterator(); while ( filesIterator.hasNext() ) { @@ -152,25 +206,102 @@ 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() ); - - 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 ); + if ( generateHtml ) + { + transformXhtml( xhtmlTransformer, docbookFile ); + } + if ( generatePdf ) + { + transformPdf( xslfoTransformer, docbookFile, fopFactory ); + } } } + private Transformer createXSLFOTransformer(URI olinkDBURI) throws TransformerFactoryConfigurationError, TransformerException, TransformerConfigurationException { + Transformer xslfoTransformer; + TransformerFactory xslfoTf = TransformerFactory.newInstance(); + xslfoTf.setURIResolver(this.mojoResolver); + Source docbookStyleSheetSource; + if (this.xslfoCustomization==null) { + docbookStyleSheetSource = this.mojoResolver.resolve( "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() ); + + this.log.debug( "XSL:FO Style sheet loaded." ); + return xslfoTransformer; + } + + private Transformer createXHTMLTransformer(URI olinkDBURI) throws TransformerFactoryConfigurationError, TransformerException, TransformerConfigurationException { + Transformer xhtmlTransformer; + TransformerFactory xhtmlTf = TransformerFactory.newInstance(); + xhtmlTf.setURIResolver(this.mojoResolver); + Source docbookStyleSheetSource; + if (this.xhtmlCustomization==null) { + docbookStyleSheetSource = this.mojoResolver.resolve( "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", "" ); + + this.log.debug( "XHTML Style sheet loaded." ); + return xhtmlTransformer; + } + + private void transformXhtml(Transformer documentTransformer, File docbookFile) 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( '.' ) ) + + ".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) 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('.')) + + ".pdf"); + 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(); @@ -182,4 +313,18 @@ } 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/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,9 +42,7 @@ 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 * @goal transform @@ -54,6 +54,10 @@ private static String XERCES_PARSER_CONFIG = "org.apache.xerces.xni.parser.XMLParserConfiguration"; 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. @@ -93,12 +97,35 @@ * @parameter expression="${outputEncoding}" default-value="UTF-8" */ private String outputEncoding; + + /** + * 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:

+ *
<customizations>
+     *   <pdf>src/main/resources/docbook2pdf.xsl</pdf>
+     * </customizations>
+ *

All relative URLs are resolved against resourcePath

+ * @parameter + */ + private Map customizations = new HashMap(); /** * 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. + * specific version instead of the current release from the maven repository. * - * @parameter expression="${stylesheetLocation}" default-value="http://docbook.sourceforge.net/release/xsl/current/" + * @parameter expression="${stylesheetLocation}" default-value="resource://net/sourceforge/docbook/" */ private String stylesheetLocation; @@ -133,6 +160,8 @@ // 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 { @@ -143,7 +172,11 @@ this.resourceDirectory, this.databaseDirectory, this.outputDirectory, - stylesheetLocationURI ); + stylesheetLocationURI, + this.customizations); + for ( int i = 0; i < outputFormats.length; i++) { + documentTransformer.enableOutputFormat( outputFormats[i] ); + } olinkDBUpdater.update(); documentTransformer.transform(); } @@ -153,7 +186,7 @@ } catch ( TransformerException exc ) { - throw new MojoFailureException( exc.getLocalizedMessage() ); + throw new MojoExecutionException( exc.getLocalizedMessage(), exc ); } catch ( URISyntaxException exc ) { @@ -173,6 +206,7 @@ if ( xercesParser != null ) { System.setProperty( TransformMojo.XERCES_PARSER_CONFIG, xercesParser ); + System.setProperty( TransformMojo.XERCES_RESOLVER_CONFIG, entityResolver ); } else { @@ -178,6 +212,7 @@ { // 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 )