All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.utils.rename.PackageRenamer Maven / Gradle / Ivy

There is a newer version: 5.0.0-B04
Show newest version
/*
 * Copyright (c) 1998, 2024 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.utils.rename;

import java.io.*;
import java.util.*;

/**
 * This class performs package renaming. It demonstrates the following:
 *
 * a) Reading the properties file to be a reference for changing the package
 * name from your source code.
 *
 * b) Traverse source root directory for creating a corresponding output
 * directory and finding the java source file(s) to be changing the package
 * name.
 *
 * c) Search and replace the old TopLink package name(s) with new one(s)
 * according to the reference.
 *
 * You will be able to see the logging message at the command line window where
 * the PackageRenamer is running.
 *
 */
public class PackageRenamer {
    private static int BUFSIZ = 1024 * 4;

    private List ignoreFiles = new ArrayList<>();

    private List renameValues = new ArrayList<>();

    private int numberOfTotalFile = 0;

    private int numberOfChangedFile = 0;

    // contains the source-root-directory
    File sourceRootDirFile;

    // contains the destination-root-directory
    File destinationRootDir;

    public PackageRenamer(String sourceFolder, String targetFolder,
            Properties properties) {
        this.sourceRootDirFile = buildAndCheckExistingDirFile(sourceFolder);
        this.destinationRootDir = buildAndCheckDestinationFile(targetFolder);
        initialize(this.sourceRootDirFile, properties);
    }

    public List getIgnoreFiles() {
        return ignoreFiles;
    }

    public List getRenameValues() {
        return renameValues;
    }

    /**
     * Do a binary copy of the file byte buffer by byte buffer.
     */
    public void binaryCopy(File inFile, File outFile)
            throws FileNotFoundException, IOException {
        byte[] buf = new byte[BUFSIZ];
        FileInputStream in = new FileInputStream(inFile);

        // make sure the directories under this file are available
        String parent = outFile.getParent();
        if (parent != null) {
            File parentFile = new File(parent);
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
        }
        FileOutputStream out = new FileOutputStream(outFile);

        int nBytesRead;
        while ((nBytesRead = in.read(buf)) != -1) {
            out.write(buf, 0, nBytesRead);
        }
        in.close();
        out.close();
    }

    private boolean bufferContainsNullChar(byte[] buffer, int bufferLength) {
        for (int i = 0; i < bufferLength; i++) {
            if (buffer[i] == 0) {
                return true;
            }
        }
        return false;
    }

    public File buildAndCheckDestinationFile(String aDirString) {
        if (aDirString == null) {
            throw new RuntimeException("Invalid destination directory entered.");
        }

        File aDirFile = new File(aDirString);

        // Check if the destination directory is within the source directory.
        // This would create an infinite loop.
        if (directoryIsSubdirectory(sourceRootDirFile, aDirFile)) {
            throw new RuntimeException("Invalid destination directory entered:"
                    + "  '" + aDirString + "'"
                    + "It cannot be a sub-directory of the source directory.");
        }

        return aDirFile;
    }

    public File buildAndCheckExistingDirFile(String aDirString) {
        if (aDirString == null) {
            throw new RuntimeException("Invalid source directory entered.");
        }

        File aDirFile = new File(aDirString);

        if (!aDirFile.exists() || !aDirFile.isDirectory()) {
            throw new RuntimeException("Input Directory:  '" + aDirString + "'"
                    + "does not exist or is not a directory.");
        }

        return aDirFile;
    }

    /**
     * Returns the extension of the given file. Returns and empty string if none
     * was found.
     */
    protected static String parseFileExtension(String fileName) {
        int index = fileName.lastIndexOf('.');
        if (index == -1) {
            return "";
        } else {
            return fileName.substring(index + 1);
        }
    }

    /**
     * Return true if directory2 is contained within directory1. Both
     * directories must be absolute.
     */
    public static boolean directoryIsSubdirectory(File directory1,
            File directory2) {
        // System.out.println(directory1 + " contains " + directory2);
        if (directory2 == null) {
            return false;
        } else if (directory1.equals(directory2)) {
            return true;
        } else {
            return directoryIsSubdirectory(directory1, directory2
                    .getParentFile());
        }
    }

