Package com.netthreads.mavenize

Source Code of com.netthreads.mavenize.Mavenize$FilePredicate

/*
* Copyright 2011 - Alistair Rutherford - www.netthreads.co.uk
*
* 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.
*
*/
package com.netthreads.mavenize;

import com.netthreads.mavenize.model.ProjectFiles;
import com.netthreads.mavenize.pom.PomGenerator;
import com.netthreads.mavenize.pom.PomGeneratorFactory;
import com.netthreads.mavenize.project.NetbeansJavaProjectType;
import com.netthreads.mavenize.project.ProjectType;
import com.netthreads.mavenize.project.ProjectTypeFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Mavenize
*
* Attempts to convert an existing project into a Maven project by splitting the
* source code and resources into the relevant dirs and making a stab at the pom
* if you specify a source project type i.e. "netbeans".
*
* The only specific types currently implemented are:
*
* - Normal java project "default".
* - NetBeans java module netbeans.
*
*/
@SuppressWarnings("unchecked")
public class Mavenize
{

    private static Logger logger = LoggerFactory.getLogger(ProjectFileFinder.class);
    private static final String APP_MESSAGE = "Mavenize  version 1.0.0\nAlistair Rutherford, www.netthreads.co.uk, 2011.\nLicensed under the Apache License, Version 2.0.\n\n";
    private static final String ARGS_MESSAGE = "Arguments: -i<source dir> -o<target dir> -t<project type>[Optional] -v<version>[Optional] -p<packaging>[Optional]";
    private static final String TEXT_SRC = "src";
    private static final String TEXT_MAIN = "main";
    private static final String TEXT_TEST = "test";
    private static final String TEXT_JAVA = "java";
    private static final String TEXT_RESOURCES = "resources";
    private static final String DIR_MAIN_JAVA = "/" + TEXT_MAIN + "/" + TEXT_JAVA;
    private static final String DIR_MAIN_RESOURCES = "/" + TEXT_MAIN + "/" + TEXT_RESOURCES;
    private static final String DIR_TEST_JAVA = "/" + TEXT_TEST + "/" + TEXT_JAVA;
    private static final String DIR_TEST_RESOURCES = "/" + TEXT_TEST + "/" + TEXT_RESOURCES;
    private static final String ARG_INPUT = "-i";
    private static final String ARG_OUTPUT = "-o";
    private static final String ARG_TYPE = "-t";
    private static final String ARG_VERSION = "-v";
    private static final String ARG_PACKAGING = "-p";

    /**
     * Main method.
     *
     * @param args
     */
    public static void main(String[] args)
    {
        if (args.length > 1)
        {
            String sourcePath = "";
            String targetPath = "";
            String projectTypeName = ProjectType.Types.DEFAULT.toString();
            String version = PomGenerator.DEFAULT_VERSION;
            String packaging = PomGenerator.DEFAULT_PACKAGING_TYPE;

            boolean isInput = false;
            boolean isOutput = false;
            for (String arg : args)
            {
                try
                {
                    if (arg.startsWith(ARG_INPUT))
                    {
                        sourcePath = arg.substring(ARG_INPUT.length());
                        isInput = true;
                    }
                    else if (arg.startsWith(ARG_OUTPUT))
                    {
                        targetPath = arg.substring(ARG_OUTPUT.length());
                        isOutput = true;
                    }
                    else if (arg.startsWith(ARG_TYPE))
                    {
                        projectTypeName = arg.substring(ARG_TYPE.length());
                    }
                    else if (arg.startsWith(ARG_VERSION))
                    {
                        version = arg.substring(ARG_VERSION.length());
                    }
                    else if (arg.startsWith(ARG_PACKAGING))
                    {
                        packaging = arg.substring(ARG_PACKAGING.length());
                    }
                }
                catch (Exception e)
                {
                    logger.error("Can't process argument, " + arg + ", " + e.getMessage());
                }
            }

            // Project type.
            ProjectType projectType = ProjectTypeFactory.instance().getProjectType(projectTypeName);

            // Execute conversion.
            try
            {
                if (isInput && isOutput)
                {
                    if (!sourcePath.equals(targetPath))
                    {
                        Mavenize mvnGather = new Mavenize();

                        mvnGather.process(sourcePath, targetPath, projectType, version, packaging);
                    }
                    else
                    {
                        throw new MavenizeException("Input and output directories cannot be the same.");
                    }
                }
                else
                {
                    throw new MavenizeException("You must specify input and output directories");
                }
            }
            catch (MavenizeException e)
            {
                logger.error("Application error, " + e);
            }
            catch (IOException ioe)
            {
                logger.error("Application error, " + ioe);
            }
        }
        else
        {
            System.out.println(APP_MESSAGE + ARGS_MESSAGE);
        }
    }

