1 /* 2 * The contents of this file are subject to the terms of the Common Development and 3 * Distribution License (the License). You may not use this file except in compliance with the 4 * License. 5 * 6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 7 * specific language governing permission and limitations under the License. 8 * 9 * When distributing Covered Software, include this CDDL Header Notice in each file and include 10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 11 * Header, with the fields enclosed by brackets [] replaced by your own identifying 12 * information: "Portions copyright [year] [name of copyright owner]". 13 * 14 * Copyright 2015 ForgeRock AS. 15 */ 16 17 package org.forgerock.doc.maven.post; 18 19 import org.apache.commons.io.FileUtils; 20 import org.apache.commons.io.filefilter.FileFilterUtils; 21 import org.apache.maven.plugin.MojoExecutionException; 22 import org.forgerock.doc.maven.AbstractDocbkxMojo; 23 24 import java.io.File; 25 import java.io.IOException; 26 27 /** 28 * Fix man page file locations. 29 */ 30 public class ManpagePost extends AbstractDocbkxMojo { 31 32 /** 33 * The Mojo that holds configuration and related methods. 34 */ 35 private AbstractDocbkxMojo m; 36 37 /** 38 * Constructor setting the Mojo that holds the configuration. 39 * 40 * @param mojo The Mojo that holds the configuration. 41 */ 42 public ManpagePost(final AbstractDocbkxMojo mojo) { 43 m = mojo; 44 } 45 46 /** 47 * Fix man page file locations. 48 * <br> 49 * Man page generation replaces spaces in path name with underscores. 50 * As a result, if man pages are built in a project directory like 51 * {@code /path/to/My Doc Project}, 52 * then the generated man pages end up by default in 53 * {@code /path/to/My_Doc_Project/target/docbkx/manpages}. 54 * <br> 55 * This method copies the result to the expected location. 56 * <br> 57 * This method then attempts to remove the extra generated directory, 58 * though failure to remove the extra directory only logs an informational message 59 * and does no throw an exception. 60 * 61 * @throws MojoExecutionException Failed to copy files. 62 */ 63 public void execute() throws MojoExecutionException { 64 File manPageOutputDir = new File(m.getDocbkxOutputDirectory(), "manpages"); 65 File generatedManPageDir = new File(manPageOutputDir.getAbsolutePath().replace(' ', '_')); 66 if (generatedManPageDir.equals(manPageOutputDir)) { 67 return; // Nothing to copy, and do not delete the man page directory. 68 } 69 if (!generatedManPageDir.exists() || !hasChildren(generatedManPageDir)) { 70 m.getLog().info("No man pages found in " + generatedManPageDir.getAbsolutePath()); 71 return; // No man pages. Nothing to do. 72 } 73 74 // The generated man page dir is different from the expected man page output dir, 75 // so copy the content to the expected location and try to delete the generated dir. 76 try { 77 FileUtils.copyDirectory(generatedManPageDir, manPageOutputDir, FileFilterUtils.trueFileFilter()); 78 } catch (IOException e) { 79 throw new MojoExecutionException(e.getMessage(), e); 80 } 81 82 File topGeneratedDirWithUnderscore = getTopAncestorWithUnderscore(generatedManPageDir); 83 try { 84 FileUtils.deleteDirectory(topGeneratedDirWithUnderscore); 85 } catch (IOException e) { 86 m.getLog().info("Failed to delete generated man page dir: " + generatedManPageDir + e.getMessage()); 87 } 88 } 89 90 /** 91 * Returns true if the specified directory has children. 92 * @param directory The directory to check. 93 * @return True if the specified directory has children. 94 */ 95 private boolean hasChildren(final File directory) { 96 String[] children = directory.list(); 97 return children.length > 0; 98 } 99 100 /** 101 * Returns the top ancestor directory that contains an underscore in the path. 102 * @param directory Returns this directory or an ancestor. 103 * @return The top ancestor directory that contains an underscore in the path. 104 */ 105 private File getTopAncestorWithUnderscore(final File directory) { 106 File topAncestorWithUnderscore = directory; 107 while (topAncestorWithUnderscore.getParent().contains("_")) { 108 topAncestorWithUnderscore = topAncestorWithUnderscore.getParentFile(); 109 } 110 return topAncestorWithUnderscore; 111 } 112 }