/* * 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); } //only put unused errors if there are no other errors //this is because you end up with false unused errors if you don't do this. if(designErrors.isEmpty()) 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 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); } }