    /**
     * Return true if the PackageRenamer should work on the given file
     * extension.
     */
    public boolean isExtensionSupported(String extension) {
        return extension.equalsIgnoreCase("java")
                || extension.equalsIgnoreCase("xml")
                || extension.equalsIgnoreCase("mwp");
    }

    /**
     * This run() method performs, reading the properties file into properties
     * variable to be a reference for changing package name. creating an
     * destination-root-direetory. and, calling traverseSourceDirectory()
     * method.
     */
    public void run() {
        System.out.println("LOG MESSAGES FROM packageRenamer");
        System.out.println("");
        System.out.println("INPUT: -----------------> "
                + sourceRootDirFile.toString());
        System.out.println("OUTPUT: ----------------> "
                + destinationRootDir.toString());

        // Listing the changed file(s)
        System.out.println("List of changed file(s): ");
        traverseSourceDirectory(sourceRootDirFile);

        System.out.println("Total Changed File(s): ------> "
                + numberOfChangedFile);
        System.out.println("Total File(s):         ------> "
                + numberOfTotalFile);
    }

    /**
     * This runSearchAndReplacePackageName() reads an pre-rename source file all
     * into string variable and replacing the old package names with the new
     * ones according to the properties file.
     */
    public void runSearchAndReplacePackageName(File sourceFile) {
        if (getIgnoreFiles().contains(sourceFile)) {
            return;
        }

        String stringContainAllFile = "";
        String sourceFileName = sourceFile.toString();
        String sourceFileNameWithoutRoot = sourceFile.toString().substring(
                sourceRootDirFile.toString().length() + 1);
        String destinationFileNameWithoutRoot = renameFile(sourceFileNameWithoutRoot);

        String destinationFileName = destinationRootDir.toString()
                + File.separator + destinationFileNameWithoutRoot;
        File destFile = new File(destinationFileName);

        if (destFile.exists()) {
            System.out.println("WARNING: Skipping pre-existing: " + destFile);
            return;
        }
        System.out.print("MIGRATING: " + sourceFileName);

        // Reading file into string.
        // stringContainAllFile = readAllStringsFromFile(sourceFileName);
        try {

            FileInputStream fis = new FileInputStream(sourceFileName);
            byte[] buf = new byte[BUFSIZ];
            StringBuilder strBuf = new StringBuilder((int) new File(
                    sourceFileName).length());
            int i = 0;
            while ((i = fis.read(buf)) != -1) {
                if (bufferContainsNullChar(buf, i)) {
                    // This is a binary file, just copy it byte by byte to the
                    // new location. Do not do any renaming.
                    fis.close();
                    binaryCopy(sourceFile, new File(destinationFileName));
                    return;
                }
                String str = new String(buf, 0, i);
                strBuf.append(str);
            }
            fis.close();
            stringContainAllFile = new String(strBuf);

        } catch (IOException ioException) {
            throw new RuntimeException(
                    "Unexpected exception was thrown during file manipulation."
                            + ioException.getMessage());
        }

        System.out.print(" -> ");
        // Starting to rename.

        RenameFileData fileData = new RenameFileData(stringContainAllFile,
                false);
        // Make sure package is correct

        String sourcePackageName = null;
        String destPackageName = null;

        if (sourceFileNameWithoutRoot.lastIndexOf('\\') >= 0) {
            sourceFileNameWithoutRoot = sourceFileNameWithoutRoot.substring(0,
                    sourceFileNameWithoutRoot.lastIndexOf('\\'));
            destinationFileNameWithoutRoot = destinationFileNameWithoutRoot
                    .substring(0, destinationFileNameWithoutRoot
                            .lastIndexOf('\\'));
        }
        sourcePackageName = sourceFileNameWithoutRoot.replace('\\', '.');
        destPackageName = destinationFileNameWithoutRoot.replace('\\', '.');
        fileData = new RenameValue("package " + sourcePackageName + ";",
                "package " + destPackageName + ";").replace(fileData);

        for (RenameValue rv : getRenameValues()) {
            fileData = rv.replace(fileData);
        }

        if (fileData.isChanged()) {
            this.numberOfChangedFile++;
        }

        System.out.println(destFile);
        // Writing output file.
        try {

            destFile.getParentFile().mkdirs();

            FileWriter writer = new FileWriter(destFile);
            java.io.PrintWriter out = new java.io.PrintWriter(writer);
            out.print(fileData.getFileContentsString());
            out.close();

        } catch (FileNotFoundException fileNotFoundException) {
            throw new RuntimeException("Could not find file to write:" + "  '"
                    + destinationFileName + "'"
                    + fileNotFoundException.getMessage());
        } catch (IOException ioException) {
            throw new RuntimeException(
                    "Unexpected exception was thrown while writing the file: '"
                            + destinationFileName + "', "
                            + ioException.getMessage());
        }
    }

