NameUtils.java
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2012-2015 ForgeRock AS.
*/
package org.forgerock.doc.maven.utils;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.codehaus.plexus.util.StringUtils;
/**
* Utility methods to work with documents.
*/
public final class NameUtils {
/**
* Pattern to validate the document names.
*
* <br>
*
* project-doc-version names are not expected in published docs,
* @see #renameDoc(String, String, String, String)
*
* <br>
*
* When published, documentation file names
* should include the version before the document name:
* Project-Version-Doc-Name.ext
*
* @deprecated since 3.0.0
*
* <p>Valid names:</p>
* <ul>
* <li>guide</li>
* <li>admin-quide</li>
* <li>OpenTEST-guide</li>
* <li>OpenTEST-admin-guide</li>
* <li>OpenTEST-admin-guide-1.1.1.0</li>
* <li>OpenTEST-admin-guide-1.1.1.0-SNAPSHOT</li>
* <li>OpenTEST-admin-guide-1.1.1.0-express</li>
* <li>OpenTEST-admin-guide-1.1.1.0-Xpress</li>
* <li>OpenTEST-admin-guide-1.1.1.0-Xpress1</li>
* <li>OpenTEST-10.1.0-admin-guide</li>
* <li>OpenTEST-10.1.0-SNAPSHOT-admin-guide</li>
* <li>OpenTEST-10.1.0-Xpress2-admin-guide</li>
* <li>db2-connector-1.1.0.0-SNAPSHOT</li>
* </ul>
*
* <p>Invalid names:</p>
* <ul>
* <li>guide.</li>
* <li>guide-1</li>
* <li>guide-.</li>
* </ul>
*/
@Deprecated
public static final Pattern DOCUMENT_FILE_PATTERN = Pattern
.compile("^([a-zA-Z0-9]+)(-?[0-9].[0-9\\.]*[0-9])?(-SNAPSHOT|(-Ex|-ex|-X)press[0-9])"
+ "?([a-zA-Z-]*)((-?[0-9].[0-9\\.]*[0-9])?-?(SNAPSHOT|(Ex|ex|X)press[0-9]?)?)$");
/**
* Rename document to reflect project and document name. For example,
* index.pdf could be renamed OpenAM-Admin-Guide.pdf.
*
* @param projectName
* Short name of the project, such as OpenAM, OpenDJ, OpenIDM
* @param docName
* Short name for the document, such as admin-guide,
* release-notes, reference
* @param extension
* File name extension not including dot, e.g. pdf
* @return New name for document. Can be "" if rename failed.
*/
public static String renameDoc(final String projectName,
final String docName,
final String extension) {
return renameDoc(projectName, docName, "", extension);
}
/**
* Rename document to reflect project and document name. For example,
* index.pdf could be renamed OpenAM-10.0.0-Admin-Guide.pdf.
*
* @param projectName
* Short name of the project, such as OpenAM, OpenDJ, OpenIDM
* @param docName
* Short name for the document, such as admin-guide,
* release-notes, reference
* @param version
* Document version such as 10.0.0, 2.5.0, 2.0.2
* @param extension
* File name extension not including dot, e.g. pdf
* @return New name for document. Can be "" if rename failed.
*/
public static String renameDoc(final String projectName,
final String docName,
final String version,
final String extension) {
// Doc name must be non-empty.
if (!StringUtils.isNotBlank(docName)) {
return "";
}
StringBuilder sb = new StringBuilder();
// If project name exists, capitalize it, replace spaces with hyphens,
// and follow the result with a hyphen.
if (StringUtils.isNotBlank(projectName)) {
sb.append(spacesToHyphens(capitalize(projectName))).append('-');
// Version precedes the document name.
// It only makes sense to use a version if a project name is defined.
// If version exists, follow it with a hyphen.
if (StringUtils.isNotBlank(version)) {
sb.append(version).append('-');
}
}
// Capitalize the doc name.
sb.append(capitalize(docName));
// If extension exists, precede it with a .
if (StringUtils.isNotBlank(extension)) {
sb.append('.').append(extension);
}
return sb.toString();
}
/**
* Capitalize initial letters in a document name.
*
* @param docName
* Name of the document such as reference or admin-guide
* @return Capitalized name such as Reference or Admin-Guide
*/
protected static String capitalize(final String docName) {
char[] chars = docName.toCharArray();
boolean isInitial = true;
for (int i = 0; i < chars.length; i++) {
if (isInitial && Character.isLetter(chars[i])) {
chars[i] = Character.toUpperCase(chars[i]);
isInitial = false;
} else {
isInitial = !Character.isLetter(chars[i]);
}
}
return String.valueOf(chars);
}
/**
* Replace spaces with hyphens.
*
* @param string String in which to replace spaces with hyphens
* @return String with spaces replaced by hyphens.
*/
protected static String spacesToHyphens(final String string) {
return string.replaceAll(" ", "-");
}
/**
* Returns names of directories that mirror the document names and contain
* DocBook XML documents to build.
*
* @param srcDir
* Directory containing DocBook XML sources. Document directories
* like admin-guide or reference are one level below this
* directory.
* @param docFile
* Name of a file common to all documents to build, such as
* index.xml.
* @return Document names, as in admin-guide or reference
*/
public static Set<String> getDocumentNames(final File srcDir,
final String docFile) {
Set<String> documentDirectories = new TreeSet<String>();
// Match directories containing DocBook document entry point files,
// and ignore everything else.
FileFilter filter = new FileFilter() {
@Override
public boolean accept(final File file) {
return file.isDirectory();
}
};
File[] directories = srcDir.listFiles(filter);
if (directories != null && directories.length > 0) {
FilenameFilter nameFilter = new FilenameFilter() {
@Override
public boolean accept(final File file, final String name) {
return name.equalsIgnoreCase(docFile);
}
};
for (File dir : directories) {
String[] found = dir.list(nameFilter);
if (found.length > 0) {
documentDirectories.add(dir.getName());
}
}
}
return documentDirectories;
}
/**
* Rename a single built document.
* For example, rename {@code index.pdf} to {@code OpenAM-Admin-Guide.pdf}.
*
* @param builtDocument File to rename, such as {@code index.pdf}.
* @param docName Simple document name such as {@code admin-guide}.
* @param projectName Project name, such as {@code OpenAM}.
* @throws IOException Something went wrong renaming the file.
*/
public static void renameDocument(final File builtDocument,
final String docName,
final String projectName)
throws IOException {
String ext = FilenameUtils.getExtension(builtDocument.getName());
File newFile = new File(builtDocument.getParent(), renameDoc(projectName, docName, ext));
if (!newFile.exists()) {
FileUtils.moveFile(builtDocument, newFile);
}
}
/**
* Not used.
*/
private NameUtils() {
}
}