net.java.jpatch.maven.PatchMojo.java Source code

Java tutorial

Introduction

Here is the source code for net.java.jpatch.maven.PatchMojo.java

Source

/*
 * Copyright 2012 Andrej Petras <andrej@ajka-andrej.com>.
 *
 * 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 net.java.jpatch.maven;

import java.io.File;
import java.io.IOException;
import java.util.*;
import net.java.jpatch.maven.common.AbstractPatchMojo;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.FileUtils;

/**
 * The patch build action.
 *
 * @author Andrej Petras <andrej@ajka-andrej.com> 
 * 
 * @goal patch
 * 
 * @threadSafe
 * @phase package
 */
public class PatchMojo extends AbstractPatchMojo {

    /** The default exclude path. */
    private static final String[] DEFAULT_EXCLUDE_PATH = { "maven" };

    /** The default remove path. */
    private static final String[] DEFAULT_REMOVE_PATH = { "MANIFEST.MF" };

    /**
     * The list of exclude files from patch.
     *
     * @parameter expression="${excludesFromPatch}"
     */
    protected List<String> excludesFromPatch;

    /**
     * The list of remove files from patch.
     *
     * @parameter expression="${removesFromPatch}"
     */
    protected List<String> removesFromPatch;

    /**
     * Creates the patch.
     * 
     * @exception  MojoExecutionException if the method fails.
     */
    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        // Create new patch artifact
        Artifact patchArtifact = createNewPatchArtifact();

        // Creates release directory.
        File releaseDirectory = setupReleaseDirectory();

        // Setup release
        Properties releaseProperties = loadReleaseProperties();

        // Load project for the patch
        List<MavenProject> mavenProjects = loadMavenProjectsForPatch(releaseProperties, patchArtifact);

        // Check project
        if (mavenProjects == null || mavenProjects.isEmpty()) {
            getLog().warn("The list of maven projects is empty! Nothing to build");
        } else {

            // Create patch directory
            File outputDirectory = createTargetDirectory(patchArtifact.getVersion());

            // Exclude directory and files
            if (excludesFromPatch == null) {
                excludesFromPatch = new ArrayList<String>();
            }
            excludesFromPatch.addAll(Arrays.asList(DEFAULT_EXCLUDE_PATH));
            Set<String> exclude = new HashSet<String>(excludesFromPatch);

            // Removes the directory and files
            if (removesFromPatch == null) {
                removesFromPatch = new ArrayList<String>();
                removesFromPatch.addAll(Arrays.asList(DEFAULT_REMOVE_PATH));
            }
            Set<String> remove = new HashSet<String>(removesFromPatch);

            // Copy and unpack the project in the patch directory
            for (MavenProject project : mavenProjects) {
                Artifact artifact = project.getArtifact();
                resolveArtifactFromLocalRepository(artifact);
                File libDir = unpackArtifactFile(outputDirectory, artifact.getFile());

                // Remove same files frtom the patch
                File releaseLib = new File(releaseDirectory, libDir.getName());
                removeNoChangedFiles(releaseLib, libDir, exclude, remove);
            }

            // Create patch for the release.
            createPatch(outputDirectory, patchArtifact);
        }
    }

    private void removeNoChangedFiles(File releaseDirectory, File patchDirectory, Set<String> exclude,
            Set<String> remove) throws MojoFailureException {

        File[] sreleaseFiles = releaseDirectory.listFiles();
        File[] patchFiles = patchDirectory.listFiles();

        Map<String, File> releaseMap = new HashMap<String, File>();
        for (File item : sreleaseFiles) {
            releaseMap.put(item.getName(), item);
        }

        Map<String, File> patchMap = new HashMap<String, File>();
        for (File item : patchFiles) {
            patchMap.put(item.getName(), item);
        }

        // intersection
        Set<String> keys = new HashSet<String>(patchMap.keySet());
        Set<String> keys2 = new HashSet<String>(releaseMap.keySet());
        keys.retainAll(keys2);

        for (String item : keys) {
            File patchFile = patchMap.get(item);
            File releaseFile = releaseMap.get(item);
            String name = patchFile.getName();
            if (!exclude.contains(name)) {
                if (patchFile.isFile() && releaseFile.isFile()) {
                    if (remove.contains(name) || patchFile.length() == releaseFile.length()) {
                        try {
                            FileUtils.forceDelete(patchFile);
                            getLog().info("Delete file " + patchFile.getAbsolutePath());
                        } catch (IOException ex) {
                            getLog().error("Can not delete file " + patchFile.getAbsolutePath());
                        }
                    }
                } else if (patchFile.isDirectory() && releaseFile.isDirectory()) {
                    removeNoChangedFiles(releaseFile, patchFile, exclude, remove);
                    if (patchFile.listFiles() == null || patchFile.listFiles().length == 0) {
                        try {
                            FileUtils.forceDelete(patchFile);
                            getLog().info("Delete file " + patchFile.getAbsolutePath());
                        } catch (IOException ex) {
                            getLog().error("Can not delete file " + patchFile.getAbsolutePath());
                        }
                    }
                } else {
                    getLog().error("Can not compare file and directory");
                    getLog().error("Patch: " + patchFile.getAbsolutePath());
                    getLog().error("Release: " + releaseFile.getAbsolutePath());
                    throw new MojoFailureException("Can not compare file and directory!");
                }
            }
        }

        // item only in the patch directory
        Set<String> patchKeys = new HashSet<String>(patchMap.keySet());
        patchKeys.removeAll(keys);
        for (String item : patchKeys) {
            getLog().warn("New file: " + item);
        }

        // item only in the release directoryy
        Set<String> releaseKeys = new HashSet<String>(releaseMap.keySet());
        releaseKeys.removeAll(keys);
        for (String item : releaseKeys) {
            getLog().warn("Missing file: " + item);
        }
    }

    private Artifact createNewPatchArtifact() throws MojoExecutionException {

        // Create the patch artifact
        Artifact patchArtifact = createPatchArtifact();

        // Load all version of the patch artifact
        List<ArtifactVersion> versions = findAllVersionOfArtifact(patchArtifact);

        int number = -1;

        // Check the list of versions
        if (versions == null || versions.isEmpty()) {
            getLog().warn("No patchs for the artifact " + patchArtifact.getId() + " found!");
        } else {
            int tmp;
            for (ArtifactVersion version : versions) {
                tmp = getPatchNumber(version);
                if (number < tmp) {
                    number = tmp;
                }
            }
        }

        number = number + 1;

        Artifact result = createPatchArtifact(number);
        return result;
    }

    private void createPatch(File outputDirectory, Artifact patchArtifact)
            throws MojoExecutionException, MojoFailureException {

        // Create package file
        String fileName = mavenProject.getBuild().getFinalName();
        File packFile = new File(mavenProject.getBuild().getDirectory(), fileName + ".zip");
        packDirectory(outputDirectory, packFile);

        // Attached the package to the project
        patchArtifact.setFile(packFile);
        mavenProject.addAttachedArtifact(patchArtifact);
        getLog().info("Create patch " + patchArtifact.getId());

        // Create build file (project.jpatch)
        createBuildFile();
    }

}