    /**
     * Main process method.
     *
     * @param sourcePath
     * @param targetPath
     * @throws IOException
     */
    private void process(String sourcePath, String targetPath, ProjectType projectType, String version, String packaging) throws IOException
    {
        // Generate records for all source parent, child and target directories.
        List<ProjectFiles> sourceFiles = buildProjectFiles(projectType, sourcePath, targetPath);

        logger.info("Source Files, " + sourceFiles.size());

        List<ProjectFiles> resourceFiles = buildResourceFiles(projectType, sourcePath, targetPath);

        logger.info("Resource Files, " + resourceFiles.size());

        logger.info("Generate directory structure, " + sourceFiles.size());

        // Generate Maven directory structure
        makeMavenDirs(projectType, sourceFiles);

        logger.info("Copy main files.");

        // Copy over project files.
        insertMainProjectFiles(projectType, sourceFiles, resourceFiles);

        logger.info("Copy test files.");

        // Copy over test files.
        insertTestProjectFiles(projectType, sourceFiles, resourceFiles);

        logger.info("Generate pom(s).");

        // Generate pom(s).
        insertProjectPom(projectType, version, packaging, sourceFiles);
       
        logger.info("Done.");
    }

    /**
     * Make Maven directory structure.
     *
     * @param projectType The conversion project type.
     * @param projects The profile files structure.
     *
     * @throws IOException
     */
    private void makeMavenDirs(ProjectType projectType, List<ProjectFiles> projects) throws IOException
    {
        logger.info("Creating Maven directory structure.");

        for (ProjectFiles project : projects)
        {
            File targetSrc = project.getTargetSrc();
            String targetSrcPath = targetSrc.getAbsolutePath();

            if (isValidSourceDir(projectType, targetSrcPath))
            {
                // Create directories
                createDir(DIR_MAIN_JAVA, targetSrcPath);
                createDir(DIR_MAIN_RESOURCES, targetSrcPath);
                createDir(DIR_TEST_JAVA, targetSrcPath);
                createDir(DIR_TEST_RESOURCES, targetSrcPath);
            }
        }
    }

    /**
     * Will copy project files to main area.
     *
     * @param projectType
     * @param sourceFiles
     * @param resourceFiles
     */
    private void insertMainProjectFiles(ProjectType projectType, List<ProjectFiles> sourceFiles, List<ProjectFiles> resourceFiles) throws IOException
    {
        copyMainFiles(projectType, DIR_MAIN_JAVA, sourceFiles);

        copyMainFiles(projectType, DIR_MAIN_RESOURCES, resourceFiles);
    }

    /**
     * Will copy any test files into test area.
     *
     * @param projectType
     * @param sourceFiles
     * @param resourceFiles
     */
    private void insertTestProjectFiles(ProjectType projectType, List<ProjectFiles> sourceFiles, List<ProjectFiles> resourceFiles) throws IOException
    {

        copyTestFiles(projectType, DIR_TEST_JAVA, sourceFiles);

        copyTestFiles(projectType, DIR_TEST_RESOURCES, resourceFiles);

    }

