JarJarDiff.java :  » Code-Analyzer » DependencyFinder » com » jeantessier » dependencyfinder » ant » Java Open Source

Java Open Source » Code Analyzer » DependencyFinder 
DependencyFinder » com » jeantessier » dependencyfinder » ant » JarJarDiff.java
/*
 *  Copyright (c) 2001-2007, Jean Tessier
 *  All rights reserved.
 *  
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *  
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *  
 *      * Neither the name of Jean Tessier nor the names of his contributors
 *        may be used to endorse or promote products derived from this software
 *        without specific prior written permission.
 *  
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jeantessier.dependencyfinder.ant;

import java.io.*;
import java.util.*;
import java.lang.reflect.*;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;

import com.jeantessier.classreader.*;
import com.jeantessier.diff.*;

public class JarJarDiff extends Task {
    public static final String API_STRATEGY          = "api";
    public static final String INCOMPATIBLE_STRATEGY = "incompatible";

    public static final String DEFAULT_LEVEL = API_STRATEGY;

    private String  name      = "";
    private Path    oldPath;
    private String  oldLabel;
    private Path    newPath;
    private String  newLabel;
    private File    filter;
    private String  level     = DEFAULT_LEVEL;
    private boolean code;
    private String  encoding  = Report.DEFAULT_ENCODING;
    private String  dtdPrefix = Report.DEFAULT_DTD_PREFIX;
    private String  indentText;
    private File    destfile;

    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Path createOld() {
        if (oldPath == null) {
            oldPath = new Path(getProject());
        }

        return oldPath;
    }
    
    public Path getOld() {
        return oldPath;
    }

    public String getOldlabel() {
        return oldLabel;
    }
    
    public void setOldlabel(String oldLabel) {
        this.oldLabel = oldLabel;
    }

    public Path createNew() {
        if (newPath == null) {
            newPath = new Path(getProject());
        }

        return newPath;
    }
    
    public Path getNew() {
        return newPath;
    }

    public String getNewlabel() {
        return newLabel;
    }
    
    public void setNewlabel(String newLabel) {
        this.newLabel = newLabel;
    }

    public File getFilter() {
        return filter;
    }

    public void setfilter(File filter) {
        this.filter = filter;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    public boolean getCode() {
        return code;
    }

    public void setCode(boolean code) {
        this.code = code;
    }

    public String getEncoding() {
        return encoding;
    }
    
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public String getDtdprefix() {
        return dtdPrefix;
    }
    
    public void setDtdprefix(String dtdPrefix) {
        this.dtdPrefix = dtdPrefix;
    }

    public String getIndenttext() {
        return indentText;
    }
    
    public void setIntenttext(String indentText) {
        this.indentText = indentText;
    }

    public File getDestfile() {
        return destfile;
    }
    
    public void setDestfile(File destfile) {
        this.destfile = destfile;
    }
    
    public void execute() throws BuildException {
        // first off, make sure that we've got what we need

        if (getOld() == null) {
            throw new BuildException("old must be set!");
        }

        if (getNew() == null) {
            throw new BuildException("new must be set!");
        }

        if (getDestfile() == null) {
            throw new BuildException("destfile must be set!");
        }

        VerboseListener verboseListener = new VerboseListener(this);

        try {
            // Collecting data, first classfiles from JARs,
            // then package/class trees using NodeFactory.

            log("Loading old classes from path " + getOld());
            PackageMapper oldPackages = new PackageMapper();
            ClassfileLoader oldJar = new AggregatingClassfileLoader();
            oldJar.addLoadListener(oldPackages);
            oldJar.addLoadListener(verboseListener);
            oldJar.load(Arrays.asList(getOld().list()));

            log("Loading new classes from path " + getNew());
            PackageMapper newPackages = new PackageMapper();
            ClassfileLoader newJar = new AggregatingClassfileLoader();
            newJar.addLoadListener(newPackages);
            newJar.addLoadListener(verboseListener);
            newJar.load(Arrays.asList(getNew().list()));

            DifferenceStrategy baseStrategy = getDefaultStrategy(getCode());
            DifferenceStrategy strategy = getStrategy(getLevel(), baseStrategy);

            if (getFilter() != null) {
                strategy = new ListBasedDifferenceStrategy(strategy, getFilter());
            }

            // Starting to compare, first at package level,
            // then descending to class level for packages
            // that are in both the old and the new codebase.

            log("Comparing old and new classes ...");

            String name = getName();
            String oldLabel = (getOldlabel() != null) ? getOldlabel() : getOld().toString();
            String newLabel = (getNewlabel() != null) ? getNewlabel() : getNew().toString();

            DifferencesFactory factory = new DifferencesFactory(strategy);
            Differences differences = factory.createProjectDifferences(name, oldLabel, oldPackages, newLabel, newPackages);

            log("Saving difference report to " + getDestfile().getAbsolutePath());

            com.jeantessier.diff.Printer printer = new Report(getEncoding(), getDtdprefix());
            if (getIndenttext() != null) {
                printer.setIndentText(getIndenttext());
            }

            differences.accept(printer);

            PrintWriter out = new PrintWriter(new FileWriter(getDestfile()));
            out.print(printer);
            out.close();
        } catch (IOException ex) {
            throw new BuildException(ex);
        }
    }

    private DifferenceStrategy getStrategy(String level, DifferenceStrategy baseStrategy) {
        DifferenceStrategy strategy;
        if (API_STRATEGY.equals(level)) {
            strategy = new APIDifferenceStrategy(baseStrategy);
        } else if (INCOMPATIBLE_STRATEGY.equals(level)) {
            strategy = new IncompatibleDifferenceStrategy(baseStrategy);
        } else {
            try {
                Constructor constructor;
                try {
                    constructor = Class.forName(level).getConstructor(DifferenceStrategy.class);
                    strategy = (DifferenceStrategy) constructor.newInstance(baseStrategy);
                } catch (NoSuchMethodException ex) {
                    strategy = (DifferenceStrategy) Class.forName(level).newInstance();
                }
            } catch (InvocationTargetException ex) {
                log("Unknown level \"" + level + "\", using default level \"" + DEFAULT_LEVEL + "\": " + ex.getMessage());
                strategy = getDefaultStrategy(baseStrategy);
            } catch (InstantiationException ex) {
                log("Unknown level \"" + level + "\", using default level \"" + DEFAULT_LEVEL + "\": " + ex.getMessage());
                strategy = getDefaultStrategy(baseStrategy);
            } catch (IllegalAccessException ex) {
                log("Unknown level \"" + level + "\", using default level \"" + DEFAULT_LEVEL + "\": " + ex.getMessage());
                strategy = getDefaultStrategy(baseStrategy);
            } catch (ClassNotFoundException ex) {
                log("Unknown level \"" + level + "\", using default level \"" + DEFAULT_LEVEL + "\": " + ex.getMessage());
                strategy = getDefaultStrategy(baseStrategy);
            } catch (ClassCastException ex) {
                log("Unknown level \"" + level + "\", using default level \"" + DEFAULT_LEVEL + "\": " + ex.getMessage());
                strategy = getDefaultStrategy(baseStrategy);
            }
        }
        return strategy;
    }

    private DifferenceStrategy getDefaultStrategy(boolean useCode) {
        DifferenceStrategy baseStrategy;
        if (useCode) {
            baseStrategy = new CodeDifferenceStrategy();
        } else {
            baseStrategy = new NoDifferenceStrategy();
        }
        return baseStrategy;
    }

    private APIDifferenceStrategy getDefaultStrategy(DifferenceStrategy baseStrategy) {
        return new APIDifferenceStrategy(baseStrategy);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.