summaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java')
-rw-r--r--src/java/net/sf/antcontrib/design/Design.java588
-rw-r--r--src/java/net/sf/antcontrib/design/Package.java125
-rw-r--r--src/java/net/sf/antcontrib/design/VerifyDesignDelegate.java850
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&gt;Preferences&gt;Java&gt;Code Generation&gt;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);
+ }
+}