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.utils; 018 019import org.apache.commons.io.FileUtils; 020import org.apache.commons.io.filefilter.FileFilterUtils; 021import org.apache.commons.io.filefilter.HiddenFileFilter; 022import org.apache.commons.io.filefilter.IOFileFilter; 023 024import java.io.File; 025import java.io.FileFilter; 026import java.io.IOException; 027import java.util.HashMap; 028import java.util.List; 029import java.util.Map; 030import java.util.Set; 031 032/** 033 * Utility methods to prepare built HTML docs for publication. 034 */ 035public final class HtmlUtils { 036 /** 037 * Add a <code>.htaccess</code> file to the base directory, for publication 038 * on an Apache HTTPD server. 039 * <p> 040 * According to Apache documentation on <a 041 * href="http://httpd.apache.org/docs/2.4/howto/htaccess.html#how">How 042 * directives are applied</a>, "The configuration directives found in a 043 * .htaccess file are applied to the directory in which the .htaccess file 044 * is found, and to all subdirectories thereof." So there is no need to copy 045 * the file recursively to all directories. 046 * 047 * @param baseDir 048 * Base directory under which to add the file 049 * @param htaccess 050 * <code>.htaccess</code> file to copy 051 * @throws IOException 052 * Something went wrong during copy procedure. 053 */ 054 public static void addHtaccess(final String baseDir, final File htaccess) throws IOException { 055 FileUtils.copyFileToDirectory(htaccess, new File(baseDir)); 056 } 057 058 /** 059 * Add custom CSS with XML wrapper to document source directories. 060 * 061 * <p> 062 * 063 * See <a href="http://docbook.sourceforge.net/release/xsl/current/doc/html/custom.css.source.html" 064 * >custom.css.source</a> for details. 065 * 066 * @param cssFile The CSS file to wrap in XML. 067 * @param srcDir The source directory for DocBook XML documents. 068 * @param documentSrcName The top-level entry file to DocBook XML documents. 069 * @throws IOException Something went wrong adding CSS. 070 */ 071 public static void addCustomCss(final File cssFile, 072 final File srcDir, 073 final String documentSrcName) 074 throws IOException { 075 if (!cssFile.exists()) { 076 throw new IOException(cssFile.getPath() + " not found"); 077 } 078 079 final String cssString = FileUtils.readFileToString(cssFile); 080 081 Set<String> docNames = NameUtils.getDocumentNames( 082 srcDir, documentSrcName); 083 if (docNames.isEmpty()) { 084 throw new IOException("No document names found."); 085 } 086 087 for (String docName : docNames) { 088 089 final File parent = new File(srcDir, docName); 090 final File xmlFile = new File(parent, cssFile.getName() + ".xml"); 091 092 if (!xmlFile.exists()) { // Do not append the document again to the same file. 093 FileUtils.write(xmlFile, "<?xml version=\"1.0\"?>\n", true); 094 FileUtils.write(xmlFile, "<style>\n", true); 095 FileUtils.write(xmlFile, cssString, true); 096 FileUtils.write(xmlFile, "</style>\n", true); 097 } 098 } 099 } 100 101 /** 102 * Replace HTML tags with additional content. 103 * 104 * @param baseDir 105 * Base directory under which to find HTML files recursively 106 * @param replacements 107 * Keys are tags to replace. Values are replacements, including 108 * the original tag. 109 * @return List of files updated 110 * @throws IOException 111 * Something went wrong reading or writing files. 112 */ 113 public static List<File> updateHtml(final String baseDir, 114 final Map<String, String> replacements) 115 throws IOException { 116 // Match normal directories, and HTML files. 117 IOFileFilter dirFilter = FileFilterUtils 118 .and(FileFilterUtils.directoryFileFilter(), 119 HiddenFileFilter.VISIBLE); 120 IOFileFilter fileFilter = FileFilterUtils.and( 121 FileFilterUtils.fileFileFilter(), 122 FileFilterUtils.suffixFileFilter(".html")); 123 FileFilter filter = FileFilterUtils.or(dirFilter, fileFilter); 124 125 FilteredFileUpdater ffu = new FilteredFileUpdater(replacements, filter); 126 return ffu.update(new File(baseDir)); 127 } 128 129 130 /** 131 * Fix links to arbitrary resources in HTML files. 132 * 133 * <p> 134 * 135 * Chunked HTML and webhelp have extra directories in the path. 136 * Links like {@code ../resources/file.txt} that work in the source 137 * do not work as is in these formats. 138 * Instead the links need an extra .. as in {@code ../../resources/file.txt}. 139 * 140 * @param htmlDir Path to a directory containing HTML. 141 * @param resourcesDirBaseName Base name of the resources directory. 142 * @throws IOException Something went wrong updating links. 143 */ 144 public static void fixResourceLinks(final String htmlDir, final String resourcesDirBaseName) 145 throws IOException { 146 147 HashMap<String, String> replacements = new HashMap<String, String>(); 148 replacements.put("href=\'../" + resourcesDirBaseName, "href=\'../../" + resourcesDirBaseName); 149 replacements.put("href=\"../" + resourcesDirBaseName, "href=\"../../" + resourcesDirBaseName); 150 151 updateHtml(htmlDir, replacements); 152 } 153 154 /** 155 * Not used. 156 */ 157 private HtmlUtils() { 158 } 159}