This is an automated email from the ASF dual-hosted git repository. hboutemy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-pdf-plugin.git
The following commit(s) were added to refs/heads/master by this push: new b03faf6 [MPDF-8] pdf:aggregate creates one PDF from a multi module project b03faf6 is described below commit b03faf60df1ba44f284bc294c0bf8bda8e3ec99b Author: Hervé Boutemy <herve.bout...@free.fr> AuthorDate: Wed May 30 16:32:12 2018 +0200 [MPDF-8] pdf:aggregate creates one PDF from a multi module project --- pom.xml | 13 ++ src/it/pdf-aggregate/invoker.properties | 19 ++ src/it/pdf-aggregate/mod-a/pom.xml | 36 +++ src/it/pdf-aggregate/mod-a/src/site/apt/index.apt | 31 +++ src/it/pdf-aggregate/mod-a/src/site/site.xml | 28 +++ src/it/pdf-aggregate/mod-b/pom.xml | 36 +++ src/it/pdf-aggregate/mod-b/src/site/apt/index.apt | 31 +++ src/it/pdf-aggregate/mod-b/src/site/site.xml | 28 +++ src/it/pdf-aggregate/pom.xml | 105 +++++++++ src/it/pdf-aggregate/src/site/apt/index.apt | 35 +++ src/it/pdf-aggregate/src/site/site.xml | 28 +++ src/it/pdf-aggregate/verify.groovy | 25 ++ .../apache/maven/plugins/pdf/AbstractPdfMojo.java | 68 ++++++ .../apache/maven/plugins/pdf/PdfAggregateMojo.java | 257 +++++++++++++++++++++ .../java/org/apache/maven/plugins/pdf/PdfMojo.java | 106 +++++---- .../apache/maven/plugins/pdf/TocFileHelper.java | 91 ++++++++ 16 files changed, 889 insertions(+), 48 deletions(-) diff --git a/pom.xml b/pom.xml index fd2c995..38f0be8 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,12 @@ under the License. </roles> </contributor> <contributor> + <name>Anthony Beurive</name> + <roles> + <role>MPDF-8: pdf:aggregate to create one PDF for a multi-module project</role> + </roles> + </contributor> + <contributor> <name>Taciano Tres</name> <roles> <role>Translator: Portuguese (Brazil)</role> @@ -246,6 +252,13 @@ under the License. </exclusions> </dependency> + <!-- JSON --> + <dependency> + <groupId>org.kopitubruk.util</groupId> + <artifactId>JSONUtil</artifactId> + <version>1.10.2-java6</version> + </dependency> + <!-- test dependencies --> <dependency> <groupId>junit</groupId> diff --git a/src/it/pdf-aggregate/invoker.properties b/src/it/pdf-aggregate/invoker.properties new file mode 100644 index 0000000..fa2c540 --- /dev/null +++ b/src/it/pdf-aggregate/invoker.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +invoker.goals = pdf:aggregate +invoker.debug = false \ No newline at end of file diff --git a/src/it/pdf-aggregate/mod-a/pom.xml b/src/it/pdf-aggregate/mod-a/pom.xml new file mode 100644 index 0000000..b70ddff --- /dev/null +++ b/src/it/pdf-aggregate/mod-a/pom.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.maven.its.pdf</groupId> + <artifactId>root</artifactId> + <version>1.0-SNAPSHOT</version> + </parent> + + <artifactId>mod-a</artifactId> + <name>PDF:aggregate test: module A</name> + <description> + This is module A for multi-module PDF. + </description> +</project> diff --git a/src/it/pdf-aggregate/mod-a/src/site/apt/index.apt b/src/it/pdf-aggregate/mod-a/src/site/apt/index.apt new file mode 100644 index 0000000..95721b4 --- /dev/null +++ b/src/it/pdf-aggregate/mod-a/src/site/apt/index.apt @@ -0,0 +1,31 @@ + ------ + Multi-module PDF: module A + ------ + Lukas Theussl + ------ + 2009-05-31 + ------ + +~~ Licensed to the Apache Software Foundation (ASF) under one +~~ or more contributor license agreements. See the NOTICE file +~~ distributed with this work for additional information +~~ regarding copyright ownership. The ASF licenses this file +~~ to you 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. + +~~ NOTE: For help with the syntax of this file, see: +~~ http://maven.apache.org/doxia/references/apt-format.html + +Overview + + This is module A. diff --git a/src/it/pdf-aggregate/mod-a/src/site/site.xml b/src/it/pdf-aggregate/mod-a/src/site/site.xml new file mode 100644 index 0000000..3aac823 --- /dev/null +++ b/src/it/pdf-aggregate/mod-a/src/site/site.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project> + <body> + <menu name="Overview"> + <item name="Introduction" href="index.html"/> + </menu> + </body> +</project> diff --git a/src/it/pdf-aggregate/mod-b/pom.xml b/src/it/pdf-aggregate/mod-b/pom.xml new file mode 100644 index 0000000..336d785 --- /dev/null +++ b/src/it/pdf-aggregate/mod-b/pom.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.maven.its.pdf</groupId> + <artifactId>root</artifactId> + <version>1.0-SNAPSHOT</version> + </parent> + + <artifactId>mod-b</artifactId> + <name>PDF:aggregate test: module B</name> + <description> + This is module B for multi-module PDF. + </description> +</project> diff --git a/src/it/pdf-aggregate/mod-b/src/site/apt/index.apt b/src/it/pdf-aggregate/mod-b/src/site/apt/index.apt new file mode 100644 index 0000000..c283fc1 --- /dev/null +++ b/src/it/pdf-aggregate/mod-b/src/site/apt/index.apt @@ -0,0 +1,31 @@ + ------ + Multi-module PDF: module B + ------ + Lukas Theussl + ------ + 2009-05-31 + ------ + +~~ Licensed to the Apache Software Foundation (ASF) under one +~~ or more contributor license agreements. See the NOTICE file +~~ distributed with this work for additional information +~~ regarding copyright ownership. The ASF licenses this file +~~ to you 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. + +~~ NOTE: For help with the syntax of this file, see: +~~ http://maven.apache.org/doxia/references/apt-format.html + +Overview + + This is module B. diff --git a/src/it/pdf-aggregate/mod-b/src/site/site.xml b/src/it/pdf-aggregate/mod-b/src/site/site.xml new file mode 100644 index 0000000..3aac823 --- /dev/null +++ b/src/it/pdf-aggregate/mod-b/src/site/site.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project> + <body> + <menu name="Overview"> + <item name="Introduction" href="index.html"/> + </menu> + </body> +</project> diff --git a/src/it/pdf-aggregate/pom.xml b/src/it/pdf-aggregate/pom.xml new file mode 100644 index 0000000..40b4898 --- /dev/null +++ b/src/it/pdf-aggregate/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.maven.its.pdf</groupId> + <artifactId>root</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>PDF:aggregate test: multi-module root</name> + <description> + Tests a PDF generation for a multi-module, running pdf:aggregate (that forks pdf:pdf for each module before aggregating). + </description> + + <organization> + <name>The Apache Software Foundation</name> + <url>http://www.apache.org/</url> + </organization> + + <contributors> + <contributor> + <name>Anthony Beurivé</name> + </contributor> + </contributors> + + <issueManagement> + <system>JIRA</system> + <url>https://issues.apache.org/jira/browse/MPDF</url> + </issueManagement> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> + + <modules> + <module>mod-a</module> + <module>mod-b</module> + </modules> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-clean-plugin</artifactId> + <version>2.4.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pdf-plugin</artifactId> + <version>@project.version@</version> + </plugin> + </plugins> + </build> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>2.9</version> + <reportSets> + <reportSet> + <reports> + <report>cim</report> + <report>dependencies</report><!-- generated xdoc is not valid XML: missing <table> --> + <report>dependency-convergence</report><!-- generated xdoc is not valid XML: missing <table> --> + <report>dependency-info</report> + <report>dependency-management</report> + <report>issue-tracking</report> + <report>license</report> + <report>mailing-list</report> + <report>plugins</report> + <report>summary</report> + </reports> + </reportSet> + </reportSets> + </plugin> + </plugins> + </reporting> + +</project> diff --git a/src/it/pdf-aggregate/src/site/apt/index.apt b/src/it/pdf-aggregate/src/site/apt/index.apt new file mode 100644 index 0000000..edf3806 --- /dev/null +++ b/src/it/pdf-aggregate/src/site/apt/index.apt @@ -0,0 +1,35 @@ + ------ + Multi-module PDF + ------ + Lukas Theussl + ------ + 2009-05-31 + ------ + +~~ Licensed to the Apache Software Foundation (ASF) under one +~~ or more contributor license agreements. See the NOTICE file +~~ distributed with this work for additional information +~~ regarding copyright ownership. The ASF licenses this file +~~ to you 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. + +~~ NOTE: For help with the syntax of this file, see: +~~ http://maven.apache.org/doxia/references/apt-format.html + +Overview + + This test shows how multi-module PDF generation works, running: + ++--------+ +mvn pdf:stage ++--------+ diff --git a/src/it/pdf-aggregate/src/site/site.xml b/src/it/pdf-aggregate/src/site/site.xml new file mode 100644 index 0000000..3aac823 --- /dev/null +++ b/src/it/pdf-aggregate/src/site/site.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you 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. +--> + +<project> + <body> + <menu name="Overview"> + <item name="Introduction" href="index.html"/> + </menu> + </body> +</project> diff --git a/src/it/pdf-aggregate/verify.groovy b/src/it/pdf-aggregate/verify.groovy new file mode 100644 index 0000000..bc03a20 --- /dev/null +++ b/src/it/pdf-aggregate/verify.groovy @@ -0,0 +1,25 @@ + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +pdfFile = new File( basedir, "target/pdf-aggregate/root.pdf" ) + +assert pdfFile.text.contains( "PDF:aggregate test: multi-module root" ) +assert pdfFile.text.contains( "PDF:aggregate test: module A" ) +assert pdfFile.text.contains( "PDF:aggregate test: module B" ) diff --git a/src/main/java/org/apache/maven/plugins/pdf/AbstractPdfMojo.java b/src/main/java/org/apache/maven/plugins/pdf/AbstractPdfMojo.java new file mode 100644 index 0000000..152ed69 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/pdf/AbstractPdfMojo.java @@ -0,0 +1,68 @@ +package org.apache.maven.plugins.pdf; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.File; +import java.io.IOException; + +import org.apache.maven.plugin.AbstractMojo; + +/** + * Common code to create pdf, either module pdf or reactor aggregate. + * + * @since 1.5 + */ +public abstract class AbstractPdfMojo + extends AbstractMojo +{ + protected abstract File getOutputDirectory(); + protected abstract File getWorkingDirectory(); + protected abstract boolean isIncludeReports(); + + /** + * The temp Site dir to have all site and generated-site files. + * + * @since 1.1 + */ + private File siteDirectoryTmp; + + protected abstract void prepareTempSiteDirectory( final File tmpSiteDir ) + throws IOException; + + /** + * @return the default tmpSiteDirectory. + * @throws IOException if any + * @since 1.1 + */ + protected File getSiteDirectoryTmp() + throws IOException + { + if ( this.siteDirectoryTmp == null ) + { + final File tmpSiteDir = new File( getWorkingDirectory(), "site.tmp" ); + prepareTempSiteDirectory( tmpSiteDir ); + + this.siteDirectoryTmp = tmpSiteDir; + } + + return this.siteDirectoryTmp; + } + +} diff --git a/src/main/java/org/apache/maven/plugins/pdf/PdfAggregateMojo.java b/src/main/java/org/apache/maven/plugins/pdf/PdfAggregateMojo.java new file mode 100644 index 0000000..e45342c --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/pdf/PdfAggregateMojo.java @@ -0,0 +1,257 @@ +package org.apache.maven.plugins.pdf; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.maven.doxia.document.DocumentModel; +import org.apache.maven.doxia.document.DocumentTOC; +import org.apache.maven.doxia.document.DocumentTOCItem; +import org.apache.maven.model.Reporting; +import org.apache.maven.plugins.annotations.Execute; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * Forks {@code pdf} goal then aggregates PDF content from all modules in the reactor. + * + * @author anthony-beurive + * @since 1.5 + */ +@Mojo( name = "aggregate", aggregator = true, requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true ) +@Execute( goal = "pdf" ) +public class PdfAggregateMojo + extends PdfMojo // TODO should extend AbstractPdfMojo, but requires extensive refactoring +{ + /** + * The reactor projects. + */ + @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true ) + private List<MavenProject> reactorProjects; + + /** + * Output directory where aggregated PDF files should be created. + */ + @Parameter( defaultValue = "${project.build.directory}/pdf-aggregate", required = true ) + private File aggregatedOutputDirectory; + + /** + * Working directory for aggregated working files like temp files/resources. + */ + @Parameter( defaultValue = "${project.build.directory}/pdf-aggregate", required = true ) + private File aggregatedWorkingDirectory; + + protected File getOutputDirectory() + { + return aggregatedOutputDirectory; + } + + protected File getWorkingDirectory() + { + return aggregatedWorkingDirectory; + } + + protected boolean isIncludeReports() + { + return false; // reports were generate (or not) during pdf:pdf: here, we only aggregate + } + + protected void prepareTempSiteDirectory( final File tmpSiteDir ) + throws IOException + { + tmpSiteDir.mkdirs(); + } + + @Override + protected void appendGeneratedReports( DocumentModel model, Locale locale ) + { + super.appendGeneratedReports( model, locale ); + + getLog().info( "Appending staged reports." ); + + DocumentTOC toc = model.getToc(); + + File dstSiteTmp = null; + try + { + dstSiteTmp = getSiteDirectoryTmp(); + } + catch ( IOException ioe ) + { + getLog().error( "unexpected IOException while getting aggregator root tmp site dir", ioe ); + } + if ( !dstSiteTmp.exists() ) + { + getLog().error( "Top-level project does not have src.tmp directory" ); + return; + } + + for ( MavenProject reactorProject : reactorProjects ) + { + getLog().info( "Appending " + reactorProject.getArtifactId() + " reports." ); + + copySiteDirectoryTmp( reactorProject, dstSiteTmp ); + + addTOCItems( toc, reactorProject ); + } + } + + private void copySiteDirectoryTmp( MavenProject project, File dstSiteTmp ) + { + Reporting reporting = project.getReporting(); + if ( reporting == null ) + { + getLog().info( "Skipping reactor project " + project + ": no reporting" ); + return; + } + + File srcSiteTmp = getModuleSiteDirectoryTmp( project ); + if ( !srcSiteTmp.exists() ) + { + getLog().info( "Skipping reactor project " + project + ": no site.tmp directory" ); + return; + } + + String stagedId = getStagedId( project ); + + try + { + String defaultExcludes = FileUtils.getDefaultExcludesAsString(); + List<String> srcDirNames = FileUtils.getDirectoryNames( srcSiteTmp, "*", defaultExcludes, false ); + for ( String srcDirName : srcDirNames ) + { + File srcDir = new File( srcSiteTmp, srcDirName ); + File dstDir = new File( new File( dstSiteTmp, srcDirName ), stagedId ); + if ( !dstDir.exists() && !dstDir.mkdirs() ) + { + getLog().error( "Could not create directory: " + dstDir ); + return; + } + + FileUtils.copyDirectoryStructure( srcDir, dstDir ); + } + } + catch ( IOException e ) + { + getLog().error( "Error while copying sub-project " + project.getArtifactId() + + " site.tmp: " + e.getMessage(), e ); + } + } + + private void addTOCItems( DocumentTOC topLevelToc, MavenProject project ) + { + String stagedId = getStagedId( project ); + + Map<String, Object> toc = loadToc( project ); + + List<Map<String, Object>> items = (ArrayList) toc.get( "items" ); + + DocumentTOCItem tocItem = new DocumentTOCItem(); + tocItem.setName( project.getName() ); + tocItem.setRef( stagedId ); + + if ( items.size() == 1 && "project-info".equals( items.get( 0 ).get( "ref" ) ) ) + { + // Special case where a sub-project only contains generated reports. + items = (List) items.get( 0 ).get( "items" ); + } + + for ( Map<String, Object> item : items ) + { + addTOCItems( tocItem, item, stagedId ); + } + + topLevelToc.addItem( tocItem ); + } + + private Map<String, Object> loadToc( MavenProject project ) + { + try + { + return TocFileHelper.loadToc( getModuleWorkingDirectory( project ) ); + } + catch ( IOException e ) + { + getLog().error( "Error while reading table of contents of module " + project.getArtifactId(), e ); + return Collections.<String, Object>emptyMap(); + } + } + + private void addTOCItems( DocumentTOCItem parent, Map<String, Object> item, String stagedId ) + { + DocumentTOCItem tocItem = new DocumentTOCItem(); + tocItem.setName( (String) item.get( "name" ) ); + tocItem.setRef( stagedId + "/" + item.get( "ref" ) ); + + List<Map<String, Object>> items = (ArrayList) item.get( "items" ); + + for ( Map<String, Object> it : items ) + { + addTOCItems( tocItem, it, stagedId ); + } + + parent.addItem( tocItem ); + } + + private String getStagedId( MavenProject p ) + { + Deque<String> projectPath = new ArrayDeque<String>(); + projectPath.addFirst( p.getArtifactId() ); + while ( p.getParent() != null ) + { + p = p.getParent(); + projectPath.addFirst( p.getArtifactId() ); + } + + StringBuilder stagedId = new StringBuilder(); + Iterator<String> artifactIds = projectPath.iterator(); + while ( artifactIds.hasNext() ) + { + stagedId.append( artifactIds.next() ); + if ( artifactIds.hasNext() ) + { + stagedId.append( '/' ); + } + } + return stagedId.toString(); + } + + private File getModuleWorkingDirectory( MavenProject project ) + { + return new File( project.getBuild().getDirectory(), "pdf" ); + } + + private File getModuleSiteDirectoryTmp( MavenProject project ) + { + return new File( getModuleWorkingDirectory( project ), "site.tmp" ); + } +} diff --git a/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java b/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java index dc8cdbc..86bd35c 100644 --- a/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java +++ b/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java @@ -48,6 +48,7 @@ import org.apache.maven.doxia.docrenderer.DocumentRendererException; import org.apache.maven.doxia.docrenderer.pdf.PdfRenderer; import org.apache.maven.doxia.document.DocumentMeta; import org.apache.maven.doxia.document.DocumentModel; +import org.apache.maven.doxia.document.DocumentTOC; import org.apache.maven.doxia.document.DocumentTOCItem; import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Writer; import org.apache.maven.doxia.index.IndexEntry; @@ -68,13 +69,13 @@ import org.apache.maven.doxia.tools.SiteToolException; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.ReportPlugin; import org.apache.maven.model.Reporting; -import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.PluginManager; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectBuilder; import org.apache.maven.reporting.AbstractMavenReportRenderer; @@ -104,9 +105,9 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException; * * @author ltheussl */ -@Mojo( name = "pdf", threadSafe = true ) +@Mojo( name = "pdf", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true ) public class PdfMojo - extends AbstractMojo implements Contextualizable + extends AbstractPdfMojo implements Contextualizable { /** @@ -187,7 +188,7 @@ public class PdfMojo * The Maven Project Object. */ @Parameter( defaultValue = "${project}", readonly = true, required = true ) - private MavenProject project; + protected MavenProject project; /** * The Maven Settings. @@ -343,13 +344,6 @@ public class PdfMojo private DecorationModel defaultDecorationModel; /** - * The temp Site dir to have all site and generated-site files. - * - * @since 1.1 - */ - private File siteDirectoryTmp; - - /** * The temp Generated Site dir to have generated reports by this plugin. * * @since 1.1 @@ -406,6 +400,21 @@ public class PdfMojo container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); } + protected File getOutputDirectory() + { + return outputDirectory; + } + + protected File getWorkingDirectory() + { + return workingDirectory; + } + + protected boolean isIncludeReports() + { + return includeReports; + } + // ---------------------------------------------------------------------- // Private methods // ---------------------------------------------------------------------- @@ -451,7 +460,8 @@ public class PdfMojo private void copyGeneratedPdf() throws MojoExecutionException, IOException { - boolean requireCopy = !outputDirectory.getCanonicalPath().equals( workingDirectory.getCanonicalPath() ); + boolean requireCopy = + !getOutputDirectory().getCanonicalPath().equals( getWorkingDirectory().getCanonicalPath() ); String outputName = getDocumentModel( getDefaultLocale() ).getOutputName().trim(); if ( !outputName.endsWith( ".pdf" ) ) @@ -461,7 +471,7 @@ public class PdfMojo for ( final Locale locale : getAvailableLocales() ) { - File generatedPdfSource = new File( getLocaleDirectory( workingDirectory, locale ), outputName ); + File generatedPdfSource = new File( getLocaleDirectory( getWorkingDirectory(), locale ), outputName ); if ( !generatedPdfSource.exists() ) { @@ -469,7 +479,7 @@ public class PdfMojo continue; } - File generatedPdfDest = new File( getLocaleDirectory( outputDirectory, locale ), outputName ); + File generatedPdfDest = new File( getLocaleDirectory( getOutputDirectory(), locale ), outputName ); if ( requireCopy ) { @@ -495,7 +505,7 @@ public class PdfMojo for ( final Locale locale : getAvailableLocales() ) { - final File workingDir = getLocaleDirectory( workingDirectory, locale ); + final File workingDir = getLocaleDirectory( getWorkingDirectory(), locale ); File siteDirectoryFile = getLocaleDirectory( getSiteDirectoryTmp(), locale ); @@ -536,25 +546,6 @@ public class PdfMojo } /** - * @return the default tmpSiteDirectory. - * @throws IOException if any - * @since 1.1 - */ - private File getSiteDirectoryTmp() - throws IOException - { - if ( this.siteDirectoryTmp == null ) - { - final File tmpSiteDir = new File( workingDirectory, "site.tmp" ); - prepareTempSiteDirectory( tmpSiteDir ); - - this.siteDirectoryTmp = tmpSiteDir; - } - - return this.siteDirectoryTmp; - } - - /** * @return the default tmpGeneratedSiteDirectory when report will be created. * @since 1.1 */ @@ -562,7 +553,7 @@ public class PdfMojo { if ( this.generatedSiteDirectoryTmp == null ) { - this.generatedSiteDirectoryTmp = new File( workingDirectory, "generated-site.tmp" ); + this.generatedSiteDirectoryTmp = new File( getWorkingDirectory(), "generated-site.tmp" ); } return this.generatedSiteDirectoryTmp; @@ -578,7 +569,7 @@ public class PdfMojo * @throws IOException if any * @since 1.1 */ - private void prepareTempSiteDirectory( final File tmpSiteDir ) + protected void prepareTempSiteDirectory( final File tmpSiteDir ) throws IOException { // safety @@ -696,6 +687,8 @@ public class PdfMojo appendGeneratedReports( doc, locale ); + saveTOC( doc.getToc(), locale ); + return doc; } @@ -708,6 +701,8 @@ public class PdfMojo appendGeneratedReports( model, locale ); + saveTOC( model.getToc(), locale ); + debugLogGeneratedModel( model ); return model; @@ -902,7 +897,7 @@ public class PdfMojo project.getName(), locale ); context.addSiteDirectory( new File( siteDirectory, locale.getLanguage() ) ); - siteRenderer.copyResources( context, workingDirectory ); + siteRenderer.copyResources( context, getWorkingDirectory() ); } catch ( IOException e ) { @@ -976,7 +971,7 @@ public class PdfMojo private void generateMavenReports( Locale locale ) throws MojoExecutionException, IOException { - if ( !includeReports ) + if ( !isIncludeReports() ) { getLog().info( "Skipped report generation." ); return; @@ -1086,6 +1081,9 @@ public class PdfMojo getLog().info( "Generating \"" + localReportName + "\" report." ); } + // The report will eventually generate output by itself, so we set its output directory anyway. + report.setReportOutputDirectory( outDir ); + StringWriter sw = new StringWriter(); PdfXdocSink pdfXdocSink = null; @@ -1190,10 +1188,10 @@ public class PdfMojo /** * Append generated reports to the toc only if <code>generateReports</code> is enabled, for instance: * <pre> - * <item name="Project Reports" ref="/project-info"> - * <item name="Project License" ref="/license" /> - * <item name="Project Team" ref="/team-list" /> - * <item name="Continuous Integration" ref="/integration" /> + * <item name="Project Reports" ref="project-info"> + * <item name="Project License" ref="license" /> + * <item name="Project Team" ref="team-list" /> + * <item name="Continuous Integration" ref="integration" /> * ... * </item> * </pre> @@ -1203,9 +1201,9 @@ public class PdfMojo * @see #generateMavenReports(Locale) * @since 1.1 */ - private void appendGeneratedReports( DocumentModel model, Locale locale ) + protected void appendGeneratedReports( DocumentModel model, Locale locale ) { - if ( !includeReports ) + if ( !isIncludeReports() ) { return; } @@ -1216,7 +1214,7 @@ public class PdfMojo final DocumentTOCItem documentTOCItem = new DocumentTOCItem(); documentTOCItem.setName( i18n.getString( "pdf-plugin", locale, "toc.project-info.item" ) ); - documentTOCItem.setRef( "/project-info" ); // see #generateMavenReports(Locale) + documentTOCItem.setRef( "project-info" ); // see #generateMavenReports(Locale) List<String> addedRef = new ArrayList<String>( 4 ); @@ -1227,7 +1225,7 @@ public class PdfMojo { final DocumentTOCItem reportItem = new DocumentTOCItem(); reportItem.setName( report.getName( locale ) ); - reportItem.setRef( "/" + report.getOutputName() ); + reportItem.setRef( report.getOutputName() ); items.add( reportItem ); @@ -1267,7 +1265,7 @@ public class PdfMojo { final DocumentTOCItem reportItem = new DocumentTOCItem(); reportItem.setName( title ); - reportItem.setRef( "/" + ref ); + reportItem.setRef( ref ); items.add( reportItem ); } @@ -1287,6 +1285,18 @@ public class PdfMojo model.getToc().addItem( documentTOCItem ); } + private void saveTOC( DocumentTOC toc, Locale locale ) + { + try + { + TocFileHelper.saveTOC( getWorkingDirectory(), toc, locale ); + } + catch ( IOException e ) + { + getLog().error( "Error while writing table of contents", e ); + } + } + /** * Parse a generated Doxia file and returns its title. * @@ -1348,7 +1358,7 @@ public class PdfMojo { reader = ReaderFactory.newXmlReader( generatedReport ); - doxia.parse( reader, generatedReport.getParentFile().getName(), sinkAdapter ); + doxia.parse( reader, "xdoc", sinkAdapter ); reader.close(); reader = null; diff --git a/src/main/java/org/apache/maven/plugins/pdf/TocFileHelper.java b/src/main/java/org/apache/maven/plugins/pdf/TocFileHelper.java new file mode 100644 index 0000000..c42b29f --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/pdf/TocFileHelper.java @@ -0,0 +1,91 @@ +package org.apache.maven.plugins.pdf; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.Locale; +import java.util.Map; + +import org.apache.maven.doxia.document.DocumentTOC; +import org.apache.maven.doxia.document.DocumentTOCItem; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.WriterFactory; +import org.kopitubruk.util.json.IndentPadding; +import org.kopitubruk.util.json.JSONConfig; +import org.kopitubruk.util.json.JSONParser; +import org.kopitubruk.util.json.JSONUtil; + +/** + * Helper to save then reload TOC content (to a json file), to be able to aggregate TOCs. + * + * @author anthony-beurive + * @since 1.5 + */ +class TocFileHelper +{ + private static final String FILENAME = "toc.json"; + + static void saveTOC( File workingDirectory, DocumentTOC toc, Locale locale ) + throws IOException + { + // FIXME: manage locales. + JSONConfig jsonConfig = new JSONConfig(); + jsonConfig.setIndentPadding( new IndentPadding( " ", "\n" ) ); + jsonConfig.addReflectClass( DocumentTOC.class ); + jsonConfig.addReflectClass( DocumentTOCItem.class ); + + Writer writer = null; + try + { + writer = WriterFactory.newWriter( getTocFile( workingDirectory ), "UTF-8" ); + JSONUtil.toJSON( toc, jsonConfig, writer ); + writer.close(); + writer = null; + } + finally + { + IOUtil.close( writer ); + } + } + + static Map<String, Object> loadToc( File workingDirectory ) + throws IOException + { + Reader reader = null; + try + { + reader = ReaderFactory.newReader( getTocFile( workingDirectory ), "UTF-8" ); + return (Map) JSONParser.parseJSON( reader ); + } + finally + { + IOUtil.close( reader ); + } + } + + private static File getTocFile( File workingDirectory ) + { + return new File( workingDirectory, FILENAME ); + } +} -- To stop receiving notification emails like this one, please contact hbout...@apache.org.