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.FileUtils;
020import org.apache.commons.io.FilenameUtils;
021import org.apache.maven.plugin.MojoExecutionException;
022import org.forgerock.doc.maven.AbstractDocbkxMojo;
023import org.forgerock.doc.maven.utils.ImageCopier;
024import org.forgerock.doc.maven.utils.NameUtils;
025import org.forgerock.doc.maven.utils.OLinkUtils;
026import org.twdata.maven.mojoexecutor.MojoExecutor;
027
028import java.io.File;
029import java.io.IOException;
030import java.util.ArrayList;
031
032/**
033 * Build EPUB output format.
034 */
035public class Epub {
036
037    /**
038     * The Mojo that holds configuration and related methods.
039     */
040    private AbstractDocbkxMojo m;
041
042    /**
043     * The Executor to run docbkx-tools.
044     */
045    private final Executor executor;
046
047    /**
048     * Constructor setting the Mojo that holds the configuration.
049     *
050     * @param mojo The Mojo that holds the configuration.
051     */
052    public Epub(final AbstractDocbkxMojo mojo) {
053        m = mojo;
054        this.executor = new Executor();
055    }
056
057    /**
058     * Build documents from DocBook XML sources.
059     *
060     * @throws MojoExecutionException Failed to build output.
061     */
062    public void execute() throws MojoExecutionException {
063        executor.prepareOlinkDB();
064        executor.build();
065    }
066
067    /**
068     * Get absolute path to an Olink target database XML document
069     * that points to the individual generated Olink DB files
070     * for EPUB.
071     *
072     * @return Absolute path to the file.
073     * @throws MojoExecutionException Could not write target DB file.
074     */
075    final String getTargetDB() throws MojoExecutionException {
076        File targetDB = new File(m.getBuildDirectory(), "olinkdb-epub.xml");
077
078        try {
079            OLinkUtils.createTargetDatabase(targetDB, "epub", m);
080        } catch (Exception e) {
081            throw new MojoExecutionException(
082                    "Failed to write link target database: " + targetDB.getPath(), e);
083        }
084
085        return targetDB.getPath();
086    }
087
088    /**
089     * Enclose methods to run plugins.
090     */
091    class Executor extends MojoExecutor {
092
093        // Absolute path to Olink target database XML document.
094        private String targetDatabaseDocument;
095
096        /**
097         * Get the olink target database XML document path.
098         *
099         * @return Absolute path to the file.
100         * @throws MojoExecutionException Could not write target DB file.
101         */
102        String getTargetDatabaseDocument() throws MojoExecutionException {
103            // If it has not been set yet, then set it now.
104            if (targetDatabaseDocument == null || targetDatabaseDocument.isEmpty()) {
105                targetDatabaseDocument = getTargetDB();
106            }
107
108            return targetDatabaseDocument;
109        }
110
111        /**
112         * Prepare olink target database from DocBook XML sources.
113         *
114         * @throws MojoExecutionException Failed to build target database.
115         */
116        void prepareOlinkDB() throws MojoExecutionException {
117
118            for (String docName : m.getDocNames()) {
119                ArrayList<MojoExecutor.Element> cfg = new ArrayList<MojoExecutor.Element>();
120                cfg.addAll(m.getBaseConfiguration());
121                cfg.add(element(name("xincludeSupported"), m.isXincludeSupported()));
122                cfg.add(element(name("sourceDirectory"), m.path(m.getDocbkxModifiableSourcesDirectory())));
123                cfg.add(element(name("collectXrefTargets"), "yes"));
124                cfg.add(element(name("includes"), docName + "/" + m.getDocumentSrcName()));
125                cfg.add(element(name("currentDocid"), docName));
126                cfg.add(element(name("targetDatabaseDocument"), getTargetDatabaseDocument()));
127                cfg.add(element(name("targetDirectory"), m.path(m.getDocbkxOutputDirectory()) + "/epub"));
128                cfg.add(element(name("targetsFilename"), m.getDocumentSrcName() + ".epub.target.db"));
129
130                executeMojo(
131                        plugin(
132                                groupId("com.agilejava.docbkx"),
133                                artifactId("docbkx-maven-plugin"),
134                                version(m.getDocbkxVersion())),
135                        goal("generate-epub"),
136                        configuration(cfg.toArray(new Element[cfg.size()])),
137                        executionEnvironment(m.getProject(), m.getSession(), m.getPluginManager())
138                );
139            }
140        }
141
142        /**
143         * Build documents from DocBook XML sources.
144         *
145         * @throws MojoExecutionException Failed to build the output.
146         */
147        void build() throws MojoExecutionException {
148
149            try {
150                ImageCopier.copyImages("epub", "", m);
151            } catch (IOException e) {
152                throw new MojoExecutionException("Failed to copy images", e);
153            }
154
155            for (String docName : m.getDocNames()) {
156                ArrayList<Element> cfg = new ArrayList<MojoExecutor.Element>();
157                cfg.addAll(m.getBaseConfiguration());
158                cfg.add(element(name("epubCustomization"), m.path(m.getEpubCustomization())));
159                cfg.add(element(name("targetDatabaseDocument"), getTargetDatabaseDocument()));
160                cfg.add(element(name("targetDirectory"), m.path(m.getDocbkxOutputDirectory()) + "/epub"));
161
162                cfg.add(element(name("includes"), docName + "/" + m.getDocumentSrcName()));
163
164                executeMojo(
165                        plugin(
166                                groupId("com.agilejava.docbkx"),
167                                artifactId("docbkx-maven-plugin"),
168                                version(m.getDocbkxVersion())),
169                        goal("generate-epub"),
170                        configuration(cfg.toArray(new Element[cfg.size()])),
171                        executionEnvironment(m.getProject(), m.getSession(), m.getPluginManager()));
172
173                File outputEpub = FileUtils.getFile(
174                        m.getDocbkxOutputDirectory(), "epub",
175                        FilenameUtils.getBaseName(m.getDocumentSrcName()) + ".epub");
176
177                try {
178                    NameUtils.renameDocument(outputEpub, docName, m.getProjectName());
179                } catch (IOException e) {
180                    throw new MojoExecutionException("Failed to rename document", e);
181                }
182            }
183        }
184    }
185}