From 523a67f3ba7be687e152b31e81c7f0697ebb5d6e Mon Sep 17 00:00:00 2001 From: Stephane Bailliez Date: Tue, 31 Jul 2001 08:40:13 +0000 Subject: [PATCH] JProbe Coverage tasks: covmerge, covreport, coverage git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269413 13f79535-47bb-0310-9956-ffa450edef68 --- .../taskdefs/optional/sitraka/CovMerge.java | 227 +++++++ .../taskdefs/optional/sitraka/CovReport.java | 386 ++++++++++++ .../taskdefs/optional/sitraka/Coverage.java | 461 ++++++++++++++ .../taskdefs/optional/sitraka/Filters.java | 143 +++++ .../optional/sitraka/ReportFilters.java | 165 +++++ .../ant/taskdefs/optional/sitraka/Socket.java | 85 +++ .../taskdefs/optional/sitraka/StringUtil.java | 84 +++ .../taskdefs/optional/sitraka/Triggers.java | 147 +++++ .../taskdefs/optional/sitraka/XMLReport.java | 573 ++++++++++++++++++ .../optional/sitraka/bytecode/ClassFile.java | 200 ++++++ .../sitraka/bytecode/ClassPathLoader.java | 351 +++++++++++ .../optional/sitraka/bytecode/FieldInfo.java | 132 ++++ .../sitraka/bytecode/FieldInfoList.java | 106 ++++ .../sitraka/bytecode/InterfaceList.java | 105 ++++ .../optional/sitraka/bytecode/MethodInfo.java | 167 +++++ .../sitraka/bytecode/MethodInfoList.java | 119 ++++ .../optional/sitraka/bytecode/Utils.java | 385 ++++++++++++ .../bytecode/attributes/AttributeInfo.java | 146 +++++ .../attributes/AttributeInfoList.java | 102 ++++ .../sitraka/bytecode/attributes/Code.java | 160 +++++ .../bytecode/attributes/ConstantValue.java | 85 +++ .../bytecode/attributes/Deprecated.java | 70 +++ .../bytecode/attributes/Exceptions.java | 71 +++ .../bytecode/attributes/InnerClasses.java | 72 +++ .../bytecode/attributes/LineNumberTable.java | 97 +++ .../attributes/LocalVariableTable.java | 105 ++++ .../bytecode/attributes/SourceDir.java | 84 +++ .../bytecode/attributes/SourceFile.java | 84 +++ .../bytecode/attributes/Synthetic.java | 70 +++ .../sitraka/bytecode/attributes/Unknown.java | 69 +++ 30 files changed, 5051 insertions(+) create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovMerge.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovReport.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Coverage.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Filters.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/ReportFilters.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Socket.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/StringUtil.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Triggers.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassPathLoader.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfo.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfoList.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/InterfaceList.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfoList.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/Utils.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfo.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfoList.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Code.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/ConstantValue.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Deprecated.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Exceptions.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/InnerClasses.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LineNumberTable.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LocalVariableTable.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceDir.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceFile.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Synthetic.java create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Unknown.java diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovMerge.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovMerge.java new file mode 100644 index 000000000..a1f0df2e9 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovMerge.java @@ -0,0 +1,227 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.*; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.CommandlineJava; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.DirectoryScanner; +import java.util.Vector; +import java.util.Random; +import java.io.File; +import java.io.FilenameFilter; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.io.IOException; + +/** + * Convenient task to run the snapshot merge utility for JProbe Coverage. + * + * @author Stephane Bailliez + */ +public class CovMerge extends Task { + + /** coverage home, it is mandatory */ + private File home = null; + + /** the name of the output snapshot */ + private File tofile = null; + + /** the filesets that will get all snapshots to merge */ + private Vector filesets = new Vector(); + + private boolean verbose; + + /** + * set the coverage home. it must point to JProbe coverage + * directories where are stored native librairies and jars + */ + public void setHome(File value) { + this.home = value; + } + + /** + * Set the output snapshot file + */ + public void setTofile(File value) { + this.tofile = value; + } + + /** run the merging in verbose mode */ + public void setVerbose(boolean flag){ + this.verbose = flag; + } + + /** add a fileset containing the snapshots to include/exclude */ + public void addFileset(FileSet fs){ + filesets.addElement(fs); + } + + //---------------- the tedious job begins here + + public CovMerge() { + } + + /** execute the jpcovmerge by providing a parameter file */ + public void execute() throws BuildException { + checkOptions(); + + File paramfile = createParamFile(); + try{ + Commandline cmdl = new Commandline(); + cmdl.setExecutable( new File(home, "jpcovmerge").getAbsolutePath() ); + if (verbose) { + cmdl.createArgument().setValue("-v"); + } + cmdl.createArgument().setValue("-jp_paramfile=" + paramfile.getAbsolutePath()); + + LogStreamHandler handler = new LogStreamHandler(this,Project.MSG_INFO,Project.MSG_WARN); + Execute exec = new Execute(handler); + log(cmdl.toString(), Project.MSG_VERBOSE); + exec.setCommandline(cmdl.getCommandline()); + + // JProbe process always return 0 so we will not be + // able to check for failure ! :-( + int exitValue = exec.execute(); + if (exitValue!=0) { + throw new BuildException("JProbe Coverage Merging failed (" + exitValue + ")"); + } + } catch (IOException e) { + throw new BuildException("Failed to run JProbe Coverage Merge: " + e); + } finally { + //@todo should be removed once switched to JDK1.2 + paramfile.delete(); + } + } + + /** check for mandatory options */ + protected void checkOptions() throws BuildException { + if (tofile == null) { + throw new BuildException("'tofile' attribute must be set."); + } + if (home == null) { + throw new BuildException("'home' attribute must be set to JProbe Coverage home directory"); + } + File jar = new File(home, "coverage.jar"); + if (!jar.exists()) { + throw new BuildException("'home' attribute is not set to Coverage home directory: " + home); + } + + } + + /** get the snapshots from the filesets */ + protected File[] getSnapshots() { + Vector v = new Vector(); + final int size = filesets.size(); + for (int i = 0; i < size; i++) { + FileSet fs = (FileSet) filesets.elementAt(i); + DirectoryScanner ds = fs.getDirectoryScanner(getProject()); + ds.scan(); + String[] f = ds.getIncludedFiles(); + for (int j = 0; j < f.length; j++) { + String pathname = f[j]; + File file = new File(ds.getBasedir(), pathname); + file = project.resolveFile(file.getPath()); + v.addElement( file ); + } + } + + File[] files = new File[v.size()]; + v.copyInto(files); + return files; + } + + + /** + * create the parameters file that contains all file to merge + * and the output filename. + */ + protected File createParamFile() throws BuildException { + File[] snapshots = getSnapshots(); + File file = createTmpFile(); + FileWriter fw = null; + try { + fw = new FileWriter(file); + PrintWriter pw = new PrintWriter(fw); + for (int i = 0; i < snapshots.length; i++) { + pw.println(snapshots[i].getAbsolutePath()); + } + // last file is the output snapshot + pw.println(project.resolveFile(tofile.getPath())); + pw.flush(); + return file; + } catch (IOException e){ + if (fw != null) { + try { + fw.close(); + } catch (IOException ignored){ + } + } + throw new BuildException("I/O error while writing to " + file, e); + } + } + + /** create a temporary file in the current dir (For JDK1.1 support) */ + protected File createTmpFile(){ + final long rand = (new Random(System.currentTimeMillis())).nextLong(); + File file = new File("jpcovmerge" + rand + ".tmp"); + return file; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovReport.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovReport.java new file mode 100644 index 000000000..248f4ffc9 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/CovReport.java @@ -0,0 +1,386 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.*; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.CommandlineJava; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.DirectoryScanner; +import java.util.Vector; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; + +import javax.xml.transform.*; +import javax.xml.transform.stream.*; +import javax.xml.transform.dom.*; +import org.w3c.dom.Document; + +import org.apache.tools.ant.taskdefs.optional.depend.*; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.*; +import java.io.*; + +/** + * Convenient task to run the snapshot merge utility for JProbe Coverage 3.0. + * + * @author Stephane Bailliez + */ +public class CovReport extends Task { +/* +jpcoverport [options] -output=file -snapshot=snapshot.jpc +jpcovreport [options] [-paramfile=file] -output= -snapshot= + + Generate a report based on the indicated snapshot + + -paramfile=file + A text file containing the report generation options. + + -format=(html|text|xml) defaults to html + The format of the generated report. + + -type=(executive|summary|detailed|verydetailed) defaults to detailed + The type of report to be generated. For -format=xml, + use -type=verydetailed to include source code lines. + + Note: A very detailed report can be VERY large. + + -percent=num Min 1 Max 101 Default 101 + An integer representing a percentage of coverage. + Only methods with test case coverage less than the + percentage are included in reports. + + -filters=string + A comma-separated list of filters in the form + .:V, where V can be I for Include or + E for Exclude. For the default package, omit . + + -filters_method=string + Optional. A comma-separated list of methods that + correspond one-to-one with the entries in -filters. + + -output=string Must be specified + The absolute path and file name for the generated + report file. + + -snapshot=string Must be specified + The absolute path and file name of the snapshot file. + + -inc_src_text=(on|off) defaults to on + Include text of the source code lines. + Only applies for -format=xml and -type=verydetailed. + + -sourcepath=string defaults to . + A semicolon-separated list of source paths. + +/* + + /** coverage home, mandatory */ + private File home = null; + + /** format of generated report, optional */ + private String format = null; + + /** the name of the output snapshot, mandatory */ + private File tofile = null; + + /** type of report, optional */ + private String type = null; + + /** threshold value for printing methods, optional */ + private Integer percent = null; + + /** comma separated list of filters (???)*/ + private String filters = null; + + /** name of the snapshot file to create report from */ + private File snapshot = null; + + /** sourcepath to use */ + private Path sourcePath = null; + + /** include the text for each line of code (xml report verydetailed)*/ + private boolean includeSource = true; + + private Path coveragePath = null; + + /** */ + private Reference reference = null; + + + /** + * Set the coverage home. it must point to JProbe coverage + * directories where are stored native libraries and jars. + */ + public void setHome(File value) { + this.home = value; + } + + public static class ReportFormat extends EnumeratedAttribute { + public String[] getValues(){ + return new String[]{"html", "text", "xml"}; + } + } + /** set the format of the report html|text|xml*/ + public void setFormat(ReportFormat value){ + this.format = value.getValue(); + } + + public static class ReportType extends EnumeratedAttribute { + public String[] getValues(){ + return new String[]{"executive", "summary", "detailed", "verydetailed"}; + } + } + /** sets the report type executive|summary|detailed|verydetailed */ + public void setType(ReportType value){ + this.type = value.getValue(); + } + + /** include source code lines. XML report only */ + public void setIncludesource(boolean value){ + this.includeSource = value; + } + + /** sets the threshold printing method 0-100*/ + public void setPercent(Integer value){ + this.percent = value; + } + + /** set the filters */ + public void setFilters(String values){ + this.filters = values; + } + + public Path createSourcepath(){ + if (sourcePath == null) { + sourcePath = new Path(project); + } + return sourcePath.createPath(); + } + + public void setSnapshot(File value){ + this.snapshot = value; + } + + /** + * Set the output snapshot file + */ + public void setTofile(File value) { + this.tofile = value; + } + + //@todo to remove + public Path createCoveragepath(){ + if (coveragePath == null) { + coveragePath = new Path(project); + } + return coveragePath.createPath(); + } + + public Reference createReference(){ + if (reference == null){ + reference = new Reference(); + } + return reference; + } + + + public CovReport() { + } + + /** check for mandatory options */ + protected void checkOptions() throws BuildException { + if (tofile == null) { + throw new BuildException("'tofile' attribute must be set."); + } + if (snapshot == null) { + throw new BuildException("'snapshot' attribute must be set."); + } + if (home == null) { + throw new BuildException("'home' attribute must be set to JProbe home directory"); + } + home = new File(home,"Coverage"); + File jar = new File(home, "coverage.jar"); + if (!jar.exists()) { + throw new BuildException("Cannot find Coverage directory: " + home); + } + if (reference != null && !"xml".equals(format)){ + log("Ignored reference. It cannot be used in non XML report."); + reference = null; // nullify it so that there is no ambiguity + } + + } + + public void execute() throws BuildException { + checkOptions(); + try { + Commandline cmdl = new Commandline(); + // we need to run Coverage from his directory due to dll/jar issues + cmdl.setExecutable( new File(home, "jpcovreport").getAbsolutePath() ); + String[] params = getParameters(); + for (int i = 0; i < params.length; i++) { + cmdl.createArgument().setValue(params[i]); + } + + // use the custom handler for stdin issues + LogStreamHandler handler = new LogStreamHandler(this,Project.MSG_INFO,Project.MSG_WARN); + Execute exec = new Execute( handler ); + log(cmdl.toString(), Project.MSG_VERBOSE); + exec.setCommandline(cmdl.getCommandline()); + int exitValue = exec.execute(); + if (exitValue != 0) { + throw new BuildException("JProbe Coverage Report failed (" + exitValue + ")"); + } + log("coveragePath: " + coveragePath, Project.MSG_VERBOSE); + log("format: " + format, Project.MSG_VERBOSE); + if (reference != null && "xml".equals(format)){ + reference.createEnhancedXMLReport(); + } + + } catch (IOException e){ + throw new BuildException("Failed to execute JProbe Coverage Report.", e); + } + } + + + protected String[] getParameters(){ + Vector v = new Vector(); + if (format != null) { + v.addElement("-format=" + format); + } + if (type != null) { + v.addElement("-type=" + type); + } + if (percent != null) { + v.addElement("-percent=" + percent); + } + if (filters != null) { + v.addElement("-filters=" + filters); + } + v.addElement("-output=" + project.resolveFile(tofile.getPath())); + v.addElement("-snapshot=" + project.resolveFile(snapshot.getPath())); + // as a default -sourcepath use . in JProbe, so use project . + if (sourcePath == null) { + sourcePath = new Path(project); + sourcePath.createPath().setLocation(project.resolveFile(".")); + } + v.addElement("-sourcepath=" + sourcePath); + + if ("verydetailed".equalsIgnoreCase(format) && "xml".equalsIgnoreCase(type)) { + v.addElement("-inc_src_text=" + (includeSource ? "on" : "off")); + } + + String[] params = new String[v.size()]; + v.copyInto(params); + return params; + } + + + public class Reference { + protected Path classPath; + protected ReportFilters filters; + public Path createClasspath(){ + if (classPath == null) { + classPath = new Path(project); + } + return classPath.createPath(); + } + public ReportFilters createFilters(){ + if (filters == null){ + filters = new ReportFilters(); + } + return filters; + } + protected void createEnhancedXMLReport() throws BuildException { + // we need a classpath element + if (classPath == null){ + throw new BuildException("Need a 'classpath' element."); + } + // and a valid one... + String[] paths = classPath.list(); + if (paths.length == 0){ + throw new BuildException("Coverage path is invalid. It does not contain any existing path."); + } + // and we need at least one filter include/exclude. + if (filters == null || filters.size() == 0){ + createFilters(); + log("Adding default include filter to *.*()", Project.MSG_VERBOSE); + ReportFilters.Include include = new ReportFilters.Include(); + filters.addInclude( include ); + } + try { + log("Creating enhanced XML report", Project.MSG_VERBOSE); + XMLReport report = new XMLReport(CovReport.this, tofile); + report.setReportFilters(filters); + report.setJProbehome( new File(home.getParent()) ); + Document doc = report.createDocument(paths); + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + Source src = new DOMSource(doc); + Result res = new StreamResult( "file:///" + tofile.toString() ); + transformer.transform(src, res); + } catch (Exception e){ + throw new BuildException("Error while performing enhanced XML report from file " + tofile, e); + } + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Coverage.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Coverage.java new file mode 100644 index 000000000..7b7e74dcf --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Coverage.java @@ -0,0 +1,461 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.FileWriter; +import java.io.File; +import java.io.OutputStream; +import java.io.IOException; +import java.util.Vector; +import java.util.Random; +import java.util.Hashtable; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.CommandlineJava; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.taskdefs.Execute; +import org.apache.tools.ant.taskdefs.LogStreamHandler; + +/** + * Convenient task to run Sitraka JProbe Coverage from Ant. + * Options are pretty numerous, you'd better check the manual for a full + * descriptions of options. (not that simple since they differ from the online + * help, from the usage command line and from the examples...) + *

+ * For additional information, visit www.sitraka.com + * + * @author Stephane Bailliez + */ +public class Coverage extends Task { + + protected File home; + + protected Commandline cmdl = new Commandline(); + + protected CommandlineJava cmdlJava = new CommandlineJava(); + + protected String function = "coverage"; + + protected String seedName; + + protected File inputFile; + + protected File javaExe; + + protected String vm; + + protected boolean applet = false; + + /** this is a somewhat annoying thing, set it to never */ + protected String exitPrompt = "never"; + + protected Filters filters = new Filters(); + + protected Triggers triggers; + + protected String finalSnapshot = "coverage"; + + protected String recordFromStart = "coverage"; + + protected File snapshotDir; + + protected File workingDir; + + protected boolean trackNatives = false; + + protected Socket socket; + + protected int warnLevel = 0; + + protected Vector filesets = new Vector(); + + //--------- setters used via reflection -- + + /** set the coverage home directory where are libraries, jars and jplauncher */ + public void setHome(File value){ + home = value; + } + + /** seed name for snapshot file. can be null, default to snap */ + public void setSeedname(String value){ + seedName = value; + } + + public void setInputfile(File value){ + inputFile = value; + } + + public void setJavaexe(File value){ + javaExe = value; + } + + public static class Javavm extends EnumeratedAttribute { + public String[] getValues(){ + return new String[]{"java2", "jdk118", "jdk117"}; + } + } + /** jdk117, jdk118 or java2, can be null, default to java2 */ + public void setVm(Javavm value) { + vm = value.getValue(); + } + + /** default to false unless file is htm or html */ + public void setApplet(boolean value){ + applet = value; + } + + /** always, error, never */ + public void setExitprompt(String value){ + exitPrompt = value; + } + + public Filters createFilters(){ + return filters; + } + + public Triggers createTriggers(){ + if (triggers == null) { + triggers = new Triggers(); + } + return triggers; + } + + public Socket createSocket(){ + if (socket == null ) { + socket = new Socket(); + } + return socket; + } + + public static class Finalsnapshot extends EnumeratedAttribute { + public String[] getValues(){ + return new String[]{"coverage", "none", "all"}; + } + } + + /** none, coverage, all. can be null, default to none */ + public void setFinalsnapshot(String value){ + finalSnapshot = value; + } + + public static class Recordfromstart extends EnumeratedAttribute { + public String[] getValues(){ + return new String[]{"coverage", "none", "all"}; + } + } + /** all, coverage, none */ + public void setRecordfromstart(Recordfromstart value) { + recordFromStart = value.getValue(); + } + + public void setWarnlevel(Integer value){ + warnLevel = value.intValue(); + } + + public void setSnapshotdir(File value){ + snapshotDir = value; + } + + public void setWorkingdir(File value){ + workingDir = value; + } + + public void setTracknatives(boolean value){ + trackNatives = value; + } + + // + + /** the jvm arguments */ + public Commandline.Argument createJvmarg() { + return cmdlJava.createVmArgument(); + } + + /** the command arguments */ + public Commandline.Argument createArg() { + return cmdlJava.createArgument(); + } + + /** classpath to run the files */ + public Path createClasspath() { + return cmdlJava.createClasspath(project).createPath(); + } + + /** classname to run as standalone or runner for filesets */ + public void setClassname(String value){ + cmdlJava.setClassname(value); + } + + /** the classnames to execute */ + public void addFileset(FileSet fs){ + filesets.addElement(fs); + } + + + //---------------- the tedious job begins here + + public Coverage(){ + } + + /** execute the jplauncher by providing a parameter file */ + public void execute() throws BuildException { + File paramfile = null; + // if an input file is used, all other options are ignored... + if (inputFile == null){ + checkOptions(); + paramfile = createParamFile(); + } else { + paramfile = inputFile; + } + try { + // we need to run Coverage from his directory due to dll/jar issues + cmdl.setExecutable( new File(home, "jplauncher").getAbsolutePath() ); + cmdl.createArgument().setValue("-jp_input=" + paramfile.getAbsolutePath()); + + // use the custom handler for stdin issues + LogStreamHandler handler = new CoverageStreamHandler(this); + Execute exec = new Execute( handler ); + log(cmdl.toString(), Project.MSG_VERBOSE); + exec.setCommandline(cmdl.getCommandline()); + int exitValue = exec.execute(); + if (exitValue != 0) { + throw new BuildException("JProbe Coverage failed (" + exitValue + ")"); + } + } catch (IOException e){ + throw new BuildException("Failed to execute JProbe Coverage.", e); + } finally { + //@todo should be removed once switched to JDK1.2 + if (inputFile == null && paramfile != null){ + paramfile.delete(); + } + } + } + + /** wheck what is necessary to check, Coverage will do the job for us */ + protected void checkOptions() throws BuildException { + // check coverage home + if (home == null || !home.isDirectory() ) { + throw new BuildException("Invalid home directory. Must point to JProbe home directory"); + } + home = new File(home,"Coverage"); + File jar = new File(home, "coverage.jar"); + if (!jar.exists()) { + throw new BuildException("Cannot find Coverage directory: " + home); + } + + // make sure snapshot dir exists and is resolved + if (snapshotDir == null) { + snapshotDir = new File("."); + } + snapshotDir = project.resolveFile(snapshotDir.getPath()); + if (!snapshotDir.isDirectory() || !snapshotDir.exists()) { + throw new BuildException("Snapshot directory does not exists :" + snapshotDir); + } + if (workingDir == null) { + workingDir = new File("."); + } + workingDir = project.resolveFile(workingDir.getPath()); + + // check for info, do your best to select the java executable. + // JProbe 3.0 fails if there is no javaexe option. So + if (javaExe == null && ( vm == null || "java2".equals(vm) ) ) { + String version = System.getProperty("java.version"); + // make we are using 1.2+, if it is, then do your best to + // get a javaexe + if ( !version.startsWith("1.1") ){ + if (vm == null){ + vm = "java2"; + } + // if we are here obviously it is java2 + String home = System.getProperty("java.home"); + boolean isUnix = File.separatorChar == '/'; + javaExe = isUnix ? new File(home, "bin/java") : new File(home,"/bin/java.exe"); + } + } + } + + /** + * return the command line parameters. Parameters can either be passed + * to the command line and stored to a file (then use the -jp_input=) + * if they are too numerous. + */ + protected String[] getParameters(){ + Vector params = new Vector(); + params.addElement("-jp_function=" + function); + if (vm != null) { + params.addElement("-jp_vm=" + vm); + } + if (javaExe != null) { + params.addElement("-jp_java_exe=" + project.resolveFile(javaExe.getPath())); + } + params.addElement("-jp_working_dir=" + workingDir.getPath() ); + params.addElement("-jp_snapshot_dir=" + snapshotDir.getPath() ); + params.addElement("-jp_record_from_start=" + recordFromStart); + params.addElement("-jp_warn=" + warnLevel); + if (seedName != null) { + params.addElement("-jp_output_file=" + seedName); + } + params.addElement("-jp_filter=" + filters.toString() ); + if (triggers != null) { + params.addElement("-jp_trigger=" + triggers.toString() ); + } + if (finalSnapshot != null) { + params.addElement("-jp_final_snapshot=" + finalSnapshot); + } + params.addElement("-jp_exit_prompt=" + exitPrompt); + //params.addElement("-jp_append=" + append); + params.addElement("-jp_track_natives=" + trackNatives); + //.... now the jvm + // arguments + String[] vmargs = cmdlJava.getVmCommand().getArguments(); + for (int i = 0; i < vmargs.length; i++) { + params.addElement(vmargs[i]); + } + // classpath + Path classpath = cmdlJava.getClasspath(); + if (classpath != null && classpath.size() > 0) { + params.addElement("-classpath " + classpath.toString()); + } + // classname (runner or standalone) + if (cmdlJava.getClassname() != null) { + params.addElement(cmdlJava.getClassname()); + } + // arguments for classname + String[] args = cmdlJava.getJavaCommand().getArguments(); + for (int i = 0; i < args.length; i++) { + params.addElement(args[i]); + } + + String[] array = new String[params.size()]; + params.copyInto(array); + return array; + } + + + /** + * create the parameter file from the given options. The file is + * created with a random name in the current directory. + * @return the file object where are written the configuration to run + * JProbe Coverage + * @throws BuildException thrown if something bad happens while writing + * the arguments to the file. + */ + protected File createParamFile() throws BuildException { + //@todo change this when switching to JDK 1.2 and use File.createTmpFile() + File file = createTmpFile(); + log("Creating parameter file: " + file, Project.MSG_VERBOSE); + + // options need to be one per line in the parameter file + // so write them all in a single string + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + String[] params = getParameters(); + for (int i = 0; i < params.length; i++){ + pw.println(params[i]); + } + pw.flush(); + log("JProbe Coverage parameters:\n" + sw.toString(), Project.MSG_VERBOSE); + + // now write them to the file + FileWriter fw = null; + try { + fw = new FileWriter(file); + fw.write(sw.toString()); + fw.flush(); + } catch (IOException e){ + throw new BuildException("Could not write parameter file " + file, e); + } finally { + if (fw != null) { + try { + fw.close(); + } catch (IOException ignored){} + } + } + return file; + } + + /** create a temporary file in the current dir (For JDK1.1 support) */ + protected File createTmpFile(){ + final long rand = (new Random(System.currentTimeMillis())).nextLong(); + File file = new File("jpcoverage" + rand + ".tmp"); + return file; + } + + /** specific pumper to avoid those nasty stdin issues */ + static class CoverageStreamHandler extends LogStreamHandler { + CoverageStreamHandler(Task task){ + super(task, Project.MSG_INFO, Project.MSG_WARN); + } + /** + * there are some issues concerning all JProbe executable + * In our case a 'Press ENTER to close this window..." will + * be displayed in the current window waiting for enter. + * So I'm closing the stream right away to avoid problems. + */ + public void setProcessInputStream(OutputStream os) { + try { + os.close(); + } catch (IOException ignored){ + } + } + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Filters.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Filters.java new file mode 100644 index 000000000..fd2eae1c3 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Filters.java @@ -0,0 +1,143 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import java.util.Vector; + +/** + * Filters information from coverage, somewhat similar to a FileSet. + * + * @author Stephane Bailliez + */ +public class Filters { + + /** default regexp to exclude everything */ + public final static String DEFAULT_EXCLUDE = "*.*():E"; + + /** say whether we should use the default excludes or not */ + protected boolean defaultExclude = true; + + /** user defined filters */ + protected Vector filters = new Vector(); + + public Filters(){ + } + + public void setDefaultExclude(boolean value){ + defaultExclude = value; + } + + public void addInclude(Include incl){ + filters.addElement(incl); + } + + public void addExclude(Exclude excl){ + filters.addElement(excl); + } + + public String toString(){ + StringBuffer buf = new StringBuffer(); + final int size = filters.size(); + if (defaultExclude) { + buf.append(DEFAULT_EXCLUDE); + if (size > 0) { + buf.append(','); + } + } + for (int i = 0; i < size; i++) { + buf.append(filters.elementAt(i).toString()); + if ( i < size - 1) { + buf.append(','); + } + } + return buf.toString(); + } + + public static abstract class FilterElement { + protected String clazz; + protected String method = "*"; // default is all methods + protected boolean enabled = true; // default is enable + public void setName(String value){ // this one is deprecated. + clazz = value; + } + public void setClass(String value){ + clazz = value; + } + public void setMethod(String value){ + method = value; + } + public void setEnabled(boolean value){ + enabled = value; + } + public String toString(){ + return clazz + "." + method + "()"; + } + } + + public static class Include extends FilterElement { + public String toString(){ + return super.toString() + ":I" + (enabled ? "" : "#"); + } + } + + public static class Exclude extends FilterElement { + public String toString() { + return super.toString() + ":E" + (enabled ? "" : "#"); + } + } +} + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/ReportFilters.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/ReportFilters.java new file mode 100644 index 000000000..4ded331fe --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/ReportFilters.java @@ -0,0 +1,165 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import java.util.Vector; +import java.util.Enumeration; +import org.apache.tools.ant.util.regexp.*; + +/** + * Filters information from coverage, somewhat similar to a FileSet. + * + * @author Stephane Bailliez + */ +public class ReportFilters { + + /** user defined filters */ + protected Vector filters = new Vector(); + + /** cached matcher for each filter */ + protected Vector matchers = null; + + public ReportFilters(){ + } + + public void addInclude(Include incl){ + filters.addElement(incl); + } + + public void addExclude(Exclude excl){ + filters.addElement(excl); + } + + public int size(){ + return filters.size(); + } + + /** + * Check whether a given <classname><method>() is accepted by the list + * of filters or not. + * @param methodname the full method name in the format <classname><method>() + */ + public boolean accept(String methodname){ + // I'm deferring matcher instantiations at runtime to avoid computing + // the filters at parsing time + if (matchers == null){ + createMatchers(); + } + boolean result = false; + // assert filters.size() == matchers.size() + final int size = filters.size(); + for (int i = 0; i < size; i++){ + FilterElement filter = (FilterElement)filters.elementAt(i); + RegexpMatcher matcher = (RegexpMatcher)matchers.elementAt(i); + if (filter instanceof Include){ + result = result || matcher.matches(methodname); + } else if (filter instanceof Exclude){ + result = result && !matcher.matches(methodname); + } else{ + //not possible + throw new IllegalArgumentException("Invalid filter element: " + filter.getClass().getName()); + } + } + return result; + } + + /** should be called only once to cache matchers */ + protected void createMatchers(){ + RegexpMatcherFactory factory = new RegexpMatcherFactory(); + final int size = filters.size(); + matchers = new Vector(); + for (int i = 0; i < size; i++){ + FilterElement filter = (FilterElement)filters.elementAt(i); + RegexpMatcher matcher = factory.newRegexpMatcher(); + String pattern = filter.getAsPattern(); + matcher.setPattern(pattern); + matchers.addElement(matcher); + } + } + + + /** default abstract filter element class */ + public static abstract class FilterElement { + protected String clazz = "*"; // default is all classes + protected String method = "*"; // default is all methods + + public void setClass(String value){ + clazz = value; + } + public void setMethod(String value){ + method = value; + } + + public String getAsPattern(){ + StringBuffer buf = new StringBuffer(toString()); + StringUtil.replace(buf, ".", "\\."); + StringUtil.replace(buf, "*", ".*"); + StringUtil.replace(buf, "(", "\\("); + StringUtil.replace(buf, ")", "\\)"); + return buf.toString(); + } + + public String toString(){ + return clazz + "." + method + "()"; + } + } + + /** concrete include class */ + public static class Include extends FilterElement {} + + /** concrete exclude class */ + public static class Exclude extends FilterElement {} +} + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Socket.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Socket.java new file mode 100644 index 000000000..4478dfd05 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Socket.java @@ -0,0 +1,85 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka; + +/** + * Socket element for connection. + * <socket/> defaults to host 127.0.0.1 and port 4444 + * + * Otherwise it requires the host and port attributes to be set: + * + * <socket host="e;175.30.12.1"e; port="e;4567"e;/> + * + */ +public class Socket { + + /** default to localhost */ + private String host = "127.0.0.1"; + + /** default to 4444 */ + private int port = 4444; + + public void setHost(String value){ + host = value; + } + + public void setPort(Integer value){ + port = value.intValue(); + } + + /** if no host is set, returning ':', will take localhost */ + public String toString(){ + return host + ":" + port; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/StringUtil.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/StringUtil.java new file mode 100644 index 000000000..c8d73b90a --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/StringUtil.java @@ -0,0 +1,84 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka; + +/** + * String utilities method. + * @author Stephane Bailliez + */ +public final class StringUtil { + /** private constructor, it's a utility class */ + private StringUtil() { + } + + /** + * Replaces all occurences of find with replacement in the + * source StringBuffer. + * @param src the original string buffer to modify. + * @param find the string to be replaced. + * @param replacement the replacement string for find matches. + */ + public static void replace(StringBuffer src, String find, String replacement){ + int index = 0; + while (index < src.length() ){ + index = src.toString().indexOf(find, index); + if (index == -1){ + break; + } + src.delete(index, index + find.length()); + src.insert(index, replacement); + index += replacement.length() + 1; + } + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Triggers.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Triggers.java new file mode 100644 index 000000000..69fa2a254 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/Triggers.java @@ -0,0 +1,147 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import java.util.Vector; +import java.util.Hashtable; +import org.apache.tools.ant.BuildException; + +/** + * Trigger information. It will return as a command line argument by calling + * the toString() method. + * + * @author Stephane Bailliez + */ +public class Triggers { + + protected Vector triggers = new Vector(); + + public Triggers(){ + } + + public void addMethod(Method method){ + triggers.addElement(method); + } + + // -jp_trigger=ClassName.*():E:S,ClassName.MethodName():X:X + public String toString(){ + StringBuffer buf = new StringBuffer(); + final int size = triggers.size(); + for(int i = 0; i < size; i++) { + buf.append( triggers.elementAt(i).toString() ); + if (i < size - 1) { + buf.append(','); + } + } + return buf.toString(); + } + + + public static class Method { + protected String name; + protected String event; + protected String action; + protected String param; + public void setName(String value){ + name = value; + } + public void setEvent(String value){ + if (eventMap.get(value) == null) { + throw new BuildException("Invalid event, must be one of " + eventMap); + } + event = value; + } + public void setAction(String value) throws BuildException { + if (actionMap.get(value) == null) { + throw new BuildException("Invalid action, must be one of " + actionMap); + } + action = value; + } + public void setParam(String value){ + param = value; + } + + // return ::[:param] + public String toString(){ + StringBuffer buf = new StringBuffer(); + buf.append(name).append(":"); //@todo name must not be null, check for it + buf.append(eventMap.get(event)).append(":"); + buf.append(actionMap.get(action)); + if (param != null) { + buf.append(":").append(param); + } + return buf.toString(); + } + } + + /** mapping of actions to cryptic command line mnemonics */ + private final static Hashtable actionMap = new Hashtable(3); + + /** mapping of events to cryptic command line mnemonics */ + private final static Hashtable eventMap = new Hashtable(3); + + static { + actionMap.put("enter", "E"); + actionMap.put("exit", "X"); + // clear|pause|resume|snapshot|suspend|exit + eventMap.put("clear", "C"); + eventMap.put("pause", "P"); + eventMap.put("resume", "R"); + eventMap.put("snapshot", "S"); + eventMap.put("suspend", "A"); + eventMap.put("exit", "X"); + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java new file mode 100644 index 000000000..416eb56e7 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/XMLReport.java @@ -0,0 +1,573 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.*; +import javax.xml.transform.dom.*; +import javax.xml.transform.stream.*; + +import org.w3c.dom.*; +import org.xml.sax.*; +import java.io.*; +import java.util.*; +import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.*; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.Project; + +/** + * Little hack to process XML report from JProbe. It will fix + * some reporting errors from JProbe 3.0 and makes use of a reference + * classpath to add classes/methods that were not reported by JProbe + * as being used (ie loaded) + * + * @author Stephane Bailliez + */ +public class XMLReport { + /** task caller, can be null, used for logging purpose */ + protected Task task; + + /** the XML file to process just from CovReport */ + protected File file; + + /** jprobe home path. It is used to get the DTD */ + protected File jprobeHome; + + /** parsed document */ + protected Document report; + + /** mapping package name / package node for faster access */ + protected Hashtable pkgMap; + + /** mapping classname / class node for faster access */ + protected Hashtable classMap; + + /** method filters */ + protected ReportFilters filters; + + /** create a new XML report, logging will be on stdout */ + public XMLReport(File file){ + this(null, file); + } + + /** create a new XML report, logging done on the task */ + public XMLReport(Task task, File file){ + this.file = file; + this.task = task; + } + + /** set the JProbe home path. Used to get the DTD */ + public void setJProbehome(File home){ + jprobeHome = home; + } + + /** set the */ + public void setReportFilters(ReportFilters filters){ + this.filters = filters; + } + + + + /** create node maps so that we can access node faster by their name */ + protected void createNodeMaps(){ + pkgMap = new Hashtable(); + classMap = new Hashtable(); + // create a map index of all packages by their name + // @todo can be done faster by direct access. + NodeList packages = report.getElementsByTagName("package"); + final int pkglen = packages.getLength(); + log("Indexing " + pkglen + " packages"); + for (int i = pkglen-1; i > -1 ; i--){ + Element pkg = (Element)packages.item(i); + String pkgname = pkg.getAttribute("name"); + + int nbclasses = 0; + // create a map index of all classes by their fully + // qualified name. + NodeList classes = pkg.getElementsByTagName("class"); + final int classlen = classes.getLength(); + log("Indexing " + classlen + " classes in package " + pkgname); + for (int j = classlen-1; j > -1 ; j--){ + Element clazz = (Element)classes.item(j); + String classname = clazz.getAttribute("name"); + if (pkgname != null && pkgname.length() != 0){ + classname = pkgname + "." + classname; + } + + int nbmethods = 0; + NodeList methods = clazz.getElementsByTagName("method"); + final int methodlen = methods.getLength(); + for (int k = methodlen-1; k > -1; k--){ + Element meth = (Element)methods.item(k); + StringBuffer methodname = new StringBuffer(meth.getAttribute("name")); + methodname.delete(methodname.toString().indexOf("(") , methodname.toString().length()); + String signature = classname + "." + methodname + "()"; + if (filters.accept(signature)){ + log("keeped method:" + signature); + nbmethods++; + } + else { + clazz.removeChild(meth); + } + } + // if we don't keep any method, we don't keep the class + if (nbmethods != 0){ + log("Adding class '" + classname + "'"); + classMap.put(classname, clazz); + nbclasses++; + } + else { + pkg.removeChild(clazz); + } + } + if (nbclasses != 0){ + log("Adding package '" + pkgname + "'"); + pkgMap.put(pkgname, pkg); + } + else { + pkg.getParentNode().removeChild(pkg); + } + } + log("Indexed " + classMap.size() + " classes in " + pkgMap.size() + " packages"); + } + + /** create the whole new document */ + public Document createDocument(String[] classPath) throws Exception { + + DocumentBuilder dbuilder = newBuilder(); + InputSource is = new InputSource( new FileInputStream(file) ); + if (jprobeHome != null){ + File dtdDir = new File(jprobeHome, "Dtd/snapshot.dtd"); + is.setSystemId( "file:///" + dtdDir.getAbsolutePath() ); + } + report = dbuilder.parse( is ); + report.normalize(); + + // create maps for faster node access + createNodeMaps(); + + // iterate over the classpath... + ClassPathLoader cpl = new ClassPathLoader(classPath); + Enumeration enum = cpl.loaders(); + while ( enum.hasMoreElements() ){ + ClassPathLoader.FileLoader fl = (ClassPathLoader.FileLoader)enum.nextElement(); + ClassFile[] classes = fl.getClasses(); + log("Processing " + classes.length + " classes in " + fl.getFile()); + // process all classes + for (int i = 0; i < classes.length; i++){ + serializeClass(classes[i]); + } + } + // update the document with the stats + update(); + return report; + } + + /** + * JProbe does not put the java.lang prefix for classes + * in this package, so used this nice method so that + * I have the same signature for methods + */ + protected String getMethodSignature(MethodInfo method){ + StringBuffer buf = new StringBuffer(method.getName()); + buf.append("("); + String[] params = method.getParametersType(); + for (int i = 0; i < params.length; i++){ + String type = params[i]; + int pos = type.lastIndexOf('.'); + if (pos != -1){ + String pkg = type.substring(0, pos); + if ("java.lang".equals(pkg)){ + params[i] = type.substring(pos + 1); + } + } + buf.append(params[i]); + if (i != params.length - 1){ + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + /** + * Convert to a CovReport-like signature ie, .() + */ + protected String getMethodSignature(ClassFile clazz, MethodInfo method){ + StringBuffer buf = new StringBuffer(clazz.getFullName()); + buf.append("."); + buf.append(method.getName()); + buf.append("()"); + return buf.toString(); + } + + /** + * Do additional work on an element to remove abstract methods that + * are reported by JProbe 3.0 + */ + protected void removeAbstractMethods(ClassFile classFile, Element classNode){ + MethodInfoList methods = classFile.getMethods(); + Hashtable methodNodeList = getMethods(classNode); + // assert xmlMethods.size() == methods.length() + final int size = methods.length(); + for (int i = 0; i < size; i++){ + MethodInfo method = methods.getMethod(i); + String methodSig = getMethodSignature(method); + Element methodNode = (Element)methodNodeList.get(methodSig); + if ( methodNode != null && + Utils.isAbstract(method.getAccessFlags())) { + log("\tRemoving method " + methodSig); + classNode.removeChild(methodNode); + } + } + } + + /** create an empty method element with its cov.data values */ + protected Element createMethodElement(MethodInfo method){ + String methodsig = getMethodSignature(method); + Element methodElem = report.createElement("method"); + methodElem.setAttribute("name", methodsig); + // create the method cov.data element + Element methodData = report.createElement("cov.data"); + methodElem.appendChild(methodData); + methodData.setAttribute("calls", "0"); + methodData.setAttribute("hit_lines", "0"); + methodData.setAttribute("total_lines", String.valueOf(method.getNumberOfLines())); + return methodElem; + } + + /** create an empty package element with its default cov.data (0) */ + protected Element createPackageElement(String pkgname){ + Element pkgElem = report.createElement("package"); + pkgElem.setAttribute("name", pkgname); + // create the package cov.data element / default + // must be updated at the end of the whole process + Element pkgData = report.createElement("cov.data"); + pkgElem.appendChild(pkgData); + pkgData.setAttribute("calls", "0"); + pkgData.setAttribute("hit_methods", "0"); + pkgData.setAttribute("total_methods", "0"); + pkgData.setAttribute("hit_lines", "0"); + pkgData.setAttribute("total_lines", "0"); + return pkgElem; + } + + /** create an empty class element with its default cov.data (0) */ + protected Element createClassElement(ClassFile classFile){ + // create the class element + Element classElem = report.createElement("class"); + classElem.setAttribute("name", classFile.getName()); + classElem.setAttribute("source", classFile.getSourceFile()); + // create the cov.data elem + Element classData = report.createElement("cov.data"); + classElem.appendChild(classData); + // create the class cov.data element + classData.setAttribute("calls", "0"); + classData.setAttribute("hit_methods", "0"); + classData.setAttribute("total_methods", "0"); + classData.setAttribute("hit_lines", "0"); + classData.setAttribute("total_lines", "0"); + return classElem; + } + + /** serialize a classfile into XML */ + protected void serializeClass(ClassFile classFile){ + // the class already is reported so ignore it + String fullclassname = classFile.getFullName(); + log("Looking for '" + fullclassname + "'"); + Element clazz = (Element)classMap.get(fullclassname); + + // ignore classes that are already reported, all the information is + // already there. + if ( clazz != null ){ + log("Ignoring " + fullclassname); + removeAbstractMethods(classFile, clazz); + return; + } + + // ignore interfaces files, there is no code in there to cover. + if (Utils.isInterface(classFile.getAccess())){ + return; + } + + Vector methods = getFilteredMethods(classFile); + // no need to process, there are no methods to add for this class. + if (methods.size() == 0){ + return; + } + + String pkgname = classFile.getPackage(); + // System.out.println("Looking for package " + pkgname); + Element pkgElem = (Element)pkgMap.get(pkgname); + if (pkgElem == null){ + pkgElem = createPackageElement(pkgname); + report.getDocumentElement().appendChild(pkgElem); + pkgMap.put(pkgname, pkgElem); // add the pkg to the map + } + // this is a brand new class, so we have to create a new node + + // create the class element + Element classElem = createClassElement(classFile); + pkgElem.appendChild(classElem); + + int total_lines = 0; + int total_methods = 0; + for (int i = 0; i < methods.size(); i++){ + // create the method element + MethodInfo method = (MethodInfo)methods.elementAt(i); + if ( Utils.isAbstract(method.getAccessFlags() ) ){ + continue; // no need to report abstract methods + } + Element methodElem = createMethodElement(method); + classElem.appendChild(methodElem); + total_lines += method.getNumberOfLines(); + total_methods++; + } + // create the class cov.data element + Element classData = getCovDataChild(classElem); + classData.setAttribute("total_methods", String.valueOf(total_methods)); + classData.setAttribute("total_lines", String.valueOf(total_lines)); + + // add itself to the node map + classMap.put(fullclassname, classElem); + } + + protected Vector getFilteredMethods(ClassFile classFile){ + Vector methods = new Vector(); + MethodInfoList methodlist = classFile.getMethods(); + for (int i = 0; i < methodlist.length(); i++){ + MethodInfo method = methodlist.getMethod(i); + String signature = getMethodSignature(classFile, method); + if (filters.accept(signature)){ + methods.addElement(method); + log("keeping " + signature); + } else { +// log("discarding " + signature); + } + } + return methods; + } + + + /** update the count of the XML, that is accumulate the stats on + * methods, classes and package so that the numbers are valid + * according to the info that was appended to the XML. + */ + protected void update(){ + int calls = 0; + int hit_methods = 0; + int total_methods = 0; + int hit_lines = 0; + int total_lines = 0; + + // use the map for access, all nodes should be there + Enumeration enum = pkgMap.elements(); + while ( enum.hasMoreElements() ){ + Element pkgElem = (Element)enum.nextElement(); + String pkgname = pkgElem.getAttribute("name"); + Element[] classes = getClasses(pkgElem); + int pkg_calls = 0; + int pkg_hit_methods = 0; + int pkg_total_methods = 0; + int pkg_hit_lines = 0; + int pkg_total_lines = 0; + //System.out.println("Processing package '" + pkgname + "': " + classes.length + " classes"); + for (int j = 0; j < classes.length; j++){ + Element clazz = classes[j]; + String classname = clazz.getAttribute("name"); + if (pkgname != null && pkgname.length() != 0){ + classname = pkgname + "." + classname; + } + // there's only cov.data as a child so bet on it + Element covdata = getCovDataChild(clazz); + try { + pkg_calls += Integer.parseInt(covdata.getAttribute("calls")); + pkg_hit_methods += Integer.parseInt(covdata.getAttribute("hit_methods")); + pkg_total_methods += Integer.parseInt(covdata.getAttribute("total_methods")); + pkg_hit_lines += Integer.parseInt(covdata.getAttribute("hit_lines")); + pkg_total_lines += Integer.parseInt(covdata.getAttribute("total_lines")); + } catch (NumberFormatException e){ + System.err.println("Error parsing '" + classname + "' (" + j + "/" + classes.length + ") in package '" + pkgname + "'"); + throw e; + } + } + Element covdata = getCovDataChild(pkgElem); + covdata.setAttribute("calls", String.valueOf(pkg_calls)); + covdata.setAttribute("hit_methods", String.valueOf(pkg_hit_methods)); + covdata.setAttribute("total_methods", String.valueOf(pkg_total_methods)); + covdata.setAttribute("hit_lines", String.valueOf(pkg_hit_lines)); + covdata.setAttribute("total_lines", String.valueOf(pkg_total_lines)); + calls += pkg_calls; + hit_methods += pkg_hit_methods; + total_methods += pkg_total_methods; + hit_lines += pkg_hit_lines; + total_lines += pkg_total_lines; + } + Element covdata = getCovDataChild(report.getDocumentElement()); + covdata.setAttribute("calls", String.valueOf(calls)); + covdata.setAttribute("hit_methods", String.valueOf(hit_methods)); + covdata.setAttribute("total_methods", String.valueOf(total_methods)); + covdata.setAttribute("hit_lines", String.valueOf(hit_lines)); + covdata.setAttribute("total_lines", String.valueOf(total_lines)); + } + + protected Element getCovDataChild(Element parent){ + NodeList children = parent.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++){ + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE){ + Element elem = (Element)child; + if ("cov.data".equals(elem.getNodeName())){ + return elem; + } + } + } + throw new NoSuchElementException("Could not find 'cov.data' element in parent '" + parent.getNodeName() + "'"); + } + + protected Hashtable getMethods(Element clazz){ + Hashtable map = new Hashtable(); + NodeList children = clazz.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++){ + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE){ + Element elem = (Element)child; + if ("method".equals(elem.getNodeName())){ + String name = elem.getAttribute("name"); + map.put(name, elem); + } + } + } + return map; + } + + protected Element[] getClasses(Element pkg){ + Vector v = new Vector(); + NodeList children = pkg.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++){ + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE){ + Element elem = (Element)child; + if ("class".equals(elem.getNodeName())){ + v.addElement(elem); + } + } + } + Element[] elems = new Element[v.size()]; + v.copyInto(elems); + return elems; + + } + + protected Element[] getPackages(Element snapshot){ + Vector v = new Vector(); + NodeList children = snapshot.getChildNodes(); + int len = children.getLength(); + for (int i = 0; i < len; i++){ + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE){ + Element elem = (Element)child; + if ("package".equals(elem.getNodeName())){ + v.addElement(elem); + } + } + } + Element[] elems = new Element[v.size()]; + v.copyInto(elems); + return elems; + } + + private static DocumentBuilder newBuilder() { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(true); + factory.setValidating(false); + return factory.newDocumentBuilder(); + } catch (Exception e){ + throw new ExceptionInInitializerError(e); + } + } + + public void log(String message){ + if (task == null){ + //System.out.println(message); + } else { + task.log(message, Project.MSG_DEBUG); + } + } + + public static void main(String[] args) throws Exception { + File reportFile = new File( XMLReport.class.getResource("covreport-test.xml").getFile() ); + XMLReport report = new XMLReport( reportFile ); + report.setJProbehome(new File("d:/Program Files/JProbe")); + ReportFilters filters = new ReportFilters(); + ReportFilters.Include incl = new ReportFilters.Include(); + incl.setClass("*"); + incl.setMethod("set*"); + filters.addInclude(incl); + report.setReportFilters(filters); + Document doc = report.createDocument( new String[]{"Z:/imediation/ichannel/sources/toolkit/lib/imtoolkit.jar"} ); + TransformerFactory tfactory = TransformerFactory.newInstance(); + Transformer transformer = tfactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.transform(new DOMSource(doc), new StreamResult( new FileOutputStream( "d:/tmp/snapshot_merge.xml"))); + } + +} + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java new file mode 100644 index 000000000..4635bea73 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassFile.java @@ -0,0 +1,200 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo; +import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.*; + + +/** + * Object representing a class. + * + * @author Stephane Bailliez + */ +public class ClassFile { + + protected ConstantPool constantPool; + + protected InterfaceList interfaces; + + protected FieldInfoList fields; + + protected MethodInfoList methods; + + protected String sourceDir; + + protected String sourceFile; + + protected int access_flags; + + protected int this_class; + + protected int super_class; + + protected boolean isSynthetic; + + protected boolean isDeprecated; + + public ClassFile(InputStream is) throws IOException { + DataInputStream dis = new DataInputStream(is); + constantPool = new ConstantPool(); + + int magic = dis.readInt(); // 0xCAFEBABE + int minor = dis.readShort(); + int major = dis.readShort(); + + constantPool.read(dis); + constantPool.resolve(); + + access_flags = dis.readShort(); + this_class = dis.readShort(); + super_class = dis.readShort(); + + interfaces = new InterfaceList(constantPool); + interfaces.read(dis); + //System.out.println(interfaces.toString()); + + fields = new FieldInfoList(constantPool); + fields.read(dis); + //System.out.println(fields.toString()); + + methods = new MethodInfoList(constantPool); + methods.read(dis); + //System.out.println(methods.toString()); + + AttributeInfoList attributes = new AttributeInfoList(constantPool); + attributes.read(dis); + SourceFile srcFile = (SourceFile)attributes.getAttribute(AttributeInfo.SOURCE_FILE); + if (srcFile != null){ + sourceFile = srcFile.getValue(); + } + SourceDir srcDir = (SourceDir)attributes.getAttribute(AttributeInfo.SOURCE_DIR); + if (srcDir != null){ + sourceDir = srcDir.getValue(); + } + isSynthetic = attributes.getAttribute(AttributeInfo.SYNTHETIC) != null; + isDeprecated = attributes.getAttribute(AttributeInfo.DEPRECATED) != null; + } + + public int getAccess(){ + return access_flags; + } + public InterfaceList getInterfaces(){ + return interfaces; + } + public String getSourceFile(){ + return sourceFile; + } + public String getSourceDir(){ + return sourceDir; + } + public boolean isSynthetic() { + return isSynthetic; + } + public boolean isDeprecated() { + return isDeprecated; + } + public MethodInfoList getMethods(){ + return methods; + } + public FieldInfoList getFields(){ + return fields; + } + public String getSuperName(){ + return Utils.getUTF8Value(constantPool, super_class); + } + public String getFullName(){ + return ((ClassCPInfo)constantPool.getEntry(this_class)).getClassName().replace('/','.'); + } + public String getName(){ + String name = getFullName(); + int pos = name.lastIndexOf('.'); + if (pos == -1){ + return ""; + } + return name.substring(pos + 1); + } + public String getPackage(){ + String name = getFullName(); + int pos = name.lastIndexOf('.'); + if (pos == -1){ + return ""; + } + return name.substring(0, pos); + } + + /** dirty test method, move it into a testcase */ + public static void main(String[] args) throws Exception { + System.out.println("loading classfile..."); + InputStream is = ClassLoader.getSystemResourceAsStream("java/util/Vector.class"); + ClassFile clazzfile = new ClassFile(is); + System.out.println("Class name: " + clazzfile.getName()); + MethodInfoList methods = clazzfile.getMethods(); + for (int i = 0; i < methods.length(); i++){ + MethodInfo method = methods.getMethod(i); + System.out.println("Method: " + method.getFullSignature()); + System.out.println("line: " + method.getNumberOfLines()); + LineNumberTable lnt = method.getCode().getLineNumberTable(); + } + } + +} + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassPathLoader.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassPathLoader.java new file mode 100644 index 000000000..bd270faa8 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/ClassPathLoader.java @@ -0,0 +1,351 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +/** + * Core of the bytecode analyzer. It loads classes from a given classpath. + * + * @author Stephane Bailliez + */ +public class ClassPathLoader { + + public final static FileLoader NULL_LOADER = new NullLoader(); + + /** the list of files to look for */ + protected File[] files; + + /** + * create a new instance with a given classpath. It must be urls + * separated by the platform specific path separator. + * @param classPath the classpath to load all the classes from. + */ + public ClassPathLoader(String classPath){ + StringTokenizer st = new StringTokenizer(classPath, File.pathSeparator); + Vector entries = new Vector(); + while (st.hasMoreTokens()){ + File file = new File(st.nextToken()); + entries.addElement(file); + } + files = new File[entries.size()]; + entries.copyInto(files); + } + + /** + * create a new instance with a given set of urls. + * @param entries valid file urls (either .jar, .zip or directory) + */ + public ClassPathLoader(String[] entries){ + files = new File[entries.length]; + for (int i = 0; i < entries.length; i++){ + files[i] = new File(entries[i]); + } + } + + /** + * create a new instance with a given set of urls + * @param entries file urls to look for classes (.jar, .zip or directory) + */ + public ClassPathLoader(File[] entries){ + files = entries; + } + + /** the interface to implement to look up for specific resources */ + public interface FileLoader { + /** the file url that is looked for .class files */ + public File getFile(); + /** return the set of classes found in the file */ + public ClassFile[] getClasses() throws IOException; + } + + /** + * @return the set of FileLoader loaders matching the given classpath. + */ + public Enumeration loaders(){ + return new LoaderEnumeration(); + } + + /** + * return the whole set of classes in the classpath. Note that this method + * can be very resource demanding since it must load all bytecode from + * all classes in all resources in the classpath at a time. + * To process it in a less resource demanding way, it is maybe better to + * use the loaders() that will return loader one by one. + * + * @return the hashtable containing ALL classes that are found in the given + * classpath. Note that the first entry of a given classname will shadow + * classes with the same name (as a classloader does) + */ + public Hashtable getClasses() throws IOException { + Hashtable map = new Hashtable(); + Enumeration enum = loaders(); + while ( enum.hasMoreElements() ){ + FileLoader loader = (FileLoader)enum.nextElement(); + System.out.println("Processing " + loader.getFile()); + long t0 = System.currentTimeMillis(); + ClassFile[] classes = loader.getClasses(); + long dt = System.currentTimeMillis() - t0; + System.out.println("" + classes.length + " loaded in " + dt + "ms"); + for (int j = 0; j < classes.length; j++){ + String name = classes[j].getName(); + // do not allow duplicates entries to preserve 'classpath' behavior + // first class in wins + if ( !map.contains(name) ){ + map.put(name, classes[j]); + } + } + } + return map; + } + + /** dirty little test, should be moved to a testcase */ + public static void main(String[] args) throws Exception { + ClassPathLoader cl = new ClassPathLoader("e:/jdk/jdk1.3.1/lib/tools.jar;e:/jdk/jdk1.3.1/jre/lib/rt.jar"); + Hashtable map = cl.getClasses(); + System.out.println("Loaded classes: " + map.size()); + } + + /** the loader enumeration that will return loaders */ + protected class LoaderEnumeration implements Enumeration { + protected int index = 0; + public boolean hasMoreElements(){ + return index < files.length; + } + public Object nextElement(){ + if (index >= files.length){ + throw new NoSuchElementException(); + } + File file = files[index++]; + if ( !file.exists() ){ + return new NullLoader(file); + } + if ( file.isDirectory() ){ + // it's a directory + return new DirectoryLoader(file); + } else if ( file.getName().endsWith(".zip") || file.getName().endsWith(".jar") ){ + // it's a jar/zip file + return new JarLoader(file); + } + return new NullLoader(file); + + } + } + + /** + * useful methods to read the whole input stream in memory so that + * it can be accessed faster. Processing rt.jar and tools.jar from JDK 1.3.1 + * brings time from 50s to 7s. + */ + public static InputStream getCachedStream(InputStream is) throws IOException { + is = new BufferedInputStream(is); + byte[] buffer = new byte[8192]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(2048); + int n; + baos.reset(); + while ((n = is.read(buffer, 0, buffer.length)) != -1) { + baos.write(buffer, 0, n); + } + is.close(); + return new ByteArrayInputStream(baos.toByteArray()); + } +} + +/** a null loader to return when the file is not valid */ +class NullLoader implements ClassPathLoader.FileLoader { + private File file; + NullLoader(){ + this(null); + } + NullLoader(File file){ + this.file = file; + } + public File getFile(){ + return file; + } + public ClassFile[] getClasses() throws IOException { + return new ClassFile[0]; + } +} + +/** + * jar loader specified in looking for classes in jar and zip + * @todo read the jar manifest in case there is a Class-Path + * entry. + */ +class JarLoader implements ClassPathLoader.FileLoader { + private File file; + JarLoader(File file){ + this.file = file; + } + public File getFile(){ + return file; + } + public ClassFile[] getClasses() throws IOException { + ZipFile zipFile = new ZipFile(file); + Vector v = new Vector(); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()){ + ZipEntry entry = (ZipEntry)entries.nextElement(); + if (entry.getName().endsWith(".class")){ + InputStream is = ClassPathLoader.getCachedStream(zipFile.getInputStream(entry)); + ClassFile classFile = new ClassFile(is); + is.close(); + v.addElement(classFile); + } + } + ClassFile[] classes = new ClassFile[v.size()]; + v.copyInto(classes); + return classes; + } +} + +/** + * directory loader that will look all classes recursively + * @todo should discard classes which package name does not + * match the directory ? + */ +class DirectoryLoader implements ClassPathLoader.FileLoader { + private File directory; + + DirectoryLoader(File dir){ + directory = dir; + } + public File getFile(){ + return directory; + } + public ClassFile[] getClasses() throws IOException { + Vector v = new Vector(); + Vector files = listFiles( directory, new ClassFilter(), true); + for (int i = 0; i < files.size(); i++){ + File file = (File)files.elementAt(i); + InputStream is = null; + try { + is = ClassPathLoader.getCachedStream(new FileInputStream(file)); + ClassFile classFile = new ClassFile(is); + is.close(); + is = null; + v.addElement(classFile); + } finally { + if (is != null){ + try { + is.close(); + } catch (IOException ignored){} + } + } + } + ClassFile[] classes = new ClassFile[v.size()]; + v.copyInto(classes); + return classes; + } + + /** + * List files that obeys to a specific filter recursively from a given base + * directory. + * @param directory the directory where to list the files from. + * @param filter the file filter to apply + * @param recurse tells whether or not the listing is recursive. + * @return the list of File objects that applies to the given + * filter. + */ + public static Vector listFiles(File directory, FilenameFilter filter, boolean recurse){ + if (!directory.isDirectory()){ + throw new IllegalArgumentException(directory + " is not a directory"); + } + Vector list = new Vector(); + listFilesTo(list, directory, filter, recurse); + return list; + } + + /** + * List and add files to a given list. As a convenience it sends back the + * instance of the list given as a parameter. + * @param list the list of files where the filtered files should be added + * @param directory the directory where to list the files from. + * @param filter the file filter to apply + * @param recurse tells whether or not the listing is recursive. + * @return the list instance that was passed as the list argument. + */ + private static Vector listFilesTo(Vector list, File directory, FilenameFilter filter, boolean recurse){ + String[] files = directory.list(filter); + for (int i = 0; i < files.length; i++){ + list.addElement( new File(directory, files[i]) ); + } + files = null; // we don't need it anymore + if (recurse){ + String[] subdirs = directory.list( new DirectoryFilter() ); + for (int i = 0; i < subdirs.length; i++){ + listFilesTo(list, new File(directory, subdirs[i]), filter, recurse); + } + } + return list; + } + +} + +/** Convenient filter that accepts only directory File */ +class DirectoryFilter implements FilenameFilter { + public boolean accept(File directory, String name){ + File pathname = new File(directory, name); + return pathname.isDirectory(); + } +} +/** convenient filter to accept only .class files */ +class ClassFilter implements FilenameFilter { + public boolean accept(File dir, String name){ + return name.endsWith(".class"); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfo.java new file mode 100644 index 000000000..3510169be --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfo.java @@ -0,0 +1,132 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.*; + +/** + * field structure + * + * @author Stephane Bailliez + */ +public class FieldInfo { + + protected ConstantPool constantPool; + protected int access_flags; + protected int name_index; + protected int descriptor_index; + protected AttributeInfoList attributes; + protected boolean synthetic; + protected boolean deprecated; + protected boolean constant; + + public FieldInfo(ConstantPool pool){ + constantPool = pool; + } + + public void read(DataInputStream dis) throws IOException { + access_flags = dis.readShort(); + name_index = dis.readShort(); + descriptor_index = dis.readShort(); + attributes = new AttributeInfoList(constantPool); + attributes.read(dis); + constant = attributes.getAttribute(AttributeInfo.CONSTANT_VALUE) != null; + deprecated = attributes.getAttribute(AttributeInfo.DEPRECATED) != null; + synthetic = attributes.getAttribute(AttributeInfo.SYNTHETIC) != null; + } + + public int getAccessFlags(){ + return access_flags; + } + + public String getName(){ + return Utils.getUTF8Value(constantPool, name_index); + } + + public String getDescriptor(){ + return Utils.getUTF8Value(constantPool, descriptor_index); + } + + public boolean isDeprecated(){ + return deprecated; + } + + public boolean isSynthetic(){ + return synthetic; + } + + public boolean isConstant(){ + return constant; + } + + public String getAccess(){ + return Utils.getFieldAccess(access_flags); + } + + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append("Field: "); + sb.append(getAccess()).append(" "); + Utils.descriptor2java(getDescriptor(),0,sb); + sb.append(" ").append(getName()); + return sb.toString(); + } +} + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfoList.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfoList.java new file mode 100644 index 000000000..a89620f54 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/FieldInfoList.java @@ -0,0 +1,106 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * field structure list + * + * @author Stephane Bailliez + */ +public class FieldInfoList { + + protected ConstantPool constantPool; + + protected FieldInfo[] fields; + + public FieldInfoList(ConstantPool pool){ + constantPool = pool; + } + + public void read(DataInputStream dis) throws IOException { + int numFields = dis.readShort(); + fields = new FieldInfo[numFields]; + for (int i = 0; i < fields.length; i++){ + fields[i] = new FieldInfo(constantPool); + fields[i].read(dis); + } + } + + public String getFieldName(int index){ + return getField(index).getName(); + } + + public FieldInfo getField(int index){ + return fields[index]; + } + + public int length(){ + return fields.length; + } + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append("Fields: ").append(fields.length).append("\n"); + for (int i = 0; i < fields.length; i++){ + sb.append("\t"); + sb.append(getField(i).toString()); + } + return sb.toString(); + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/InterfaceList.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/InterfaceList.java new file mode 100644 index 000000000..0469a3128 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/InterfaceList.java @@ -0,0 +1,105 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.*; + +/** + * list of interfaces implemented in a class. + * + * @author Stephane Bailliez + */ +public class InterfaceList { + protected ConstantPool constantPool; + protected int[] interfaces; + + public InterfaceList(ConstantPool pool){ + constantPool = pool; + } + public void read(DataInputStream dis) throws IOException { + int count = dis.readShort(); + interfaces = new int[count]; + for (int i = 0; i < count; i++){ + interfaces[i] = dis.readShort(); + } + } + public int length(){ + return interfaces.length; + } + public String getInterface(int i){ + int index = interfaces[i]; + ClassCPInfo cp = (ClassCPInfo)constantPool.getEntry(index); + return cp.getClassName().replace('/','.'); + } + public String[] getInterfaces(){ + String[] classes = new String[interfaces.length]; + for (int i = 0; i < classes.length; i++){ + classes[i] = getInterface(i); + } + return classes; + } + public String toString(){ + StringBuffer sb = new StringBuffer("Interfaces: "); + String[] names = getInterfaces(); + for (int i = 0; i < names.length; i++){ + sb.append(names[i]); + if (i != names.length - 1){ + sb.append(", "); + } + } + return sb.toString(); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java new file mode 100644 index 000000000..4bdf1b931 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfo.java @@ -0,0 +1,167 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.*; +import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes.*; + +/** + * Method info structure. + * @todo give a more appropriate name to methods. + * + * @author Stephane Bailliez + */ +public class MethodInfo { + protected ConstantPool constantPool; + protected int access_flags; + protected int name_index; + protected int descriptor_index; + protected Code code; + protected boolean deprecated; + protected boolean synthetic; + protected Exceptions exceptions; + public MethodInfo(ConstantPool pool){ + constantPool = pool; + } + + public void read(DataInputStream dis) throws IOException { + access_flags = dis.readShort(); + name_index = dis.readShort(); + descriptor_index = dis.readShort(); + AttributeInfoList attrlist = new AttributeInfoList(constantPool); + attrlist.read(dis); + code = (Code)attrlist.getAttribute(AttributeInfo.CODE); + synthetic = attrlist.getAttribute(AttributeInfo.SYNTHETIC) != null; + deprecated = attrlist.getAttribute(AttributeInfo.DEPRECATED) != null; + exceptions = (Exceptions)attrlist.getAttribute(AttributeInfo.EXCEPTIONS); + } + + public int getAccessFlags(){ + return access_flags; + } + + public String getName(){ + return Utils.getUTF8Value(constantPool, name_index); + } + + public String getDescriptor(){ + return Utils.getUTF8Value(constantPool, descriptor_index); + } + + public String getFullSignature(){ + return getReturnType() + " " + getShortSignature(); + } + + public String getShortSignature(){ + StringBuffer buf = new StringBuffer(getName()); + buf.append("("); + String[] params = getParametersType(); + for (int i = 0; i < params.length; i++){ + buf.append(params[i]); + if (i != params.length - 1){ + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + public String getReturnType(){ + return Utils.getMethodReturnType(getDescriptor()); + } + + public String[] getParametersType(){ + return Utils.getMethodParams(getDescriptor()); + } + + public Code getCode(){ + return code; + } + + public int getNumberOfLines(){ + int len = -1; + if (code != null){ + LineNumberTable lnt = code.getLineNumberTable(); + if (lnt != null){ + len = lnt.length(); + } + } + return len; + } + + public boolean isDeprecated(){ + return deprecated; + } + + public boolean isSynthetic(){ + return synthetic; + } + + public String getAccess(){ + return Utils.getMethodAccess(access_flags); + } + + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append("Method: ").append(getAccess()).append(" "); + sb.append(getFullSignature()); + sb.append(" synthetic:").append(synthetic); + sb.append(" deprecated:").append(deprecated); + return sb.toString(); + } +} + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfoList.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfoList.java new file mode 100644 index 000000000..5afd256f1 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/MethodInfoList.java @@ -0,0 +1,119 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * A list of method_info structures. + * + * @author Stephane Bailliez + */ +public class MethodInfoList { + /** pool containing all the information */ + protected ConstantPool constantPool; + + /** methods in this list */ + protected MethodInfo[] methods; + + + public MethodInfoList(ConstantPool pool){ + constantPool = pool; + } + + /** read the bytecode from the stream */ + public void read(DataInputStream dis) throws IOException { + int count = dis.readShort(); + methods = new MethodInfo[count]; + for (int i = 0; i < count; i++){ + methods[i] = new MethodInfo(constantPool); + methods[i].read(dis); + } + } + + /** the size of the list */ + public int length(){ + return methods.length; + } + + /** + * get a method in the list. + * @param i the index of the method to retrieve + * @return the method matching the index. + */ + public MethodInfo getMethod(int i){ + return methods[i]; + } + + /** + * return the set of methods in this list. Mostly as a debugging purpose. + */ + public String toString(){ + StringBuffer sb = new StringBuffer(); + sb.append("Methods: ").append(methods.length).append("\n"); + for (int i = 0; i < methods.length; i++){ + sb.append("\t"); + sb.append(getMethod(i).toString()); + sb.append("\n"); + } + return sb.toString(); + } + +} + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/Utils.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/Utils.java new file mode 100644 index 000000000..82a771b2f --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/Utils.java @@ -0,0 +1,385 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.*; +import java.util.Vector; + +/** + * Utilities mostly to manipulate methods and access flags. + * + * @author Stephane Bailliez + */ +public class Utils { + /** public access flag */ + public static final short ACC_PUBLIC = 1; + /** private access flag */ + public static final short ACC_PRIVATE = 2; + /** protected access flag */ + public static final short ACC_PROTECTED = 4; + /** static access flag */ + public static final short ACC_STATIC = 8; + /** final access flag */ + public static final short ACC_FINAL = 16; + /** super access flag */ + public static final short ACC_SUPER = 32; + /** synchronized access flag */ + public static final short ACC_SYNCHRONIZED = 32; + /** volatile access flag */ + public static final short ACC_VOLATILE = 64; + /** transient access flag */ + public static final short ACC_TRANSIENT = 128; + /** native access flag */ + public static final short ACC_NATIVE = 256; + /** interface access flag */ + public static final short ACC_INTERFACE = 512; + /** abstract access flag */ + public static final short ACC_ABSTRACT = 1024; + /** strict access flag */ + public static final short ACC_STRICT = 2048; + + /** private constructor */ + private Utils(){ + } + + /** + * return an UTF8 value from the pool located a a specific index. + * @param pool the constant pool to look at + * @param index index of the UTF8 value in the constant pool + * @return the value of the string if it exists + * @throws ClassCastException if the index is not an UTF8 constant. + */ + public static String getUTF8Value(ConstantPool pool, int index){ + return ((Utf8CPInfo)pool.getEntry(index)).getValue(); + } + + /** + * parse all parameters from a descritor into fields of java name. + * @param descriptor of a method. + * @return the parameter list of a given method descriptor. Each string + * represent a java object with its fully qualified classname or the + * primitive name such as int, long, ... + */ + public static String[] getMethodParams(String descriptor){ + int i = 0; + if (descriptor.charAt(i) != '('){ + throw new IllegalArgumentException("Method descriptor should start with a '('"); + } + Vector params = new Vector(); + StringBuffer param = new StringBuffer(); + i++; + while ( (i = descriptor2java(descriptor, i, param)) < descriptor.length() ){ + params.add(param.toString()); + param.setLength(0); // reset + if (descriptor.charAt(i) == ')'){ + i++; + break; + } + } + String[] array = new String[params.size()]; + params.copyInto(array); + return array; + } + + /** + * return the object type of a return type. + * @param descriptor + * @return get the return type objet of a given descriptor + */ + public static String getMethodReturnType(String descriptor){ + int pos = descriptor.indexOf(')'); + StringBuffer rettype = new StringBuffer(); + descriptor2java(descriptor, pos + 1, rettype); + return rettype.toString(); + } + + /** + * Parse a single descriptor symbol and returns it java equivalent. + * @param descriptor the descriptor symbol. + * @param i the index to look at the symbol in the descriptor string + * @param sb the stringbuffer to return the java equivalent of the symbol + * @return the index after the descriptor symbol + */ + public static int descriptor2java(String descriptor, int i, StringBuffer sb){ + // get the dimension + StringBuffer dim = new StringBuffer(); + for (;descriptor.charAt(i) == '['; i++){ + dim.append("[]"); + } + // now get the type + switch (descriptor.charAt(i)){ + case 'B': sb.append("byte"); break; + case 'C': sb.append("char"); break; + case 'D': sb.append("double"); break; + case 'F': sb.append("float"); break; + case 'I': sb.append("int"); break; + case 'J': sb.append("long"); break; + case 'S': sb.append("short"); break; + case 'Z': sb.append("boolean"); break; + case 'V': sb.append("void"); break; + case 'L': + // it is a class + int pos = descriptor.indexOf(';', i + 1); + String classname = descriptor.substring(i + 1, pos).replace('/', '.'); + sb.append(classname); + i = pos; + break; + default: + //@todo, yeah this happens because I got things like: + // ()Ljava/lang/Object; and it will return and ) will be here + // think about it. + + //ooooops should never happen + //throw new IllegalArgumentException("Invalid descriptor symbol: '" + i + "' in '" + descriptor + "'"); + } + sb.append(dim.toString()); + return ++i; + } + + /** + * check for abstract access + * @param access_flags access flags + */ + public static boolean isAbstract(int access_flags) { + return (access_flags & ACC_ABSTRACT) != 0; + } + /** + * check for public access + * @param access_flags access flags + */ + public static boolean isPublic(int access_flags) { + return (access_flags & ACC_PUBLIC) != 0; + } + /** + * check for a static access + * @param access_flags access flags + */ + public static boolean isStatic(int access_flags) { + return (access_flags & ACC_STATIC) != 0; + } + /** + * check for native access + * @param access_flags access flags + */ + public static boolean isNative(int access_flags) { + return (access_flags & ACC_NATIVE) != 0; + } + /** + * check for class access + * @param access_flags access flags + */ + public static boolean isClass(int access_flags) { + return !isInterface(access_flags); + } + /** + * check for strict access + * @param access_flags access flags + */ + public static boolean isStrict(int access_flags) { + return (access_flags & ACC_STRICT) != 0; + } + /** + * check for interface access + * @param access_flags access flags + */ + public static boolean isInterface(int access_flags) { + return (access_flags & ACC_INTERFACE) != 0; + } + /** + * check for private access + * @param access_flags access flags + */ + public static boolean isPrivate(int access_flags) { + return (access_flags & ACC_PRIVATE) != 0; + } + /** + * check for transient flag + * @param access_flags access flags + */ + public static boolean isTransient(int access_flags) { + return (access_flags & ACC_TRANSIENT) != 0; + } + /** + * check for volatile flag + * @param access_flags access flags + */ + public static boolean isVolatile(int access_flags){ + return (access_flags & ACC_VOLATILE) != 0; + } + /** + * check for super flag + * @param access_flags access flag + */ + public static boolean isSuper(int access_flags) { + return (access_flags & ACC_SUPER) != 0; + } + /** + * check for protected flag + * @param access_flags access flags + */ + public static boolean isProtected(int access_flags) { + return (access_flags & ACC_PROTECTED) != 0; + } + /** + * chck for final flag + * @param access_flags access flags + */ + public static boolean isFinal(int access_flags) { + return (access_flags & ACC_FINAL) != 0; + } + /** + * check for synchronized flag + * @param access_flags access flags + */ + public static boolean isSynchronized(int access_flags) { + return (access_flags & ACC_SYNCHRONIZED) != 0; + } + + /** + * return the method access flag as java modifiers + * @param access_flags access flags + * @return the access flags as modifier strings + */ + public static String getMethodAccess(int access_flags) { + StringBuffer sb = new StringBuffer(); + if(isPublic(access_flags)){ + sb.append("public "); + } else if(isPrivate(access_flags)){ + sb.append("private "); + } else if(isProtected(access_flags)){ + sb.append("protected "); + } + if(isFinal(access_flags)){ + sb.append("final "); + } + if(isStatic(access_flags)){ + sb.append("static "); + } + if(isSynchronized(access_flags)){ + sb.append("synchronized "); + } + if(isNative(access_flags)){ + sb.append("native "); + } + if(isAbstract(access_flags)){ + sb.append("abstract "); + } + return sb.toString().trim(); + } + + /** + * return the field access flag as java modifiers + * @param access_flags access flags + * @return the access flags as modifier strings + */ + public static String getFieldAccess(int access_flags) { + StringBuffer sb = new StringBuffer(); + if(isPublic(access_flags)){ + sb.append("public "); + } else if(isPrivate(access_flags)){ + sb.append("private "); + } else if (isProtected(access_flags)){ + sb.append("protected "); + } + if(isFinal(access_flags)){ + sb.append("final "); + } + if(isStatic(access_flags)){ + sb.append("static "); + } + if(isVolatile(access_flags)){ + sb.append("volatile "); + } + if(isTransient(access_flags)){ + sb.append("transient "); + } + return sb.toString().trim(); + } + + /** + * return the class access flag as java modifiers + * @param access_flags access flags + * @return the access flags as modifier strings + */ + public static String getClassAccess(int access_flags) { + StringBuffer sb = new StringBuffer(); + if(isPublic(access_flags)){ + sb.append("public "); + } else if (isProtected(access_flags)){ + sb.append("protected "); + } else if (isPrivate(access_flags)){ + sb.append("private "); + } + if(isFinal(access_flags)){ + sb.append("final "); + } + if(isSuper(access_flags)){ + sb.append("/*super*/ "); + } + if(isInterface(access_flags)){ + sb.append("interface "); + } + if(isAbstract(access_flags)){ + sb.append("abstract "); + } + if(isClass(access_flags)){ + sb.append("class "); + } + return sb.toString().trim(); + } +} + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfo.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfo.java new file mode 100644 index 000000000..035a91b01 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfo.java @@ -0,0 +1,146 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.*; +import org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.*; + +/** + * Attribute info structure that provides base methods + * + * @author Stephane Bailliez + */ +public abstract class AttributeInfo { + + public final static String SOURCE_FILE = "SourceFile"; + + public final static String CONSTANT_VALUE = "ConstantValue"; + + public final static String CODE = "Code"; + + public final static String EXCEPTIONS = "Exceptions"; + + public final static String LINE_NUMBER_TABLE = "LineNumberTable"; + + public final static String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; + + public final static String INNER_CLASSES = "InnerClasses"; + + public final static String SOURCE_DIR = "SourceDir"; + + public final static String SYNTHETIC = "Synthetic"; + + public final static String DEPRECATED = "Deprecated"; + + public final static String UNKNOWN = "Unknown"; + + protected int name_index; + + protected ConstantPool constantPool; + + protected AttributeInfo(int attr_index, ConstantPool pool){ + name_index = attr_index; + constantPool = pool; + } + + /** + * @param dis + * @throws IOException + */ + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); + dis.skipBytes(len); + } + + public String getName(){ + return Utils.getUTF8Value(constantPool, name_index); + } + + /** + * @param attr_index + * @param dis + * @param pool + */ + public static AttributeInfo newAttribute(int attr_index, DataInputStream dis, ConstantPool pool) throws IOException { + AttributeInfo attr = null; + final String name = Utils.getUTF8Value(pool, attr_index); + if (SOURCE_FILE.equals(name)){ + attr = new SourceFile(attr_index, pool); + } else if (CONSTANT_VALUE.equals(name)){ + attr = new ConstantValue(attr_index, pool); + } else if (CODE.equals(name)){ + attr = new Code(attr_index, pool); + } else if (EXCEPTIONS.equals(name)){ + attr = new Exceptions(attr_index, pool); + } else if (LINE_NUMBER_TABLE.equals(name)){ + attr = new LineNumberTable(attr_index, pool); + } else if (LOCAL_VARIABLE_TABLE.equals(name)){ + attr = new LocalVariableTable(attr_index, pool); + } else if (INNER_CLASSES.equals(name)){ + attr = new InnerClasses(attr_index, pool); + } else if (SOURCE_DIR.equals(name)){ + attr = new SourceDir(attr_index, pool); + } else if (SYNTHETIC.equals(name)){ + attr = new Synthetic(attr_index, pool); + } else if (DEPRECATED.equals(name)){ + attr = new Deprecated(attr_index, pool); + } else { + attr = new Unknown(attr_index, pool); + } + attr.read(dis); + return attr; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfoList.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfoList.java new file mode 100644 index 000000000..d9a4854b8 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/AttributeInfoList.java @@ -0,0 +1,102 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * list of attributes + * + * @author Stephane Bailliez + */ +public class AttributeInfoList { + + protected AttributeInfo[] attributes; + + protected ConstantPool constantPool; + + public AttributeInfoList(ConstantPool pool){ + constantPool = pool; + } + + public void read(DataInputStream dis) throws IOException { + final int attributes_count = dis.readUnsignedShort(); + attributes = new AttributeInfo[attributes_count]; + for (int i = 0; i < attributes_count; i++){ + int attr_id = dis.readShort(); + attributes[i] = AttributeInfo.newAttribute(attr_id, dis, constantPool); + } + } + + public AttributeInfo[] getAttributes(){ + return attributes; + } + + public AttributeInfo getAttribute(String name){ + for (int i = 0; i < attributes.length; i++){ + if (name.equals(attributes[i].getName())){ + return attributes[i]; + } + } + return null; + } + + public int size(){ + return attributes.length; + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Code.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Code.java new file mode 100644 index 000000000..b8e0a34c6 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Code.java @@ -0,0 +1,160 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * Code structure. + * + * @author Stephane Bailliez + */ +public class Code extends AttributeInfo { + + protected int length; + + protected int max_stack; + + protected int max_locals; + + protected byte[] code; + + protected ExceptionInfo[] exceptions; + + protected LineNumberTable lineNumberTable; + + public Code(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + + public void read(DataInputStream dis) throws IOException { + length = dis.readInt(); + max_stack = dis.readShort(); + max_locals = dis.readShort(); + + // read bytecode... + int bytecode_len = dis.readInt(); + //code = new byte[bytecode_len]; + //dis.readFully(code); + dis.skip(bytecode_len); + + // read exceptions... + int exception_count = dis.readShort(); + exceptions = new ExceptionInfo[exception_count]; + for (int i = 0; i < exception_count; i++){ + exceptions[i] = new ExceptionInfo(constantPool); + exceptions[i].read(dis); + } + + // read attributes... + AttributeInfoList attributes = new AttributeInfoList(constantPool); + attributes.read(dis); + lineNumberTable = (LineNumberTable)attributes.getAttribute(AttributeInfo.LINE_NUMBER_TABLE); + } + + public int getMaxStack(){ + return max_stack; + } + + public int getMaxLocals(){ + return max_locals; + } + + public byte[] getCode(){ + return code; + } + + public ExceptionInfo[] getExceptions(){ + return exceptions; + } + + public LineNumberTable getLineNumberTable(){ + return lineNumberTable; + } + + public static class ExceptionInfo { + protected ConstantPool constantPool; + protected int startPC; + protected int endPC; + protected int handlerPC; + protected int catchType; + public ExceptionInfo(ConstantPool pool){ + constantPool = pool; + } + public void read(DataInputStream dis) throws IOException { + startPC = dis.readShort(); + endPC = dis.readShort(); + handlerPC = dis.readShort(); + catchType = dis.readShort(); + } + public int getStartPC(){ + return startPC; + } + public int getEndPC(){ + return endPC; + } + public int getHandlerPC(){ + return handlerPC; + } + public int getCatchType(){ + return catchType; + } + } + +} + + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/ConstantValue.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/ConstantValue.java new file mode 100644 index 000000000..0b60b74b7 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/ConstantValue.java @@ -0,0 +1,85 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * constant value structure + * + * @author Stephane Bailliez + */ +public class ConstantValue extends AttributeInfo { + + protected int name_index; + + public ConstantValue(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); // assert 2 == len : len + if (len != 2){ + throw new IllegalStateException("Constant value length should be 2 but was " + len); + } + name_index = dis.readShort(); + } + + public String getValue(){ + return ((Utf8CPInfo)constantPool.getEntry(name_index)).getValue(); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Deprecated.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Deprecated.java new file mode 100644 index 000000000..55540b557 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Deprecated.java @@ -0,0 +1,70 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * deprecated structure + * + * @author Stephane Bailliez + */ +public class Deprecated extends AttributeInfo { + public Deprecated(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Exceptions.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Exceptions.java new file mode 100644 index 000000000..7f1645e43 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Exceptions.java @@ -0,0 +1,71 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * exceptions structure + * + * @author Stephane Bailliez + */ +public class Exceptions extends AttributeInfo { + public Exceptions(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/InnerClasses.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/InnerClasses.java new file mode 100644 index 000000000..5a23667a4 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/InnerClasses.java @@ -0,0 +1,72 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * inner classes structure + * @author Stephane Bailliez + */ +public class InnerClasses extends AttributeInfo { + + public InnerClasses(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + +} + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LineNumberTable.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LineNumberTable.java new file mode 100644 index 000000000..0389de4b0 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LineNumberTable.java @@ -0,0 +1,97 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * line number table structure + * @author Stephane Bailliez + */ +public class LineNumberTable extends AttributeInfo { + + protected int count; + + protected int[] varTable; + + public LineNumberTable(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); + count = dis.readShort(); + varTable = new int[ count * 2 ]; + for (int i = 0; i < varTable.length; i++){ + varTable[i] = dis.readShort(); + } + } + + public int getStartPC(int i){ + return varTable[2*i]; + } + + public int getLineNumber(int i){ + return varTable[2*i + 1]; + } + + public int length(){ + return count; + } + +} + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LocalVariableTable.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LocalVariableTable.java new file mode 100644 index 000000000..2b11b2229 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/LocalVariableTable.java @@ -0,0 +1,105 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * local variable table. + * @author Stephane Bailliez + */ +public class LocalVariableTable extends AttributeInfo { + + protected int count; + + protected int[] varTable; + + public LocalVariableTable(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); + count = dis.readShort(); + varTable = new int[count * 5]; + for (int i = 0; i < varTable.length; i++){ + varTable[i] = dis.readShort(); + } + } + + public int getStartPC(int index){ + return varTable[5*index]; + } + public int getEndPC(int index){ + return varTable[5*index] + varTable[5*index + 1]; + } + public String getVariableName(int index){ + int i = varTable[5*index + 2]; + return ((Utf8CPInfo)constantPool.getEntry(i)).getValue(); + } + public String getType(int index){ + int i = varTable[5*index + 3]; + return ((Utf8CPInfo)constantPool.getEntry(i)).getValue(); + } + public int getSlot(int index){ + return varTable[5*index + 4]; + } + public int length(){ + return count; + } +} + diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceDir.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceDir.java new file mode 100644 index 000000000..c80d80c65 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceDir.java @@ -0,0 +1,84 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * source directory structure. + * + * @author Stephane Bailliez + */ +public class SourceDir extends AttributeInfo { + + protected int name_index; + + public SourceDir(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); + // assert len == 2 + name_index = dis.readShort(); + } + + public String getValue(){ + return ((Utf8CPInfo)constantPool.getEntry(name_index)).getValue(); + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceFile.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceFile.java new file mode 100644 index 000000000..31c44b18f --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/SourceFile.java @@ -0,0 +1,84 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * source file structure + * + * @author Stephane Bailliez + */ +public class SourceFile extends AttributeInfo { + + protected int name_index; + + public SourceFile(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } + + protected void read(DataInputStream dis) throws IOException { + int len = dis.readInt(); + // assert len == 2 + name_index = dis.readShort(); + } + + public String getValue(){ + return ((Utf8CPInfo)constantPool.getEntry(name_index)).getValue(); + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Synthetic.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Synthetic.java new file mode 100644 index 000000000..83c79ee79 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Synthetic.java @@ -0,0 +1,70 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.Utf8CPInfo; + +/** + * synthetic structure + * + * @author Stephane Bailliez + */ +public class Synthetic extends AttributeInfo { + public Synthetic(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Unknown.java b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Unknown.java new file mode 100644 index 000000000..1e649f45c --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/sitraka/bytecode/attributes/Unknown.java @@ -0,0 +1,69 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional.sitraka.bytecode.attributes; + +import java.io.*; + +import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool; + +/** + * unknown structure attribute + * + * @author Stephane Bailliez + */ +public class Unknown extends AttributeInfo { + public Unknown(int attr_index, ConstantPool pool){ + super(attr_index, pool); + } +}