001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2012-2015 ForgeRock AS.
015 */
016
017package org.forgerock.doc.maven.build;
018
019import org.apache.commons.io.FilenameUtils;
020import org.apache.maven.plugin.MojoExecutionException;
021import org.forgerock.doc.maven.AbstractDocbkxMojo;
022import org.forgerock.doc.maven.utils.ImageCopier;
023import org.forgerock.doc.maven.utils.OLinkUtils;
024import org.twdata.maven.mojoexecutor.MojoExecutor;
025
026import java.io.File;
027import java.io.IOException;
028import java.util.ArrayList;
029
030/**
031 * Build chunked HTML output.
032 */
033public class ChunkedHtml {
034
035    /**
036     * The Mojo that holds configuration and related methods.
037     */
038    private AbstractDocbkxMojo m;
039
040    /**
041     * The Executor to run docbkx-tools.
042     */
043    private final Executor executor;
044
045    /**
046     * Constructor setting the Mojo that holds the configuration.
047     *
048     * @param mojo The Mojo that holds the configuration.
049     */
050    public ChunkedHtml(final AbstractDocbkxMojo mojo) {
051        m = mojo;
052        this.executor = new Executor();
053    }
054
055    /**
056     * Build documents from DocBook XML sources.
057     *
058     * @throws MojoExecutionException Failed to build output.
059     */
060    public void execute() throws MojoExecutionException {
061        executor.prepareOlinkDB();
062        executor.build();
063    }
064
065    /**
066     * Get absolute path to an Olink target database XML document
067     * that points to the individual generated Olink DB files,
068     * for chunked HTML.
069     *
070     * @return Absolute path to the file.
071     * @throws MojoExecutionException Could not write target DB file.
072     */
073    final String getTargetDB() throws MojoExecutionException {
074        File targetDB = new File(m.getBuildDirectory(), "olinkdb-chunked-html.xml");
075
076        try {
077            OLinkUtils.createTargetDatabase(targetDB, "html", m, true);
078        } catch (Exception e) {
079            throw new MojoExecutionException(
080                    "Failed to write link target database: " + targetDB.getPath(), e);
081        }
082
083        return targetDB.getPath();
084    }
085
086    /**
087     * Enclose methods to run plugins.
088     */
089    class Executor extends MojoExecutor {
090
091        /**
092         * Prepare olink target database from DocBook XML sources.
093         *
094         * @throws MojoExecutionException Failed to build target database.
095         */
096        void prepareOlinkDB() throws MojoExecutionException {
097
098            for (String docName : m.getDocNames()) {
099                ArrayList<Element> cfg = new ArrayList<MojoExecutor.Element>();
100                cfg.add(element(name("xincludeSupported"), m.isXincludeSupported()));
101                cfg.add(element(name("sourceDirectory"), m.path(m.getDocbkxModifiableSourcesDirectory())));
102                cfg.add(element(name("chunkedOutput"), "true"));
103
104                cfg.add(element(name("htmlCustomization"), m.path(m.getChunkedHTMLCustomization())));
105                cfg.add(element(name("collectXrefTargets"), "only"));
106
107                cfg.add(element(name("currentDocid"), docName));
108                cfg.add(element(name("includes"), docName + "/" + m.getDocumentSrcName()));
109                cfg.add(element(name("targetDirectory"), m.path(m.getDocbkxOutputDirectory()) + "/html"));
110                cfg.add(element(name("targetsFilename"), m.getDocumentSrcName() + ".html.target.db"));
111
112                final String base = FilenameUtils.getBaseName(m.getDocumentSrcName());
113                final String chunkBaseDir = m.path(m.getDocbkxOutputDirectory())
114                        + "/html/" + docName + "/" + base + "/";
115                cfg.add(element(name("chunkBaseDir"), chunkBaseDir));
116
117                executeMojo(
118                        plugin(
119                                groupId("com.agilejava.docbkx"),
120                                artifactId("docbkx-maven-plugin"),
121                                version(m.getDocbkxVersion())),
122                        goal("generate-html"),
123                        configuration(cfg.toArray(new Element[cfg.size()])),
124                        executionEnvironment(m.getProject(), m.getSession(), m.getPluginManager()));
125            }
126        }
127
128        /**
129         * Build documents from DocBook XML sources.
130         *
131         * @throws MojoExecutionException Failed to build the output.
132         */
133        void build() throws MojoExecutionException {
134
135            String documentSrcName = FilenameUtils.getBaseName(m.getDocumentSrcName());
136            try {
137                ImageCopier.copyImages("html", documentSrcName, m);
138            } catch (IOException e) {
139                throw new MojoExecutionException("Failed to copy images", e);
140            }
141
142            for (String docName : m.getDocNames()) {
143                ArrayList<MojoExecutor.Element> cfg = new ArrayList<MojoExecutor.Element>();
144                cfg.addAll(m.getBaseConfiguration());
145                cfg.add(element(name("chunkedOutput"), "true"));
146                cfg.add(element(name("htmlCustomization"), m.path(m.getChunkedHTMLCustomization())));
147                cfg.add(element(name("targetDatabaseDocument"), getTargetDB()));
148                cfg.add(element(name("generateManifest"), "1"));
149
150                cfg.add(element(name("includes"), docName + "/" + m.getDocumentSrcName()));
151
152                final String base = FilenameUtils.getBaseName(m.getDocumentSrcName());
153                final String chunkBaseDir = m.path(m.getDocbkxOutputDirectory())
154                        + "/html/" + docName + "/" + base + "/";
155                cfg.add(element(name("chunkBaseDir"), chunkBaseDir));
156
157                cfg.add(element(name("manifest"),
158                        m.getDocbkxOutputDirectory().getPath()
159                                + "/" + docName + ".manifest"));
160
161                executeMojo(
162                        plugin(
163                                groupId("com.agilejava.docbkx"),
164                                artifactId("docbkx-maven-plugin"),
165                                version(m.getDocbkxVersion())),
166                        goal("generate-html"),
167                        configuration(cfg.toArray(new Element[cfg.size()])),
168                        executionEnvironment(m.getProject(), m.getSession(), m.getPluginManager()));
169            }
170        }
171    }
172}