[SCM] UNNAMED PROJECT branch, jh-symbols, updated. 0.36-4-g27acb14

Niels Thykier nthykier at alioth.debian.org
Tue Jul 5 19:36:22 UTC 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "UNNAMED PROJECT".

The branch, jh-symbols has been updated
       via  27acb14876246d175f39dd3e3a5b3a139caa18d8 (commit)
       via  90f24c7a0b11cd5607cc8542d04d2cf42181b334 (commit)
      from  e85be8e8d68a6fb28d4210cc893c65e815e4c830 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 27acb14876246d175f39dd3e3a5b3a139caa18d8
Author: Niels Thykier <niels at thykier.net>
Date:   Tue Jul 5 12:17:27 2011 +0200

    Created a IDifferenceMaker to diff two symbol containers
    
    Useful for determining if symbols have been added or removed.

commit 90f24c7a0b11cd5607cc8542d04d2cf42181b334
Author: Niels Thykier <niels at thykier.net>
Date:   Tue Jul 5 12:16:55 2011 +0200

    Made anonymous classes private

-----------------------------------------------------------------------

Summary of changes:
 src/org/debian/javahelper/symbols/Factory.java     |   11 ++
 .../javahelper/symbols/IDifferenceMaker.java       |    9 ++
 .../javahelper/symbols/ISymbolCheckResult.java     |    6 +
 .../debian/javahelper/symbols/ISymbolChecker.java  |   13 +++
 .../javahelper/symbols/ISymbolContainer.java       |    1 +
 src/org/debian/javahelper/symbols/ISymbolDiff.java |   61 +++++++++++
 src/org/debian/javahelper/symbols/Main.java        |   58 +++++++++++
 .../symbols/internal/BCELLibraryParser.java        |    9 +-
 .../symbols/internal/EmptySymbolContainer.java     |   19 ++++
 .../symbols/internal/SimpleSymbolDifference.java   |   54 ++++++++++
 .../internal/SymbolContainerDifference.java        |   63 +++++++++++
 .../javahelper/symbols/internal/SymbolDiffer.java  |  109 ++++++++++++++++++++
 12 files changed, 410 insertions(+), 3 deletions(-)

diff --git a/src/org/debian/javahelper/symbols/Factory.java b/src/org/debian/javahelper/symbols/Factory.java
index b2cc186..30189b4 100644
--- a/src/org/debian/javahelper/symbols/Factory.java
+++ b/src/org/debian/javahelper/symbols/Factory.java
@@ -2,6 +2,7 @@ package org.debian.javahelper.symbols;
 
 import org.debian.javahelper.symbols.internal.BCELLibraryParser;
 import org.debian.javahelper.symbols.internal.SymbolData;
+import org.debian.javahelper.symbols.internal.SymbolDiffer;
 
 /**
  * Factory class to create instances of {@link ILibrarySymbolData}
@@ -23,6 +24,11 @@ public abstract class Factory {
 	public abstract ILibrarySymbolData createSymbolData();
 
 	/**
+	 * @return A new {@link IDifferenceMaker}
+	 */
+	public abstract IDifferenceMaker createDifferenceMaker();
+
+	/**
 	 * @return A new Factory
 	 */
 	public static final Factory newInstance(){
@@ -36,6 +42,11 @@ public abstract class Factory {
 			public ILibrarySymbolData createSymbolData(){
 				return new SymbolData();
 			}
+
+			@Override
+			public IDifferenceMaker createDifferenceMaker() {
+				return new SymbolDiffer();
+			}
 		};
 	}
 }