    public String renameFile(String source) {
        String extension = parseFileExtension(source);
        String resourceName = source.substring(0, source.length()
                - (extension.length() + 1));
        String packageName = resourceName;
        if ("java".equals(extension)) {
            packageName = resourceName.replace('\\', '.');
        }
        String targetPackageName = packageName;

        RenameFileData fileData = new RenameFileData(targetPackageName, true);
        for (RenameValue rv : getRenameValues()) {
            fileData = rv.replace(fileData);
        }

        if ("java".equals(extension)) {
            fileData.setFileContentsString(fileData.getFileContentsString().replace('.', '\\'));
        }

        if (extension != null && !extension.isEmpty()) {
            fileData.setFileContentsString(fileData.getFileContentsString()
                    + "." + extension);
        }

        return fileData.getFileContentsString();
    }

    /**
     * This traverseSourceDirectory() traverse source-root-directory, creating
     * an corresponding output directory, and calling another method for
     * replacing old TopLink package name.
     */
    public void traverseSourceDirectory(File directory) {
        File[] filesAndDirectories = directory.listFiles();

        for (int i = 0; i < filesAndDirectories.length; i++) {
            File fileOrDirectory = filesAndDirectories[i];

            if (fileOrDirectory.isDirectory()) {
                if (!fileOrDirectory.getName().equalsIgnoreCase(".svn")) {
                    traverseSourceDirectory(fileOrDirectory);
                }
            } else {
                this.numberOfTotalFile++;
                // Check that it does not have an unsupported file extension
                String fileExtension = parseFileExtension(fileOrDirectory
                        .getName());
                if (isExtensionSupported(fileExtension)) {
                    runSearchAndReplacePackageName(fileOrDirectory);
                }
            }
        }
    }

    /**
     *
     */
    private void initialize(File srcRoot, Properties properties) {
        for (Object key : properties.keySet()) {
            String packageOrClassName = (String) key;
            String value = properties.getProperty(packageOrClassName);

            if (value.equalsIgnoreCase("ignore")) {
                File folder = new File(srcRoot, packageOrClassName.replace('.',
                        '\\'));

                if (folder.exists() && folder.isDirectory()) {
                    addIgnoreFolder(folder, ignoreFiles);
                } else {
                    File file = new File(srcRoot, packageOrClassName.replace(
                            '.', '\\')
                            + ".java");

                    if (file.exists()) {
                        ignoreFiles.add(file);
                    }/*
                         * else { throw new IllegalArgumentException( "Could not
                         * find src to ignore: " + srcRoot + " :: " +
                         * packageOrClassName); }
                         */
                }
            } else {
                renameValues.add(new RenameValue(packageOrClassName, value));
            }
        }
        renameValues.sort(RenameValue.renameValueComparator());

        /*
         * System.out.println("FILES TO IGNORE"); for (File file : ignoreFiles) {
         * System.out.println("\t> " + file); }
         *
         * System.out.println("\nRENAME VALUES"); for (RenameValue rv :
         * renameValues) { System.out.println("\t" + rv); }
         */
    }

    /**
     *
     */
    private void addIgnoreFolder(File folder, List ignoreFiles) {
        File[] files = folder.listFiles();

        for (int index = 0; index < files.length; index++) {
            File file = files[index];

            if (file.isFile()
                    && isExtensionSupported(parseFileExtension(file.getName()))) {
                ignoreFiles.add(file);
            } else if (file.isDirectory()
                    && !file.getName().equalsIgnoreCase(".svn")) {
                addIgnoreFolder(file, ignoreFiles);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy