Package org.hybridlabs.source.formatter.m2

Source Code of org.hybridlabs.source.formatter.m2.FormatManager$DirectoryFilter

package org.hybridlabs.source.formatter.m2;

/**
* Copyright 2008 hybrid labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hybridlabs.file.FileHelper;
import org.hybridlabs.source.beautifier.BeautifierWithConvention;
import org.hybridlabs.source.beautifier.CharacterSequence;
import org.hybridlabs.source.beautifier.JavaImportBeautifierImpl;

/**
* A utility to drive the code beautifier. Note the system properties that point
* to the various configuration parameters used by the utility.
*
* @author Jack Archer, Bob Fields
* @version 1.0, Feb. 2007
*/
public class FormatManager {
  private String conventionFilePath = System
      .getProperty("convention.file.path");

  private String conventionFileName = System.getProperty(
      "convention.file.name", "default-convention.xml");

  private final String slash = System.getProperty("file.separator");

  private static final Log LOG = LogFactory.getLog(FormatManager.class);

  /**
   * Run as ant task from BuildCT.xml. Formats imports and Jalopy. If args[1]
   * is empty, source input directory files will be overwritten. System
   * properties control behavior: convention.file.path is the path to the
   * Jalopy convention file (normally org/hybridlabs under ${m2repo}
   * convention.file.name is the name if the Jalopy convention file
   * updateImports true = convert fully qualified classnames to imports
   * updateJalopy true = run Jalopy formatting against output files
   *
   * @param args
   *            1 - root directory of the source to be formatted 2- target
   *            directory to write formatted source to
   */
  public static void main(String[] args) {
    try {
      // Format imports and Jalopy separately because file will be rolled
      // back if
      // Jalopy parsing fails.
      boolean updateImports = Boolean.parseBoolean(System.getProperty(
          "updateImports", "true"));

      boolean updateJalopy = Boolean.parseBoolean(System.getProperty(
          "updateJalopy", "true"));

      LOG.info("Formatting " + args[0] + " updateImports="
          + updateImports + " updateJalopy=" + updateJalopy);
      if (args.length > 1) {
        if (updateImports) {
          FormatManager.formatImportsAllFiles(args[0], args[1]);
        }
        if (updateJalopy) {
          FormatManager.formatJalopyAllFiles(args[0], args[1]);
        }
      } else {
        if (updateImports) {
          FormatManager.formatImportsAllFiles(args[0]);
        }
        if (updateJalopy) {
          FormatManager.formatJalopyAllFiles(args[0]);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Formats all Java files discovered in the supplied directory and
   * subdirectories.
   *
   * @param sourceRootDirectory
   *            Directory for Java files to format and replace
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatJalopyAllFiles(String sourceRootDirectory)
      throws FileNotFoundException, IOException {
    formatAllFiles(sourceRootDirectory, sourceRootDirectory, false, true);
  }

  /**
   * Formats all Java files discovered in the supplied directory and
   * subdirectories.
   *
   * @param sourceRootDirectory
   *            Directory for Java files to format and replace
   * @param targetRootDirectory
   *            Target Java source output directory (if null, use source
   *            directory)
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatImportsAllFiles(String sourceRootDirectory,
      String targetRootDirectory) throws FileNotFoundException,
      IOException {
    formatAllFiles(sourceRootDirectory, targetRootDirectory, true, false);
  }

  /**
   * Formats all Java files discovered in the supplied directory and
   * subdirectories.
   *
   * @param sourceRootDirectory
   *            Directory for Java files to format and replace
   * @param targetRootDirectory
   *            Target Java source output directory (if null, use source
   *            directory)
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatJalopyAllFiles(String sourceRootDirectory,
      String targetRootDirectory) throws FileNotFoundException,
      IOException {
    formatAllFiles(sourceRootDirectory, targetRootDirectory, false, true);
  }

  /**
   * Formats all Java files discovered in the supplied directory and
   * subdirectories.
   *
   * @param sourceRootDirectory
   *            Directory for Java files to format and replace
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatImportsAllFiles(String sourceRootDirectory)
      throws FileNotFoundException, IOException {
    formatAllFiles(sourceRootDirectory, sourceRootDirectory, true, false);
  }

  /**
   * Formats all Java files discovered in the supplied directory.
   *
   * @param sourceRootDirectory
   *            Directory for Java files to format
   * @param targetRootDirectory
   *            Output directory for
   * @param imports
   *            Change fully qualified classnames to imports in file
   * @param jalopy
   *            Run jalopy against file
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatAllFiles(String sourceRootDirectory,
      String targetRootDirectory, boolean imports, boolean jalopy)
      throws FileNotFoundException, IOException {
    String message = "Formatting ";
    if (imports) {
      message += "imports";
      if (jalopy) {
        message += " and jalopy";
      }
    } else if (jalopy) {
      message += "jalopy";
    }
    message += ": ";
    LOG.info(message + " under " + targetRootDirectory);

    JavaImportBeautifierImpl beautifier = new JavaImportBeautifierImpl();
    FormatManager manager = new FormatManager();
    manager.setConvention(beautifier);
    beautifier.setOrganizeImports(imports);
    // There are problems with the Jalopy parser for the generated files:
    // Unexpected char '<'
    beautifier.setFormat(jalopy);

    List<File> sourceFiles = manager.getAllJavaFiles(sourceRootDirectory);

    // Now reformat and save the targeted files to the target directory
    int listSize = sourceFiles.size();
    for (int i = 0; i < listSize; i++) {
      File sourceFile = (File) sourceFiles.get(i);
      LOG.info(message + sourceFile.getName() + " under "
          + sourceFile.getParent());

      CharacterSequence sequence = new CharacterSequence(
          FileHelper.loadStringBuffer(sourceFile));
      String original = sequence.getString();

      try {
        beautifier.beautify(sequence);
        // Only overwrite the file if the beautifier changes it, or if a
        // different directory
        // Sometimes Jalopy throws an error and returns a zero length
        // file.
        if (sequence.length() > 1
            && (!original.equals(sequence.getString()))) {
          File targetFile = new File((manager.getTargetDirectory(
              sourceFile, sourceRootDirectory,
              targetRootDirectory)), sourceFile.getName());
          // File targetDirectory = new
          // File((manager.getTargetDirectory(
          // sourceFile, targetRootDirectory)), sourceFile.getName());
          FileOutputStream outputSource = new FileOutputStream(
              targetFile);
          outputSource.write(sequence.getString().getBytes());
          outputSource.flush();
          outputSource.close();
        }
      } catch (RuntimeException e) {
        LOG.error("Exception formatting file: " + sourceFile.getName(),
            e);
        // System.out.println("Exception formatting file: " +
        // sourceFile.getName());
        // e.printStackTrace();
      }
    }
    LOG.info("Finished Formatting all files under " + sourceRootDirectory);
  }

  /**
   * Formats a single Java file.
   *
   * @param sourceFile
   *            Java file to format
   * @param targetRootDirectory
   *            Output directory for
   * @param imports
   *            Change fully qualified classnames to imports in file
   * @param jalopy
   *            Run jalopy against file
   * @throws FileNotFoundException
   *             If required files or directories do not exist
   * @throws IOException
   *             If the creation of a new file or directory fails
   */
  public static void formatFile(File sourceFile, String targetRootDirectory,
      boolean imports, boolean jalopy) throws FileNotFoundException,
      IOException {
    JavaImportBeautifierImpl beautifier = new JavaImportBeautifierImpl();
    FormatManager manager = new FormatManager();
    manager.setConvention(beautifier);
    beautifier.setOrganizeImports(imports);
    // There are problems with the Jalopy parser for the generated files:
    // Unexpected char '<'
    beautifier.setFormat(jalopy);

    LOG.info("Formatting file: " + sourceFile.getName());

    CharacterSequence sequence = new CharacterSequence(
        FileHelper.loadStringBuffer(sourceFile));

    try {
      beautifier.beautify(sequence);
      // Only overwrite the file if the beautifier changes it, or if a
      // different directory
      // Sometimes Jalopy throws an error and returns a zero length file.
      if (sequence.length() > 1) {
        File targetFile = null;
        if (targetRootDirectory == null
            || "".equals(targetRootDirectory)) {
          targetFile = sourceFile;
        } else {
          targetFile = new File(targetRootDirectory,
              sourceFile.getName());
          targetFile = new File((manager.getTargetDirectory(
              sourceFile, sourceFile.getParent(),
              targetRootDirectory)), sourceFile.getName());
        }
        // File targetDirectory = new File((manager.getTargetDirectory(
        // sourceFile, targetRootDirectory)), sourceFile.getName());
        FileOutputStream outputSource = new FileOutputStream(targetFile);
        outputSource.write(sequence.getString().getBytes());
        outputSource.flush();
        outputSource.close();
      }
    } catch (RuntimeException e) {
      LOG.error("Exception formatting file: " + sourceFile.getName(), e);
      // System.out.println("Exception formatting file: " +
      // sourceFile.getName());
      // e.printStackTrace();
    }
    LOG.info("Finished Formatting all files");
  }

  /**
   * Locates and sets Jalopy formatting convention file
   *
   * @param beautifier
   *            Instance of the beautifier class, not yet set to with external
   *            Jalopy formatting conventions
   * @throws FileNotFoundException
   *             If the convention file cannot be located
   */
  private void setConvention(BeautifierWithConvention beautifier) {
    String fileName = this.conventionFilePath + this.slash
        + this.conventionFileName;
    File conventionFile = new File(fileName);

    if (conventionFile.exists()) {
      beautifier.setConventionFilePath(fileName);
    } else {
      this.conventionFilePath = "/default-convention.xml";
      beautifier.setConventionFilePath("/default-convention.xml");
    }
  }

  /**
   * Fetches a target directory, creating it if it doesn't exist
   *
   * @param sourceFile
   *            Filename to create
   * @param sourceRootDirectory
   *            sourceFile directory
   * @param targetRootDirectory
   *            target directory root to create and return
   * @return the target output directory for the specified re-formatted source
   *         File
   */
  private File getTargetDirectory(File sourceFile,
      String sourceRootDirectory, String targetRootDirectory) {
    String path = sourceFile.getParent();
    // Find the part of the source file below the source directory, append
    // to target directory
    int index = path.indexOf(sourceRootDirectory);
    if (index == -1) {
      if (sourceRootDirectory.indexOf("/") > -1) {
        // Pathname translation - replace doesn't work with //
        sourceRootDirectory = replace(sourceRootDirectory, "/", "\\");
        index = path.indexOf(sourceRootDirectory);
      } else {
        sourceRootDirectory = replace(sourceRootDirectory, "\\", "/");
        index = path.indexOf(sourceRootDirectory);
      }
    }
    String sourcePath = path
        .substring(index + sourceRootDirectory.length());
    if (targetRootDirectory == null || targetRootDirectory.equals("")) {
      targetRootDirectory = sourceRootDirectory;
    }
    File targetPath = new File(targetRootDirectory + sourcePath);
    targetPath.mkdirs();

    return targetPath;
  }

  /**
   * The String / stringBuffer replace command does not work with // !
   *
   * @param target
   * @param toReplace
   * @param replaceBy
   * @return String with replaced tokens
   */
  public static String replace(String target, String toReplace,
      String replaceBy) {
    // StringBuffer result = new StringBuffer(target);
    int i = 0;
    // int j = 0;
    int toRepLength = toReplace.length();
    // int lengthDecrease = toRepLength - replaceBy.length();
    while ((i = target.indexOf(toReplace, i)) != -1) {
      target = target.substring(0, i)
          + replaceBy
          + new StringBuffer(target.substring(i + toRepLength,
              target.length()));
      // result.replace(i - j, toRepLength, replaceBy);
      // i += toRepLength;
      // j += lengthDecrease;
    }
    return target;
  }

  /**
   * Traverses to the end of a directory tree, starting at indicated source
   * directory, and collects all found Java source files.
   *
   * @param rootDirName
   *            The full path name of root of the directory tree to search for
   *            Java source files
   * @return List of Java source file discovered in the indicated directory
   *         tree, returned as Files
   * @throws FileNotFoundException
   *             if the root directory does not exist
   */
  private List<File> getAllJavaFiles(String rootDirName)
      throws FileNotFoundException {
    List<File> javaFiles = new ArrayList<File>();
    List<File> sourceDirs = new ArrayList<File>();
    File rootDir = asDirectory(rootDirName);

    // Traverse the directory tree from the starting source directory,
    // collect all the subdirectories
    List<File> subDirs = new ArrayList<File>();
    subDirs.add(rootDir);
    int listSize = 0;
    while (subDirs.size() > 0) {
      List<File> tempDirs = new ArrayList<File>();
      listSize = subDirs.size();
      for (int i = 0; i < listSize; i++) {
        File subDir = (File) subDirs.get(i);
        sourceDirs.add(subDir);
        tempDirs.addAll(getDirectories(subDir));
      }

      subDirs = tempDirs;
    }
    listSize = sourceDirs.size();
    for (int i = 0; i < listSize; i++) {
      File sourceDir = (File) sourceDirs.get(i);
      javaFiles.addAll(getJavaFiles(sourceDir));
    }

    return javaFiles;
  }

  /**
   * Collects the Java files in the indicated directory
   *
   * @param dir
   *            The directory to search for Java source files
   * @return List of discovered Java source files as 'File' instances
   */
  private List<File> getJavaFiles(File dir) {
    List<File> files = new ArrayList<File>();

    // Capture the Java source in the source directory
    JavaSourceFilter javaFilter = new JavaSourceFilter();

    String[] fileNames = dir.list(javaFilter);

    int listSize = fileNames.length;

    for (int i = 0; i < listSize; i++) {
      String fileName = fileNames[i];

      File file = new File(dir.getAbsolutePath(), fileName);
      // Directories might end in .java also
      if (file.isFile()) {
        files.add(file);
      }
    }

    return files;
  }

  /**
   * Collects the subdirectories for the indicated directory
   *
   * @param dir
   *            The directory to find subdirectories for
   * @return List of discovered subdirectories as 'File' instances
   */
  private List<File> getDirectories(File dir) {
    List<File> dirs = new ArrayList<File>();

    // Capture the subdirectories the source directory
    DirectoryFilter dirFilter = new DirectoryFilter();

    String[] dirNameArray = dir.list(dirFilter);

    int listSize = dirNameArray.length;

    for (int i = 0; i < listSize; i++) {
      String dirName = dirNameArray[i];
      File subDir = new File(dir.getAbsolutePath(), dirName);
      dirs.add(subDir);
    }

    return dirs;
  }

  /**
   * Verifies the incoming path name exists and is a directory; if not throws
   * exception
   *
   * @param dirPath
   *            Path to check
   * @return The directory specified in the incoming text as a File instance
   * @throws FileNotFoundException
   *             if the incoming path name does not exist or is not a
   *             directory
   */
  private File asDirectory(String dirPath) throws FileNotFoundException {
    File dir = new File(dirPath);

    if (!dir.isDirectory()) {
      StringBuffer msg = new StringBuffer(300);
      msg.append("Path ");
      msg.append(dirPath);
      msg.append(" does not exist or is not a directory.");
      throw new FileNotFoundException(msg.toString());
    }

    return new File(dirPath);
  }

  /**
   * This Filter identifies Java source code files
   */
  private class JavaSourceFilter implements FilenameFilter {
    /**
     * Checks for files ending with '.java', identifying them as Java source
     *
     * @param dir
     *            the path name of the file to be filtered
     * @param name
     *            the name of the file (or last element of a directory path)
     *            of the file to be filtered
     * @return True If the file is a Java source file (has '.java'
     *         extension)
     */
    public boolean accept(File dir, String name) {
      return name.endsWith(".java");
    }
  }

  /**
   * This Filter identifies the directories with a list of files
   */
  private class DirectoryFilter implements FilenameFilter {
    /**
     * Filters incoming file to see if it is a directory
     *
     * @param dir
     *            Absolute path of the file being filtered
     * @param name
     *            he name of the file (or last element of a directory path)
     *            of the file to be filtered
     * @return True is a File is a directory
     */
    public boolean accept(File dir, String name) {
      File temp = new File(dir.getAbsoluteFile(), name);

      return temp.isDirectory();
    }
  }
}
TOP

Related Classes of org.hybridlabs.source.formatter.m2.FormatManager$DirectoryFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.