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.post;
018
019import org.apache.commons.io.IOUtils;
020
021import org.apache.maven.plugin.MojoExecutionException;
022import org.forgerock.doc.maven.AbstractDocbkxMojo;
023import org.forgerock.doc.maven.utils.HtmlUtils;
024import org.forgerock.doc.maven.utils.BootstrapCopier;
025import org.forgerock.doc.maven.utils.NameUtils;
026
027import java.io.File;
028import java.io.IOException;
029import java.util.HashMap;
030
031/**
032 * HTML post-processor for Bootstrap-formatted HTML formats.
033 */
034public class Bootstrap {
035
036    /**
037     * The Mojo that holds configuration and related methods.
038     */
039    private AbstractDocbkxMojo m;
040
041    /**
042     * Constructor setting the Mojo that holds the configuration.
043     *
044     * @param mojo The Mojo that holds the configuration.
045     */
046    public Bootstrap(final AbstractDocbkxMojo mojo) {
047        m = mojo;
048
049        outputDirectories = new String[1];
050        outputDirectories[0] = "";
051    }
052
053    /**
054     * Post-processes Bootstrap formats.
055     *
056     * @throws MojoExecutionException Failed to post-process Bootstrap format.
057     */
058    public void execute() throws MojoExecutionException {
059
060        // Add HtmlForBootstrap files.
061        final File htmlDir = new File(m.getDocbkxOutputDirectory(),
062                "bootstrap");
063
064        String[] outputDirectories = new String[m.getDocNames().size()];
065
066        int i = 0;
067        for (final String docName : m.getDocNames()) {
068
069            final File docDir = new File(htmlDir, docName);
070
071            // If PDFs are also being built, edit Bootstrap HTML with a link
072            if (m.getFormats().contains(AbstractDocbkxMojo.Format.pdf)) {
073                addPDFLink(docDir.getPath(), docName);
074            }
075
076            // Example:
077            // ${project.build.directory}/docbkx/html/my-book
078            outputDirectories[i] = docDir.getPath();
079            ++i;
080
081        }
082        editBuiltHtml(htmlDir.getPath());
083
084        if (m.isDraftMode().equals("yes")) {
085            addDraftAlert(htmlDir.getPath());
086        }
087
088        BootstrapCopier copier =
089                new BootstrapCopier(outputDirectories);
090        try {
091            copier.copy();
092        } catch (IOException e) {
093            throw new MojoExecutionException(
094                    "Failed to copy files: " + e.getMessage(), e);
095        }
096
097    }
098
099    /**
100     * Add essentials to the built Bootstrap HTML.
101     *
102     * <p>
103     *
104     * - Add Google Analytics tracking code to the Bootstrap HTML
105     *
106     *
107     * @param htmlDir Directory under which to find Bootstrap output.
108     * @throws MojoExecutionException Something went wrong when updating HTML.
109     */
110    final void editBuiltHtml(final String htmlDir) throws
111            MojoExecutionException {
112        try {
113            HashMap<String, String> replacements = new HashMap<String, String>();
114
115            String gascript = IOUtils.toString(
116                    getClass().getResourceAsStream("/endhead-ga.txt"), "UTF-8");
117            gascript = gascript.replace("ANALYTICS-ID", m.getGoogleAnalyticsId());
118            replacements.put("</head>", gascript);
119
120            HtmlUtils.updateHtml(htmlDir, replacements);
121        } catch (IOException e) {
122            throw new MojoExecutionException(
123                    "Failed to update output HTML correctly: " + e.getMessage());
124        }
125    }
126
127
128
129    final void addDraftAlert(final String htmlDir) throws
130        MojoExecutionException {
131        try {
132            HashMap<String, String> replacements = new HashMap<String, String>();
133            String draftAlert = IOUtils.toString(
134                    getClass().getResourceAsStream("/endbody-draftalert.txt"), "UTF-8");
135            replacements.put("</body>", draftAlert);
136            HtmlUtils.updateHtml(htmlDir, replacements);
137        } catch (IOException e) {
138            throw new MojoExecutionException(
139                    "Failed to update output HTML correctly: " + e.getMessage());
140        }
141    }
142
143    /**
144     * Add a link to the PDF in the built Bootstrap HTML.
145     *
146     * <p>
147     *
148     * If both Bootstrap and PDF formats are being built, link to the PDFs
149     * from the Bootstrap.
150     *
151     *
152     * @param htmlDir Directory under which to find Bootstrap output.
153     * @param docName The short name of the document, for example "dev-guide".
154     * @throws MojoExecutionException Something went wrong when updating HTML.
155     */
156    final void addPDFLink(final String htmlDir, final String docName) throws
157            MojoExecutionException {
158        try {
159            HashMap<String, String> replacements = new HashMap<String, String>();
160
161            String linkToPdf = getLinkToPdf(docName);
162            replacements.put("<ul id=\"pdf-link\">", linkToPdf);
163
164            HtmlUtils.updateHtml(htmlDir, replacements);
165        } catch (IOException e) {
166            throw new MojoExecutionException(
167                    "Failed to inject PDF link HTML correctly: " + e.getMessage());
168        }
169    }
170
171    private String getLinkToPdf(final String docName) {
172        // Note: No closing UL required, it's already in the HTML
173        String link = "<ul id=\"pdf-link\" "
174            + "class=\"nav navbar-nav navbar-right hidden-xs\">"
175            + "<li><a href=\"PDF-URL\" target=\"_blank\">"
176            + "<span class=\"glyphicon glyphicon-save\"></span> "
177            + "Download PDF Version</a></li>";
178
179        String pdfUrl = "../../" + NameUtils.renameDoc(m.getProjectName(),
180                docName, "pdf");
181        link = link.replaceFirst("PDF-URL", pdfUrl);
182
183        return link;
184    }
185
186    /**
187     * Directories where scripts and CSS are to be added.
188     */
189    private String[] outputDirectories;
190}