You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/12/25 03:32:43 UTC
[commons-vfs] 03/09: added -a option that lets the user specify the
access modifier level used to compare classes and class members
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to annotated tag japicmp-base-0.0.2
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git
commit 53a32f8f836bc6e2cb573b4404d9ec58f1ee67a9
Author: siom79 <ma...@googlemail.com>
AuthorDate: Thu Oct 3 22:15:56 2013 +0200
added -a option that lets the user specify the access modifier level used to compare classes and class members
---
README.md | 47 ++++++++++++----------
.../src/main/java/japicmp/test/Modifier.java | 12 ++++++
.../src/main/java/japicmp/test/Modifier.java | 12 ++++++
.../src/test/java/japicmp/test/BasicTest.java | 29 ++-----------
.../src/test/java/japicmp/test/ModifierTest.java | 44 ++++++++++++++++++++
.../src/test/java/japicmp/test/util/Helper.java | 32 +++++++++++++++
japicmp/src/main/java/japicmp/cli/CliParser.java | 26 +++++++++++-
.../src/main/java/japicmp/cmp/AccessModifier.java | 15 +++++++
.../src/main/java/japicmp/cmp/ClassComparator.java | 18 ++++++---
.../main/java/japicmp/cmp/ClassesComparator.java | 8 ++--
.../java/japicmp/cmp/JarArchiveComparator.java | 21 ++++++----
.../japicmp/cmp/JarArchiveComparatorOptions.java | 9 +++++
japicmp/src/main/java/japicmp/config/Options.java | 10 +++++
japicmp/src/main/java/japicmp/model/JApiClass.java | 23 ++++++++++-
.../src/main/java/japicmp/model/JApiMethod.java | 23 ++++++++++-
.../output/stdout/StdoutOutputGenerator.java | 2 +-
.../src/main/java/japicmp/util/ModifierHelper.java | 29 +++++++++++++
.../test/java/japicmp/util/ModifierHelperTest.java | 41 +++++++++++++++++++
18 files changed, 334 insertions(+), 67 deletions(-)
diff --git a/README.md b/README.md
index 31554de..27f33b2 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ japicmp
japicmp is a tool to compare two versions of a jar archive:
- java -jar japicmp-0.0.1-SNAPSHOT.jar -n new-version.jar -o old-version.jar
+ java -jar japicmp-0.0.1.jar -n new-version.jar -o old-version.jar
It can also be used as a library to integrate its functionality in some other kind of software:
@@ -24,9 +24,11 @@ library to inspect the class files. This way you only have to provide the two ja
##Features##
-* Comparison of two jar archives without the need to add all of their dependencies to the classpath
+* Comparison of two jar archives without the need to add all of their dependencies to the classpath.
* Differences are printed on the command line in a simple diff format.
* Differences can optionally be printed to an xml file. This can be transformed to an HTML file using XSLT.
+* Per default only public classes and class members are compared. If necessary, the access modifier of the classes and class members to be
+ compared can be set to package, protected or private.
##Usage##
@@ -36,31 +38,34 @@ The tool has a set of CLI parameters that are described in the following:
-o <pathToOldVersionJar> Provides the path to the old version of the jar.
-n <pathToNewVersionJar> Provides the path to the new version of the jar.
-x <pathToXmlOutputFile> Provides the path to the xml output file. If not given, stdout is used.
+ -a <accessModifier> Sets the access modifier level (public, package, protected, private), which should be used.
-m Outputs only modified classes/methods. If not given, all classes and methods are printed.
###Example###
In the following you see the beginning of the xml output file after having computed the differences between the versions 4.0.1 and 4.2.3 of httpclient:
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <japicmp newJar="D:\Programmierung\japicmp\github\japicmp\japicmp\httpclient-4.2.3.jar" oldJar="D:\Programmierung\japicmp\github\japicmp\japicmp\httpclient-4.0.1.jar">
- <class changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.GuardedBy" type="ANNOTATION">
- <method changeStatus="REMOVED" name="value" returnType="java.lang.String"/>
- </class>
- <class changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.Immutable" type="ANNOTATION"/>
- <class changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.NotThreadSafe" type="ANNOTATION"/>
- <class changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.ThreadSafe" type="ANNOTATION"/>
- <class changeStatus="NEW" fullyQualifiedName="org.apache.http.auth.AuthOption" type="CLASS">
- <method changeStatus="NEW" name="getAuthScheme" returnType="org.apache.http.auth.AuthScheme"/>
- <method changeStatus="NEW" name="getCredentials" returnType="org.apache.http.auth.Credentials"/>
- <method changeStatus="NEW" name="toString" returnType="java.lang.String"/>
- </class>
- <class changeStatus="NEW" fullyQualifiedName="org.apache.http.auth.AuthProtocolState" type="ENUM">
- <method changeStatus="NEW" name="valueOf" returnType="org.apache.http.auth.AuthProtocolState">
- <parameter type="java.lang.String"/>
- </method>
- <method changeStatus="NEW" name="values" returnType="org.apache.http.auth.AuthProtocolState[]"/>
- </class>
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <japicmp newJar="D:\Programmierung\japicmp\github\japicmp\japicmp\httpclient-4.2.3.jar" oldJar="D:\Programmierung\japicmp\github\japicmp\japicmp\httpclient-4.0.1.jar">
+ <class accessModifierNew="n.a." accessModifierOld="PUBLIC" changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.GuardedBy" type="ANNOTATION">
+ <method accessModifierNew="n.a." accessModifierOld="PUBLIC" changeStatus="REMOVED" name="value" returnType="java.lang.String"/>
+ </class>
+ <class accessModifierNew="n.a." accessModifierOld="PUBLIC" changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.Immutable" type="ANNOTATION"/>
+ <class accessModifierNew="n.a." accessModifierOld="PUBLIC" changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.NotThreadSafe" type="ANNOTATION"/>
+ <class accessModifierNew="n.a." accessModifierOld="PUBLIC" changeStatus="REMOVED" fullyQualifiedName="org.apache.http.annotation.ThreadSafe" type="ANNOTATION"/>
+ <class accessModifierNew="PUBLIC" accessModifierOld="PUBLIC" changeStatus="UNCHANGED" fullyQualifiedName="org.apache.http.auth.AUTH" type="CLASS"/>
+ <class accessModifierNew="PUBLIC" accessModifierOld="PUBLIC" changeStatus="UNCHANGED" fullyQualifiedName="org.apache.http.auth.AuthenticationException" type="CLASS"/>
+ <class accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" fullyQualifiedName="org.apache.http.auth.AuthOption" type="CLASS">
+ <method accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" name="getAuthScheme" returnType="org.apache.http.auth.AuthScheme"/>
+ <method accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" name="getCredentials" returnType="org.apache.http.auth.Credentials"/>
+ <method accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" name="toString" returnType="java.lang.String"/>
+ </class>
+ <class accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" fullyQualifiedName="org.apache.http.auth.AuthProtocolState" type="ENUM">
+ <method accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" name="valueOf" returnType="org.apache.http.auth.AuthProtocolState">
+ <parameter type="java.lang.String"/>
+ </method>
+ <method accessModifierNew="PUBLIC" accessModifierOld="n.a." changeStatus="NEW" name="values" returnType="org.apache.http.auth.AuthProtocolState[]"/>
+ </class>
...
##Downloads##
diff --git a/japicmp-testbase/japicmp-test-v1/src/main/java/japicmp/test/Modifier.java b/japicmp-testbase/japicmp-test-v1/src/main/java/japicmp/test/Modifier.java
new file mode 100644
index 0000000..b53a7bf
--- /dev/null
+++ b/japicmp-testbase/japicmp-test-v1/src/main/java/japicmp/test/Modifier.java
@@ -0,0 +1,12 @@
+package japicmp.test;
+
+public class Modifier {
+
+ public void publicToPrivateMethod() {
+
+ }
+
+ public static class ModifierPublicToProtected {
+
+ }
+}
diff --git a/japicmp-testbase/japicmp-test-v2/src/main/java/japicmp/test/Modifier.java b/japicmp-testbase/japicmp-test-v2/src/main/java/japicmp/test/Modifier.java
new file mode 100644
index 0000000..65bf223
--- /dev/null
+++ b/japicmp-testbase/japicmp-test-v2/src/main/java/japicmp/test/Modifier.java
@@ -0,0 +1,12 @@
+package japicmp.test;
+
+public class Modifier {
+
+ private void publicToPrivateMethod() {
+
+ }
+
+ private static class ModifierPublicToProtected {
+
+ }
+}
diff --git a/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/BasicTest.java b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/BasicTest.java
index 7abab9b..c02ea3a 100644
--- a/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/BasicTest.java
+++ b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/BasicTest.java
@@ -4,12 +4,13 @@ import japicmp.cmp.JarArchiveComparator;
import japicmp.cmp.JarArchiveComparatorOptions;
import japicmp.model.JApiChangeStatus;
import japicmp.model.JApiClass;
-import japicmp.model.JApiMethod;
import org.junit.Test;
-import java.io.File;
import java.util.List;
+import static japicmp.test.util.Helper.getArchive;
+import static japicmp.test.util.Helper.getJApiClass;
+import static japicmp.test.util.Helper.getJApiMethod;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
@@ -20,7 +21,7 @@ public class BasicTest {
public void test() {
JarArchiveComparator jarArchiveComparator = new JarArchiveComparator(new JarArchiveComparatorOptions());
List<JApiClass> jApiClasses = jarArchiveComparator.compare(getArchive("japicmp-test-v1.jar"), getArchive("japicmp-test-v2.jar"));
- assertThat(jApiClasses.size(), is(3));
+ assertThat(jApiClasses.size(), is(5));
JApiClass jApiClassRemoved = getJApiClass(jApiClasses, Removed.class.getName());
JApiClass jApiClassAdded = getJApiClass(jApiClasses, Added.class.getName());
JApiClass jApiClassUnchanged = getJApiClass(jApiClasses, Unchanged.class.getName());
@@ -32,26 +33,4 @@ public class BasicTest {
assertThat(jApiClassUnchanged.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
assertThat(getJApiMethod(jApiClassUnchanged.getMethods(), "unchangedMethod"), is(notNullValue()));
}
-
- private File getArchive(String filename) {
- return new File("target" + File.separator + filename);
- }
-
- private JApiClass getJApiClass(List<JApiClass> jApiClasses, String fqn) {
- for (JApiClass jApiClass : jApiClasses) {
- if (jApiClass.getFullyQualifiedName().equals(fqn)) {
- return jApiClass;
- }
- }
- throw new IllegalArgumentException("No class found with name " + fqn + ".");
- }
-
- private JApiMethod getJApiMethod(List<JApiMethod> jApiMethods, String name) {
- for(JApiMethod jApiMethod : jApiMethods) {
- if(jApiMethod.getName().equals(name)) {
- return jApiMethod;
- }
- }
- throw new IllegalArgumentException("No method found with name " + name + ".");
- }
}
diff --git a/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/ModifierTest.java b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/ModifierTest.java
new file mode 100644
index 0000000..f939228
--- /dev/null
+++ b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/ModifierTest.java
@@ -0,0 +1,44 @@
+package japicmp.test;
+
+import japicmp.cmp.AccessModifier;
+import japicmp.cmp.JarArchiveComparator;
+import japicmp.cmp.JarArchiveComparatorOptions;
+import japicmp.model.JApiChangeStatus;
+import japicmp.model.JApiClass;
+import japicmp.test.util.Helper;
+import org.junit.Test;
+
+import java.util.List;
+
+import static japicmp.test.util.Helper.getArchive;
+import static japicmp.test.util.Helper.getJApiClass;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+public class ModifierTest {
+
+ @Test
+ public void testOptionPublicModifier() {
+ JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
+ options.setModifierLevel(AccessModifier.PUBLIC);
+ JarArchiveComparator jarArchiveComparator = new JarArchiveComparator(options);
+ List<JApiClass> jApiClasses = jarArchiveComparator.compare(getArchive("japicmp-test-v1.jar"), getArchive("japicmp-test-v2.jar"));
+ JApiClass modifierInnerClass = getJApiClass(jApiClasses, Modifier.ModifierPublicToProtected.class.getName());
+ JApiClass modifierClass = getJApiClass(jApiClasses, Modifier.class.getName());
+ assertThat(modifierInnerClass.getChangeStatus(), is(JApiChangeStatus.REMOVED));
+ assertThat(Helper.getJApiMethod(modifierClass.getMethods(), "publicToPrivateMethod").getChangeStatus(), is(JApiChangeStatus.REMOVED));
+ }
+
+ @Test
+ public void testOptionPrivateModifier() {
+ JarArchiveComparatorOptions options = new JarArchiveComparatorOptions();
+ options.setModifierLevel(AccessModifier.PRIVATE);
+ JarArchiveComparator jarArchiveComparator = new JarArchiveComparator(options);
+ List<JApiClass> jApiClasses = jarArchiveComparator.compare(getArchive("japicmp-test-v1.jar"), getArchive("japicmp-test-v2.jar"));
+ JApiClass modifierInnerClass = getJApiClass(jApiClasses, Modifier.ModifierPublicToProtected.class.getName());
+ JApiClass modifierClass = getJApiClass(jApiClasses, Modifier.class.getName());
+ assertThat(modifierInnerClass.getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
+ assertThat(Helper.getJApiMethod(modifierClass.getMethods(), "publicToPrivateMethod").getChangeStatus(), is(JApiChangeStatus.UNCHANGED));
+ }
+}
diff --git a/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/util/Helper.java b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/util/Helper.java
new file mode 100644
index 0000000..c98da86
--- /dev/null
+++ b/japicmp-testbase/japicmp-test/src/test/java/japicmp/test/util/Helper.java
@@ -0,0 +1,32 @@
+package japicmp.test.util;
+
+import japicmp.model.JApiClass;
+import japicmp.model.JApiMethod;
+
+import java.io.File;
+import java.util.List;
+
+public class Helper {
+
+ public static File getArchive(String filename) {
+ return new File("target" + File.separator + filename);
+ }
+
+ public static JApiClass getJApiClass(List<JApiClass> jApiClasses, String fqn) {
+ for (JApiClass jApiClass : jApiClasses) {
+ if (jApiClass.getFullyQualifiedName().equals(fqn)) {
+ return jApiClass;
+ }
+ }
+ throw new IllegalArgumentException("No class found with name " + fqn + ".");
+ }
+
+ public static JApiMethod getJApiMethod(List<JApiMethod> jApiMethods, String name) {
+ for(JApiMethod jApiMethod : jApiMethods) {
+ if(jApiMethod.getName().equals(name)) {
+ return jApiMethod;
+ }
+ }
+ throw new IllegalArgumentException("No method found with name " + name + ".");
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/cli/CliParser.java b/japicmp/src/main/java/japicmp/cli/CliParser.java
index 1e1f788..db1e287 100644
--- a/japicmp/src/main/java/japicmp/cli/CliParser.java
+++ b/japicmp/src/main/java/japicmp/cli/CliParser.java
@@ -1,6 +1,7 @@
package japicmp.cli;
import com.google.common.base.Optional;
+import japicmp.cmp.AccessModifier;
import japicmp.config.Options;
import japicmp.util.StringArrayEnumeration;
@@ -32,9 +33,19 @@ public class CliParser {
System.out.println("-o <pathToOldVersionJar> Provides the path to the old version of the jar.");
System.out.println("-n <pathToNewVersionJar> Provides the path to the new version of the jar.");
System.out.println("-x <pathToXmlOutputFile> Provides the path to the xml output file. If not given, stdout is used.");
+ System.out.println("-a <accessModifier> Sets the access modifier level (public, package, protected, private), which should be used.");
System.out.println("-m Outputs only modified classes/methods. If not given, all classes and methods are printed.");
System.exit(0);
}
+ if ("-a".equals(arg)) {
+ String accessModifierArg = getOptionWithArgument("-a", sae);
+ try {
+ AccessModifier accessModifier = AccessModifier.valueOf(accessModifierArg.toUpperCase());
+ options.setAcessModifier(accessModifier);
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException(String.format("Invalid value for option -a: %s. Possible values are: %s.", accessModifierArg, listOfAccessModifiers()));
+ }
+ }
}
checkForMandatoryOptions(options);
return options;
@@ -52,7 +63,7 @@ public class CliParser {
private String getOptionWithArgument(String option, StringArrayEnumeration sae) {
if (sae.hasMoreElements()) {
String value = sae.nextElement();
- if(value.startsWith("-")) {
+ if (value.startsWith("-")) {
throw new IllegalArgumentException(String.format("Missing argument for option %s.", option));
}
return value;
@@ -60,4 +71,17 @@ public class CliParser {
throw new IllegalArgumentException(String.format("Missing argument for option %s.", option));
}
}
+
+ private String listOfAccessModifiers() {
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ for (AccessModifier am : AccessModifier.values()) {
+ if (i > 0) {
+ sb.append(",");
+ }
+ sb.append(am.toString());
+ i++;
+ }
+ return sb.toString();
+ }
}
diff --git a/japicmp/src/main/java/japicmp/cmp/AccessModifier.java b/japicmp/src/main/java/japicmp/cmp/AccessModifier.java
new file mode 100644
index 0000000..8f9ffec
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/cmp/AccessModifier.java
@@ -0,0 +1,15 @@
+package japicmp.cmp;
+
+public enum AccessModifier {
+ PUBLIC(3), PACKAGE(2), PROTECTED(1), PRIVATE(0);
+
+ private int level;
+
+ AccessModifier(int level) {
+ this.level = level;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+}
diff --git a/japicmp/src/main/java/japicmp/cmp/ClassComparator.java b/japicmp/src/main/java/japicmp/cmp/ClassComparator.java
index 92838e7..0bcb783 100644
--- a/japicmp/src/main/java/japicmp/cmp/ClassComparator.java
+++ b/japicmp/src/main/java/japicmp/cmp/ClassComparator.java
@@ -5,6 +5,7 @@ import japicmp.model.JApiChangeStatus;
import japicmp.model.JApiClass;
import japicmp.model.JApiMethod;
import japicmp.model.JApiParameter;
+import japicmp.util.ModifierHelper;
import japicmp.util.SignatureParser;
import javassist.CtClass;
import javassist.CtMethod;
@@ -13,6 +14,11 @@ import java.util.HashMap;
import java.util.Map;
public class ClassComparator {
+ private final JarArchiveComparatorOptions options;
+
+ public ClassComparator(JarArchiveComparatorOptions options) {
+ this.options = options;
+ }
public void compare(JApiClass jApiClass) {
Map<String, CtMethod> oldMethodsMap = createMethodMap(jApiClass.getOldClass());
@@ -27,14 +33,14 @@ public class ClassComparator {
signatureParser.parse(ctMethod.getSignature());
CtMethod foundMethod = newMethodsMap.get(longName);
if (foundMethod == null) {
- JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.REMOVED, Optional.of(ctMethod), Optional.<CtMethod>absent(), signatureParser.getReturnType());
+ JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.REMOVED, Optional.of(ctMethod), Optional.<CtMethod>absent(), signatureParser.getReturnType(), Optional.of(ModifierHelper.translateToModifierLevel(ctMethod.getModifiers())), Optional.<AccessModifier>absent());
addParametersToMethod(signatureParser, jApiMethod);
jApiClass.addMethod(jApiMethod);
if(jApiClass.getChangeStatus() == JApiChangeStatus.UNCHANGED) {
jApiClass.setChangeStatus(JApiChangeStatus.MODIFIED);
}
} else {
- JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.UNCHANGED, Optional.of(ctMethod), Optional.of(foundMethod), signatureParser.getReturnType());
+ JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.UNCHANGED, Optional.of(ctMethod), Optional.of(foundMethod), signatureParser.getReturnType(), Optional.of(ModifierHelper.translateToModifierLevel(ctMethod.getModifiers())), Optional.of(ModifierHelper.translateToModifierLevel(foundMethod.getModifiers())));
addParametersToMethod(signatureParser, jApiMethod);
jApiClass.addMethod(jApiMethod);
}
@@ -44,7 +50,7 @@ public class ClassComparator {
signatureParser.parse(ctMethod.getSignature());
CtMethod foundMethod = oldMethodsMap.get(longName);
if (foundMethod == null) {
- JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.NEW, Optional.<CtMethod>absent(), Optional.of(ctMethod), signatureParser.getReturnType());
+ JApiMethod jApiMethod = new JApiMethod(ctMethod.getName(), JApiChangeStatus.NEW, Optional.<CtMethod>absent(), Optional.of(ctMethod), signatureParser.getReturnType(), Optional.<AccessModifier>absent(), Optional.of(ModifierHelper.translateToModifierLevel(ctMethod.getModifiers())));
addParametersToMethod(signatureParser, jApiMethod);
jApiClass.addMethod(jApiMethod);
if(jApiClass.getChangeStatus() == JApiChangeStatus.UNCHANGED) {
@@ -63,8 +69,10 @@ public class ClassComparator {
private Map<String, CtMethod> createMethodMap(Optional<CtClass> ctClass) {
Map<String, CtMethod> methods = new HashMap<String, CtMethod>();
if (ctClass.isPresent()) {
- for (CtMethod ctMethod : ctClass.get().getMethods()) {
- methods.put(ctMethod.getLongName(), ctMethod);
+ for (CtMethod ctMethod : ctClass.get().getDeclaredMethods()) {
+ if(ModifierHelper.matchesModifierLevel(ctMethod.getModifiers(), options.getModifierLevel())) {
+ methods.put(ctMethod.getLongName(), ctMethod);
+ }
}
}
return methods;
diff --git a/japicmp/src/main/java/japicmp/cmp/ClassesComparator.java b/japicmp/src/main/java/japicmp/cmp/ClassesComparator.java
index ee02733..b8e2b48 100644
--- a/japicmp/src/main/java/japicmp/cmp/ClassesComparator.java
+++ b/japicmp/src/main/java/japicmp/cmp/ClassesComparator.java
@@ -3,8 +3,8 @@ package japicmp.cmp;
import com.google.common.base.Optional;
import japicmp.model.JApiChangeStatus;
import japicmp.model.JApiClass;
+import japicmp.util.ModifierHelper;
import javassist.CtClass;
-import javassist.Modifier;
import java.util.HashMap;
import java.util.LinkedList;
@@ -25,15 +25,15 @@ public class ClassesComparator {
for(CtClass ctClass : oldClassesMap.values()) {
CtClass foundClass = newClassesMap.get(ctClass.getName());
if(foundClass == null) {
- classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>of(ctClass), Optional.<CtClass>absent(), JApiChangeStatus.REMOVED, getType(ctClass)));
+ classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>of(ctClass), Optional.<CtClass>absent(), JApiChangeStatus.REMOVED, getType(ctClass), Optional.of(ModifierHelper.translateToModifierLevel(ctClass.getModifiers())), Optional.<AccessModifier>absent()));
} else {
- classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>of(ctClass), Optional.<CtClass>of(foundClass), JApiChangeStatus.UNCHANGED, getType(ctClass)));
+ classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>of(ctClass), Optional.<CtClass>of(foundClass), JApiChangeStatus.UNCHANGED, getType(ctClass), Optional.of(ModifierHelper.translateToModifierLevel(ctClass.getModifiers())), Optional.of(ModifierHelper.translateToModifierLevel(foundClass.getModifiers()))));
}
}
for(CtClass ctClass : newClassesMap.values()) {
CtClass foundClass = oldClassesMap.get(ctClass.getName());
if(foundClass == null) {
- classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>absent(), Optional.<CtClass>of(ctClass), JApiChangeStatus.NEW, getType(ctClass)));
+ classes.add(new JApiClass(ctClass.getName(), Optional.<CtClass>absent(), Optional.<CtClass>of(ctClass), JApiChangeStatus.NEW, getType(ctClass), Optional.<AccessModifier>absent(), Optional.of(ModifierHelper.translateToModifierLevel(ctClass.getModifiers()))));
}
}
}
diff --git a/japicmp/src/main/java/japicmp/cmp/JarArchiveComparator.java b/japicmp/src/main/java/japicmp/cmp/JarArchiveComparator.java
index 06097d1..3dbdda4 100644
--- a/japicmp/src/main/java/japicmp/cmp/JarArchiveComparator.java
+++ b/japicmp/src/main/java/japicmp/cmp/JarArchiveComparator.java
@@ -1,8 +1,10 @@
package japicmp.cmp;
import japicmp.model.JApiClass;
+import japicmp.util.ModifierHelper;
import javassist.ClassPool;
import javassist.CtClass;
+import javassist.Modifier;
import org.apache.log4j.Logger;
import java.io.File;
@@ -14,15 +16,16 @@ import java.util.jar.JarFile;
public class JarArchiveComparator {
private static final Logger logger = Logger.getLogger(JarArchiveComparator.class);
+ private JarArchiveComparatorOptions options;
public JarArchiveComparator(JarArchiveComparatorOptions options) {
-
+ this.options = options;
}
public List<JApiClass> compare(File oldArchive, File newArchive) {
ClassPool classPool = new ClassPool();
try {
- ClassesComparator classesComparator = compareClassLists(oldArchive, newArchive, classPool);
+ ClassesComparator classesComparator = compareClassLists(oldArchive, newArchive, classPool, options);
List<JApiClass> classList = classesComparator.getClasses();
compareClasses(classList);
return classList;
@@ -34,14 +37,14 @@ public class JarArchiveComparator {
private void compareClasses(List<JApiClass> classList) {
for (JApiClass jApiClass : classList) {
- ClassComparator classComparator = new ClassComparator();
+ ClassComparator classComparator = new ClassComparator(options);
classComparator.compare(jApiClass);
}
}
- private ClassesComparator compareClassLists(File oldArchive, File newArchive, ClassPool classPool) throws Exception {
- List<CtClass> oldClasses = createListOfCtClasses(oldArchive, classPool);
- List<CtClass> newClasses = createListOfCtClasses(newArchive, classPool);
+ private ClassesComparator compareClassLists(File oldArchive, File newArchive, ClassPool classPool, JarArchiveComparatorOptions options) throws Exception {
+ List<CtClass> oldClasses = createListOfCtClasses(oldArchive, classPool, options);
+ List<CtClass> newClasses = createListOfCtClasses(newArchive, classPool, options);
ClassesComparator classesComparator = new ClassesComparator();
classesComparator.compare(oldClasses, newClasses);
if (logger.isDebugEnabled()) {
@@ -52,7 +55,7 @@ public class JarArchiveComparator {
return classesComparator;
}
- private List<CtClass> createListOfCtClasses(File archive, ClassPool classPool) throws Exception {
+ private List<CtClass> createListOfCtClasses(File archive, ClassPool classPool, JarArchiveComparatorOptions options) throws Exception {
List<CtClass> classes = new LinkedList<CtClass>();
JarFile oldJar = null;
try {
@@ -69,7 +72,9 @@ public class JarArchiveComparator {
logger.error(String.format("Failed to load file from jar '%s' as class file: %s.", name, e.getMessage()));
throw e;
}
- classes.add(ctClass);
+ if(ModifierHelper.matchesModifierLevel(ctClass.getModifiers(), options.getModifierLevel())) {
+ classes.add(ctClass);
+ }
if (logger.isDebugEnabled()) {
logger.debug(String.format("Adding class '%s' with jar name '%s' to list.", ctClass.getName(), name));
}
diff --git a/japicmp/src/main/java/japicmp/cmp/JarArchiveComparatorOptions.java b/japicmp/src/main/java/japicmp/cmp/JarArchiveComparatorOptions.java
index c474ef6..cd2a328 100644
--- a/japicmp/src/main/java/japicmp/cmp/JarArchiveComparatorOptions.java
+++ b/japicmp/src/main/java/japicmp/cmp/JarArchiveComparatorOptions.java
@@ -6,6 +6,7 @@ import java.util.List;
public class JarArchiveComparatorOptions {
private List<String> packagesInclude = new LinkedList<String>();
private List<String> packagesExclude = new LinkedList<String>();
+ private AccessModifier modifierLevel = AccessModifier.PUBLIC;
public List<String> getPackagesExclude() {
return packagesExclude;
@@ -14,4 +15,12 @@ public class JarArchiveComparatorOptions {
public List<String> getPackagesInclude() {
return packagesInclude;
}
+
+ public AccessModifier getModifierLevel() {
+ return modifierLevel;
+ }
+
+ public void setModifierLevel(AccessModifier modifierLevel) {
+ this.modifierLevel = modifierLevel;
+ }
}
diff --git a/japicmp/src/main/java/japicmp/config/Options.java b/japicmp/src/main/java/japicmp/config/Options.java
index 4576f72..6337fac 100644
--- a/japicmp/src/main/java/japicmp/config/Options.java
+++ b/japicmp/src/main/java/japicmp/config/Options.java
@@ -1,12 +1,14 @@
package japicmp.config;
import com.google.common.base.Optional;
+import japicmp.cmp.AccessModifier;
public class Options {
private String oldArchive;
private String newArchive;
private boolean outputOnlyModifications = false;
private Optional<String> xmlOutputFile = Optional.<String>absent();
+ private AccessModifier acessModifier = AccessModifier.PUBLIC;
public String getNewArchive() {
return newArchive;
@@ -39,4 +41,12 @@ public class Options {
public void setXmlOutputFile(Optional<String> xmlOutputFile) {
this.xmlOutputFile = xmlOutputFile;
}
+
+ public void setAcessModifier(AccessModifier acessModifier) {
+ this.acessModifier = acessModifier;
+ }
+
+ public AccessModifier getAcessModifier() {
+ return acessModifier;
+ }
}
diff --git a/japicmp/src/main/java/japicmp/model/JApiClass.java b/japicmp/src/main/java/japicmp/model/JApiClass.java
index e1d429f..242b6c3 100644
--- a/japicmp/src/main/java/japicmp/model/JApiClass.java
+++ b/japicmp/src/main/java/japicmp/model/JApiClass.java
@@ -1,6 +1,7 @@
package japicmp.model;
import com.google.common.base.Optional;
+import japicmp.cmp.AccessModifier;
import javassist.CtClass;
import javax.xml.bind.annotation.XmlAttribute;
@@ -16,17 +17,21 @@ public class JApiClass {
private List<JApiMethod> methods = new LinkedList<JApiMethod>();
private JApiChangeStatus changeStatus;
private final Type type;
+ private Optional<AccessModifier> accessModifierOld;
+ private Optional<AccessModifier> accessModifierNew;
public enum Type {
ANNOTATION, INTERFACE, CLASS, ENUM
}
- public JApiClass(String fullyQualifiedName, Optional<CtClass> oldClass, Optional<CtClass> newClass, JApiChangeStatus changeStatus, Type type) {
+ public JApiClass(String fullyQualifiedName, Optional<CtClass> oldClass, Optional<CtClass> newClass, JApiChangeStatus changeStatus, Type type, Optional<AccessModifier> oldModifierLevel, Optional<AccessModifier> newModifierLevel) {
this.changeStatus = changeStatus;
this.fullyQualifiedName = fullyQualifiedName;
this.newClass = newClass;
this.oldClass = oldClass;
this.type = type;
+ this.accessModifierOld = oldModifierLevel;
+ this.accessModifierNew = newModifierLevel;
}
public void addMethod(JApiMethod jApiMethod) {
@@ -71,6 +76,22 @@ public class JApiClass {
return type;
}
+ @XmlAttribute(name = "accessModifierNew")
+ public String getAccessModifierNew() {
+ if(this.accessModifierNew.isPresent()) {
+ return this.accessModifierNew.get().toString();
+ }
+ return "n.a.";
+ }
+
+ @XmlAttribute(name = "accessModifierOld")
+ public String getAccessModifierOld() {
+ if(this.accessModifierOld.isPresent()) {
+ return this.accessModifierOld.get().toString();
+ }
+ return "n.a.";
+ }
+
@Override
public String toString() {
return "JApiClass{" +
diff --git a/japicmp/src/main/java/japicmp/model/JApiMethod.java b/japicmp/src/main/java/japicmp/model/JApiMethod.java
index ab04e1f..b23c44a 100644
--- a/japicmp/src/main/java/japicmp/model/JApiMethod.java
+++ b/japicmp/src/main/java/japicmp/model/JApiMethod.java
@@ -1,6 +1,7 @@
package japicmp.model;
import com.google.common.base.Optional;
+import japicmp.cmp.AccessModifier;
import javassist.CtMethod;
import javax.xml.bind.annotation.XmlAttribute;
@@ -15,14 +16,18 @@ public class JApiMethod {
private final Optional<CtMethod> oldMethod;
private final Optional<CtMethod> newMethod;
private final String returnType;
+ private Optional<AccessModifier> accessModifierOld;
+ private Optional<AccessModifier> accessModifierNew;
private final List<JApiParameter> parameters = new LinkedList<JApiParameter>();
- public JApiMethod(String name, JApiChangeStatus changeStatus, Optional<CtMethod> oldClass, Optional<CtMethod> newClass, String returnType) {
+ public JApiMethod(String name, JApiChangeStatus changeStatus, Optional<CtMethod> oldClass, Optional<CtMethod> newClass, String returnType, Optional<AccessModifier> oldModifierLevel, Optional<AccessModifier> newModifierLevel) {
this.name = name;
this.changeStatus = changeStatus;
this.oldMethod = oldClass;
this.newMethod = newClass;
this.returnType = returnType;
+ this.accessModifierOld = oldModifierLevel;
+ this.accessModifierNew = newModifierLevel;
}
@XmlAttribute
@@ -58,4 +63,20 @@ public class JApiMethod {
public void addParameter(JApiParameter jApiParameter) {
parameters.add(jApiParameter);
}
+
+ @XmlAttribute(name = "accessModifierNew")
+ public String getAccessModifierNew() {
+ if(this.accessModifierNew.isPresent()) {
+ return this.accessModifierNew.get().toString();
+ }
+ return "n.a.";
+ }
+
+ @XmlAttribute(name = "accessModifierOld")
+ public String getAccessModifierOld() {
+ if(this.accessModifierOld.isPresent()) {
+ return this.accessModifierOld.get().toString();
+ }
+ return "n.a.";
+ }
}
diff --git a/japicmp/src/main/java/japicmp/output/stdout/StdoutOutputGenerator.java b/japicmp/src/main/java/japicmp/output/stdout/StdoutOutputGenerator.java
index e379095..b981804 100644
--- a/japicmp/src/main/java/japicmp/output/stdout/StdoutOutputGenerator.java
+++ b/japicmp/src/main/java/japicmp/output/stdout/StdoutOutputGenerator.java
@@ -57,7 +57,7 @@ public class StdoutOutputGenerator {
int paramCount = 0;
for (JApiParameter jApiParameter : jApiMethod.getParameters()) {
if (paramCount > 0) {
- sb.append(",");
+ sb.append(", ");
}
sb.append(jApiParameter.getType());
paramCount++;
diff --git a/japicmp/src/main/java/japicmp/util/ModifierHelper.java b/japicmp/src/main/java/japicmp/util/ModifierHelper.java
new file mode 100644
index 0000000..416888e
--- /dev/null
+++ b/japicmp/src/main/java/japicmp/util/ModifierHelper.java
@@ -0,0 +1,29 @@
+package japicmp.util;
+
+import japicmp.cmp.AccessModifier;
+
+import java.lang.reflect.Modifier;
+
+public class ModifierHelper {
+
+ private ModifierHelper() {
+
+ }
+
+ public static boolean matchesModifierLevel(int modifierOfElement, AccessModifier modifierLevel) {
+ AccessModifier modifierLevelOfElement = translateToModifierLevel(modifierOfElement);
+ return (modifierLevelOfElement.getLevel() >= modifierLevel.getLevel());
+ }
+
+ public static AccessModifier translateToModifierLevel(int modifier) {
+ if(Modifier.isPublic(modifier)) {
+ return AccessModifier.PUBLIC;
+ } else if(Modifier.isProtected(modifier)) {
+ return AccessModifier.PROTECTED;
+ } else if(Modifier.isPrivate(modifier)) {
+ return AccessModifier.PRIVATE;
+ } else {
+ return AccessModifier.PACKAGE;
+ }
+ }
+}
diff --git a/japicmp/src/test/java/japicmp/util/ModifierHelperTest.java b/japicmp/src/test/java/japicmp/util/ModifierHelperTest.java
new file mode 100644
index 0000000..4f0b95f
--- /dev/null
+++ b/japicmp/src/test/java/japicmp/util/ModifierHelperTest.java
@@ -0,0 +1,41 @@
+package japicmp.util;
+
+import japicmp.cmp.AccessModifier;
+import javassist.Modifier;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ModifierHelperTest {
+
+ @Test
+ public void publicToPublic() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPublic(0), AccessModifier.PUBLIC), is(true));
+ }
+
+ @Test
+ public void publicToProtected() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPublic(0), AccessModifier.PROTECTED), is(true));
+ }
+
+ @Test
+ public void publicToPrivate() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPublic(0), AccessModifier.PRIVATE), is(true));
+ }
+
+ @Test
+ public void privateToPublic() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPrivate(0), AccessModifier.PUBLIC), is(false));
+ }
+
+ @Test
+ public void privateToProtected() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPrivate(0), AccessModifier.PROTECTED), is(false));
+ }
+
+ @Test
+ public void privateToPrivate() {
+ assertThat(ModifierHelper.matchesModifierLevel(Modifier.setPrivate(0), AccessModifier.PRIVATE), is(true));
+ }
+}