diff --git a/src/org/debian/javahelper/symbols/IDifferenceMaker.java b/src/org/debian/javahelper/symbols/IDifferenceMaker.java
new file mode 100644
index 0000000..53cdab4
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/IDifferenceMaker.java
@@ -0,0 +1,9 @@
+package org.debian.javahelper.symbols;
+
+import org.debian.javahelper.symbols.internal.EmptySymbolContainer;
+
+public interface IDifferenceMaker {
+	public static final ISymbolContainer EMPTY_SYMBOL_CONTAINER = new EmptySymbolContainer();
+
+	public ISymbolDiff diff(ISymbolContainer oldCon, ISymbolContainer newCon);
+}
diff --git a/src/org/debian/javahelper/symbols/ISymbolCheckResult.java b/src/org/debian/javahelper/symbols/ISymbolCheckResult.java
new file mode 100644
index 0000000..08de84a
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/ISymbolCheckResult.java
@@ -0,0 +1,6 @@
+package org.debian.javahelper.symbols;
+
+public interface ISymbolCheckResult {
+
+
+}
diff --git a/src/org/debian/javahelper/symbols/ISymbolChecker.java b/src/org/debian/javahelper/symbols/ISymbolChecker.java
new file mode 100644
index 0000000..e1ba6cd
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/ISymbolChecker.java
@@ -0,0 +1,13 @@
+package org.debian.javahelper.symbols;
+
+public interface ISymbolChecker {
+
+	/**
+	 * Compare the old data set (oData) to a new data set (nData)
+	 * 
+	 * @param oData The old / original data set
+	 * @param nData The new data set
+	 * @return The result
+	 */
+	public ISymbolCheckResult analyse(ILibrarySymbolData oData, ILibrarySymbolData nData);
+}
diff --git a/src/org/debian/javahelper/symbols/ISymbolContainer.java b/src/org/debian/javahelper/symbols/ISymbolContainer.java
index 7677356..b6eae95 100644
--- a/src/org/debian/javahelper/symbols/ISymbolContainer.java
+++ b/src/org/debian/javahelper/symbols/ISymbolContainer.java
@@ -19,4 +19,5 @@ public interface ISymbolContainer {
 	 * @return The symbol if present or <code>null</code>
 	 */
 	public ISymbol getSymbol(String name);
+
 }
diff --git a/src/org/debian/javahelper/symbols/ISymbolDiff.java b/src/org/debian/javahelper/symbols/ISymbolDiff.java
new file mode 100644
index 0000000..770412c
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/ISymbolDiff.java
@@ -0,0 +1,61 @@
+package org.debian.javahelper.symbols;
+
+import java.util.List;
+
+public interface ISymbolDiff {
+
+	public SymbolDiffStatus getDiffStatus();
+
+	/**
+	 * Returns the "symbol" being diffed if any (see return).  The symbol
+	 * data may refer to the new or the old version or even just a "proxy"
+	 * symbol (implementation defined).
+	 *   If the real symbol being diffed implements {@link IClassSymbol},
+	 * then the value returned here must also implement
+	 * {@link IClassSymbol}.
+	 * 
+	 *   Note that {@link ISymbol#getVersion()} of the returned symbol is
+	 * not required to make sense and may throw
+	 * {@link UnsupportedOperationException}
+	 * 
+	 * @return The symbol in consideration; <code>null</code> if
+	 * this diff is not between two symbols, but two {@link ILibrarySymbolData}.
+	 */
+	public ISymbol getSymbol();
+
+	public List<ISymbolDiff> getNewSymbols();
+	public List<ISymbolDiff> getMissingSymbols();
+	public List<ISymbolDiff> getUnchangedSymbols();
+	public List<ISymbolDiff> getModifiedSymbols();
+
+	public enum SymbolDiffStatus {
+		/**
+		 * The symbol and all sub-symbols (if any) are completely
+		 * unchanged (in terms of signature).
+		 */
+		UNCHANGED,
+		/**
+		 * This symbol was not present in the original container,
+		 * but is present in the new one.  All sub-symbols (if any)
+		 * are therefore also "ADDED".
+		 */
+		ADDED,
+		/**
+		 * This symbol was present in the original container,
+		 * but is not present in the new one.  All sub-symbols (if any)
+		 * are therefore also "REMOVED".
+		 */
+		REMOVED,
+		/**
+		 * This symbol was present in the original container
+		 * and is also present in the new container.  However
+		 * the symbol itself has changed (e.g. it received a
+		 * new sub-symbol or it lost a sub-symbol).
+		 * 
+		 * Note renaming a symbol will be classified as adding
+		 * a new symbol and removing an old one rather than
+		 * "changing" the symbol.
+		 */
+		CHANGED;
+	}
+}
diff --git a/src/org/debian/javahelper/symbols/Main.java b/src/org/debian/javahelper/symbols/Main.java
index 77de94b..f3a7518 100644
--- a/src/org/debian/javahelper/symbols/Main.java
+++ b/src/org/debian/javahelper/symbols/Main.java
@@ -1,6 +1,9 @@
 package org.debian.javahelper.symbols;
 
 import java.io.File;
