org.nuxeo.build.ant.ZipDiffTask.java Source code

Java tutorial

Introduction

Here is the source code for org.nuxeo.build.ant.ZipDiffTask.java

Source

/*
 * (C) Copyright 2011-2014 Nuxeo SA (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     Julien Carsique
 *
 */

package org.nuxeo.build.ant;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.io.IOUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.PatternSet.NameEntry;

/**
 * Compares two ZIP files, generating a {@link PatternSet}
 */
public class ZipDiffTask extends Task {

    public static String newline = System.getProperty("line.separator");

    protected File file1;

    protected File file2;

    protected File includesfile;

    protected File excludesfile;

    private FileWriter fileWriter;

    private PatternSet patternSet;

    private boolean ignoreContent = false;

    private String ignoreContentPattern = ".*(?<!SNAPSHOT)\\.jar$";

    public void setFile1(File file1) {
        this.file1 = file1;
    }

    public void setFile2(File file2) {
        this.file2 = file2;
    }

    public void setIncludesfile(File includesfile) {
        this.includesfile = includesfile;
    }

    public void setExcludesfile(File excludesfile) {
        this.excludesfile = excludesfile;
    }

    public void setPatternsetid(String id) {
        patternSet = new PatternSet();
        getProject().addReference(id, patternSet);
    }

    /**
     * If two files have same name, their content is compared. This option
     * allows to bypass the content check.
     *
     * @param ignoreContent if true, files' content is not checked
     * @since 1.13
     */
    public void setIgnoreContent(boolean ignoreContent) {
        this.ignoreContent = ignoreContent;
    }

    /**
     * If two files have same name, their content is compared. This option
     * allows to bypass the content check for filenames matching the given
     * pattern.
     *
     * @param ignoreContentPattern Pattern of filenames for which content must
     *            not be checked. Default value bypass content check for JAR
     *            files but SNAPSHOT ones.
     * @since 1.13
     */
    public void setIgnoreContentPattern(String ignoreContentPattern) {
        this.ignoreContentPattern = ignoreContentPattern;
    }

    @Override
    public void execute() throws BuildException {
        ZipFile zipfile1 = null;
        ZipFile zipfile2 = null;
        try {
            zipfile1 = new ZipFile(file1);
            zipfile2 = new ZipFile(file2);

            Set<String> set1 = new LinkedHashSet<>();
            for (Enumeration<? extends ZipEntry> zipEntries = zipfile1.entries(); zipEntries.hasMoreElements();) {
                set1.add((zipEntries.nextElement()).getName());
            }
            Set<String> set2 = new LinkedHashSet<>();
            for (Enumeration<? extends ZipEntry> zipEntries = zipfile2.entries(); zipEntries.hasMoreElements();) {
                set2.add((zipEntries.nextElement()).getName());
            }

            try {
                if (includesfile != null) {
                    includesfile.createNewFile();
                    fileWriter = new FileWriter(includesfile);
                }

                // includes (files from file1 not present or differ in file2)
                for (Iterator<String> i = set1.iterator(); i.hasNext();) {
                    String filename = i.next();
                    if (!set2.contains(filename)) {
                        log("Only in " + file1.getName() + ": " + filename, Project.MSG_INFO);
                        include(filename, fileWriter);
                        continue;
                    }
                    set2.remove(filename);
                    if (!ignoreContent && !filename.matches(ignoreContentPattern)) {
                        try {
                            if (!IOUtils.contentEquals(zipfile1.getInputStream(zipfile1.getEntry(filename)),
                                    zipfile2.getInputStream(zipfile2.getEntry(filename)))) {
                                log("Content differs: " + filename, Project.MSG_INFO);
                                include(filename, fileWriter);
                            }
                        } catch (IOException e) {
                            log(e, Project.MSG_WARN);
                        }
                    }
                }
            } catch (IOException e) {
                throw new BuildException(e);
            } finally {
                IOUtils.closeQuietly(fileWriter);
            }

            // excludes (files from file2 not present in file1)
            try {
                if (excludesfile != null) {
                    excludesfile.createNewFile();
                    fileWriter = new FileWriter(excludesfile);
                }
                for (Iterator<String> i = set2.iterator(); i.hasNext();) {
                    String filename = i.next();
                    log("Only in " + file2.getName() + ": " + filename, Project.MSG_INFO);
                    exclude(filename, fileWriter);
                }
            } catch (IOException e) {
                throw new BuildException(e);
            } finally {
                IOUtils.closeQuietly(fileWriter);
            }
        } catch (IOException e) {
            throw new BuildException("Error opening " + file1 + " or " + file2, e);
        } finally {
            if (zipfile1 != null) {
                try {
                    zipfile1.close();
                } catch (IOException e) {
                    throw new BuildException(e);
                }
            }
            if (zipfile2 != null) {
                try {
                    zipfile2.close();
                } catch (IOException e) {
                    throw new BuildException(e);
                }
            }
        }
    }

    protected void exclude(String filename, FileWriter writer) throws IOException {
        if (patternSet != null) {
            NameEntry exclude = patternSet.createExclude();
            exclude.setName(filename);
        }
        write(filename, writer);
    }

    protected void include(String filename, FileWriter writer) throws IOException {
        if (patternSet != null) {
            NameEntry include = patternSet.createInclude();
            include.setName(filename);
        }
        write(filename, writer);
    }

    private void write(String filename, FileWriter writer) throws IOException {
        if (writer != null) {
            writer.write(filename + newline);
        }
    }
}