    /**
     * Attempt to generate pom.
     *
     * We can't do much for a general java project but for specific types it might
     * be possible to glean something from the project definition files.
     *
     * @param projectType
     * @param projectFiles
     *
     * @throws IOException
     */
    private void insertProjectPom(ProjectType projectType, String version, String packaging, List<ProjectFiles> projectFiles) throws IOException
    {
        PomGenerator pomGenerator = PomGeneratorFactory.instance().getGenerator(projectType);

        // For each project generate an appropriate pom file.
        for (ProjectFiles project : projectFiles)
        {
            File targetSrc = project.getTargetSrc();
            String targetSrcPath = targetSrc.getAbsolutePath();

            // If is a valid source direcory according to type.
            if (isValidSourceDir(projectType, targetSrcPath))
            {
                pomGenerator.generate(project, version, packaging);
            }
        }
    }

    /**
     * Copy test files.
     *
     * @param projectType
     * @param subDir
     * @param projectFiles
     *
     * @throws IOException
     */
    private void copyMainFiles(ProjectType projectType, String subDir, List<ProjectFiles> projectFiles) throws IOException
    {
        for (ProjectFiles project : projectFiles)
        {
            File targetSrc = project.getTargetSrc();
            String targetSrcPath = targetSrc.getAbsolutePath();

            // If is a valid source direcory according to type.
            if (isValidSourceDir(projectType, targetSrcPath))
            {
                copyFiles(targetSrcPath, subDir, project);
            }

        }
    }

    /**
     * Copy test files.
     *
     * @param projectType
     * @param subDir
     * @param projectFiles
     *
     * @throws IOException
     */
    private void copyTestFiles(ProjectType projectType, String subDir, List<ProjectFiles> projectFiles) throws IOException
    {
        // If not a specific type of project then don't bother.
        ProjectType.Types type = projectType.getType();
        if (type != ProjectType.Types.DEFAULT)
        {
            for (ProjectFiles project : projectFiles)
            {
                File sourceSrc = project.getSourceSrc();
                String sourceSrcPath = sourceSrc.getAbsolutePath();

                // If is source of tests according to project type.
                if (isTestDir(projectType, sourceSrcPath))
                {
                    File targetSrc = project.getTargetSrc();
                    String targetSrcPath = targetSrc.getAbsolutePath();

                    // Adjust according to target type.
                    String adjustedTestPath = adjustTestDir(projectType, targetSrcPath);

                    copyFiles(adjustedTestPath, subDir, project);
                }
            }
        }
    }

    /**
     * Adjust the supplied directory to Maven style path.
     *
     */
    private String adjustTestDir(ProjectType projectType, String sourceDir)
    {
        String adjustedDir = sourceDir;

        switch (projectType.getType())
        {
            // If netbeans then ignore the test/unit directory
            case NETBEANS:
                int index = sourceDir.length() - NetbeansJavaProjectType.TEST_DIR.length();
                adjustedDir = sourceDir.substring(0, index) + TEXT_SRC;
                break;
            default:
                break;
        }

        return adjustedDir;
    }

    /**
     * Copy files to target.
     *
     * @param targetPath
     * @param targetPathType
     * @param projectFiles
     */
    private void copyFiles(String targetSrcPath, String subDir, ProjectFiles projectFiles) throws IOException
    {
        List<File> files = projectFiles.getFiles();

        for (File file : files)
        {
            String sourceSrcPath = projectFiles.getSourceSrc().getAbsolutePath();
            String filePath = file.getAbsolutePath();

            String partial = filePath.substring(sourceSrcPath.length());

            String targetPath = targetSrcPath + subDir + partial;

            logger.debug("From : " + filePath + ", To :" + targetPath);

            FileUtils.copyFile(file, new File(targetPath), true);
        }
    }

    /**
     * Depending on the project target type test to see if we are interested in
     * target directory.
     *
     * @param projectType
     * @param sourceDirParent
     *
     * @return Directory is valid.
     */
    private boolean isValidSourceDir(ProjectType projectType, String sourceDir)
    {
        boolean status = true;

        switch (projectType.getType())
        {
            // If netbeans then ignore the test/unit directory
            case NETBEANS:
                status = !isTestDir(projectType, sourceDir);
                break;
            default:
                break;
        }

        return status;
    }