+import java.util.List;
+
+import org.debian.javahelper.symbols.ISymbolDiff.SymbolDiffStatus;
 
 public class Main {
 
@@ -34,6 +37,33 @@ public class Main {
 		} else if(args[0].equals("read")){
 			symdata = fac.createSymbolData();
 			symdata.read(args[1]);
+		} else if(args[0].equals("diff")){
+			IDifferenceMaker differ = fac.createDifferenceMaker();
+			ILibrarySymbolData oData;
+			ILibrarySymbolData nData;
+			ISymbolDiff diff;
+			if(args.length != 3) {
+				throw new IllegalArgumentException("Usage: diff <org lib/sym-file> <new lib/sym-file>");
+			}
+			if(args[1].toLowerCase().endsWith(".jar") || args[1].toLowerCase().endsWith(".zip")){
+				ILibraryParser libpar = fac.createLibraryParser();
+				libpar.parseLibrary(new File(args[1]), "<pkg>", "0.0");
+				oData = libpar.getExportedSymbols();
+			} else {
+				oData = fac.createSymbolData();
+				oData.read(args[1]);
+			}
+			if(args[2].toLowerCase().endsWith(".jar") || args[2].toLowerCase().endsWith(".zip")){
+				ILibraryParser libpar = fac.createLibraryParser();
+				libpar.parseLibrary(new File(args[2]), "<pkg>", "0.0");
+				nData = libpar.getExportedSymbols();
+			} else {
+				nData = fac.createSymbolData();
+				nData.read(args[2]);
+			}
+			diff = differ.diff(oData, nData);
+			printDiff(diff);
+			return;
 		} else {
 			throw new IllegalArgumentException("Usage: gen <library> <pkg> <version> [write-to] || read <symbol>");
 		}
@@ -47,4 +77,32 @@ public class Main {
 		}
 	}
 
+	private static void printDiff(ISymbolDiff diff) {
+		printDiff(diff, "");
+	}
+
+	private static void printDiff(ISymbolDiff diff, String pre) {
+		SymbolDiffStatus stat = diff.getDiffStatus();
+		if(stat == SymbolDiffStatus.UNCHANGED){
+			return;
+		}
+		printDiffList(diff.getNewSymbols(), "+", pre);
+		printDiffList(diff.getMissingSymbols(), "-", pre);
+		printDiffList(diff.getModifiedSymbols(), " ", pre);
+	}
+
+	private static void printDiffList(List<ISymbolDiff> syms, String s, String pre){
+		for(ISymbolDiff diff : syms){
+			ISymbol sym = diff.getSymbol();
+			if(sym == null) {
+				throw new IllegalArgumentException();
+			}
+			if(sym.isClassSymbol()){
+				System.out.println(s + pre + sym.getClassName() + ":");
+				printDiff(diff, pre + "  ");
+			} else {
+				System.out.println(s + pre + sym.getName());
+			}
+		}
+	}
 }
