diff options
author | deanhiller <[email protected]> | 2006-09-19 13:55:04 +0000 |
---|---|---|
committer | deanhiller <[email protected]> | 2006-09-19 13:55:04 +0000 |
commit | ae11d8363bbc9fe4bb3ac8d04e7ee68f16f53ccf (patch) | |
tree | 0b064f20cc2ca87b6adf9f2301e6dac467be6a0c /src/java/net/sf/antcontrib/design | |
parent | 98d6077c1d5f4e37889123fdd6c2b4bb32014328 (diff) |
upgrade ant-contrib to newer verifydesign that breaks telling you to remove
outdated documentation so it forces you to keep design file up to date.
git-svn-id: file:///home/sven/projects/JOGL/temp/ant-contrib/svn/ant-contrib-code/trunk/ant-contrib@45 32d7a393-a5a9-423c-abd3-5d954feb1f2f
Diffstat (limited to 'src/java/net/sf/antcontrib/design')
-rw-r--r-- | src/java/net/sf/antcontrib/design/Design.java | 588 | ||||
-rw-r--r-- | src/java/net/sf/antcontrib/design/Package.java | 125 | ||||
-rw-r--r-- | src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java | 850 |
3 files changed, 821 insertions, 742 deletions
diff --git a/src/java/net/sf/antcontrib/design/Design.java b/src/java/net/sf/antcontrib/design/Design.java index 6da018d..08d0fce 100644 --- a/src/java/net/sf/antcontrib/design/Design.java +++ b/src/java/net/sf/antcontrib/design/Design.java @@ -1,271 +1,319 @@ -/* - * Copyright (c) 2001-2005 Ant-Contrib project. All rights reserved. - * - * 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.sf.antcontrib.design; - -import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Location; -import org.apache.tools.ant.Project; - - -/* - * Created on Aug 24, 2003 - * - * To change the template for this generated file go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ -/** - * FILL IN JAVADOC HERE - * - * @author Dean Hiller([email protected]) - */ -public class Design { - - private Map nameToPackage = new HashMap(); - private Map packageNameToPackage = new HashMap(); - private boolean isCircularDesign; - private Log log; - private Location location; - - private String currentClass = null; - private String currentPackageName = null; - private Package currentAliasPackage = null; - - private HashSet primitives = new HashSet(); - - public Design(boolean isCircularDesign, Log log, Location loc) { - //by default, add java as a configured package with the name java - Package p = new Package(); - p.setIncludeSubpackages(true); - p.setName("java"); - p.setNeedDeclarations(false); - p.setPackage("java"); - addConfiguredPackage(p); - - this.isCircularDesign = isCircularDesign; - this.log = log; - this.location = loc; - - primitives.add("boolean"); - - //integral types - primitives.add("byte"); - primitives.add("short"); - primitives.add("int"); - primitives.add("long"); - primitives.add("char"); - - //floating point types - primitives.add("double"); - primitives.add("float"); - } - - public Package getPackage(String nameAttribute) { - return (Package)nameToPackage.get(nameAttribute); - } - - private Package retreivePack(String thePackage) { - if(thePackage == null) - throw new IllegalArgumentException("Cannot retrieve null packages"); - - Package result = null; - String currentPackage = thePackage; - while(!Package.DEFAULT.equals(currentPackage)) { - result = (Package)packageNameToPackage.get(currentPackage); - if(result != null) { - if(currentPackage.equals(thePackage)) - return result; - else if(result.isIncludeSubpackages()) - return result; - return null; - } - currentPackage = VerifyDesignDelegate.getPackageName(currentPackage); - } - - //result must now be default package - if(result != null && result.isIncludeSubpackages()) - return result; - - return null; - } - - public void addConfiguredPackage(Package p) { - - String pack = p.getPackage(); - - Depends[] depends = p.getDepends(); - - if(depends != null && !isCircularDesign) { - //make sure all depends are in Map first - //circular references then are not a problem because they must - //put the stuff in order - for(int i = 0; i < depends.length; i++) { - Package dependsPackage = (Package)nameToPackage.get(depends[i].getName()); - - if(dependsPackage == null) { - throw new RuntimeException("package name="+p.getName()+" did not\n" + - "have "+depends[i]+" listed before it. circularDesign is off\n"+ - "so package="+p.getName()+" must be moved up in the xml file"); - } - } - } - - nameToPackage.put(p.getName(), p); - packageNameToPackage.put(p.getPackage(), p); - } - - public void verifyDependencyOk(String className) { - log.log(" className="+className, Project.MSG_DEBUG); - if(className.startsWith("L")) - className = className.substring(1, className.length()); - - String classPackage = VerifyDesignDelegate.getPackageName(className); - - //check if this is an needdeclarations="false" package, if so, the dependency is ok if it - //is not declared - log.log(" classPackage="+classPackage, Project.MSG_DEBUG); - Package p = retreivePack(classPackage); - if(p != null && !p.isNeedDeclarations()) - return; - - String pack = currentAliasPackage.getPackage(); - - log.log(" AllowedDepends="+pack, Project.MSG_DEBUG); - log.log(" CurrentDepends="+className, Project.MSG_DEBUG); - if(isClassInPackage(className, currentAliasPackage)) - return; - - Depends[] depends = currentAliasPackage.getDepends(); - - //probably want to create a regular expression out of all the depends and just match on that - //each time. for now though, just get it working and do the basic(optimize later if needed) - for(int i = 0; i < depends.length; i++) { - Depends d = depends[i]; - String name = d.getName(); - - Package temp = getPackage(name); - log.log(" AllowedDepends="+temp.getPackage(), Project.MSG_DEBUG); - log.log(" CurrentDepends="+className, Project.MSG_DEBUG); - if(isClassInPackage(className, temp)) - return; - } - - log.log("***************************************", Project.MSG_DEBUG); - log.log("***************************************", Project.MSG_DEBUG); - - throw new BuildException(Design.getErrorMessage(currentClass, className), location); - } - - public boolean isClassInPackage(String className, Package p) { - String classPackage = VerifyDesignDelegate.getPackageName(className); - if(p.isIncludeSubpackages()) { - if(className.startsWith(p.getPackage())) - return true; - } else { //if not including subpackages, the it must be the exact package. - if(classPackage.equals(p.getPackage())) - return true; - } - return false; - } - /** - * @param className - * @return whether or not this class needs to be checked. (ie. if the - * attribute needdepends=false, we don't care about this package. - */ - public boolean needEvalCurrentClass(String className) { - currentClass = className; - String packageName = VerifyDesignDelegate.getPackageName(className); -// log("class="+className, Project.MSG_DEBUG); - if(!packageName.equals(currentPackageName) || currentAliasPackage == null) { - currentPackageName = packageName; - log.log("\nEvaluating package="+currentPackageName, Project.MSG_INFO); - currentAliasPackage = retreivePack(packageName); - //DEANDO: test this scenario - if(currentAliasPackage == null) { - log.log(" class="+className, Project.MSG_VERBOSE); - throw new BuildException(getNoDefinitionError(className), location); - } - } - log.log(" class="+className, Project.MSG_VERBOSE); - - if(!className.startsWith(currentPackageName)) - throw new RuntimeException("Internal Error"); - - if(!currentAliasPackage.getNeedDepends()) - return false; - return true; - } - - public String getCurrentClass() { - return currentClass; - } - - void checkClass(String dependsOn) { - log.log(" dependsOn1="+dependsOn, Project.MSG_DEBUG); - if(dependsOn.endsWith("[]")) { - int index = dependsOn.indexOf("["); - dependsOn = dependsOn.substring(0, index); - log.log(" dependsOn2="+dependsOn, Project.MSG_DEBUG); - } - - if(primitives.contains(dependsOn)) - return; - - //Anything in java.lang package seems to be passed in as just the - //className with no package like Object, String or Class, so here we try to - //see if the name is a java.lang class.... - String tempTry = "java.lang."+dependsOn; - try { - Class c = VerifyDesign.class.getClassLoader().loadClass(tempTry); - return; - } catch(ClassNotFoundException e) { - //not found, continue on... - } - //sometimes instead of passing java.lang.String or java.lang.Object, the bcel - //passes just String or Object -// if("String".equals(dependsOn) || "Object".equals(dependsOn)) -// return; - - verifyDependencyOk(dependsOn); - - } - - public static String getErrorMessage(String className, String dependsOnClass) { - String s = "\nYou are violating your own design...." + - "\nClass = "+className+" depends on\nClass = "+dependsOnClass+ - "\nThe dependency to allow this is not defined in your design" + - "\nPackage="+VerifyDesignDelegate.getPackageName(className)+" is not defined to depend on"+ - "\nPackage="+VerifyDesignDelegate.getPackageName(dependsOnClass)+ - "\nChange the code or the design"; - return s; - } - - public static String getNoDefinitionError(String className) { - String s = "\nPackage="+VerifyDesignDelegate.getPackageName(className)+" is not defined in the design.\n"+ - "All packages with classes must be declared in the design file\n"+ - "Class found in the offending package="+className; - return s; - } - - public static String getWrapperMsg(File originalFile, String message) { - String s = "\nThe file '" + originalFile.getAbsolutePath() + "' failed due to: " + message; - return s; - } +/*
+ * Copyright (c) 2001-2005 Ant-Contrib project. All rights reserved.
+ *
+ * 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.sf.antcontrib.design;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+
+
+/*
+ * Created on Aug 24, 2003
+ *
+ * To change the template for this generated file go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+/**
+ * FILL IN JAVADOC HERE
+ *
+ * @author Dean Hiller([email protected])
+ */
+public class Design {
+
+ private Map nameToPackage = new HashMap();
+ private Map packageNameToPackage = new HashMap();
+ private boolean isCircularDesign;
+ private Log log;
+ private Location location;
+
+ private String currentClass = null;
+ private String currentPackageName = null;
+ private Package currentAliasPackage = null;
+
+ private HashSet primitives = new HashSet();
+
+ public Design(boolean isCircularDesign, Log log, Location loc) {
+ //by default, add java as a configured package with the name java
+ Package p = new Package();
+ p.setIncludeSubpackages(true);
+ p.setName("java");
+ p.setNeedDeclarations(false);
+ p.setPackage("java");
+ addConfiguredPackage(p);
+
+ this.isCircularDesign = isCircularDesign;
+ this.log = log;
+ this.location = loc;
+
+ primitives.add("boolean");
+
+ //integral types
+ primitives.add("byte");
+ primitives.add("short");
+ primitives.add("int");
+ primitives.add("long");
+ primitives.add("char");
+
+ //floating point types
+ primitives.add("double");
+ primitives.add("float");
+ }
+
+ public Package getPackage(String nameAttribute) {
+ return (Package)nameToPackage.get(nameAttribute);
+ }
+
+ private Package retreivePack(String thePackage) {
+ if(thePackage == null)
+ throw new IllegalArgumentException("Cannot retrieve null packages");
+
+ Package result = null;
+ String currentPackage = thePackage;
+ while(!Package.DEFAULT.equals(currentPackage)) {
+ result = (Package)packageNameToPackage.get(currentPackage);
+ if(result != null) {
+ if(currentPackage.equals(thePackage))
+ return result;
+ else if(result.isIncludeSubpackages())
+ return result;
+ return null;
+ }
+ currentPackage = VerifyDesignDelegate.getPackageName(currentPackage);
+ }
+
+ //result must now be default package
+ if(result != null && result.isIncludeSubpackages())
+ return result;
+
+ return null;
+ }
+
+ public void addConfiguredPackage(Package p) {
+
+ String pack = p.getPackage();
+
+ Depends[] depends = p.getDepends();
+
+ if(depends != null && !isCircularDesign) {
+ //make sure all depends are in Map first
+ //circular references then are not a problem because they must
+ //put the stuff in order
+ for(int i = 0; i < depends.length; i++) {
+ Package dependsPackage = (Package)nameToPackage.get(depends[i].getName());
+
+ if(dependsPackage == null) {
+ throw new RuntimeException("package name="+p.getName()+" did not\n" +
+ "have "+depends[i]+" listed before it. circularDesign is off\n"+
+ "so package="+p.getName()+" must be moved up in the xml file");
+ }
+ }
+ }
+
+ nameToPackage.put(p.getName(), p);
+ packageNameToPackage.put(p.getPackage(), p);
+ }
+
+ /**
+ * @param className Class name of a class our currentAliasPackage depends on.
+ */
+ public void verifyDependencyOk(String className) {
+ log.log(" className="+className, Project.MSG_DEBUG);
+ if(className.startsWith("L"))
+ className = className.substring(1, className.length());
+
+ //get the classPackage our currentAliasPackage depends on....
+ String classPackage = VerifyDesignDelegate.getPackageName(className);
+
+ //check if this is an needdeclarations="false" package, if so, the dependency is ok if it
+ //is not declared
+ log.log(" classPackage="+classPackage, Project.MSG_DEBUG);
+ Package p = retreivePack(classPackage);
+ p.setUsed(true); //set package to used since we have classes in it
+ if(p != null && !p.isNeedDeclarations())
+ return;
+
+ String pack = currentAliasPackage.getPackage();
+
+ log.log(" AllowedDepends="+pack, Project.MSG_DEBUG);
+ log.log(" CurrentDepends="+className, Project.MSG_DEBUG);
+ if(isClassInPackage(className, currentAliasPackage))
+ return;
+
+ Depends[] depends = currentAliasPackage.getDepends();
+
+ //probably want to create a regular expression out of all the depends and just match on that
+ //each time. for now though, just get it working and do the basic(optimize later if needed)
+ for(int i = 0; i < depends.length; i++) {
+ Depends d = depends[i];
+ String name = d.getName();
+
+ Package temp = getPackage(name);
+ log.log(" AllowedDepends="+temp.getPackage(), Project.MSG_DEBUG);
+ log.log(" CurrentDepends="+className, Project.MSG_DEBUG);
+ if(isClassInPackage(className, temp)) {
+ temp.setUsed(true); //set package to used since we are depending on it(could be external package like junit)
+ currentAliasPackage.addUsedDependency(d);
+ return;
+ }
+ }
+
+ log.log("***************************************", Project.MSG_DEBUG);
+ log.log("***************************************", Project.MSG_DEBUG);
+
+ throw new BuildException(Design.getErrorMessage(currentClass, className), location);
+ }
+
+ public boolean isClassInPackage(String className, Package p) {
+ String classPackage = VerifyDesignDelegate.getPackageName(className);
+ if(p.isIncludeSubpackages()) {
+ if(className.startsWith(p.getPackage()))
+ return true;
+ } else { //if not including subpackages, the it must be the exact package.
+ if(classPackage.equals(p.getPackage()))
+ return true;
+ }
+ return false;
+ }
+ /**
+ * @param className
+ * @return whether or not this class needs to be checked. (ie. if the
+ * attribute needdepends=false, we don't care about this package.
+ */
+ public boolean needEvalCurrentClass(String className) {
+ currentClass = className;
+ String packageName = VerifyDesignDelegate.getPackageName(className);
+// log("class="+className, Project.MSG_DEBUG);
+ if(!packageName.equals(currentPackageName) || currentAliasPackage == null) {
+ currentPackageName = packageName;
+ log.log("\nEvaluating package="+currentPackageName, Project.MSG_INFO);
+ currentAliasPackage = retreivePack(packageName);
+ //DEANDO: test this scenario
+ if(currentAliasPackage == null) {
+ log.log(" class="+className, Project.MSG_VERBOSE);
+ throw new BuildException(getNoDefinitionError(className), location);
+ }
+
+ currentAliasPackage.setUsed(true);
+ }
+ log.log(" class="+className, Project.MSG_VERBOSE);
+
+ if(!className.startsWith(currentPackageName))
+ throw new RuntimeException("Internal Error");
+
+ if(!currentAliasPackage.getNeedDepends())
+ return false;
+ return true;
+ }
+
+ public String getCurrentClass() {
+ return currentClass;
+ }
+
+ void checkClass(String dependsOn) {
+ log.log(" dependsOn1="+dependsOn, Project.MSG_DEBUG);
+ if(dependsOn.endsWith("[]")) {
+ int index = dependsOn.indexOf("[");
+ dependsOn = dependsOn.substring(0, index);
+ log.log(" dependsOn2="+dependsOn, Project.MSG_DEBUG);
+ }
+
+ if(primitives.contains(dependsOn))
+ return;
+
+ //Anything in java.lang package seems to be passed in as just the
+ //className with no package like Object, String or Class, so here we try to
+ //see if the name is a java.lang class....
+ String tempTry = "java.lang."+dependsOn;
+ try {
+ Class c = VerifyDesign.class.getClassLoader().loadClass(tempTry);
+ return;
+ } catch(ClassNotFoundException e) {
+ //not found, continue on...
+ }
+ //sometimes instead of passing java.lang.String or java.lang.Object, the bcel
+ //passes just String or Object
+// if("String".equals(dependsOn) || "Object".equals(dependsOn))
+// return;
+
+ verifyDependencyOk(dependsOn);
+
+ }
+
+ public static String getErrorMessage(String className, String dependsOnClass) {
+ String s = "\nYou are violating your own design...." +
+ "\nClass = "+className+" depends on\nClass = "+dependsOnClass+
+ "\nThe dependency to allow this is not defined in your design" +
+ "\nPackage="+VerifyDesignDelegate.getPackageName(className)+" is not defined to depend on"+
+ "\nPackage="+VerifyDesignDelegate.getPackageName(dependsOnClass)+
+ "\nChange the code or the design";
+ return s;
+ }
+
+ public static String getNoDefinitionError(String className) {
+ String s = "\nPackage="+VerifyDesignDelegate.getPackageName(className)+" is not defined in the design.\n"+
+ "All packages with classes must be declared in the design file\n"+
+ "Class found in the offending package="+className;
+ return s;
+ }
+
+ public static String getWrapperMsg(File originalFile, String message) {
+ String s = "\nThe file '" + originalFile.getAbsolutePath() + "' failed due to: " + message;
+ return s;
+ }
+
+ /**
+ * @param designErrors
+ */
+ public void fillInUnusedPackages(Vector designErrors)
+ {
+ Collection values = nameToPackage.values();
+ Iterator iterator = values.iterator();
+ while(iterator.hasNext()) {
+ Package pack = (Package)iterator.next();
+ if(!pack.isUsed()) {
+ String msg = "Package name="+pack.getName()+" is unused. Full package="+pack.getPackage();
+ log.log(msg, Project.MSG_ERR);
+ designErrors.add(new BuildException(msg));
+ } else {
+ fillInUnusedDepends(designErrors, pack);
+ }
+ }
+ }
+
+ /**
+ * @param designErrors
+ * @param pack
+ */
+ private void fillInUnusedDepends(Vector designErrors, Package pack)
+ {
+ Iterator iterator = pack.getUnusedDepends().iterator();
+ while(iterator.hasNext()) {
+ Depends depends = (Depends)iterator.next();
+ String msg = "Package name="+pack.getName()+" has a dependency declared that is not true anymore. Please erase the dependency <depends>"+depends.getName()+"</depends> from package="+pack.getName();
+ log.log(msg, Project.MSG_ERR);
+ designErrors.add(new BuildException(msg));
+ }
+ }
}
\ No newline at end of file diff --git a/src/java/net/sf/antcontrib/design/Package.java b/src/java/net/sf/antcontrib/design/Package.java index a470f8c..d3015d1 100644 --- a/src/java/net/sf/antcontrib/design/Package.java +++ b/src/java/net/sf/antcontrib/design/Package.java @@ -16,7 +16,9 @@ package net.sf.antcontrib.design; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /* @@ -32,20 +34,22 @@ import java.util.List; */ public class Package { - public final static String DEFAULT = "<default package>"; + public final static String DEFAULT = "<default package>"; private String name; private String pack; //holds the name attribute of the package element of each //package this package depends on. private List depends; - private boolean isIncludeSubpackages; - private boolean needDeclarations; - private boolean needDepends; + private Set unusedDepends = new HashSet(); + private boolean isIncludeSubpackages; + private boolean needDeclarations; + private boolean needDepends; + private boolean isUsed = false; public void setName(String name) { - if("".equals(name)) - name = DEFAULT; + if("".equals(name)) + name = DEFAULT; this.name = name; } public String getName() { @@ -53,7 +57,7 @@ public class Package { } public void setPackage(String pack) { - this.pack = pack; + this.pack = pack; } public String getPackage() { @@ -61,50 +65,75 @@ public class Package { } public void addDepends(Depends d) { - if(depends == null) - depends = new ArrayList(); - depends.add(d); + if(depends == null) + depends = new ArrayList(); + depends.add(d); + unusedDepends.add(d); } public Depends[] getDepends() { - Depends[] d = new Depends[0]; - if(depends == null) - return d; - return (Depends[])depends.toArray(d); + Depends[] d = new Depends[0]; + if(depends == null) + return d; + return (Depends[])depends.toArray(d); + } + + /** + * @param b + */ + public void setIncludeSubpackages(boolean b) { + isIncludeSubpackages = b; + } + /** + * @return + */ + public boolean isIncludeSubpackages() { + return isIncludeSubpackages; + } + /** + * @param b + */ + public void setNeedDeclarations(boolean b) { + needDeclarations = b; + } + /** + * @return + */ + public boolean isNeedDeclarations() { + return needDeclarations; + } + /** + * @param b + */ + public void setNeedDepends(boolean b) { + needDepends = b; + } + + public boolean getNeedDepends() { + return needDepends; + } + /** + * @param b + */ + public void setUsed(boolean b) + { + isUsed = b; + } + public boolean isUsed() + { + return isUsed; + } + /** + * @param d + */ + public void addUsedDependency(Depends d) + { + unusedDepends.remove(d); + } + + public Set getUnusedDepends() { + return unusedDepends; } - /** - * @param b - */ - public void setIncludeSubpackages(boolean b) { - isIncludeSubpackages = b; - } - /** - * @return - */ - public boolean isIncludeSubpackages() { - return isIncludeSubpackages; - } - /** - * @param b - */ - public void setNeedDeclarations(boolean b) { - needDeclarations = b; - } - /** - * @return - */ - public boolean isNeedDeclarations() { - return needDeclarations; - } - /** - * @param b - */ - public void setNeedDepends(boolean b) { - needDepends = b; - } - - public boolean getNeedDepends() { - return needDepends; - } } + diff --git a/src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java b/src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java index 1c2fb01..3e5e715 100644 --- a/src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java +++ b/src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java @@ -1,424 +1,426 @@ -/* - * Copyright (c) 2004-2005 Ant-Contrib project. All rights reserved. - * - * 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.sf.antcontrib.design; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Vector; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; - -import org.apache.bcel.Constants; -import org.apache.bcel.classfile.ClassFormatException; -import org.apache.bcel.classfile.ClassParser; -import org.apache.bcel.classfile.Constant; -import org.apache.bcel.classfile.ConstantClass; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantUtf8; -import org.apache.bcel.classfile.DescendingVisitor; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.classfile.Utility; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.PatternSet; -import org.apache.tools.ant.util.JAXPUtils; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.XMLReader; - -/** - * - * - * - * @author dhiller - * - */ - -public class VerifyDesignDelegate implements Log { - - private File designFile; - private Vector paths = new Vector(); - private boolean isCircularDesign = false; - private boolean deleteFiles = false; - private boolean fillInBuildException = false; - private boolean needDeclarationsDefault = true; - private boolean needDependsDefault = true; - - private Task task; - private Design design; - private HashSet primitives = new HashSet(); - private Vector designErrors = new Vector(); - private boolean verifiedAtLeastOne = false; - - public VerifyDesignDelegate(Task task) { - this.task = task; - primitives.add("B"); - primitives.add("C"); - primitives.add("D"); - primitives.add("F"); - primitives.add("I"); - primitives.add("J"); - primitives.add("S"); - primitives.add("Z"); - } - - public void addConfiguredPath(Path path) { -// Path newPath = new Path(task.getProject()); -// path. - - - paths.add(path); - } - - public void setJar(File f) { - Path p = (Path)task.getProject().createDataType("path"); - p.createPathElement().setLocation(f.getAbsoluteFile()); - addConfiguredPath(p); - } - - public void setDesign(File f) { - this.designFile = f; - } - - public void setCircularDesign(boolean isCircularDesign) { - this.isCircularDesign = isCircularDesign; - } - - public void setDeleteFiles(boolean deleteFiles) { - this.deleteFiles = deleteFiles; - } - - public void setFillInBuildException(boolean b) { - fillInBuildException = b; - } - - public void setNeedDeclarationsDefault(boolean b) { - needDeclarationsDefault = b; - } - - public void setNeedDependsDefault(boolean b) { - needDependsDefault = b; - } - - public void execute() { - if(!designFile.exists() || designFile.isDirectory()) - throw new BuildException("design attribute in verifydesign element specified an invalid file="+designFile); - - verifyJarFilesExist(); - - try { - XMLReader reader = JAXPUtils.getXMLReader(); - DesignFileHandler ch = new DesignFileHandler(this, designFile, isCircularDesign, task.getLocation()); - ch.setNeedDeclarationsDefault(needDeclarationsDefault); - ch.setNeedDependsDefault(needDependsDefault); - reader.setContentHandler(ch); - //reader.setEntityResolver(ch); - //reader.setErrorHandler(ch); - //reader.setDTDHandler(ch); - - log("about to start parsing file='"+designFile+"'", Project.MSG_INFO); - FileInputStream fileInput = new FileInputStream(designFile); - InputSource src = new InputSource(fileInput); - reader.parse(src); - design = ch.getDesign(); - - Enumeration pathsEnum = paths.elements(); - Path p = null; - while (pathsEnum.hasMoreElements()) { - p = (Path)pathsEnum.nextElement(); - verifyPathAdheresToDesign(design, p); - } - - if (! designErrors.isEmpty()) { - log(designErrors.size()+"Errors.", Project.MSG_WARN); - if(!fillInBuildException) - throw new BuildException("Design check failed due to previous errors"); - throwAllErrors(); - } - - } catch (SAXException e) { - maybeDeleteFiles(); - if (e.getException() != null - && e.getException() instanceof RuntimeException) - throw (RuntimeException) e.getException(); - else if (e instanceof SAXParseException) { - SAXParseException pe = (SAXParseException) e; - throw new BuildException("\nProblem parsing design file='" - + designFile + "'. \nline=" + pe.getLineNumber() - + " column=" + pe.getColumnNumber() + " Reason:\n" - + e.getMessage() + "\n", e); - } - throw new BuildException("\nProblem parsing design file='" - + designFile + "'. Reason:\n" + e, e); - } catch (IOException e) { - maybeDeleteFiles(); - throw new RuntimeException("See attached exception", e); - // throw new BuildException("IOException on design file='" - // + designFile + "'. attached:", e); - } catch(RuntimeException e) { - maybeDeleteFiles(); - throw e; - } finally { - - } - - if(!verifiedAtLeastOne) - throw new BuildException("Did not find any class or jar files to verify"); - } - //some auto builds like cruisecontrol can only report all the - //standard ant task errors and the build exceptions so here - //we need to fill in the buildexception so the errors are reported - //correctly through those tools....though, you think ant has a hook - //in that cruisecontrol is not using like LogListeners or something - private void throwAllErrors() { - String result = "Design check failed due to following errors"; - Enumeration exceptions = designErrors.elements(); - while(exceptions.hasMoreElements()) { - BuildException be = (BuildException)exceptions.nextElement(); - String message = be.getMessage(); - result += "\n" + message; - } - throw new BuildException(result); - } - - private void verifyJarFilesExist() { - Enumeration pathsEnum = paths.elements(); - Path p = null; - while (pathsEnum.hasMoreElements()) { - p = (Path)pathsEnum.nextElement(); - String files[] = p.list(); - for (int i=0;i<files.length;i++) { - File file = new File(files[i]); - - if (!file.exists()) - throw new BuildException(VisitorImpl.getNoFileMsg(file)); - } - } - } - - private void maybeDeleteFiles() { - if (deleteFiles) { - log("Deleting all class and jar files so you do not get tempted to\n" + - "use a jar that doesn't abide by the design(This option can\n" + - "be turned off if you really want)", Project.MSG_INFO); - - Enumeration pathsEnum = paths.elements(); - Path p = null; - while (pathsEnum.hasMoreElements()) { - p = (Path)pathsEnum.nextElement(); - deleteFilesInPath(p); - } - } - } - - private void deleteFilesInPath(Path p) { - String files[] = p.list(); - for (int i=0;i<files.length;i++) { - File file = new File(files[i]); - - boolean deleted = file.delete(); - if (! deleted) { - file.deleteOnExit(); - } - } - } - - private void verifyPathAdheresToDesign(Design d, Path p) throws ClassFormatException, IOException { - String files[] = p.list(); - for (int i=0;i<files.length;i++) { - File file = new File(files[i]); - if(file.isDirectory()) { - FileSet set = new FileSet(); - set.setDir(file); - set.setProject(task.getProject()); - PatternSet.NameEntry entry1 = set.createInclude(); - PatternSet.NameEntry entry2 = set.createInclude(); - PatternSet.NameEntry entry3 = set.createInclude(); - entry1.setName("**/*.class"); - entry2.setName("**/*.jar"); - entry3.setName("**/*.war"); - DirectoryScanner scanner = set.getDirectoryScanner(task.getProject()); - scanner.setBasedir(file); - String[] scannerFiles = scanner.getIncludedFiles(); - for(int j = 0; j < scannerFiles.length; j++) { - verifyPartOfPath(scannerFiles[j], new File(file, scannerFiles[j]), d); - } - } else - verifyPartOfPath(files[i], file, d); - } - } - - private void verifyPartOfPath(String fileName, File file, Design d) throws IOException { - if (fileName.endsWith(".jar") || fileName.endsWith(".war")) { - JarFile jarFile = new JarFile(file); - verifyJarAdheresToDesign(d, jarFile, file); - } else if (fileName.endsWith(".class")) { - verifyClassAdheresToDesign(d, file); - } else - throw new BuildException("Only directories, jars, wars, and class files can be supplied to verify design, not file="+file.getAbsolutePath()); - } - - private void verifyClassAdheresToDesign(Design d, File classFile) - throws ClassFormatException, IOException { - FileInputStream fis = null; - try { - fis = new FileInputStream(classFile); - verifyClassAdheresToDesign(d, fis, classFile.getAbsolutePath(), classFile); - } - finally { - try { - if (fis != null) { - fis.close(); - } - } - catch (IOException e) { - ; //doh!! - } - } - - } - - private void verifyJarAdheresToDesign(Design d, JarFile jarFile, File original) - throws ClassFormatException, IOException { - - try { - Enumeration en = jarFile.entries(); - while(en.hasMoreElements()) { - ZipEntry entry = (ZipEntry)en.nextElement(); - InputStream in = null; - if(entry.getName().endsWith(".class")) { - in = jarFile.getInputStream(entry); - try { - in = jarFile.getInputStream(entry); - verifyClassAdheresToDesign(d, in, entry.getName(), original); - } - finally { - try { - if (in != null) { - in.close(); - } - } - catch (IOException e) { - ; // doh!!! - } - } - } - } - } - finally { - try { - jarFile.close(); - } - catch (IOException e) { - ; //doh!!! - } - } - } - - private String className = ""; - - private void verifyClassAdheresToDesign(Design d, InputStream in, String name, File originalClassOrJarFile) throws ClassFormatException, IOException { - try { - verifiedAtLeastOne = true; - ClassParser parser = new ClassParser(in, name); - JavaClass javaClass = parser.parse(); - className = javaClass.getClassName(); - - if(!d.needEvalCurrentClass(className)) - return; - - ConstantPool pool = javaClass.getConstantPool(); - processConstantPool(pool); - VisitorImpl visitor = new VisitorImpl(pool, this, d, task.getLocation()); - DescendingVisitor desc = new DescendingVisitor(javaClass, visitor); - desc.visit(); - } catch(BuildException e) { - log(Design.getWrapperMsg(originalClassOrJarFile, e.getMessage()), Project.MSG_ERR); - designErrors.addElement(e); - } - } - - private void processConstantPool(ConstantPool pool) { - Constant[] constants = pool.getConstantPool(); - if(constants == null) { - log(" constants=null", Project.MSG_VERBOSE); - return; - } - - log(" constants len="+constants.length, Project.MSG_VERBOSE); - for(int i = 0; i < constants.length; i++) { - processConstant(pool, constants[i], i); - } - } - - private void processConstant(ConstantPool pool, Constant c, int i) { - if(c == null) //don't know why, but constant[0] seems to be always null. - return; - - log(" const["+i+"]="+pool.constantToString(c)+" inst="+c.getClass().getName(), Project.MSG_DEBUG); - byte tag = c.getTag(); - switch(tag) { - //reverse engineered from ConstantPool.constantToString.. - case Constants.CONSTANT_Class: - int ind = ((ConstantClass)c).getNameIndex(); - c = pool.getConstant(ind, Constants.CONSTANT_Utf8); - String className = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false); - log(" classNamePre="+className, Project.MSG_DEBUG); - className = getRidOfArray(className); - String firstLetter = className.charAt(0)+""; - if(primitives.contains(firstLetter)) - return; - log(" className="+className, Project.MSG_VERBOSE); - design.checkClass(className); - break; - default: - - } - } - - private static String getRidOfArray(String className) { - while(className.startsWith("[")) - className = className.substring(1, className.length()); - return className; - } - - public static String getPackageName(String className) { - String packageName = Package.DEFAULT; - int index = className.lastIndexOf("."); - if(index > 0) - packageName = className.substring(0, index); - //DEANDO: test the else scenario here(it is a corner case)... - - return packageName; - } - - public void log(String msg, int level) { - //if(level == Project.MSG_WARN || level == Project.MSG_INFO - // || level == Project.MSG_ERR || level == Project.MSG_VERBOSE) - //VerifyDesignTest.log(msg); - task.log(msg, level); - } -} +/*
+ * Copyright (c) 2004-2005 Ant-Contrib project. All rights reserved.
+ *
+ * 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.sf.antcontrib.design;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Vector;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.ClassFormatException;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.Constant;
+import org.apache.bcel.classfile.ConstantClass;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.ConstantUtf8;
+import org.apache.bcel.classfile.DescendingVisitor;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Utility;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ *
+ *
+ * @author dhiller
+ *
+ */
+
+public class VerifyDesignDelegate implements Log {
+
+ private File designFile;
+ private Vector paths = new Vector();
+ private boolean isCircularDesign = false;
+ private boolean deleteFiles = false;
+ private boolean fillInBuildException = false;
+ private boolean needDeclarationsDefault = true;
+ private boolean needDependsDefault = true;
+
+ private Task task;
+ private Design design;
+ private HashSet primitives = new HashSet();
+ private Vector designErrors = new Vector();
+ private boolean verifiedAtLeastOne = false;
+
+ public VerifyDesignDelegate(Task task) {
+ this.task = task;
+ primitives.add("B");
+ primitives.add("C");
+ primitives.add("D");
+ primitives.add("F");
+ primitives.add("I");
+ primitives.add("J");
+ primitives.add("S");
+ primitives.add("Z");
+ }
+
+ public void addConfiguredPath(Path path) {
+// Path newPath = new Path(task.getProject());
+// path.
+
+
+ paths.add(path);
+ }
+
+ public void setJar(File f) {
+ Path p = (Path)task.getProject().createDataType("path");
+ p.createPathElement().setLocation(f.getAbsoluteFile());
+ addConfiguredPath(p);
+ }
+
+ public void setDesign(File f) {
+ this.designFile = f;
+ }
+
+ public void setCircularDesign(boolean isCircularDesign) {
+ this.isCircularDesign = isCircularDesign;
+ }
+
+ public void setDeleteFiles(boolean deleteFiles) {
+ this.deleteFiles = deleteFiles;
+ }
+
+ public void setFillInBuildException(boolean b) {
+ fillInBuildException = b;
+ }
+
+ public void setNeedDeclarationsDefault(boolean b) {
+ needDeclarationsDefault = b;
+ }
+
+ public void setNeedDependsDefault(boolean b) {
+ needDependsDefault = b;
+ }
+
+ public void execute() {
+ if(!designFile.exists() || designFile.isDirectory())
+ throw new BuildException("design attribute in verifydesign element specified an invalid file="+designFile);
+
+ verifyJarFilesExist();
+
+ try {
+ XMLReader reader = JAXPUtils.getXMLReader();
+ DesignFileHandler ch = new DesignFileHandler(this, designFile, isCircularDesign, task.getLocation());
+ ch.setNeedDeclarationsDefault(needDeclarationsDefault);
+ ch.setNeedDependsDefault(needDependsDefault);
+ reader.setContentHandler(ch);
+ //reader.setEntityResolver(ch);
+ //reader.setErrorHandler(ch);
+ //reader.setDTDHandler(ch);
+
+ log("about to start parsing file='"+designFile+"'", Project.MSG_INFO);
+ FileInputStream fileInput = new FileInputStream(designFile);
+ InputSource src = new InputSource(fileInput);
+ reader.parse(src);
+ design = ch.getDesign();
+
+ Enumeration pathsEnum = paths.elements();
+ Path p = null;
+ while (pathsEnum.hasMoreElements()) {
+ p = (Path)pathsEnum.nextElement();
+ verifyPathAdheresToDesign(design, p);
+ }
+
+ design.fillInUnusedPackages(designErrors);
+
+ if (! designErrors.isEmpty()) {
+ log(designErrors.size()+"Errors.", Project.MSG_WARN);
+ if(!fillInBuildException)
+ throw new BuildException("Design check failed due to previous errors");
+ throwAllErrors();
+ }
+
+ } catch (SAXException e) {
+ maybeDeleteFiles();
+ if (e.getException() != null
+ && e.getException() instanceof RuntimeException)
+ throw (RuntimeException) e.getException();
+ else if (e instanceof SAXParseException) {
+ SAXParseException pe = (SAXParseException) e;
+ throw new BuildException("\nProblem parsing design file='"
+ + designFile + "'. \nline=" + pe.getLineNumber()
+ + " column=" + pe.getColumnNumber() + " Reason:\n"
+ + e.getMessage() + "\n", e);
+ }
+ throw new BuildException("\nProblem parsing design file='"
+ + designFile + "'. Reason:\n" + e, e);
+ } catch (IOException e) {
+ maybeDeleteFiles();
+ throw new RuntimeException("See attached exception", e);
+ // throw new BuildException("IOException on design file='"
+ // + designFile + "'. attached:", e);
+ } catch(RuntimeException e) {
+ maybeDeleteFiles();
+ throw e;
+ } finally {
+
+ }
+
+ if(!verifiedAtLeastOne)
+ throw new BuildException("Did not find any class or jar files to verify");
+ }
+ //some auto builds like cruisecontrol can only report all the
+ //standard ant task errors and the build exceptions so here
+ //we need to fill in the buildexception so the errors are reported
+ //correctly through those tools....though, you think ant has a hook
+ //in that cruisecontrol is not using like LogListeners or something
+ private void throwAllErrors() {
+ String result = "Design check failed due to following errors";
+ Enumeration exceptions = designErrors.elements();
+ while(exceptions.hasMoreElements()) {
+ BuildException be = (BuildException)exceptions.nextElement();
+ String message = be.getMessage();
+ result += "\n" + message;
+ }
+ throw new BuildException(result);
+ }
+
+ private void verifyJarFilesExist() {
+ Enumeration pathsEnum = paths.elements();
+ Path p = null;
+ while (pathsEnum.hasMoreElements()) {
+ p = (Path)pathsEnum.nextElement();
+ String files[] = p.list();
+ for (int i=0;i<files.length;i++) {
+ File file = new File(files[i]);
+
+ if (!file.exists())
+ throw new BuildException(VisitorImpl.getNoFileMsg(file));
+ }
+ }
+ }
+
+ private void maybeDeleteFiles() {
+ if (deleteFiles) {
+ log("Deleting all class and jar files so you do not get tempted to\n" +
+ "use a jar that doesn't abide by the design(This option can\n" +
+ "be turned off if you really want)", Project.MSG_INFO);
+
+ Enumeration pathsEnum = paths.elements();
+ Path p = null;
+ while (pathsEnum.hasMoreElements()) {
+ p = (Path)pathsEnum.nextElement();
+ deleteFilesInPath(p);
+ }
+ }
+ }
+
+ private void deleteFilesInPath(Path p) {
+ String files[] = p.list();
+ for (int i=0;i<files.length;i++) {
+ File file = new File(files[i]);
+
+ boolean deleted = file.delete();
+ if (! deleted) {
+ file.deleteOnExit();
+ }
+ }
+ }
+
+ private void verifyPathAdheresToDesign(Design d, Path p) throws ClassFormatException, IOException {
+ String files[] = p.list();
+ for (int i=0;i<files.length;i++) {
+ File file = new File(files[i]);
+ if(file.isDirectory()) {
+ FileSet set = new FileSet();
+ set.setDir(file);
+ set.setProject(task.getProject());
+ PatternSet.NameEntry entry1 = set.createInclude();
+ PatternSet.NameEntry entry2 = set.createInclude();
+ PatternSet.NameEntry entry3 = set.createInclude();
+ entry1.setName("**/*.class");
+ entry2.setName("**/*.jar");
+ entry3.setName("**/*.war");
+ DirectoryScanner scanner = set.getDirectoryScanner(task.getProject());
+ scanner.setBasedir(file);
+ String[] scannerFiles = scanner.getIncludedFiles();
+ for(int j = 0; j < scannerFiles.length; j++) {
+ verifyPartOfPath(scannerFiles[j], new File(file, scannerFiles[j]), d);
+ }
+ } else
+ verifyPartOfPath(files[i], file, d);
+ }
+ }
+
+ private void verifyPartOfPath(String fileName, File file, Design d) throws IOException {
+ if (fileName.endsWith(".jar") || fileName.endsWith(".war")) {
+ JarFile jarFile = new JarFile(file);
+ verifyJarAdheresToDesign(d, jarFile, file);
+ } else if (fileName.endsWith(".class")) {
+ verifyClassAdheresToDesign(d, file);
+ } else
+ throw new BuildException("Only directories, jars, wars, and class files can be supplied to verify design, not file="+file.getAbsolutePath());
+ }
+
+ private void verifyClassAdheresToDesign(Design d, File classFile)
+ throws ClassFormatException, IOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(classFile);
+ verifyClassAdheresToDesign(d, fis, classFile.getAbsolutePath(), classFile);
+ }
+ finally {
+ try {
+ if (fis != null) {
+ fis.close();
+ }
+ }
+ catch (IOException e) {
+ ; //doh!!
+ }
+ }
+
+ }
+
+ private void verifyJarAdheresToDesign(Design d, JarFile jarFile, File original)
+ throws ClassFormatException, IOException {
+
+ try {
+ Enumeration en = jarFile.entries();
+ while(en.hasMoreElements()) {
+ ZipEntry entry = (ZipEntry)en.nextElement();
+ InputStream in = null;
+ if(entry.getName().endsWith(".class")) {
+ in = jarFile.getInputStream(entry);
+ try {
+ in = jarFile.getInputStream(entry);
+ verifyClassAdheresToDesign(d, in, entry.getName(), original);
+ }
+ finally {
+ try {
+ if (in != null) {
+ in.close();
+ }
+ }
+ catch (IOException e) {
+ ; // doh!!!
+ }
+ }
+ }
+ }
+ }
+ finally {
+ try {
+ jarFile.close();
+ }
+ catch (IOException e) {
+ ; //doh!!!
+ }
+ }
+ }
+
+ private String className = "";
+
+ private void verifyClassAdheresToDesign(Design d, InputStream in, String name, File originalClassOrJarFile) throws ClassFormatException, IOException {
+ try {
+ verifiedAtLeastOne = true;
+ ClassParser parser = new ClassParser(in, name);
+ JavaClass javaClass = parser.parse();
+ className = javaClass.getClassName();
+
+ if(!d.needEvalCurrentClass(className))
+ return;
+
+ ConstantPool pool = javaClass.getConstantPool();
+ processConstantPool(pool);
+ VisitorImpl visitor = new VisitorImpl(pool, this, d, task.getLocation());
+ DescendingVisitor desc = new DescendingVisitor(javaClass, visitor);
+ desc.visit();
+ } catch(BuildException e) {
+ log(Design.getWrapperMsg(originalClassOrJarFile, e.getMessage()), Project.MSG_ERR);
+ designErrors.addElement(e);
+ }
+ }
+
+ private void processConstantPool(ConstantPool pool) {
+ Constant[] constants = pool.getConstantPool();
+ if(constants == null) {
+ log(" constants=null", Project.MSG_VERBOSE);
+ return;
+ }
+
+ log(" constants len="+constants.length, Project.MSG_VERBOSE);
+ for(int i = 0; i < constants.length; i++) {
+ processConstant(pool, constants[i], i);
+ }
+ }
+
+ private void processConstant(ConstantPool pool, Constant c, int i) {
+ if(c == null) //don't know why, but constant[0] seems to be always null.
+ return;
+
+ log(" const["+i+"]="+pool.constantToString(c)+" inst="+c.getClass().getName(), Project.MSG_DEBUG);
+ byte tag = c.getTag();
+ switch(tag) {
+ //reverse engineered from ConstantPool.constantToString..
+ case Constants.CONSTANT_Class:
+ int ind = ((ConstantClass)c).getNameIndex();
+ c = pool.getConstant(ind, Constants.CONSTANT_Utf8);
+ String className = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false);
+ log(" classNamePre="+className, Project.MSG_DEBUG);
+ className = getRidOfArray(className);
+ String firstLetter = className.charAt(0)+"";
+ if(primitives.contains(firstLetter))
+ return;
+ log(" className="+className, Project.MSG_VERBOSE);
+ design.checkClass(className);
+ break;
+ default:
+
+ }
+ }
+
+ private static String getRidOfArray(String className) {
+ while(className.startsWith("["))
+ className = className.substring(1, className.length());
+ return className;
+ }
+
+ public static String getPackageName(String className) {
+ String packageName = Package.DEFAULT;
+ int index = className.lastIndexOf(".");
+ if(index > 0)
+ packageName = className.substring(0, index);
+ //DEANDO: test the else scenario here(it is a corner case)...
+
+ return packageName;
+ }
+
+ public void log(String msg, int level) {
+ //if(level == Project.MSG_WARN || level == Project.MSG_INFO
+ // || level == Project.MSG_ERR || level == Project.MSG_VERBOSE)
+ //VerifyDesignTest.log(msg);
+ task.log(msg, level);
+ }
+}
|