    /**
     * Checks to see if supplied directory is a test directory.
     *
     * @param projectType
     * @param sourceDir
     *
     * @return True is test directory for supplied project type.
     */
    private boolean isTestDir(ProjectType projectType, String sourceDir)
    {
        boolean status = false;

        switch (projectType.getType())
        {
            // If netbeans then ignore the test/unit directory
            case NETBEANS:
                int index = sourceDir.length() - NetbeansJavaProjectType.TEST_DIR.length();
                String partial = sourceDir.substring(index);
                status = pathEquals(partial, NetbeansJavaProjectType.TEST_DIR);
                break;
            default:
                break;
        }

        return status;
    }

    /**
     * Get project source files.
     *
     * @param sourcePath
     *                  The source directory path.
     * @param targetPath
     *                  The target directory path.
     *
     * @return List of parent source directories and child directories.
     *
     * @throws IOException
     */
  private List<ProjectFiles> buildProjectFiles(ProjectType projectType, String sourcePath, String targetPath) throws IOException
    {
        List<ProjectFiles> results = new LinkedList<ProjectFiles>();

        IOFileFilter srcDirFilter = DirectoryFileFilter.DIRECTORY;

        // Create a filter for Files ending in ".txt"
        String suffix = projectType.getSuffix();
        IOFileFilter srcFileFilter = FileFilterUtils.suffixFileFilter(suffix);

        // Combine the directory and file filters using an OR condition
        java.io.FileFilter srcFilter = FileFilterUtils.or(srcDirFilter, srcFileFilter);

        // Finder for all directories, no depth limit but we will limit on name.
        ProjectFileFinder projectFileFinder = new ProjectFileFinder(srcFilter, -1);

        results = projectFileFinder.find(sourcePath, targetPath, TEXT_SRC);

        return results;
    }

    /**
     * Get project resource files.
     *
     * @param sourcePath
     *                  The source directory path.
     * @param targetPath
     *                  The target directory path.
     *
     * @return List of parent source directories and child directories.
     *
     * @throws IOException
     */
    private List<ProjectFiles> buildResourceFiles(ProjectType projectType, String sourcePath, String targetPath) throws IOException
    {
        List<ProjectFiles> results = new LinkedList<ProjectFiles>();

        IOFileFilter resourceDirFilter = DirectoryFileFilter.DIRECTORY;

        // Create a filter for Files ending in ".txt"
        String suffix = projectType.getSuffix();
        IOFileFilter resourceFileFilter = FileFilterUtils.notFileFilter(FileFilterUtils.suffixFileFilter(suffix));

        // Combine the directory and file filters using an OR condition
        java.io.FileFilter srcFilter = FileFilterUtils.or(resourceDirFilter, resourceFileFilter);

        // Finder for all directories, no depth limit but we will limit on name.
        ProjectFileFinder projectFileFinder = new ProjectFileFinder(srcFilter, -1);

        results = projectFileFinder.find(sourcePath, targetPath, TEXT_SRC);

        return results;
    }

    /**
     * Create directory if it doesn't already exist.
     *
     * @param name The directory name.
     *
     * @param directory The parent directory file object.
     */
    private void createDir(String name, String path) throws IOException
    {
        String dirPath = path + name;

        File newDir = new File(dirPath);

        if (!newDir.exists())
        {
            logger.debug("Creating target directory, " + path);

            FileUtils.forceMkdir(newDir);
        }
    }

    /**
     * Helper method to replace the Windows type backslash with a proper path one.
     *
     * @param path
     *
     * @return Fixed path string.
     */
    private String fixPath(String path)
    {
        return path.replace("\\", "/");
    }

    /**
     * Compare paths so that the backslashes are removed.
     *
     * @param pathA
     * @param pathB
     *
     * @return True if paths are equal.
     */
    private boolean pathEquals(String pathA, String pathB)
    {
        return fixPath(pathA).equals(fixPath(pathB));
    }

