org.apache.usergrid.chop.plugin.Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.usergrid.chop.plugin.Utils.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.usergrid.chop.plugin;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;

import org.codehaus.plexus.archiver.zip.ZipArchiver;
import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

public class Utils {

    private final static Logger LOG = LoggerFactory.getLogger(Utils.class);

    /**
     * @param jarFile Jar file to be extracted
     * @param destinationFolder Folder which the jarFile will be extracted to. Jar file's root will be this folder once
     * it is extracted.
     */
    public static void extractJar(File jarFile, String destinationFolder) throws MojoExecutionException {
        try {
            ZipUnArchiver unArchiver = new ZipUnArchiver(jarFile);
            unArchiver.enableLogging(new ConsoleLogger(org.codehaus.plexus.logging.Logger.LEVEL_INFO, "console"));
            unArchiver.setDestDirectory(new File(destinationFolder));
            unArchiver.extract();
        } catch (Exception e) {
            throw new MojoExecutionException("Error while extracting JAR file", e);
        }
    }

    /**
     * @param jarFile Jar file to be created
     * @param sourceFolder Jar file will be created out of the contents of this folder. This corresponds to the root
     * folder of the jar file once it is created.
     */
    public static void archiveWar(File jarFile, String sourceFolder) throws MojoExecutionException {
        try {
            ZipArchiver archiver = new ZipArchiver();
            archiver.enableLogging(new ConsoleLogger(org.codehaus.plexus.logging.Logger.LEVEL_INFO, "console"));
            archiver.setDestFile(jarFile);
            archiver.addDirectory(new File(sourceFolder), "", new String[] { "**/*" }, null);
            archiver.createArchive();
        } catch (Exception e) {
            throw new MojoExecutionException("Error while creating WAR file", e);
        }
    }

    /**
     * Gets all dependency jars of the project specified by 'project' parameter from the local mirror and copies them
     * under targetFolder
     *
     * @param targetFolder The folder which the dependency jars will be copied to
     */
    public static void copyArtifactsTo(MavenProject project, String targetFolder) throws MojoExecutionException {
        File targetFolderFile = new File(targetFolder);
        for (Iterator it = project.getArtifacts().iterator(); it.hasNext();) {
            Artifact artifact = (Artifact) it.next();

            File f = artifact.getFile();

            LOG.info("Artifact {} found.", f.getAbsolutePath());

            if (f == null) {
                throw new MojoExecutionException("Cannot locate artifact file of " + artifact.getArtifactId());
            }

            // Check already existing artifacts and replace them if they are of a lower version
            try {

                List<String> existing = FileUtils.getFileNames(targetFolderFile,
                        artifact.getArtifactId() + "-*.jar", null, false);

                if (existing.size() != 0) {
                    String version = existing.get(0).split("(" + artifact.getArtifactId() + "-)")[1]
                            .split("(.jar)")[0];
                    DefaultArtifactVersion existingVersion = new DefaultArtifactVersion(version);
                    DefaultArtifactVersion artifactVersion = new DefaultArtifactVersion(artifact.getVersion());

                    if (existingVersion.compareTo(artifactVersion) < 0) { // Remove existing version
                        FileUtils.forceDelete(targetFolder + existing.get(0));
                    } else {
                        LOG.info("Artifact " + artifact.getArtifactId() + " with the same or higher "
                                + "version already exists in lib folder, skipping copy");
                        continue;
                    }
                }

                LOG.info("Copying {} to {}", f.getName(), targetFolder);
                FileUtils.copyFileToDirectory(f.getAbsolutePath(), targetFolder);
            } catch (IOException e) {
                throw new MojoExecutionException("Error while copying artifact file of " + artifact.getArtifactId(),
                        e);
            }
        }
    }

    /**
     * Copies all found resource files, including test resources to the <code>targetFolder</code>.
     * <p>
     * Resource files to be copied are filtered or included according to the configurations inside
     * <code>project</code>'s pom.xml file.
     *
     * @param project       project whose resource files to be copied
     * @param targetFolder  matching resource files are stored in this directory
     * @return
     */
    public static boolean copyResourcesTo(MavenProject project, String targetFolder) {
        File targetFolderFile = new File(targetFolder);
        String includes;
        String excludes;
        List allResources = project.getResources();
        allResources.addAll(project.getTestResources());

        // If there is no resource folder under project, mvn chop:runner goal should fail
        if (!hasResourceFolders(project)) {
            return false;
        } else {
            LOG.info("Copying resource files to runner.jar");

            for (Object res : allResources) {
                if (!(res instanceof Resource)) {
                    continue;
                }
                Resource resource = (Resource) res;
                try {
                    File baseDir = new File(resource.getDirectory());
                    includes = resource.getIncludes().toString().replace("[", "").replace("]", "").replace(" ", "");
                    excludes = resource.getExcludes().toString().replace("[", "").replace("]", "").replace(" ", "");

                    List<String> resFiles = FileUtils.getFileNames(baseDir, includes, excludes, true, true);
                    for (String resFile : resFiles) {
                        File resourceFile = new File(resFile);
                        LOG.info("Copying {} to {}", resourceFile.getName(), targetFolder);
                        FileUtils.copyFileToDirectory(resourceFile, targetFolderFile);
                    }
                } catch (IOException e) {
                    LOG.info("Error while trying to copy resource files.", e);
                } catch (IllegalStateException e) {
                    String path = resource.getDirectory();
                    path = path.substring(0, path.lastIndexOf("/"));
                    LOG.info("There is no resource folder under {} folder.", path);
                }
            }
            return true;
        }
    }