diff --git a/src/org/debian/javahelper/symbols/internal/BCELLibraryParser.java b/src/org/debian/javahelper/symbols/internal/BCELLibraryParser.java
index e747160..9b2895a 100644
--- a/src/org/debian/javahelper/symbols/internal/BCELLibraryParser.java
+++ b/src/org/debian/javahelper/symbols/internal/BCELLibraryParser.java
@@ -29,6 +29,7 @@ import org.debian.javahelper.symbols.ISymbol;
 public class BCELLibraryParser implements ILibraryParser {
 
 	private static final Pattern CLASS_PATTERN = Pattern.compile("\\.class$", Pattern.CASE_INSENSITIVE);
+	private static final Pattern ANONY_CLASS = Pattern.compile("\\$\\d++$", Pattern.CASE_INSENSITIVE);
 	private ILibrarySymbolData exportedSymbols;
 	private ILibrarySymbolData usedSymbols;
 	private Map<String, IClassSymbol> exportMap;
@@ -69,20 +70,22 @@ public class BCELLibraryParser implements ILibraryParser {
 
 	private void parseClassFile(List<IClassSymbol> symbols, String curVersion,
 			List<ISymbol> used, ZipInputStream zin, ZipEntry zen) throws IOException{
-		String clname = zen.getName().replaceAll("\\.class$", "");
+		String clname = CLASS_PATTERN.matcher(zen.getName()).replaceAll("");
 		ClassParser parser = new ClassParser(zin, zen.getName());
 		JavaClass cfile = parser.parse();
 		ConstantPool pool = cfile.getConstantPool();
 		Constant[] consts = pool.getConstantPool();
 		ClassSymbol clsym;
 		clsym = new ClassSymbol(clname, curVersion);
-		symbols.add(clsym);
 		useMap.remove(clname);
-		if(!cfile.isPublic()) {
+		// Consider non-public/protected or synthetic or anonymous ("$1") classses for private
+		if(!(cfile.isPublic() || cfile.isProtected()) || cfile.isSynthetic()
+				|| ANONY_CLASS.matcher(clname).find()) {
 			privateMap.put(clname, clsym);
 			return;
 		}
 		exportMap.put(clname, clsym);
+		symbols.add(clsym);
 		for(Method m : cfile.getMethods()){
 			String name = m.getName();
 			if(name.equals("<cinit>") || m.isSynthetic()) {
diff --git a/src/org/debian/javahelper/symbols/internal/EmptySymbolContainer.java b/src/org/debian/javahelper/symbols/internal/EmptySymbolContainer.java
new file mode 100644
index 0000000..64f22bd
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/internal/EmptySymbolContainer.java
@@ -0,0 +1,19 @@
+package org.debian.javahelper.symbols.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.debian.javahelper.symbols.ISymbol;
+import org.debian.javahelper.symbols.ISymbolContainer;
+
+public class EmptySymbolContainer implements ISymbolContainer {
+
+	public List<ISymbol> getSymbols() {
+		return Collections.emptyList();
+	}
+
+	public ISymbol getSymbol(String name) {
+		return null;
+	}
+
+}
diff --git a/src/org/debian/javahelper/symbols/internal/SimpleSymbolDifference.java b/src/org/debian/javahelper/symbols/internal/SimpleSymbolDifference.java
new file mode 100644
index 0000000..81b868c
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/internal/SimpleSymbolDifference.java
@@ -0,0 +1,54 @@
+package org.debian.javahelper.symbols.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.debian.javahelper.symbols.ISymbol;
+import org.debian.javahelper.symbols.ISymbolDiff;
+
+public class SimpleSymbolDifference implements ISymbolDiff {
+
+	protected final ISymbol sym;
+	protected final SymbolDiffStatus status;
+
+	public SimpleSymbolDifference(ISymbol sym, SymbolDiffStatus status){
+		this.sym = sym;
+		this.status = status;
+		if(status == null) {
+			throw new IllegalArgumentException();
+		}
+		if(sym == null && this.getClass() == SimpleSymbolDifference.class) {
+			// only allow sym = null if the instance extends SimpleSymbolDifference
+			throw new IllegalArgumentException();
+		}
+	}
+
+	public SymbolDiffStatus getDiffStatus() {
+		return status;
+	}
+
+	public ISymbol getSymbol() {
+		return sym;
+	}
+
+	public List<ISymbolDiff> getNewSymbols() {
+		return Collections.emptyList();
+	}
+
+	public List<ISymbolDiff> getMissingSymbols() {
+		return Collections.emptyList();
+
+	}
+
+	public List<ISymbolDiff> getUnchangedSymbols() {
+		return Collections.emptyList();
+
+	}
+
+	public List<ISymbolDiff> getModifiedSymbols() {
+		return Collections.emptyList();
+
+	}
+
+
+}
diff --git a/src/org/debian/javahelper/symbols/internal/SymbolContainerDifference.java b/src/org/debian/javahelper/symbols/internal/SymbolContainerDifference.java
new file mode 100644
index 0000000..f923044
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/internal/SymbolContainerDifference.java
@@ -0,0 +1,63 @@
+package org.debian.javahelper.symbols.internal;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.debian.javahelper.symbols.ISymbol;
+import org.debian.javahelper.symbols.ISymbolDiff;
+
+public class SymbolContainerDifference extends SimpleSymbolDifference {
+
+	protected final List<ISymbolDiff> newSD;
+	protected final List<ISymbolDiff> misSD;
+	protected final List<ISymbolDiff> chgSD;
+	protected final List<ISymbolDiff> uncSD;
+
+	public SymbolContainerDifference(ISymbol sym, SymbolDiffStatus status,
+			List<ISymbolDiff> newSD, List<ISymbolDiff> misSD,
+			List<ISymbolDiff> chgSD, List<ISymbolDiff> uncSD) {
+		super(sym, status);
+		if(newSD == null) {
+			this.newSD = Collections.emptyList();
+		} else {
+			this.newSD = newSD;
+		}
+		if(misSD == null) {
+			this.misSD = Collections.emptyList();
+		} else {
+			this.misSD = misSD;
+		}
+		if(chgSD == null) {
+			this.chgSD = Collections.emptyList();
+		} else {
+			this.chgSD = chgSD;
+		}
+		if(uncSD == null) {
+			this.uncSD = Collections.emptyList();
+		} else {
+			this.uncSD = uncSD;
+		}
+	}
+
+
+	@Override
+	public List<ISymbolDiff> getNewSymbols() {
+		return Collections.unmodifiableList(newSD);
+	}
+
+	@Override
+	public List<ISymbolDiff> getMissingSymbols() {
+		return Collections.unmodifiableList(misSD);
+	}
+
+	@Override
+	public List<ISymbolDiff> getModifiedSymbols() {
+		return Collections.unmodifiableList(chgSD);
+	}
+
+	@Override
+	public List<ISymbolDiff> getUnchangedSymbols() {
+		return Collections.unmodifiableList(uncSD);
+	}
+
+}
diff --git a/src/org/debian/javahelper/symbols/internal/SymbolDiffer.java b/src/org/debian/javahelper/symbols/internal/SymbolDiffer.java
new file mode 100644
index 0000000..bc44aa7
--- /dev/null
+++ b/src/org/debian/javahelper/symbols/internal/SymbolDiffer.java
@@ -0,0 +1,109 @@
+package org.debian.javahelper.symbols.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.debian.javahelper.symbols.IDifferenceMaker;
+import org.debian.javahelper.symbols.ISymbol;
+import org.debian.javahelper.symbols.ISymbolContainer;
+import org.debian.javahelper.symbols.ISymbolDiff;
+import org.debian.javahelper.symbols.ISymbolDiff.SymbolDiffStatus;
+
+public class SymbolDiffer implements IDifferenceMaker {
+
+	public ISymbolDiff diff(ISymbolContainer oData, ISymbolContainer nData){
+		return diff(oData, nData, null, null);
+	}
+
+	private ISymbolDiff diff(ISymbolContainer oData, ISymbolContainer nData, ISymbol sym, SymbolDiffStatus stat){
+		if(oData == null || nData == null) {
+			throw new IllegalArgumentException();
+		}
+		List<ISymbol> oSyms = oData.getSymbols();
+		List<ISymbol> nSyms = nData.getSymbols();
+		Map<String, ISymbol> oSymMap = new HashMap<String, ISymbol>(oSyms.size());
+		List<ISymbolDiff> newSymbols = new ArrayList<ISymbolDiff>();
+		List<ISymbolDiff> uncSymbols = new ArrayList<ISymbolDiff>();
+		List<ISymbolDiff> chgSymbols = new ArrayList<ISymbolDiff>();
+		List<ISymbolDiff> missingSymbols;
+		missingSymbols = new ArrayList<ISymbolDiff>();
+		for(ISymbol i : oSyms){
+			oSymMap.put(genHashKey(i), i);
+		}
+		for(ISymbol i : nSyms){
+			String key = genHashKey(i);
+			ISymbol old = oSymMap.remove(key);
+			if(old == null) {
+				ISymbolDiff d;
+				if(i.isClassSymbol()) {
+					d = diff(EMPTY_SYMBOL_CONTAINER, i.asClassSymbol(), i, SymbolDiffStatus.ADDED);
+				} else {
+					d = new SimpleSymbolDifference(i, SymbolDiffStatus.ADDED);
+				}
+				newSymbols.add(d);
+			} else {
+				if(old.isClassSymbol() == i.isClassSymbol()){
+					// both are simple or both are symbol containers
+					ISymbolDiff d;
+					if(old.isClassSymbol()){
+						d = diff(old.asClassSymbol(), i.asClassSymbol(), i, null);
+					} else {
+						d = new SimpleSymbolDifference(i, SymbolDiffStatus.UNCHANGED);
+					}
+					if(d.getDiffStatus() == SymbolDiffStatus.UNCHANGED) {
+						uncSymbols.add(d);
+					} else {
+						chgSymbols.add(d);
+					}
+				} else {
+					// only old or i is a class symbol, but not both
+					ISymbolDiff od;
+					ISymbolDiff nd;
+					System.out.println(" !! " + old.getClassName() +" - " + i.getClassName());
+					if(old.isClassSymbol()){
+						nd = new SimpleSymbolDifference(i, SymbolDiffStatus.ADDED);
+						od = diff(old.asClassSymbol(), EMPTY_SYMBOL_CONTAINER, old, SymbolDiffStatus.REMOVED);
+					} else {
+						nd = diff(EMPTY_SYMBOL_CONTAINER, i.asClassSymbol(), i, SymbolDiffStatus.ADDED);
+						od = new SimpleSymbolDifference(old, SymbolDiffStatus.REMOVED);
+					}
+					missingSymbols.add(od);
+					newSymbols.add(nd);
+				}
+			}
+		}
+		for(ISymbol s : oSymMap.values()){
+			ISymbolDiff d;
+			if(s.isClassSymbol()) {
+				d = diff(s.asClassSymbol(), EMPTY_SYMBOL_CONTAINER, s, SymbolDiffStatus.REMOVED);
+			} else {
+				d = new SimpleSymbolDifference(s, SymbolDiffStatus.REMOVED);
+			}
+			missingSymbols.add(d);
+		}
+		if(sym == null) {
+			if(nData instanceof ISymbol) {
+				sym = (ISymbol)nData;
+			} else if(oData instanceof ISymbol){
+				sym = (ISymbol)oData;
+			}
+		}
+		if(stat == null) {
+			if(missingSymbols.size() + chgSymbols.size() + newSymbols.size() > 0) {
+				stat = SymbolDiffStatus.CHANGED;
+			} else {
+				stat = SymbolDiffStatus.UNCHANGED;
+			}
+		}
+		return new SymbolContainerDifference(sym, stat, newSymbols, missingSymbols, chgSymbols, uncSymbols);
+	}
+
+	private static String genHashKey(ISymbol s){
+		if(s.isClassSymbol()) {
+			return s.getClassName();
+		}
+		return s.getClassName() + "." + s.getName();
+	}
+}


hooks/post-receive
-- 
UNNAMED PROJECT



More information about the pkg-java-commits mailing list