    /*
     * Project File Finder class.
     *
     * This class takes a target directory name and builds a list of files which
     * reside under that name. There can be multiple instances i.e multiple projects.
     *
     */
    private class ProjectFileFinder extends DirectoryWalker
    {

        private String match;
        private String sourcePath;
        private String targetPath;
        private List results;

        /**
         * Takes target directory name and filter object.
         *
         * @param target If this is null then
         * @param fileFilter
         */
        public ProjectFileFinder(FileFilter fileFilter, int depth)
        {
            super(fileFilter, depth);
        }

        /**
         * Find instances of named target directory starting at the path specified.
         *
         * @param path The starting directory.
         * @param target The name of the target directory to search for.
         *
         * @return List of search results.
         *
         * @throws IOException
         */
        public List find(String sourcePath, String targetPath, String match) throws IOException
        {
            this.results = new ArrayList();

            this.match = match;
            this.sourcePath = sourcePath;
            this.targetPath = targetPath;

            File file = new File(sourcePath);

            walk(file, results);

            return results;
        }

        /**
         * Handle hitting a file. We look for owning project in our collection and
         * if we find one then add it else create a new project entry and add it.
         *
         * @param file
         * @param depth
         * @param results
         * @throws IOException
         */
        @Override
        protected void handleFile(File file, int depth, Collection results) throws IOException
        {
            // Look for existing entry
            ProjectFiles projectFiles = (ProjectFiles) CollectionUtils.find(results, new FilePredicate(file));

            if (projectFiles != null)
            {
                logger.debug(projectFiles.getSourceSrc().getAbsolutePath() + ", " + file.getAbsolutePath());

                projectFiles.getFiles().add(file);
            }

        }

        /**
         * Handle finding a directory.
         *
         * @param directory
         * @param depth
         * @param results
         *
         * @return Returns true because we keep going,
         */
        @Override
        protected boolean handleDirectory(File directory, int depth, Collection results)
        {
            // If we have hit "target" i.e. "src" directory then we look for project
            if (directory.getName().equals(match))
            {
                String name = directory.getParent();

                // Look for existing entry
                ProjectFiles projectFiles = (ProjectFiles) CollectionUtils.find(results, new NamePredicate(name));

                if (projectFiles == null)
                {
                    logger.debug(directory.getAbsolutePath());

                    // Build target src dir to match source project
                    String partial = directory.getAbsolutePath().substring(sourcePath.length());
                    String targetSrc = targetPath + partial;
                    File target = new File(targetSrc);

                    projectFiles = new ProjectFiles(directory, target);
                    results.add(projectFiles);
                }
            }

            return true;
        }
    }

    /**
     * Implements Project file search predicate.
     *
     */
    private class NamePredicate implements Predicate
    {

        String name;

        public NamePredicate(String name)
        {
            this.name = name;
        }

        @Override
        public boolean evaluate(Object object)
        {
            ProjectFiles projectFiles = (ProjectFiles) object;

            boolean status = projectFiles.getSourceSrc().getParent().equals(name);

            return status;
        }
    }

    /**
     * Implements File predicate.
     *
     */
    private class FilePredicate implements Predicate
    {

        File file;

        public FilePredicate(File file)
        {
            this.file = file;
        }

        /**
         * Find a match for projects files to which the supplied File belongs.
         *
         * @param object
         *
         * @return True if found.
         */
        @Override
        public boolean evaluate(Object object)
        {
            boolean status = false;

            ProjectFiles projectFiles = (ProjectFiles) object;

            String projectSourceSrc = projectFiles.getSourceSrc().getAbsolutePath();
            String fileSourceSrc = file.getAbsolutePath();
            int projectSourceSrcLen = projectSourceSrc.length();
            int fileSourceSrcLen = fileSourceSrc.length();

            if (fileSourceSrcLen > projectSourceSrcLen)
            {
                // Is file part of project src dir?
                String partial = fileSourceSrc.substring(0, projectSourceSrcLen);
                status = projectSourceSrc.equals(partial);
            }

            return status;
        }
    }
}
TOP

Related Classes of com.netthreads.mavenize.Mavenize$FilePredicate

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.