    /**
     * Returns true if there is at least one resource folder inside the project.
     *
     * @param project
     * @return
     */
    public static boolean hasResourceFolders(MavenProject project) {
        List<Resource> resources = project.getResources();
        for (Resource res : resources) {
            if (FileUtils.fileExists(res.getDirectory())) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param projectPath
     * @return
     * @throws MojoExecutionException
     */
    public static String getGitConfigFolder(String projectPath) throws MojoExecutionException {
        projectPath = forceNoSlashOnDir(projectPath);

        while (!FileUtils.fileExists(projectPath + File.separator + ".git")) {
            int lastSlashIndex = projectPath.lastIndexOf(File.separator);
            if (lastSlashIndex < 1) {
                throw new MojoExecutionException("There are no local git repository associated with this project");
            }
            projectPath = projectPath.substring(0, lastSlashIndex);
        }
        return projectPath + File.separator + ".git";
    }

    /**
     * @param gitConfigFolder e.g. /your/project/root/.git
     *
     * @return Returns last commit's UUID, "nocommit" if there are no commits and returns null if an exception occured
     */
    public static String getLastCommitUuid(String gitConfigFolder) throws MojoExecutionException {
        try {
            Repository repo = new RepositoryBuilder().setGitDir(new File(gitConfigFolder)).readEnvironment()
                    .findGitDir().build();
            RevWalk walk = new RevWalk(repo);
            ObjectId head = repo.resolve("HEAD");
            if (head != null) {
                RevCommit lastCommit = walk.parseCommit(head);
                return lastCommit.getId().getName();
            } else {
                return "nocommit";
            }
        } catch (Exception e) {
            throw new MojoExecutionException("Error trying to get the last git commit uuid", e);
        }
    }

    /**
     * @param gitConfigFolder e.g. /your/project/root/.git
     *
     * @return Returns git config remote.origin.url field of the repository located at gitConfigFolder
     */
    public static String getGitRemoteUrl(String gitConfigFolder) throws MojoExecutionException {
        try {
            Repository repo = new RepositoryBuilder().setGitDir(new File(gitConfigFolder)).readEnvironment()
                    .findGitDir().build();
            Config config = repo.getConfig();
            return config.getString("remote", "origin", "url");
        } catch (Exception e) {
            throw new MojoExecutionException("Error trying to get remote origin url of git repository", e);
        }
    }

    /**
     * @param gitConfigFolder e.g. /your/project/root/.git
     *
     * @return Returns true if 'git status' has modified files inside the 'Changes to be committed' section
     */
    public static boolean isCommitNecessary(String gitConfigFolder) throws MojoExecutionException {
        try {
            Repository repo = new FileRepository(gitConfigFolder);
            Git git = new Git(repo);

            Status status = git.status().call();
            Set<String> modified = status.getModified();

            return (modified.size() != 0);
        } catch (Exception e) {
            throw new MojoExecutionException("Error trying to find out if git commit is needed", e);
        }
    }

    /**
     * Concatenates provided timestamp and commitUUID strings and returns their calculated MD5 in hexadecimal format
     *
     * @return Returns the hexadecimal representation of calculated MD5
     *
     * @throws MojoExecutionException This will probably never thrown, cause UTF-8 encoding and MD5 is defined in each
     * system
     */
    public static String getMD5(String timestamp, String commitUUID) throws MojoExecutionException {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            byte[] hash = digest.digest((timestamp + commitUUID).getBytes("UTF-8"));

            StringBuilder result = new StringBuilder(hash.length * 2);
            for (int i = 0; i < hash.length; i++) {
                result.append(String.format("%02x", hash[i] & 0xff));
            }

            return result.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new MojoExecutionException("MD5 algorithm could not be found", e);
        } catch (UnsupportedEncodingException e) {
            throw new MojoExecutionException("UTF-8 encoding is not supported", e);
        }
    }

    /** @return Returns the given date in a 'yyyy.MM.dd.HH.mm.ss' format, UTC timezone */
    public static String getTimestamp(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        return dateFormat.format(date);
    }

    /**
     * @param directory
     * @return
     */
    public static String forceSlashOnDir(String directory) {
        return directory.endsWith(File.separator) ? directory : directory + File.separator;
    }

    /**
     * @param directory
     * @return
     */
    public static String forceNoSlashOnDir(String directory) {
        return directory.endsWith(File.separator) ? directory.substring(0, directory.length() - 1) : directory;
    }
}