diff options
author | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:15:14 -0800 |
---|---|---|
committer | Andy Clement <aclement@pivotal.io> | 2019-01-30 16:15:14 -0800 |
commit | f4d5e9485ae910220e06b0b6c778587ed6b4ebb3 (patch) | |
tree | 077bc311c2f2532a81483ad8c05fa898c6b40269 /testing/src/main | |
parent | cda73a6a5864b76e252ed0d3b69ff4b55a6def4b (diff) | |
download | aspectj-f4d5e9485ae910220e06b0b6c778587ed6b4ebb3.tar.gz aspectj-f4d5e9485ae910220e06b0b6c778587ed6b4ebb3.zip |
mavenizing testing - done
Diffstat (limited to 'testing/src/main')
83 files changed, 0 insertions, 25249 deletions
diff --git a/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java b/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java deleted file mode 100644 index 8fb274176..000000000 --- a/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/Ajctest.java +++ /dev/null @@ -1,1900 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.internal.tools.ant.taskdefs; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.LayoutManager; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.DateFormat; -//import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.Vector; - -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTable; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.ListSelectionModel; -import javax.swing.border.BevelBorder; -import javax.swing.event.ListSelectionEvent; -import javax.swing.table.DefaultTableModel; -import javax.swing.table.TableModel; -import javax.swing.text.StyleContext; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Location; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Target; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.taskdefs.Delete; -//import org.apache.tools.ant.taskdefs.ExecTask; -import org.apache.tools.ant.taskdefs.Java; -import org.apache.tools.ant.taskdefs.LogOutputStream; -import org.apache.tools.ant.taskdefs.Mkdir; -import org.apache.tools.ant.taskdefs.StreamPumper; -import org.apache.tools.ant.types.Commandline; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.Reference; -import org.aspectj.util.LangUtil; - -public class Ajctest extends Task implements PropertyChangeListener { - private static Ajctest CURRENT_AJCTEST; - - // todo shutdown hook assumes one task per VM - public Ajctest() { - super(); - CURRENT_AJCTEST = this; - } - - private static boolean firstTime = true; - - public final PropertyChangeSupport bean = new PropertyChangeSupport(this); - - { - bean.addPropertyChangeListener(this); - } - - public void propertyChange(PropertyChangeEvent evt) { - String name = evt.getPropertyName(); - if ("ajdoc.good".equals(name)) ajdocStats.goods++; - else if ("ajc.good".equals(name)) ajcStats.goods++; - else if ("run.good".equals(name)) runStats.goods++; - if ("ajdoc.fail".equals(name)) ajdocStats.fails++; - else if ("ajc.fail".equals(name)) ajcStats.fails++; - else if ("run.fail".equals(name)) runStats.fails++; - } - - private void fire(String prop, Object oldval, Object newval) { - bean.firePropertyChange(prop, oldval, newval); - } - - private void fire(String prop) { - fire(prop, "dummy-old", "dummy-new"); - } - - private static boolean dumpresults = false; - private Stats ajdocStats = new Stats(); - private Stats ajcStats = new Stats(); - private Stats runStats = new Stats(); -// private Stats errorStats = new Stats(); - private static final String NO_TESTID = "NONE"; - private File workingdir = new File("ajworkingdir"); //XXX - - //fields - private String testId = NO_TESTID; - private List<Argument> args = new Vector<>(); - private List<Testset> testsets = new Vector<>(); - private Path classpath; - private Path internalclasspath; - private File destdir; - private File dir; - private File errorfile; - private List<Run> testclasses = new Vector<>(); - private boolean nocompile; - private Ajdoc ajdoc = null; - private boolean noclean; - private boolean noverify; - private List<String> depends = new Vector<>(); - //end-fields - - public Argfile createArgfile() { - return createTestset().createArgfile(); - } - - public void setNoverify(boolean input) { - if (input != noverify) noverify = input; - } - - public void setOwningTarget(Target target) { - super.setOwningTarget(target); - if (null != target) { - //setTestId(target.getName()); - } - } - - public void setTestId(String str) { - if ((null != str) && (0 < str.trim().length())) { - testId = str; - } - } - - public void setArgs(String str) { - if (str == null || str.length() < 1) return; - StringTokenizer tok = new StringTokenizer(str, ",", false); - while (tok.hasMoreTokens()) { - String name = tok.nextToken().trim(); - if (0 < name.length()) { - parse(name.startsWith("J") ? createJarg() : createArg(), name); - } - } - } - - private void parse(Argument arg, String name) { - int itilde = name.lastIndexOf("~"); - if (itilde != -1) { - name = name.substring(0, itilde) + name.substring(itilde+1); - } - int ieq = name.lastIndexOf("="); - int icolon = name.lastIndexOf(":"); - int ileft = name.lastIndexOf("["); - int iright = name.lastIndexOf("]"); - boolean always = true; - String rest = ""; - String newName = name; - if (ieq != -1) { - rest = name.substring(ieq+1); - newName = name.substring(0, ieq); - always = true; - } else if (icolon != -1) { - rest = name.substring(icolon+1); - newName = name.substring(0, icolon); - always = false; - } else if (ileft != -1) { - newName = name.substring(0, ileft); - always = true; - } - String values = ileft == -1 ? rest : - name.substring(ileft+1, iright > ileft ? iright : rest.length()-1); - String value = null; - if (itilde != -1) { - String prop = project.getUserProperty(values); - if (prop == null) { - prop = project.getProperty(values); - } - if (prop != null) { - value = prop; - } - } - if (value != null) { - arg.setValue(value); - } else { - arg.setValues(values); - } - arg.setName(newName); - arg.setAlways(always); - } - - public Argument createJarg() { - Argument arg = new Argument(true); - args.add(arg); - return arg; - } - - - public Argument createArg() { - Argument arg = new Argument(false); - args.add(arg); - return arg; - } - - public void setClasspath(Path path) { - if (classpath == null) { - classpath = path; - } else { - classpath.append(path); - } - } - - public Path createClasspath() { - if (classpath == null) { - classpath = new Path(project); - } - return classpath.createPath(); - } - - public void setClasspathRef(Reference r) { - createClasspath().setRefid(r); - } - - public void setInternalclasspath(Path path) { - if (internalclasspath == null) { - internalclasspath = path; - } else { - internalclasspath.append(path); - } - } - - public Path createInternalclasspath() { - if (internalclasspath == null) { - internalclasspath = new Path(project); - } - return internalclasspath.createPath(); - } - - public void setInternalclasspathRef(Reference r) { - createInternalclasspath().setRefid(r); - } - - public void setDestdir(String destdir) { - this.destdir = project.resolveFile(destdir); - } - - public void setDir(File dir) { - this.dir = dir; - } - - public void setErrorfile(File errorfile) { - this.errorfile = errorfile; - } - - public Run createJava() { - Run testclass = new Run(project); - testclasses.add(testclass); - return testclass; - } - - public void setClasses(String str) { - for (StringTokenizer t = new StringTokenizer(str, ", ", false); - t.hasMoreTokens();) { - createJava().setClassname(t.nextToken().trim()); - } - } - - public void setTestclass(String testclass) { - createJava().setClassname(testclass); - } - - public void setAjdoc(boolean b) { - if (b && ajdoc == null) { - createAjdoc(); - } else if (!b) { - ajdoc = null; - } - } - - public void setAjdocargs(String str) { - createAjdoc(); - for (StringTokenizer t = new StringTokenizer(str, ", ", false); - t.hasMoreTokens();) { - ajdoc.createArg().setValue(t.nextToken().trim()); - } - } - - public void addAjdoc(Ajdoc ajdoc) { - this.ajdoc = ajdoc; - } - - public Ajdoc createAjdoc() { - return ajdoc = new Ajdoc(); - } - - public static class Argument { - private String name; - private List<String> values = new Vector<>(); - private boolean always = true; - final boolean isj; - public Argument(boolean isj) { - this.isj = isj; - } - public void setName(String str) { - this.name = str.startsWith("-") ? str : - ("-" + (str.startsWith("J") ? str.substring(1) : str)); - } - public void setValues(String str) { - values = new Vector<>(); - StringTokenizer tok = new StringTokenizer(str, ", ", false); - while (tok.hasMoreTokens()) { - values.add(tok.nextToken().trim()); - } - } - public void setValue(String value) { - (values = new Vector<>()).add(value); - } - public void setAlways(boolean always) { - this.always = always; - } - public String toString() { return name + ":" + values; } - } - - public void setNocompile(boolean nocompile) { - this.nocompile = nocompile; - } - - private static class Stats { - int goods = 0; - int fails = 0; - } - - private static class Arg { - final String name; - final String value; - final boolean isj; - Arg(String name, String value, boolean isj) { - this.name = name; - this.value = value; - this.isj = isj; - } - public String toString() { - return name + (!"".equals(value) ? " " + value : ""); - } - } - - public Testset createTestset() { - Testset testset = new Testset(); - testsets.add(testset); - return testset; - } - - public void setNoclean(boolean noclean) { - this.noclean = noclean; - } - - public void setDepends(String depends) { - for (StringTokenizer t = new StringTokenizer(depends, ", ", false); - t.hasMoreTokens();) { - this.depends.add(t.nextToken().trim()); - } - } - //end-methods - - public static class Argfile { - private String name; - public void setName(String name) { this.name = name; } - } - - public class Ajdoc { - private Commandline cmd = new Commandline(); - public Commandline.Argument createArg() { return cmd.createArgument(); } - public Commandline getCommandline() { return cmd; } - public String toString() { return cmd + ""; } - } - - public class Testset extends FileSet { - private List<Argfile> argfileNames = new Vector<>(); - public List<File> argfiles; - public List<File> files; - public List<Argument> args = new Vector<>(); - public String classname; - private boolean havecludes = false; - private List<Run> testclasses = new Vector<>(); - private Path classpath; - private Path internalclasspath; - private Ajdoc ajdoc = null; - private boolean fork = false; - private boolean noclean; - private List<String> depends = new Vector<>(); - public String toString() { - String str = ""; - if (files.size() > 0) { - str += "files:" + "\n"; - for (Iterator<File> i = files.iterator(); i.hasNext();) { - str += "\t" + i.next() + "\n"; - } - } - if (argfiles.size() > 0) { - str += "argfiles:" + "\n"; - for (Iterator<File> i = argfiles.iterator(); i.hasNext();) { - str += "\t" + i.next() + "\n"; - } - } - if (args.size() > 0) { - str += "args:" + "\n"; - for (Iterator i = args.iterator(); i.hasNext();) { - str += "\t" + i.next() + "\n"; - } - } - if (testclasses.size() > 0) { - str += "classes:" + "\n"; - for (Iterator i = testclasses.iterator(); i.hasNext();) { - str += "\t" + i.next() + "\n"; - } - } - return str; - } - public void setIncludes(String includes) { - super.setIncludes(includes); - havecludes = true; - } - public void setExcludes(String excludes) { - super.setExcludes(excludes); - havecludes = true; - } - public void setIncludesfile(File includesfile) { - super.setIncludesfile(includesfile); - havecludes = true; - } - public void setExcludesfile(File excludesfile) { - super.setExcludesfile(excludesfile); - havecludes = true; - } - - public void setArgfile(String name) { - createArgfile().setName(name); - } - - public void setArgfiles(String str) { - StringTokenizer tok = new StringTokenizer(str, ", ", false); - while (tok.hasMoreTokens()) { - createArgfile().setName(tok.nextToken().trim()); - } - - } - public Argfile createArgfile() { - Argfile argfile = new Argfile(); - argfileNames.add(argfile); - return argfile; - } - public Run createJava() { - // See crashing note - //Run testclass = new Run(); - Run testclass = new Run(project); - this.testclasses.add(testclass); - return testclass; - } - public void addJava(Run run) { - this.testclasses.add(run); - } - public void setJava(String str) { - StringTokenizer t = new StringTokenizer(str, " "); - Run run = createJava(); - run.setClassname(t.nextToken().trim()); - while (t.hasMoreTokens()) { - run.createArg().setValue(t.nextToken().trim()); - } - } - public void setTestclass(String testclass) { - createJava().setClassname(testclass); - } - - public void setClasses(String str) { - for (StringTokenizer t = new StringTokenizer(str, ", ", false); - t.hasMoreTokens();) { - createJava().setClassname(t.nextToken().trim()); - } - } - public void setClasspath(Path path) { - if (classpath == null) { - classpath = path; - } else { - classpath.append(path); - } - } - - public Path createClasspath() { - if (classpath == null) { - classpath = new Path(project); - } - return classpath.createPath(); - } - - public void setClasspathRef(Reference r) { - createClasspath().setRefid(r); - } - public void setInternalclasspath(Path path) { - if (internalclasspath == null) { - internalclasspath = path; - } else { - internalclasspath.append(path); - } - } - - public Path createInternalclasspath() { - if (internalclasspath == null) { - internalclasspath = new Path(project); - } - return internalclasspath.createPath(); - } - - public void setInternalclasspathRef(Reference r) { - createInternalclasspath().setRefid(r); - } - - public void setAjdoc(boolean b) { - if (b && ajdoc == null) { - createAjdoc(); - } else if (!b) { - this.ajdoc = null; - } - } - public Ajdoc getAjdoc() { return this.ajdoc; } - public void setAjdocargs(String str) { - createAjdoc(); - for (StringTokenizer t = new StringTokenizer(str, ", ", false); - t.hasMoreTokens();) { - this.ajdoc.createArg().setValue(t.nextToken().trim()); - } - } - public void addAjdoc(Ajdoc ajdoc) { - this.ajdoc = ajdoc; - } - public Ajdoc createAjdoc() { - return this.ajdoc = new Ajdoc(); - } - public void setFork(boolean fork) { - this.fork = fork; - } - public void setNoclean(boolean noclean) { - this.noclean = noclean; - } - public void setDepends(String depends) { - for (StringTokenizer t = new StringTokenizer(depends, ", ", false); - t.hasMoreTokens();) { - this.depends.add(t.nextToken().trim()); - } - } - //end-testset-methods - - public void resolve() throws BuildException { - if (dir != null) this.setDir(dir); - File src = getDir(project); - argfiles = new Vector<>(); - files = new Vector<>(); - for(Iterator<Argfile> iter = argfileNames.iterator(); iter.hasNext();) { - String name = iter.next().name; - File argfile = new File(src, name); - if (check(argfile, name, location)) argfiles.add(argfile); - } - if (havecludes || argfiles.size() <= 0) { - String[] filenames = - getDirectoryScanner(project).getIncludedFiles(); - for (int j = 0; j < filenames.length; j++) { - String name = filenames[j]; - if (name.endsWith(".java")) { - File file = new File(src, name); - if (check(file, name, location)) files.add(file); - } - } - } - for (Iterator i = Ajctest.this.testclasses.iterator(); - i.hasNext();) { - this.testclasses.add((Run)i.next()); - } - if (this.classpath == null) { - setClasspath(Ajctest.this.classpath); - } - if (this.internalclasspath == null) { - setInternalclasspath(Ajctest.this.internalclasspath); - } - if (this.ajdoc == null) { - this.ajdoc = Ajctest.this.ajdoc; - } - if (this.fork) { - for (Iterator<Run> i = this.testclasses.iterator(); i.hasNext();) { - i.next().setFork(fork); - } - } - if (!this.noclean) { - this.noclean = Ajctest.this.noclean; - } - this.depends.addAll(Ajctest.this.depends); - } - private boolean check(File file, String name, Location loc) - throws BuildException { - loc = loc != null ? loc : location; - if (file == null) { - throw new BuildException - ("file " + name + " is null!", loc); - } - if (!file.exists()) { - throw new BuildException - ("file " + file + " with name " + name + - " doesn't exist!", loc); - } - return true; - } - public void setArgs(String str) { - if (str == null || str.length() < 1) return; - StringTokenizer tok = new StringTokenizer(str, ",", false); - while (tok.hasMoreTokens()) { - String name = tok.nextToken().trim(); - parse(name.startsWith("J") ? createJarg() : createArg(), name); - } - } - - public Argument createJarg() { - Argument arg = new Argument(true); - args.add(arg); - return arg; - } - - public Argument createArg() { - Argument arg = new Argument(false); - args.add(arg); - return arg; - } - } - - private void prepare() throws BuildException { - - } - - private void finish() throws BuildException { - if (errors.size() > 0) { - log(""); - log("There " + w(errors) + " " + errors.size() + " errors:"); - for (int i = 0; i < errors.size(); i++) { - log(" ", (Failure)errors.get(i), i); - } - } - allErrors.addAll(errors); - } - - private void log(String space, Failure failure, int num) { - String number = "[" + num + "] "; - log(enough(number, 60, '-')); - for (int i = number.length()-1; i > 0; i--) space += " "; - log(space, failure.testset.files, "files:"); - log(space, failure.testset.argfiles, "argfiles:"); - log(space, failure.args, "args:"); - log(space + "msgs:" + failure.msgs); - } - - - private String enough(String str, int size, char filler) { - while (str.length() < size) str += filler; - return str; - } - - - private void log(String space, List<?> list, String title) { - if (list == null || list.size() < 1) return; - log(space + title); - for (Iterator<?> i = list.iterator(); i.hasNext();) { - log(space + " " + i.next()); - } - } - - private void execute(Testset testset, List<Arg> args) throws BuildException { - if (testset.files.size() > 0) { - log("\tfiles:"); - for (Iterator<File> i = testset.files.iterator(); i.hasNext();) { - log("\t " + i.next()); - } - } - if (testset.argfiles.size() > 0) { - log("\targfiles:"); - for (Iterator<File> i = testset.argfiles.iterator(); i.hasNext();) { - log("\t " + i.next()); - } - } - if (args.size() > 0) { - log("\targs:"); - for (Iterator<Arg> i = args.iterator(); i.hasNext();) { - log("\t " + i.next()); - } - } - if (testset.testclasses.size() > 0) { - log("\tclasses:"); - for (Iterator<Run> i = testset.testclasses.iterator(); i.hasNext();) { - log("\t " + i.next()); - } - } - if (!testset.noclean && - (!isSet("noclean") && !isSet("nocompile"))) { - delete(destdir); - make(destdir); - } - delete(workingdir); - make(workingdir); - for (Iterator<String> i = testset.depends.iterator(); i.hasNext();) { - String target = i.next()+""; - // todo: capture failures here? - project.executeTarget(target); - } - int exit; - if (!isSet("nodoc") && testset.ajdoc != null) { - log("\tdoc... " + testset.ajdoc); - AjdocWrapper ajdoc = new AjdocWrapper(testset, args); - if ((exit = ajdoc.run()) != 0) { - post(testset, args, ajdoc.msgs, exit, "ajdoc"); - } else { - fire("ajdoc.good"); - } - fire("ajdoc.done"); - log("\tdone with ajdoc."); - } - boolean goodCompile = true; - if (!isSet("nocompile") && !nocompile) { - log("\tcompile" + - (testset.noclean ? "(boostrapped)" : "") + "..."); - //AjcWrapper ajc = new AjcWrapper(testset, args); - JavaCommandWrapper ajc; - // XXX dependency on Ant property ajctest.compiler - final String compiler = getAntProperty("ajctest.compiler"); - if ("eclipse".equals(compiler) || "eajc".equals(compiler)) { - ajc = new EAjcWrapper(testset, args); - } else if ((null == compiler) || "ajc".equals(compiler)) { - ajc = new AjcWrapper(testset, args); - } else if ("javac".equals(compiler)) { - throw new Error("javac not supported"); - //ajc = new JavacWrapper(testset, args); - } else { - throw new Error("unknown compiler: " + compiler); - } - - System.out.println("using compiler: " + ajc); - try { - if ((exit = ajc.run()) != 0) { - post(testset, args, ajc.msgs, exit, "ajc"); - goodCompile = false; - } else { - fire("ajc.good"); - } - fire("ajc.done"); - } catch (Throwable ___) { - post(testset, args, ___+"", -1, "ajc"); - goodCompile = false; - } - } - if (!goodCompile) { - post(testset, new Vector(), - "couldn't run classes " + testset.testclasses + - "due to failed compile", - -1, "run"); - - } else if (!isSet("norun")) { - for (Iterator<Run> i = testset.testclasses.iterator(); i.hasNext();) { - Run testclass = i.next(); - log("\ttest..." + testclass.classname()); - if (null != destdir) { - testclass.setClassesDir(destdir.getAbsolutePath()); - } - if ((exit = testclass.executeJava()) != 0) { - post(testset, new Vector(), testclass.msgs, exit, "run"); - } else { - fire("run.good"); - } - fire("run.done"); - } - } - log(""); - } - - public void execute() throws BuildException { - gui(this); - dumpresults = isSet("dumpresults"); - prepare(); - log(testsets.size() + " testset" + s(testsets), - Project.MSG_VERBOSE); - Map<Testset,List<List<Arg>>> testsetToArgcombo = new HashMap<>(); - List<Integer> argcombos = new Vector<>(); - for (Testset testset: testsets) { - testset.resolve(); - List<Argument> bothargs = new Vector<>(args); - bothargs.addAll(testset.args); - List<List<Arg>> argcombo = argcombo(bothargs); - argcombos.add(new Integer(argcombo.size())); - testsetToArgcombo.put(testset, argcombo); - } - while (!testsetToArgcombo.isEmpty()) { - int testsetCounter = 1; - for (Iterator<Testset> iter = testsets.iterator(); iter.hasNext(); testsetCounter++) { - Testset testset = iter.next(); - List<List<Arg>> argcombo = testsetToArgcombo.get(testset); - if (argcombo.size() == 0) { - testsetToArgcombo.remove(testset); - continue; - } - List<Arg> args = argcombo.remove(0); - final String startStr = "Testset " + testsetCounter + " of " + testsets.size(); - String str = startStr + " / Combo " + testsetCounter + " of " + argcombos.size(); - log("---------- " + str + " ----------"); - execute(testset, args); - } - } - -// for (Iterator iter = testsets.iterator(); iter.hasNext(); _++) { -// Testset testset = (Testset)iter.next(); -// testset.resolve(); -// List bothargs = new Vector(args); -// bothargs.addAll(testset.args); -// int __ = 1; -// List argcombo = argcombo(bothargs); -// log(argcombo.size() + " combination" + s(argcombo), -// Project.MSG_VERBOSE); -// final String startStr = "Testset " + _ + " of " + testsets.size(); -// for (Iterator comboiter = argcombo.iterator(); -// comboiter.hasNext(); __++) { -// List args = (List)comboiter.next(); -// execute(testset, args); -// log(""); -// } -// } - finish(); - } - - private void delete(File dir) throws BuildException { - Delete delete = (Delete)project.createTask("delete"); - delete.setDir(dir); - delete.execute(); - } - - private void make(File dir) throws BuildException { - Mkdir mkdir = (Mkdir)project.createTask("mkdir"); - mkdir.setDir(dir); - mkdir.execute(); - } - - private String getAntProperty(String name) { - String uprop = project.getUserProperty(name); - if (null == uprop) { - uprop = project.getProperty(name); - } - return uprop; - } - - private boolean isSet(String name) { - String uprop = project.getUserProperty(name); - if (uprop == null || - "no".equals(uprop) || - "false".equals(uprop)) return false; - String prop = project.getProperty(name); - if (prop == null || - "no".equals(prop) || - "false".equals(prop)) return false; - return true; - } - - /** - * Interpose Wrapper class to catch and report exceptions - * by setting a positive value for System.exit(). - * (In some cases it seems that Exceptions are not being reported - * as errors in the tests.) - * This forces the VM to fork. A forked VM is required for - * two reasons: - * (1) The wrapper class may have been defined by a different - * class loader than the target class, so it would not be able - * to load the target class; - * <p> - * (2) Since the wrapper class is generic, we have to pass in - * the name of the target class. I choose to do this using - * VM properties rather than hacking up the arguments. - * <p>todo: relies on name/value of property "taskdef.jar" - * to add jar with wrapper to invoking classpath. - * <p> - * It is beneficial for another reason: - * (3) The wrapper class can be asked to test-load all classes - * in a classes dir, by setting a VM property. This class - * sets up the property if the value is defined using - * <code>setClassesDir(String)</code> - * <p>todo: if more tunnelling, generalize and parse. - */ - public class RunWrapper extends Java { - public final Class LINK_WRAPPER_CLASS = MainWrapper.class; - /** tracked in MainWrapper.PROP_NAME */ // todo: since reflective, avoid direct - public final String PROP_NAME = "MainWrapper.classname"; - /** tracked in MainWrapper.CLASSDIR_NAME */ - public final String CLASSDIR_NAME = "MainWrapper.classdir"; - public final String WRAPPER_CLASS - = "org.aspectj.internal.tools.ant.taskdefs.MainWrapper"; - private String classname; - protected String classesDir; - /** capture classname here, replace with WRAPPER_CLASS */ - public void setClassname(String classname) { - super.setClassname(WRAPPER_CLASS); - this.classname = classname; - } - - /** - * Setup the requirements for the wrapper class: - * <li>fork to get classpath and VM properties right</li> - * <li>set VM property</li> - * <li>add ${ajctest.wrapper.jar} (with wrapper class) to the classpath</li> - */ - private void setup() { - setFork(true); - Commandline.Argument cname = createJvmarg(); - cname.setValue("-D"+PROP_NAME+"="+classname); - if (!noverify) { - cname = createJvmarg(); - cname.setValue("-Xfuture"); // todo: 1.2 or later.. - } - if (null != classesDir) { - cname = createJvmarg(); - cname.setValue("-D"+CLASSDIR_NAME+"="+classesDir); - } - // todo dependence on name/setting of ajctest.wrapper.jar - String value = project.getProperty("ajctest.wrapper.jar"); - if (null != value) { - Path wrapperPath = new Path(project, value); - RunWrapper.this.createClasspath().append(wrapperPath); - } - } - - /** do setup, then super.execute() */ - public int executeJava() { - setup(); - int result = super.executeJava(); - // snarf - also load all classes? - return result; - } - - /** set directory to scan for classes */ - public void setClassesDir(String dir) { - classesDir = dir; - } - } - - public class Run extends RunWrapper { - //public class Run extends Java - private Path bootclasspath; - public void setBootbootclasspath(Path path) { - if (bootclasspath == null) { - bootclasspath = path; - } else { - bootclasspath.append(path); - } - } - public Path createBootbootclasspath() { - if (bootclasspath == null) bootclasspath = new Path(this.project); - return bootclasspath.createPath(); - } - public void setBootbootclasspathRef(Reference r) { - createBootbootclasspath().setRefid(r); - } - private Path bootclasspatha; - public void setBootbootclasspatha(Path path) { - if (bootclasspatha == null) { - bootclasspatha = path; - } else { - bootclasspatha.append(path); - } - } - public Path createBootbootclasspatha() { - if (bootclasspatha == null) bootclasspatha = new Path(this.project); - return bootclasspatha.createPath(); - } - public void setBootbootclasspathaRef(Reference r) { - createBootbootclasspatha().setRefid(r); - } - private Path bootclasspathp; - public void setBootbootclasspathp(Path path) { - if (bootclasspathp == null) { - bootclasspathp = path; - } else { - bootclasspathp.append(path); - } - } - public Path createBootbootclasspathp() { - if (bootclasspathp == null) bootclasspathp = new Path(this.project); - return bootclasspathp.createPath(); - } - public void setBootbootclasspathpRef(Reference r) { - createBootbootclasspathp().setRefid(r); - } - public Run(Project project) { - super(); - //this.project = Ajctest.this.project; - this.setTaskName("ajcjava"); - this.project = project; - } - public String msgs = ""; - public int executeJava() { - Path cp = Ajctest.this.classpath != null ? Ajctest.this.classpath : - new Path(this.project, destdir.getAbsolutePath()); - cp.append(Path.systemClasspath); - this.setClasspath(cp); - if (bootclasspath != null) { - setFork(true); - createJvmarg().setValue("-Xbootclasspath:" + bootclasspath); - } - if (bootclasspatha != null) { - setFork(true); - createJvmarg().setValue("-Xbootclasspath/a:" + bootclasspatha); - } - if (bootclasspathp != null) { - setFork(true); - createJvmarg().setValue("-Xbootclasspath/p:" + bootclasspathp); - } - int exit = -1; - // todo: add timeout feature todo: this or below? - try { - exit = super.executeJava(); - } catch (Throwable t) { - StringWriter sw = new StringWriter(); - PrintWriter out = new PrintWriter(sw); - t.printStackTrace(out); - msgs = sw.toString(); - out.close(); - // todo: return exit code - } - return exit; - } - public String _classname; - public String classname() { return _classname; } - public void setClassname(String classname) { - super.setClassname(_classname = classname); - } - public String toString() { return _classname; } - } - // class Run - // todo: need to run in a wrapper which report non-zero int on exception - // todo: unused method? see executeJava above. -// private int java(String classname, Collection args) throws BuildException { -// Java java = (Java)project.createTask("java"); -// java.setClassname(classname); -// for (Iterator i = args.iterator(); i.hasNext();) { -// Object o = i.next(); -// Commandline.Argument arg = java.createArg(); -// if (o instanceof File) { -// arg.setFile((File)o); -// } else if (o instanceof Path) { -// arg.setPath((Path)o); -// } else { -// arg.setValue(o+""); -// } -// } -// return java.executeJava(); -// } - - private static List allErrors = new Vector(); - private List<Failure> errors = new Vector<>(); - - private void post(Testset testset, List args, - String msgs, int exit, String type) { - errors.add(new Failure(testset, args, msgs, exit, type, testId)); - fire(type + ".fail"); - } - - private static long startTime; - private static long stopTime; - - private static String date(long time) { - return DateFormat.getDateTimeInstance - (DateFormat.FULL, DateFormat.FULL). - format(new Date(time)); - } - - static { - final PrintStream err = System.err; - startTime = System.currentTimeMillis(); - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - private String ms(long start, long stop) { - long rest = Math.abs(stop-start) / 1000; - long days = rest / 86400; - long hours = (rest -= days*86400) / 3600; - long mins = (rest -= hours*3600) / 60; - long secs = (rest -= mins*60); - boolean req = false; - String str = ""; - if (req || days > 0) { - req = true; - str += days + " day" + (days != 1 ? "s" : "") + " "; - } - if (req || hours > 0) { - req = true; - str += hours + " hour" + (hours != 1 ? "s" : "") + " "; - } - if (req || mins > 0) { - req = true; - str += mins + " minute" + (mins != 1 ? "s" : "") + " "; - } - str += secs + " second" + (secs != 1 ? "s" : "") + " "; - return str; - } - - public void run() { - Ajctest current = CURRENT_AJCTEST; - String oneLine = "warning: oneLine not set."; - String multiLine = "warning: multiLine not set."; - - // setup oneLine - if (null == current) { - oneLine = "\nRESULT=\"ERROR\" null ACJTEST"; - } else { - StringBuffer sb = new StringBuffer("\n"); - int errs = Ajctest.allErrors.size(); - int allFails = errs - + current.ajdocStats.fails - + current.ajcStats.fails - + current.runStats.fails; - if (1 > allFails) { - sb.append("RESULT=\"PASS\"\terrors=\""); - } else { - sb.append("RESULT=\"FAIL\"\terrors=\""); - } - sb.append(""+errs); - sb.append("\"\tajdoc.pass=\""); - sb.append(""+current.ajdocStats.goods); - sb.append("\"\tajdoc.fail=\""); - sb.append(""+current.ajdocStats.fails); - sb.append("\"\tajc.pass=\""); - sb.append(""+current.ajcStats.goods); - sb.append("\"\tajc.fail=\""); - sb.append(""+current.ajcStats.fails); - sb.append("\"\trun.pass=\""); - sb.append(""+current.runStats.goods); - sb.append("\"\trun.fail=\""); - sb.append(""+current.runStats.fails); - sb.append("\"\ttestId=\""); - sb.append(current.testId); - sb.append("\"\tproject=\""); - Project p = current.getProject(); - if (null != p) sb.append(p.getName()); - sb.append("\"\tfile=\""); - sb.append(""+current.getLocation()); - sb.append("\""); - oneLine = sb.toString(); - } - - // setup multiLine - { - stopTime = System.currentTimeMillis(); - String str = ""; - str += "\n"; - str += - "===================================" + - "===================================" + "\n"; - str += "Test started : " + date(startTime) + "\n"; - str += "Test ended : " + date(stopTime) + "\n"; - str += "Total time : " + ms(startTime, stopTime) + "\n"; - str += - "------------------------------" + - " Summary " + - "------------------------------" + "\n"; - str += "Task\tPassed\tFailed" + "\n"; - Object[] os = new Object[] { - "ajdoc", current.ajdocStats.goods+"", current.ajdocStats.fails+"", - "ajc", current.ajcStats.goods +"", current.ajcStats.fails +"", - "run", current.runStats.goods +"", current.runStats.fails +"", - }; - for (int i = 0; i < os.length; i += 3) { - str += os[i] + "\t" + os[i+1] + "\t" + os[i+2] + "\n"; - } - if (allErrors.size() > 0) { - str += "" + "\n"; - str += - "There " + w(allErrors) + " " + - allErrors.size() + " error" + - s(allErrors) + ":" + "\n"; - for (int i = 0; i < allErrors.size(); i++) { - Failure failure = (Failure)allErrors.get(i); - str += - "---------- Error " + i + " [" + - failure.testId + "]" + - " ------------------------------" + "\n"; - str += " " + failure + "\n\n"; - } - } else { - str += "No errors." + "\n"; - } - str += "--------------------------" + - " End of Summary " + - "---------------------------" + "\n"; - multiLine = str; - } - - // print both multiLine and oneLine - err.println(multiLine); - err.println(oneLine); - if (dumpresults && (allErrors.size() + - current.ajdocStats.fails + - current.ajcStats.fails + - current.runStats.fails) > 0) { - String date = date(System.currentTimeMillis()); - String filename = "ajc-errors"; - for (StringTokenizer t = new StringTokenizer(date, ",: "); - t.hasMoreTokens();) { - filename += "-" + t.nextToken().trim(); - } - filename += ".txt"; - PrintWriter out = null; - File file = new File(filename); - System.err.println("dumping results to " + file); - try { - out = new PrintWriter(new FileWriter(file)); - out.println(multiLine); - out.println(oneLine); - System.err.println("dumped results to " + file); - } catch (IOException ioe) { - if (out != null) out.close(); - } - } - } - })); - } - - private static String w(List list) { return a(list, "were", "was"); } - private static String s(List list) { return a(list, "s", ""); } - - private static String a(List list, String some, String one) { - return list == null || list.size() != 1 ? some : one; - } - - static class Failure { - public final Testset testset; - public final List args; - public final String msgs; - public final int exit; - public final String type; - public final long time; - public final String testId; - public Failure(Testset testset, List args, - String msgs, int exit, String type, - String testId) { - this.testset = testset; - this.args = args; - this.msgs = msgs; - this.exit = exit; - this.type = type; - this.time = System.currentTimeMillis(); - this.testId = testId; - } - public String toString() { - String str = "testId:" + testId+ "\n"; - str += "type:" + type + "\n"; - str += testset + "\n"; - if (args.size() > 0) { - str += " args: " + args + "\n";; - } - str += " msgs:" + msgs + "\n"; - str += " exit:" + exit; - return str; - } - } - - private List<List<Arg>> argcombo(List<Argument> arguments) { - List<Argument> combos = new Vector<>(); - List<Arg> always = new Vector<>(); - for (Iterator<Argument> iter = arguments.iterator(); iter.hasNext();) { - Argument arg = iter.next(); - if (arg.values.size() == 0) arg.values.add(""); - if (!arg.always && !arg.values.contains(null)) arg.values.add(null); - if (arg.values.size() > 0) { - combos.add(arg); - } else if (arg.always) { - always.add(new Arg(arg.name, arg.values.get(0)+"", arg.isj)); - } - } - List<List<Arg>> argcombo = combinations(combos); - for (Iterator<Arg> iter = always.iterator(); iter.hasNext();) { - Arg arg = iter.next(); - for (Iterator<List<Arg>> comboiter = argcombo.iterator(); comboiter.hasNext();) { - comboiter.next().add(arg); - } - } - return argcombo; - } - - private abstract class ExecWrapper { - public String msgs; - public int run() { - return run(createCommandline()); - } - protected abstract Commandline createCommandline(); - protected final int run(Commandline cmd) { - Process process = null; - int exit = Integer.MIN_VALUE; - final StringBuffer buf = new StringBuffer(); - Thread errPumper = null; - Thread outPumper = null; - try { - log("\tcalling " + cmd, Project.MSG_VERBOSE); - process = Runtime.getRuntime().exec(cmd.getCommandline()); - OutputStream os = new OutputStream() { - StringBuffer sb = new StringBuffer(); - public void write(int b) throws IOException { - final char c = (char)b; - buf.append(c); - if (c != '\n') { - sb.append(c); - } else { - System.err.println(sb.toString()); - sb = new StringBuffer(); - } - } - }; - OutputStream los = new LogOutputStream(Ajctest.this, - Project.MSG_INFO); - outPumper = new Thread(new StreamPumper(process.getInputStream(), - los)); - errPumper = new Thread(new StreamPumper(process.getErrorStream(), - os)); - outPumper.setDaemon(true); - errPumper.setDaemon(true); - outPumper.start(); - errPumper.start(); - process.waitFor(); - } catch (Exception e) { - e.printStackTrace(); - //throw e; - } finally { - try { - if (outPumper != null) outPumper.join(); - if (errPumper != null) errPumper.join(); - } catch (InterruptedException ie) { - } finally { - outPumper = null; - errPumper = null; - } - exit = process.exitValue(); - msgs = buf.toString(); - if (exit != 0) { - log("Test failed with exit value: " + exit); - } else { - log("Success!", Project.MSG_VERBOSE); - } - if (process != null) process.destroy(); - process = null; - System.err.flush(); - System.out.flush(); - } - return exit; - } - } - - private class AjcWrapper extends JavaCommandWrapper { - public AjcWrapper(Testset testset, List args) { - super(testset, args, false); - if (testset.noclean) { - setExtraclasspath(new Path(project, - destdir.getAbsolutePath())); - } - } - String getMainClassName() { - return "org.aspectj.tools.ajc.Main"; - } - } - - private class EAjcWrapper extends JavaCommandWrapper { - public EAjcWrapper(Testset testset, List args) { - super(testset, args, false); - if (testset.noclean) { - setExtraclasspath(new Path(project, - destdir.getAbsolutePath())); - } - } - String getMainClassName() { - return "org.aspectj.ajdt.ajc.Main"; - } - } - - static List ajdocArgs(List args) { - List newargs = new Vector(); - for (Iterator i = args.iterator(); i.hasNext();) { - String arg = i.next() + ""; - if (arg.startsWith("-X")) { - newargs.add(arg); - } else if (arg.equals("-public") || - arg.equals("-package") || - arg.equals("-protected") || - arg.equals("-private")) { - newargs.add(arg); - } else if (arg.equals("-d") || - arg.equals("-classpath") || - arg.equals("-cp") || - arg.equals("-sourcepath") || - arg.equals("-bootclasspath") || - arg.equals("-argfile")) { - newargs.add(arg); - newargs.add(i.next()+""); - } else if (arg.startsWith("@")) { - newargs.add(arg); - } - } - return newargs; - } - - private class AjdocWrapper extends JavaCommandWrapper { - public AjdocWrapper(Testset testset, List args) { - super(testset, ajdocArgs(args), true); - String[] cmds = testset.getAjdoc().getCommandline().getCommandline(); - for (int i = 0; i < cmds.length; i++) { - this.args.add(cmds[i]); - } - } - String getMainClassName() { - return "org.aspectj.tools.ajdoc.Main"; - } - } - - private abstract class JavaCommandWrapper extends ExecWrapper { - abstract String getMainClassName(); - protected Testset testset; - protected List args; - protected boolean needsClasspath; - protected Path extraClasspath; - - public JavaCommandWrapper(Testset testset, List args, - boolean needsClasspath) { - this.testset = testset; - this.args = args; - this.needsClasspath = needsClasspath; - this.extraClasspath = testset.internalclasspath; - } - public void setExtraclasspath(Path extraClasspath) { - this.extraClasspath = extraClasspath; - } - - public String toString() { - return LangUtil.unqualifiedClassName(getClass()) - + "(" + getMainClassName() + ")"; - } - - protected Commandline createCommandline() { - Commandline cmd = new Commandline(); - cmd.setExecutable("java"); - cmd.createArgument().setValue("-classpath"); - Path cp = null; - if (extraClasspath != null) { - cp = extraClasspath; - } - if (extraClasspath == null) { - Path aspectjBuildDir = - new Path(project, - project.getProperty("ajctest.pathelement")); - // todo: dependency on ant script variable name ajctest.pathelement - if (cp == null) cp = aspectjBuildDir; - else cp.append(aspectjBuildDir); - } - if (cp == null) { - cp = Path.systemClasspath; - } else { - cp.append(Path.systemClasspath); - } - cmd.createArgument().setPath(cp); - for (Iterator iter = args.iterator(); iter.hasNext();) { - Arg arg = (Arg)iter.next(); - if (arg.isj) { - cmd.createArgument().setValue(arg.name); - if (!arg.value.equals("")) { - cmd.createArgument().setValue(arg.value); - } - } - } - cmd.createArgument().setValue(getMainClassName()); - boolean alreadySetDestDir = false; - boolean alreadySetClasspath = false; - for (Iterator iter = args.iterator(); iter.hasNext();) { - Arg arg = (Arg)iter.next(); - if (!arg.isj) { - cmd.createArgument().setValue(arg.name); - if (arg.name.equals("-d")) { - setDestdir(arg.value+""); - alreadySetDestDir = true; - } - if (arg.name.equals("-classpath")) { - alreadySetClasspath = true; - } - if (!arg.value.equals("")) { - cmd.createArgument().setValue(arg.value); - } - } - } - if (destdir == null) { - setDestdir("."); - } - if (!alreadySetDestDir) { - cmd.createArgument().setValue("-d"); - cmd.createArgument().setFile(destdir); - } - if (!alreadySetClasspath && testset.classpath != null) { - cmd.createArgument().setValue("-classpath"); - cmd.createArgument().setPath(testset.classpath); - } else if (needsClasspath) { - Path _cp = Ajctest.this.classpath != null ? Ajctest.this.classpath : - new Path(project, destdir.getAbsolutePath()); - _cp.append(Path.systemClasspath); - cmd.createArgument().setValue("-classpath"); - cmd.createArgument().setPath(_cp); - } - for (Iterator iter = testset.files.iterator(); iter.hasNext();) { - cmd.createArgument().setFile((File)iter.next()); - } - for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { - cmd.createArgument().setValue("-argfile"); - cmd.createArgument().setFile((File)iter.next()); - } - return cmd; - } - } - - /** implement invocation of ajc */ -// private void java(Testset testset, List args) throws BuildException { -// Java java = (Java)project.createTask("java"); -// java.setClassname("org.aspectj.tools.ajc.Main"); -// if (classpath != null) { -// java.setClasspath(classpath); -// } -// for (Iterator iter = args.iterator(); iter.hasNext();) { -// Arg arg = (Arg)iter.next(); -// if (arg.isj) { -// java.createJvmarg().setValue(arg.name); -// if (!arg.value.equals("")) { -// java.createJvmarg().setValue(arg.value); -// } -// } -// } -// for (Iterator iter = args.iterator(); iter.hasNext();) { -// Arg arg = (Arg)iter.next(); -// if (!arg.isj) { -// java.createArg().setValue(arg.name); -// if (!arg.value.equals("")) { -// java.createArg().setValue(arg.value); -// } -// } -// } -// for (Iterator iter = testset.files.iterator(); iter.hasNext();) { -// java.createArg().setFile((File)iter.next()); -// } -// for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { -// java.createArg().setValue("-argfile"); -// java.createArg().setFile((File)iter.next()); -// } -// java.setFork(true); -// java.execute(); -// } -// -// private void exec(Testset testset, List args) throws BuildException { -// ExecTask exec = (ExecTask)project.createTask("exec"); -// exec.setExecutable("java"); -// if (classpath != null) { -// exec.createArg().setValue("-classpath"); -// exec.createArg().setPath(classpath); -// } -// for (Iterator iter = args.iterator(); iter.hasNext();) { -// Arg arg = (Arg)iter.next(); -// if (arg.isj) { -// exec.createArg().setValue(arg.name); -// if (!arg.value.equals("")) { -// exec.createArg().setValue(arg.value); -// } -// } -// } -// exec.createArg().setValue("org.aspectj.tools.ajc.Main"); -// for (Iterator iter = args.iterator(); iter.hasNext();) { -// Arg arg = (Arg)iter.next(); -// if (!arg.isj) { -// exec.createArg().setValue(arg.name); -// if (!arg.value.equals("")) { -// exec.createArg().setValue(arg.value); -// } -// } -// } -// for (Iterator iter = testset.files.iterator(); iter.hasNext();) { -// exec.createArg().setFile((File)iter.next()); -// } -// for (Iterator iter = testset.argfiles.iterator(); iter.hasNext();) { -// exec.createArg().setValue("-argfile"); -// exec.createArg().setFile((File)iter.next()); -// } -// exec.execute(); -// } -// - public void handle(Throwable t) { - log("handling " + t); - if (t != null) t.printStackTrace(); - log("done handling " + t); - } - - private List<List<Arg>> combinations(List<Argument> arglist) { - List<List<Arg>> result = new Vector<>(); - result.add(new Vector<Arg>()); - for (Iterator<Argument> iter = arglist.iterator(); iter.hasNext();) { - Argument arg = iter.next(); - int N = result.size(); - for (int i = 0; i < N; i++) { - List<Arg> to = result.remove(0); - for (Iterator<String> valiter = arg.values.iterator(); valiter.hasNext();) { - List<Arg> newlist = new Vector<>(to); - Object val = valiter.next(); - if (val != null) newlist.add(new Arg(arg.name, val+"", arg.isj)); - result.add(newlist); - } - } - } - return result; - } - - /////////////////////// GUI support ////////////////////////////// - private static Gui gui; - - private static void gui(Ajctest ajc) { - if (firstTime && ajc.isSet("gui")) { - JFrame f = new JFrame("AspectJ Test Suite"); - f.getContentPane().add(BorderLayout.CENTER, gui = new Gui()); - f.pack(); - f.setVisible(true); - } - if (gui != null) { - ajc.bean.addPropertyChangeListener(gui); - } - firstTime = false; - } - - private static class Gui extends JPanel implements PropertyChangeListener { - private FailurePanel fail = new FailurePanel(); - private TablePanel table = new TablePanel(); - private StatusPanel status = new StatusPanel(); - public Gui() { - super(new BorderLayout()); - JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT); - split.setPreferredSize(new Dimension(500, 300)); - split.add(JSplitPane.BOTTOM, fail); - split.add(JSplitPane.TOP, table); - split.setDividerLocation(200); - add(BorderLayout.CENTER, split); - add(BorderLayout.SOUTH, status); - setPreferredSize(new Dimension(640, 680)); - } - public void propertyChange(PropertyChangeEvent evt) { - String name = evt.getPropertyName(); - if ("ajdoc.good".equals(name)) { - status.ajc.goods.inc(); - } else if ("ajc.good".equals(name)) { - status.ajc.goods.inc(); - } else if ("run.good".equals(name)) { - status.runs.goods.inc(); - } - if ("ajdoc.done".equals(name)) { - status.ajc.total.inc(); - } else if ("ajc.done".equals(name)) { - status.ajc.total.inc(); - } else if ("run.done".equals(name)) { - status.runs.total.inc(); - } - if ("ajdoc.fail".equals(name)) { - status.ajc.fails.inc(); - } else if ("ajc.fail".equals(name)) { - status.ajc.fails.inc(); - } else if ("run.fail".equals(name)) { - status.runs.fails.inc(); - } - } - - private abstract static class TitledPanel extends JPanel { - public TitledPanel(LayoutManager layout, String title) { - super(layout); - setBorder(BorderFactory.createTitledBorder(title)); - } - } - - private static class StatusPanel extends TitledPanel { - StatusInnerPanel ajdoc = new StatusInnerPanel("Ajdoc"); - StatusInnerPanel runs = new StatusInnerPanel("Runs"); - StatusInnerPanel ajc = new StatusInnerPanel("Ajc"); - - public StatusPanel() { - super(new FlowLayout(), "Status"); - add(ajdoc); - add(runs); - add(ajc); - } - - private static class StatusInnerPanel extends TitledPanel { - IntField goods = new IntField(5, Color.green.darker()); - IntField fails = new IntField(5, Color.red.darker()); - IntField total = new IntField(5, Color.blue.darker()); - public StatusInnerPanel(String str) { - super(null, str); - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - Object[] os = new Object[] { - "Passed", goods, - "Failed", fails, - "Totals", total, - }; - for (int i = 0; i < os.length; i += 2) { - JPanel p = p(); - p.add(new JLabel(os[i]+":")); - p.add((Component)os[i+1]); - this.add(p); - } - } - - private JPanel p() { - JPanel p = new JPanel(); - p.setLayout(new FlowLayout(FlowLayout.LEFT)); - return p; - } - - private class IntField extends JTextField { - public IntField(int i, Color fg) { - super("0", i); - this.setBackground(StatusInnerPanel.this.getBackground()); - this.setForeground(fg); - this.setEditable(false); - this.setBorder(BorderFactory.createEmptyBorder()); - } - public void add(int i) { - setText((Integer.parseInt(getText().trim())+i)+""); - } - public void inc() { add(1); } - } - } - } - - private class TablePanel extends TitledPanel { - private DefaultTableModel model = new DefaultTableModel(); - private TJable table; - private List failures = new Vector(); - public TablePanel() { - super(new BorderLayout(), "Failures"); - Object[] names = new String[] { - "Task", "Type", "Number", "Time" - }; - for (int i = 0; i < names.length; i++) { - model.addColumn(names[i]); - } - table = new TJable(model, failures); - this.add(new JScrollPane(table), BorderLayout.CENTER); - } - - private class TJable extends JTable { - private List list; - public TJable(TableModel model, List list) { - super(model); - this.list = list; - setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - } - public void valueChanged(ListSelectionEvent e) { - super.valueChanged(e); - if (list == null) return; - int i = (e.getFirstIndex()-e.getLastIndex())/2; - if (list.size() > 0) { - Failure f = (Failure)list.get(i); - fail.setFailure(f); - } - } - } - - public void add(Failure f, String taskname, String type, - int num, long time) { - model.addRow(new Object[]{taskname, type, - new Integer(num), date(time)}); - failures.add(f); - } - } - - private static class FailurePanel extends TitledPanel { - private JTextArea msgs = new JTextArea(10,50); - private InfoPanel info = new InfoPanel(); - - public FailurePanel() { - super(new BorderLayout(), "Failure"); - msgs.setFont(StyleContext.getDefaultStyleContext(). - getFont("SansSerif", Font.PLAIN, 10)); - add(BorderLayout.NORTH, info); - JScrollPane sc = new JScrollPane(msgs); - sc.setBorder(BorderFactory.createTitledBorder("Messages")); - add(BorderLayout.CENTER, sc); - } - - public void setText(String str) { - msgs.setText(str); - } - - public void setFailure(Failure f) { - msgs.setText(f.msgs); - info.setText("Type" , f.type); - info.setText("Args" , f.args); - info.setText("Exit" , f.exit+""); - info.setText("Time" , date(f.time)); - info.setText("Files" , f.testset.files); - info.setText("Classnames" , f.testset.testclasses); - } - - private static class InfoPanel extends JPanel { - Map fields = new HashMap(); - public void setText(String key, Object str) { - ((JTextField)fields.get(key)).setText(str+""); - } - public InfoPanel() { - super(new GridBagLayout()); - LabelFieldGBC gbc = new LabelFieldGBC(); - Object[] os = new Object[] { - "Type", - "Args", - "Exit", - "Time", - "Files", - "Classnames", - }; - for (int i = 0; i < os.length; i++) { - String name = os[i]+""; - JLabel label = new JLabel(name+":"); - JTextField comp = new JTextField(25); - comp.setEditable(false); - comp.setBackground(Color.white); - comp.setBorder(BorderFactory. - createBevelBorder(BevelBorder.LOWERED)); - label.setLabelFor(comp); - fields.put(name, comp); - add(label, gbc.forLabel()); - add(comp, gbc.forField()); - } - add(new JLabel(), gbc.forLastLabel()); - } - } - - private static class LabelFieldGBC extends GridBagConstraints { - public LabelFieldGBC() { - insets = new Insets(1,3,1,3); - gridy = RELATIVE; - gridheight = 1; - gridwidth = 1; - } - public LabelFieldGBC forLabel() { - fill = NONE; - gridx = 0; - anchor = NORTHEAST; - weightx = 0.0; - return this; - } - - public LabelFieldGBC forLastLabel() { - forLabel(); - fill = VERTICAL; - weighty = 1.0; - return this; - } - - public LabelFieldGBC forField() { - fill = HORIZONTAL; - gridx = 1; - anchor = CENTER; - weightx = 1.0; - return this; - } - - public LabelFieldGBC forLastField() { - forField(); - fill = BOTH; - weighty = 1.0; - return this; - } - } - } - } - -} diff --git a/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java b/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java deleted file mode 100644 index 6ce22df24..000000000 --- a/testing/src/main/java/org/aspectj/internal/tools/ant/taskdefs/MainWrapper.java +++ /dev/null @@ -1,181 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - - -package org.aspectj.internal.tools.ant.taskdefs; - -import java.io.File; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import org.aspectj.testing.util.LangUtil; - -/** - * Wrapper to invoke class identified by setting VM argument. - * Caller must set a system property "MainWrapper.classname" - * to the fully-qualified name of the target class to invoke, - * and the target class must be resolvable from the defining - * class loader of this class. - * VM argument name is available as <code>PROP_NAME</code>, but - * is set by adding the following to the command line: - * <code>-DMainWrapper.classname="fully.qualified.Classname"</code>. - * This returns -1 if unable to load the main method, - * 1 if the invoked method throws an exception, and 0 otherwise. - */ -public class MainWrapper { - /** MUST set the fully-qualified name of class to invoke using - * a VM property of this name - * tracked in Ajctest.java */ - public static final String PROP_NAME = "MainWrapper.classname"; - /** May set the path to a classes diretory, - * to interpret class names and load classes. - * Tracked in Ajctest.java */ - public static final String CLASSDIR_NAME = "MainWrapper.classdir"; - - /** to disable returning int via System.exit, set to boolean true value (todo: ignored) */ - public static final String SIGNAL_EXCEPTION_NAME = "MainWrapper.signalException"; - - /** to disable returning via System.exit on first Throwable, set to boolean true value (todo: ignored) */ - public static final String FAIL_ON_EXCEPTION_NAME = "MainWrapper.failOnException"; - - /** quit on first exception */ // todo public class controls - yuck - public static boolean FAIL_ON_EXCEPTION = true; - - /** signal number of exceptions with int return value */ - public static boolean SIGNAL_EXCEPTION = true; - - /** redirect messages for exceptions; if null, none printed */ - public static PrintStream OUT_STREAM = System.err; - - /** result accumulated, possibly from multiple threads */ - private static int result; - - /** - * Run target class's main(args), doing a System.exit() with - * a value > 0 for the number of Throwable that - * the target class threw that - * makes it through to a top-level ThreadGroup. (This is - * strictly speaking not correct since applications can live - * after their exceptions stop a thread.) - * Exit with a value < 0 if there were exceptions in loading - * the target class. Messages are printed to OUT_STREAM. - */ - public static void main(String[] args) { - String classname = "no property : " + PROP_NAME; - Method main = null; - // setup: this try block is for loading main method - return -1 if fail - try { - // access classname from jvm arg - classname = System.getProperty(PROP_NAME); - // this will fail if the class is not available from this classloader - Class<?> cl = Class.forName(classname); - final Class<?>[] argTypes = new Class[] {String[].class}; - // will fail if no main method - main = cl.getMethod("main", argTypes); - if (!Modifier.isStatic(main.getModifiers())) { - PrintStream outStream = OUT_STREAM; - if (null != outStream) outStream.println("main is not static"); - result = -1; - } - // if user also request loading of all classes... - String classesDir = System.getProperty(CLASSDIR_NAME); - if ((null != classesDir) && (0 < classesDir.length())) { - MainWrapper.loadAllClasses(new File(classesDir)); - } - } catch (Throwable t) { - if (1 != result) result--; - reportException("setup Throwable invoking class " + classname, t); - } - // run: this try block is for running things - get Throwable from our thread here - if ((null != main) && (0 == result)) { - try { - runInOurThreadGroup(main, args); - } catch (Throwable t) { - if (result > -1) { - result++; - } - reportException("run Throwable invoking class " + classname, t); - } - } - if ((0 != result) && (SIGNAL_EXCEPTION)) { - System.exit(result); - } - } - - static void runInOurThreadGroup(final Method main, final String[] args) { - final String classname = main.getDeclaringClass().getName(); - ThreadGroup ourGroup = new ThreadGroup("MainWrapper ThreadGroup") { - public void uncaughtException(Thread t, Throwable e) { - reportException("uncaughtException invoking " + classname, e); - result++; - if (FAIL_ON_EXCEPTION) { - System.exit((SIGNAL_EXCEPTION ? result : 0)); - } - } - }; - Runnable runner = new Runnable() { - public void run() { - try { - main.invoke(null, new Object[] {args}); - } catch (InvocationTargetException e) { - result = -1; - reportException("InvocationTargetException invoking " + classname, e); - } catch (IllegalAccessException e) { - result = -1; - reportException("IllegalAccessException invoking " + classname, e); - } - } - }; - Thread newMain = new Thread(ourGroup, runner, "pseudo-main"); - newMain.start(); - try { - newMain.join(); - } catch (InterruptedException e) { - result = -1; // todo: InterruptedException might be benign - retry? - reportException("Interrupted while waiting for to join " + newMain, e); - } - } - - /** - * Try to load all classes in a directory. - * @throws Error if any failed - */ - static protected void loadAllClasses(File classesDir) { - if (null != classesDir) { - String[] names = LangUtil.classesIn(classesDir); - StringBuffer err = new StringBuffer(); - LangUtil.loadClasses(names, null, err); - if (0 < err.length()) { - throw new Error("MainWrapper Errors loading classes: " - + err.toString()); - } - } - } - - static void reportException(String context, Throwable t) { - PrintStream outStream = OUT_STREAM; - if (null != outStream) { - while ((null != t) && - (InvocationTargetException.class.isAssignableFrom(t.getClass()))) { - t = ((InvocationTargetException) t).getTargetException(); - } - outStream.println(" context: " + context); - outStream.println(" message: " + t.getMessage()); - t.printStackTrace(outStream); - } - } - -} // MainWrapper diff --git a/testing/src/main/java/org/aspectj/testing/AjcTest.java b/testing/src/main/java/org/aspectj/testing/AjcTest.java deleted file mode 100644 index 4cb9a8722..000000000 --- a/testing/src/main/java/org/aspectj/testing/AjcTest.java +++ /dev/null @@ -1,169 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004,2018 IBM Corporation, contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * ******************************************************************/ -package org.aspectj.testing; - -import java.util.ArrayList; -import java.util.List; - -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.util.LangUtil; - -/** - * @author Adrian Colyer - * @author Andy Clement - */ -public class AjcTest { - -// private static boolean is13VMOrGreater = true; - private static boolean is14VMOrGreater = true; - private static boolean is15VMOrGreater = false; - private static boolean is16VMOrGreater = false; - private static boolean is17VMOrGreater = false; - private static boolean is18VMOrGreater = false; - private static boolean is19VMOrGreater = false; - private static boolean is10VMOrGreater = false; - private static boolean is11VMOrGreater = false; - - static { // matching logic is also in org.aspectj.util.LangUtil - is14VMOrGreater = LangUtil.is14VMOrGreater(); - is15VMOrGreater = LangUtil.is15VMOrGreater(); - is16VMOrGreater = LangUtil.is16VMOrGreater(); - is17VMOrGreater = LangUtil.is17VMOrGreater(); - is18VMOrGreater = LangUtil.is18VMOrGreater(); - is19VMOrGreater = LangUtil.is19VMOrGreater(); - is10VMOrGreater = LangUtil.is10VMOrGreater(); - is11VMOrGreater = LangUtil.is11VMOrGreater(); - } - - private List<ITestStep> testSteps = new ArrayList<ITestStep>(); - - private String dir; - private String pr; - private String title; - private String keywords; - private String comment; - private String vmLevel = "1.3"; - - public AjcTest() { - } - - public void addTestStep(ITestStep step) { - testSteps.add(step); - step.setTest(this); - } - - public boolean runTest(AjcTestCase testCase) { - if (!canRunOnThisVM()) return false; - try { - System.out.print("TEST: " + getTitle() + "\t"); - for (ITestStep step: testSteps) { - step.setBaseDir(getDir()); - System.out.print("."); - step.execute(testCase); - } - } finally { - System.out.println("DONE"); - } - return true; - } - - public boolean canRunOnThisVM() { - if (vmLevel.equals("1.3")) return true; - boolean canRun = true; - if (vmLevel.equals("1.4")) canRun = is14VMOrGreater; - if (vmLevel.equals("1.5")) canRun = is15VMOrGreater; - if (vmLevel.equals("1.6")) canRun = is16VMOrGreater; - if (vmLevel.equals("1.7")) canRun = is17VMOrGreater; - if (vmLevel.equals("1.8")) canRun = is18VMOrGreater; - if (vmLevel.equals("1.9")) canRun = is19VMOrGreater; - if (vmLevel.equals("10")) canRun = is10VMOrGreater; - if (vmLevel.equals("11")) canRun = is11VMOrGreater; - if (!canRun) { - System.out.println("***SKIPPING TEST***" + getTitle()+ " needs " + getVmLevel() - + ", currently running on " + System.getProperty("java.vm.version")); - } - return canRun; - } - - /** - * @return Returns the comment. - */ - public String getComment() { - return comment; - } - /** - * @param comment The comment to set. - */ - public void setComment(String comment) { - this.comment = comment; - } - /** - * @return Returns the dir. - */ - public String getDir() { - return dir; - } - /** - * @param dir The dir to set. - */ - public void setDir(String dir) { - dir = "../tests/" + dir; - this.dir = dir; - } - /** - * @return Returns the keywords. - */ - public String getKeywords() { - return keywords; - } - /** - * @param keywords The keywords to set. - */ - public void setKeywords(String keywords) { - this.keywords = keywords; - } - /** - * @return Returns the pr. - */ - public String getPr() { - return pr; - } - /** - * @param pr The pr to set. - */ - public void setPr(String pr) { - this.pr = pr; - } - /** - * @return Returns the title. - */ - public String getTitle() { - return title; - } - /** - * @param title The title to set. - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * @param vmLevel The vmLevel to set. - */ - public void setVm(String vmLevel) { - this.vmLevel = vmLevel; - } - - /** - * @return Returns the vmLevel. - */ - public String getVmLevel() { - return vmLevel; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/AntSpec.java b/testing/src/main/java/org/aspectj/testing/AntSpec.java deleted file mode 100644 index ceba08b29..000000000 --- a/testing/src/main/java/org/aspectj/testing/AntSpec.java +++ /dev/null @@ -1,265 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://eclipse.org/legal/epl-v10.html - * - * Contributors: - * Alexandre Vasseur initial implementation - *******************************************************************************/ -package org.aspectj.testing; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.util.StringTokenizer; - -import org.apache.tools.ant.BuildEvent; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DefaultLogger; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.ProjectHelper; -import org.apache.tools.ant.Target; -import org.apache.tools.ant.taskdefs.Java; -import org.apache.tools.ant.types.Path; -import org.aspectj.tools.ajc.AjcTestCase; - -/** - * Element that allow to run an abritrary Ant target in a sandbox. - * <p/> - * Such a spec is used in a "<ajc-test><ant file="myAnt.xml" [target="..."] [verbose="true"]/> XML element. The "target" is - * optional. If not set, default myAnt.xml target is used. The "file" file is looked up from the <ajc-test dir="..."/> attribute. If - * "verbose" is set to "true", the ant -v output is piped, else nothing is reported except errors. - * <p/> - * The called Ant target benefits from 2 implicit variables: "${aj.sandbox}" points to the test current sandbox folder. "aj.path" is - * an Ant refid on the classpath formed with the sandbox folder + ltw + the AjcTestCase classpath (ie usually aspectjrt, junit, and - * testing infra) - * <p/> - * Element "<stdout><line text="..">" and "<stderr><line text="..">" can be used. For now a full match is performed on the output of - * the runned target only (not the whole Ant invocation). This is experimental and advised to use a "<junit>" task instead or a - * "<java>" whose main that throws some exception upon failure. - * - * - * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> - */ -public class AntSpec implements ITestStep { - - // ALSO SEE AJC - private final static String DEFAULT_LTW_CLASSPATH_ENTRIES = ".." + File.separator + "asm/bin" + File.pathSeparator + ".." - + File.separator + "bridge/bin" + File.pathSeparator + ".." + File.separator + "loadtime/bin" + File.pathSeparator - + ".." + File.separator + "loadtime5/bin" + File.pathSeparator + ".." + File.separator + "weaver/bin" - + File.pathSeparator + ".." + File.separator + "org.aspectj.matcher/bin" + File.pathSeparator + ".." + File.separator - + "lib/bcel/bcel.jar" + File.pathSeparator + ".." + File.separator + "lib/bcel/bcel-verifier.jar";; - - private boolean m_verbose = false; - private AjcTest m_ajcTest; - private OutputSpec m_stdErrSpec; - private OutputSpec m_stdOutSpec; - private String m_antFile; - private String m_antTarget; - - public void execute(final AjcTestCase inTestCase) { - final String failMessage = "test \"" + m_ajcTest.getTitle() + "\" failed: "; - - File buildFile = new File(m_ajcTest.getDir() + File.separatorChar + m_antFile); - if (!buildFile.exists()) { - AjcTestCase.fail(failMessage + "no such Ant file " + buildFile.getAbsolutePath()); - } - Project p = new Project(); - final StringBuffer stdout = new StringBuffer(); - final StringBuffer stderr = new StringBuffer(); - final StringBuffer verboseLog = new StringBuffer(); - try { - // read the Ant file - p.init(); - p.setUserProperty("ant.file", buildFile.getAbsolutePath()); - // setup aj.sandbox - p.setUserProperty("aj.sandbox", inTestCase.getSandboxDirectory().getAbsolutePath()); - // setup aj.dir "modules" folder - p.setUserProperty("aj.root", new File("..").getAbsolutePath()); - - // create the test implicit path aj.path that contains the sandbox + regular test infra path - Path path = new Path(p, inTestCase.getSandboxDirectory().getAbsolutePath()); - populatePath(path, DEFAULT_LTW_CLASSPATH_ENTRIES); - populatePath(path, AjcTestCase.DEFAULT_CLASSPATH_ENTRIES); - p.addReference("aj.path", path); - p.setBasedir(buildFile.getAbsoluteFile().getParent()); - ProjectHelper helper = ProjectHelper.getProjectHelper(); - helper.parse(p, buildFile); - - // use default target if no target specified - if (m_antTarget == null) { - m_antTarget = p.getDefaultTarget(); - } - - // make sure we listen for failure - DefaultLogger consoleLogger = new DefaultLogger() { - public void buildFinished(BuildEvent event) { - super.buildFinished(event); - if (event.getException() != null) { - - try { - File antout = new File(inTestCase.getSandboxDirectory().getAbsolutePath(), "antout"); - if (antout.exists()) { - stdout.append("Forked java command stdout:\n"); - System.out.println("Forked java command stdout:"); - FileReader fr = new FileReader(antout); - BufferedReader br = new BufferedReader(fr); - String line = br.readLine(); - while (line != null) { - stdout.append(line).append("\n"); - System.out.println(stdout); - line = br.readLine(); - } - fr.close(); - } - - File anterr = new File(inTestCase.getSandboxDirectory().getAbsolutePath(), "anterr"); - if (anterr.exists()) { - stdout.append("Forked java command stderr:\n"); - System.out.println("Forked java command stderr:"); - FileReader fr = new FileReader(anterr); - BufferedReader br = new BufferedReader(fr); - String line = br.readLine(); - while (line != null) { - stdout.append(line).append("\n"); - System.out.println(stdout); - line = br.readLine(); - } - fr.close(); - } - } catch (Exception e) { - System.out.println("Exception whilst loading forked java task output " + e.getMessage() + "\n"); - e.printStackTrace(); - stdout.append("Exception whilst loading forked java task output " + e.getMessage() + "\n"); - } - - StringBuffer message = new StringBuffer(); - message.append(event.getException().toString()).append("\n"); - message.append(verboseLog); - message.append(stdout); - message.append(stderr); - // AjcTestCase.fail(failMessage + "failure " + event.getException()); - AjcTestCase.fail(message.toString()); - } - } - - public void targetFinished(BuildEvent event) { - super.targetFinished(event); - if (event.getException() != null) { - AjcTestCase.fail(failMessage + "failure in '" + event.getTarget() + "' " + event.getException()); - } - } - - public void messageLogged(BuildEvent event) { - super.messageLogged(event); - - Target target = event.getTarget(); - if (target != null && m_antTarget.equals(target.getName()) && event.getSource() instanceof Java) - switch (event.getPriority()) { - case Project.MSG_INFO: - stdout.append(event.getMessage()).append('\n'); - break; - case Project.MSG_WARN: - stderr.append(event.getMessage()).append('\n'); - break; - case Project.MSG_VERBOSE: - verboseLog.append(event.getMessage()).append('\n'); - break; - } - } - }; - consoleLogger.setErrorPrintStream(System.err); - consoleLogger.setOutputPrintStream(System.out); - consoleLogger.setMessageOutputLevel(m_verbose ? Project.MSG_VERBOSE : Project.MSG_ERR); - p.addBuildListener(consoleLogger); - } catch (Throwable t) { - AjcTestCase.fail(failMessage + "invalid Ant script :" + t.toString()); - } - try { - p.setProperty("verbose", "true"); - p.fireBuildStarted(); - p.executeTarget(m_antTarget); - p.fireBuildFinished(null); - } catch (BuildException e) { - p.fireBuildFinished(e); - } catch (Throwable t) { - AjcTestCase.fail(failMessage + "error when invoking target :" + t.toString()); - } - - /* See if stdout/stderr matches test specification */ - if (m_stdOutSpec != null) { - m_stdOutSpec.matchAgainst(stdout.toString()); - } - if (m_stdErrSpec != null) { - String stderr2 = stderr.toString(); - // Working around this rediculous message that still comes out of Java7 builds: - if (stderr2.indexOf("Class JavaLaunchHelper is implemented in both")!=-1 && stderr2.indexOf('\n')!=-1) { - stderr2 = stderr2.replaceAll("objc\\[[0-9]*\\]: Class JavaLaunchHelper is implemented in both [^\n]*\n",""); - } - // JDK 11 is complaining about illegal reflective calls - temporary measure ignore these - does that get all tests passing and this is the last problem? - if (stderr2.indexOf("WARNING: Illegal reflective access using Lookup on org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor") != -1) { -// WARNING: An illegal reflective access operation has occurred -// WARNING: Illegal reflective access using Lookup on org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor (file:/Users/aclement/gits/org.aspectj/loadtime/bin/) to class java.lang.ClassLoader -// WARNING: Please consider reporting this to the maintainers of org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor -// WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations -// WARNING: All illegal access operations will be denied in a future release - - stderr2 = stderr2.replaceAll("WARNING: An illegal reflective access operation has occurred\n",""); - stderr2 = stderr2.replaceAll("WARNING: Illegal reflective access using Lookup on org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor[^\n]*\n",""); - stderr2 = stderr2.replaceAll("WARNING: Please consider reporting this to the maintainers of org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor\n",""); - stderr2 = stderr2.replaceAll("WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\n",""); - stderr2 = stderr2.replaceAll("WARNING: All illegal access operations will be denied in a future release\n",""); - } - - m_stdErrSpec.matchAgainst(stderr2); - } - } - - public void addStdErrSpec(OutputSpec spec) { - if (m_stdErrSpec != null) - throw new UnsupportedOperationException("only one 'stderr' allowed in 'ant'"); - m_stdErrSpec = spec; - } - - public void addStdOutSpec(OutputSpec spec) { - if (m_stdOutSpec != null) - throw new UnsupportedOperationException("only one 'stdout' allowed in 'ant'"); - m_stdOutSpec = spec; - } - - public void setVerbose(String verbose) { - if (verbose != null && "true".equalsIgnoreCase(verbose)) { - m_verbose = true; - } - } - - public void setFile(String file) { - m_antFile = file; - } - - public void setTarget(String target) { - m_antTarget = target; - } - - public void addExpectedMessage(ExpectedMessageSpec message) { - throw new UnsupportedOperationException("don't use 'message' in 'ant' specs."); - } - - public void setBaseDir(String dir) { - ; - } - - public void setTest(AjcTest test) { - m_ajcTest = test; - } - - private static void populatePath(Path path, String pathEntries) { - StringTokenizer st = new StringTokenizer(pathEntries, File.pathSeparator); - while (st.hasMoreTokens()) { - path.setPath(new File(st.nextToken()).getAbsolutePath()); - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java b/testing/src/main/java/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java deleted file mode 100644 index 467d9f236..000000000 --- a/testing/src/main/java/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2005 Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * initial implementation Alexandre Vasseur - *******************************************************************************/ -package org.aspectj.testing; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; -import junit.extensions.TestSetup; - -import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.io.InputStreamReader; -import java.io.FileInputStream; - -import org.apache.commons.digester.Digester; -import org.aspectj.tools.ajc.Ajc; - -/** - * Autowiring of XML test spec file as JUnit tests. - * <p/> - * Extend this class and implement the getSpecFile and the static suite() method. - * All tests described in the XML spec file will be auto-registered as JUnit tests. - * Any regular test() method will be registered as well. - * - * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> - */ -public abstract class AutowiredXMLBasedAjcTestCase extends XMLBasedAjcTestCase { - - private Map<String,AjcTest> testMap = new HashMap<String,AjcTest>(); - - public void addTest(AjcTest test) { - testMap.put(test.getTitle(), test); - } - - /* - * Return a map from (String) test title -> AjcTest - */ - protected Map<String,AjcTest> getSuiteTests() { - return testMap; - } - - public static Test loadSuite(Class<?> testCaseClass) { - TestSuite suite = new TestSuite(testCaseClass.getName()); - //suite.addTestSuite(testCaseClass); - - // wire the spec file - try { - final AutowiredXMLBasedAjcTestCase wired = (AutowiredXMLBasedAjcTestCase) testCaseClass.newInstance(); - System.out.println("LOADING SUITE: " + wired.getSpecFile().getPath()); - Digester d = wired.getDigester(); - try { - InputStreamReader isr = new InputStreamReader(new FileInputStream(wired.getSpecFile())); - d.parse(isr); - } catch (Exception ex) { - fail("Unable to load suite " + wired.getSpecFile().getPath() + " : " + ex); - } - wired.ajc = new Ajc(); - - Map<String,AjcTest> ajTests = wired.getSuiteTests(); - - for (Iterator<Map.Entry<String,AjcTest>> iterator = ajTests.entrySet().iterator(); iterator.hasNext();) { - final Map.Entry<String,AjcTest> entry = iterator.next(); - - suite.addTest( - new TestCase(entry.getKey().toString()) { - - protected void runTest() { - entry.getValue().runTest(wired); - } - - public String getName() { - return entry.getKey(); - } - } - ); - } - } catch (Throwable t) { - final String message = t.toString(); - suite.addTest( - new TestCase("error") { - protected void runTest() { - fail(message); - } - } - ); - } - - // wire the test methods as well if any - // this simple check avoids failure when no test.. method is found. - // it could be refined to lookup in the hierarchy as well, and excluding private method as JUnit does. - Method[] testMethods = testCaseClass.getDeclaredMethods(); - for (int i = 0; i < testMethods.length; i++) { - Method testMethod = testMethods[i]; - if (testMethod.getName().startsWith("test")) { - suite.addTestSuite(testCaseClass); - break; - } - } - - TestSetup wrapper = new TestSetup(suite) { - /* (non-Javadoc) - * @see junit.extensions.TestSetup#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - //suiteLoaded = false; - } - /* (non-Javadoc) - * @see junit.extensions.TestSetup#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - //suiteLoaded = false; - } - }; - return wrapper; - - //return suite; - } - - /* (non-Javadoc) - * @see org.aspectj.tools.ajc.AjcTestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - } - - /** - * This helper method runs the test with the given title in the - * suite spec file. All tests steps in given ajc-test execute - * in the same sandbox. - */ - protected void runTest(String title) { - AjcTest currentTest = (AjcTest) testMap.get(title); - if (currentTest == null) { - fail("No test '" + title + "' in suite."); - } - ajc.setShouldEmptySandbox(true); - currentTest.runTest(this); - } - - - -} diff --git a/testing/src/main/java/org/aspectj/testing/CompileSpec.java b/testing/src/main/java/org/aspectj/testing/CompileSpec.java deleted file mode 100644 index 22570e3d1..000000000 --- a/testing/src/main/java/org/aspectj/testing/CompileSpec.java +++ /dev/null @@ -1,336 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004,2016 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.StringTokenizer; - -import org.aspectj.testing.util.TestUtil; -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.tools.ajc.CompilationResult; - -/** - * @author Adrian Colyer - * @author Andy Clement - */ -public class CompileSpec implements ITestStep { - - private List<ExpectedMessageSpec> expected = new ArrayList<ExpectedMessageSpec>(); - - private String files; - private boolean includeClassesDir; - private String aspectpath; - private String classpath; - private String modulepath; - private String inpath; - private String sourceroots; - private String outjar; - private String outxml; - private String xlintfile; - private String options; - private String baseDir; - private String extdirs; - private AjcTest myTest; - - public CompileSpec() { - } - - public void execute(AjcTestCase inTestCase) { - File base = new File(baseDir); - String[] args = buildArgs(); - CompilationResult result = inTestCase.ajc(base,args); - AjcTestCase.MessageSpec messageSpec = buildMessageSpec(); - String failMessage = "test \"" + myTest.getTitle() + "\" failed"; - inTestCase.assertMessages(result,failMessage,messageSpec); - inTestCase.setShouldEmptySandbox(false); // so subsequent steps in same test see my results - } - - public void addExpectedMessage(ExpectedMessageSpec message) { - expected.add(message); - } - - public void setBaseDir(String dir) { - this.baseDir = dir; - } - - protected String getBaseDir() { return baseDir; } - - public void setTest(AjcTest t) { - this.myTest = t; - if (options != null && (options.indexOf("-1.5") != -1)) { - myTest.setVm("1.5"); - } - } - - protected AjcTest getTest() { return myTest; } - - /** - * @return Returns the aspectpath. - */ - public String getAspectpath() { - return aspectpath; - } - /** - * @param aspectpath The aspectpath to set. - */ - public void setAspectpath(String aspectpath) { - this.aspectpath = aspectpath.replace(',',File.pathSeparatorChar); - } - /** - * @return Returns the classpath. - */ - public String getClasspath() { - return classpath; - } - /** - * @param classpath The classpath to set. - */ - public void setClasspath(String classpath) { - this.classpath = classpath.replace(',',File.pathSeparatorChar); - } - - public String getModulepath() { - return this.modulepath; - } - - public void setModulepath(String modulepath) { - this.modulepath = modulepath.replace(',', File.pathSeparatorChar); - } - /** - * @return Returns the files. - */ - public String getFiles() { - return files; - } - /** - * @param files The files to set. - */ - public void setFiles(String files) { - this.files = files; - } - /** - * @return Returns the includeClassesDir. - */ - public boolean isIncludeClassesDir() { - return includeClassesDir; - } - /** - * @param includeClassesDir The includeClassesDir to set. - */ - public void setIncludeClassesDir(boolean includeClassesDir) { - this.includeClassesDir = includeClassesDir; - } - /** - * @return Returns the inpath. - */ - public String getInpath() { - return inpath; - } - /** - * @param inpath The inpath to set. - */ - public void setInpath(String inpath) { - this.inpath = inpath.replace(',',File.pathSeparatorChar).replace(';',File.pathSeparatorChar); - } - /** - * @return Returns the options. - */ - public String getOptions() { - return options; - } - /** - * @param options The options to set. - */ - public void setOptions(String options) { - int i = options.indexOf("!eclipse"); - if (i != -1) { - this.options = options.substring(0,i); - this.options += options.substring(i + "!eclipse".length()); - } else { - this.options = options; - } - } - /** - * @return Returns the outjar. - */ - public String getOutjar() { - return outjar; - } - /** - * @param outjar The outjar to set. - */ - public void setOutjar(String outjar) { - this.outjar = outjar; - } - - /** - * @return Returns the outxml. - */ - public String getOutxmlfile() { - return outxml; - } - - /** - * @param outxml The the of the aop.xml file to generate - */ - public void setOutxmlfile(String outxml) { - this.outxml = outxml; - } - /** - * @return Returns the sourceroots. - */ - public String getSourceroots() { - return sourceroots; - } - /** - * @param sourceroots The sourceroots to set. - */ - public void setSourceroots(String sourceroots) { - this.sourceroots = sourceroots; - } - /** - * @return Returns the xlintfile. - */ - public String getXlintfile() { - return xlintfile; - } - /** - * @param xlintfile The xlintfile to set. - */ - public void setXlintfile(String xlintfile) { - this.xlintfile = xlintfile; - } - - public String getExtdirs() { return extdirs;} - public void setExtdirs(String extdirs) { this.extdirs = extdirs; } - - protected String[] buildArgs() { - StringBuffer args = new StringBuffer(); - // add any set options, and then files to compile at the end - if (getAspectpath() != null) { - args.append("-aspectpath "); - args.append(getAspectpath()); - args.append(" "); - } - if (getSourceroots() != null) { - args.append("-sourceroots "); - args.append(getSourceroots()); - args.append(" "); - } - if (getOutjar() != null) { - args.append("-outjar "); - args.append(getOutjar()); - args.append(" "); - } - if (getOutxmlfile() != null) { - args.append("-outxmlfile "); - args.append(getOutxmlfile()); - args.append(" "); - } - if (getOptions() != null) { - StringTokenizer strTok = new StringTokenizer(getOptions(),","); - while (strTok.hasMoreTokens()) { - // For an option containing a comma, pass in a { in its place - args.append(strTok.nextToken().replace('{', ',')); - args.append(" "); - } - } - if (getClasspath() != null) { - args.append("-classpath "); - args.append(getClasspath()); - args.append(" "); - } - if (getModulepath() != null) { - args.append("-p "); - args.append(rewrite(getModulepath())); - args.append(" "); - } - if (getXlintfile() != null) { - args.append("-Xlintfile "); - args.append(getXlintfile()); - args.append(" "); - } - if (getExtdirs() != null) { - args.append("-extdirs "); - args.append(getExtdirs()); - args.append(" "); - } - List<String> fileList = new ArrayList<String>(); - List<String> jarList = new ArrayList<String>(); - // convention that any jar on file list should be added to inpath - String files = getFiles(); - if (files == null) files = ""; - StringTokenizer strTok = new StringTokenizer(files,","); - while (strTok.hasMoreTokens()) { - final String file = strTok.nextToken(); - if (file.endsWith(".jar")) { - jarList.add(file); - } else { - fileList.add(file); - } - } - if ((getInpath() != null) || !jarList.isEmpty()) { - args.append("-inpath "); - if (getInpath() != null) args.append(getInpath()); - for (String jar: jarList) { - args.append(File.pathSeparator); - args.append(jar); - } - args.append(" "); - } - for (String file: fileList) { - args.append(file); - args.append(" "); - } - String argumentString = args.toString(); - strTok = new StringTokenizer(argumentString," "); - String[] ret = new String[strTok.countTokens()]; - for (int i = 0; i < ret.length; i++) { - ret[i] = strTok.nextToken(); - } - return ret; - } - - private String rewrite(String path) { - path = path.replace("$runtime", TestUtil.aspectjrtPath().toString()); - return path; - } - - protected AjcTestCase.MessageSpec buildMessageSpec() { - List<AjcTestCase.Message> infos = null; - List<AjcTestCase.Message> warnings = new ArrayList<AjcTestCase.Message>(); - List<AjcTestCase.Message> errors = new ArrayList<AjcTestCase.Message>(); - List<AjcTestCase.Message> fails = new ArrayList<AjcTestCase.Message>(); - List<AjcTestCase.Message> weaveInfos = new ArrayList<AjcTestCase.Message>(); - for (ExpectedMessageSpec exMsg: expected) { - String kind = exMsg.getKind(); - if (kind.equals("info")) { - if (infos == null) infos = new ArrayList<AjcTestCase.Message>(); - infos.add(exMsg.toMessage()); - } else if (kind.equals("warning")) { - warnings.add(exMsg.toMessage()); - } else if (kind.equals("error")) { - errors.add(exMsg.toMessage()); - } else if (kind.equals("fail")) { - fails.add(exMsg.toMessage()); - } else if (kind.equals("abort")) { - fails.add(exMsg.toMessage()); - } else if (kind.equals("weave")) { - weaveInfos.add(exMsg.toMessage()); - } - } - return new AjcTestCase.MessageSpec(infos,warnings,errors,fails,weaveInfos); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/ExpectedMessageSpec.java b/testing/src/main/java/org/aspectj/testing/ExpectedMessageSpec.java deleted file mode 100644 index 2193b55ae..000000000 --- a/testing/src/main/java/org/aspectj/testing/ExpectedMessageSpec.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -import org.aspectj.tools.ajc.AjcTestCase; - -/** - * @author colyer - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates - */ -public class ExpectedMessageSpec { - - private String kind = "error"; - private int line = -1; - private String text; - private String file; - private String details; - - public AjcTestCase.Message toMessage() { - return new AjcTestCase.Message(line,file,text,null); - } - - /** - * @return Returns the details. - */ - public String getDetails() { - return details; - } - /** - * @param details The details to set. - */ - public void setDetails(String details) { - this.details = details; - } - /** - * @return Returns the file. - */ - public String getFile() { - return file; - } - /** - * @param file The file to set. - */ - public void setFile(String file) { - this.file = file; - } - /** - * @return Returns the kind. - */ - public String getKind() { - return kind; - } - /** - * @param kind The kind to set. - */ - public void setKind(String kind) { - this.kind = kind; - } - /** - * @return Returns the line. - */ - public int getLine() { - return line; - } - /** - * @param line The line to set. - */ - public void setLine(int line) { - this.line = line; - } - /** - * @return Returns the text. - */ - public String getText() { - return text; - } - /** - * @param text The text to set. - */ - public void setText(String text) { - this.text = text; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/FileSpec.java b/testing/src/main/java/org/aspectj/testing/FileSpec.java deleted file mode 100644 index 2164f38f1..000000000 --- a/testing/src/main/java/org/aspectj/testing/FileSpec.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 Contributors - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - SpringSource - *******************************************************************************/ -package org.aspectj.testing; - -import java.io.File; - -import org.aspectj.tools.ajc.AjcTestCase; - -/** - * Support simple file system operations in a test spec. Example:<br> - * <file deletefile="foo.jar"/> will delete the file foo.jar from the sandbox. - * - * @author Andy Clement - */ -public class FileSpec implements ITestStep { - - private String toDelete; - - private String renameFrom; - private String renameTo; - - // private String dir; - // private AjcTest test; - - public FileSpec() { - } - - public void setRenameFrom(String file) { - this.renameFrom = file; - } - - public void setRenameTo(String file) { - this.renameTo = file; - } - - public void setDeletefile(String file) { - this.toDelete = file; - } - - @Override - public void addExpectedMessage(ExpectedMessageSpec message) { - } - - @Override - public void execute(AjcTestCase inTestCase) { - File sandbox = inTestCase.getSandboxDirectory(); - if (toDelete != null) { - File targetForDeletion = new File(sandbox, toDelete); - if (targetForDeletion.isFile()) { - targetForDeletion.delete(); - } else { - recursiveDelete(targetForDeletion); - } - } - if (renameFrom != null) { - if (renameTo == null) { - throw new IllegalStateException("If setting renameFrom the renameTo should also be set"); - } - File fileFrom = new File(sandbox, renameFrom); - File fileTo = new File(sandbox, renameTo); - fileFrom.renameTo(fileTo); - } - } - - private void recursiveDelete(File toDelete) { - if (toDelete.isDirectory()) { - File[] files = toDelete.listFiles(); - for (File f: files) { - recursiveDelete(f); - } - } - toDelete.delete(); - } - - @Override - public void setBaseDir(String dir) { - // this.dir = dir; - } - - @Override - public void setTest(AjcTest test) { - // this.test = test; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/ITestStep.java b/testing/src/main/java/org/aspectj/testing/ITestStep.java deleted file mode 100644 index 673d6c66d..000000000 --- a/testing/src/main/java/org/aspectj/testing/ITestStep.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -import org.aspectj.tools.ajc.AjcTestCase; - -/** - * @author Adrian Colyer - */ -public interface ITestStep { - - void execute(AjcTestCase inTestCase); - - void addExpectedMessage(ExpectedMessageSpec message); - - void setBaseDir(String dir); - - void setTest(AjcTest test); -} diff --git a/testing/src/main/java/org/aspectj/testing/MakeTestClass.java b/testing/src/main/java/org/aspectj/testing/MakeTestClass.java deleted file mode 100644 index 721cb623b..000000000 --- a/testing/src/main/java/org/aspectj/testing/MakeTestClass.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Created on 02-Aug-2004 - * - */ -package org.aspectj.testing; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.digester.Digester; - -/** - * @author colyer - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates - */ -public class MakeTestClass { - - private static final String HEADER = - "/* *******************************************************************\n" + - " * Copyright (c) 2004 IBM Corporation\n" + - " * All rights reserved.\n" + - " * This program and the accompanying materials are made available\n" + - " * under the terms of the Eclipse Public License v1.0\n" + - " * which accompanies this distribution and is available at\n" + - " * http://www.eclipse.org/legal/epl-v10.html \n" + - " * \n" + - " * ******************************************************************/\n" + - "package org.aspectj.systemtest.XXX;\n" + - "\n" + - "import java.io.File;\n" + - "import junit.framework.Test;\n" + - "import org.aspectj.testing.XMLBasedAjcTestCase;\n" + - "\n" + - "public class "; - - private static final String BODY_1 = - " extends org.aspectj.testing.XMLBasedAjcTestCase {\n" + - "\n" + - " public static Test suite() {\n" + - " return XMLBasedAjcTestCase.loadSuite("; - - private static final String BODY_2 = - ".class);\n" + - " }\n" + - "\n" + - " protected File getSpecFile() {\n" + - " return new File(\""; - - private static final String BODY_3 = - "\");\n" + - " }\n"; - - private static final String FOOTER = - "}\n"; - - private List<AjcTest> tests = new ArrayList<AjcTest>(); - private String className; - private String suiteFile; - - public static void main(String[] args) throws Exception { - new MakeTestClass(args[0],args[1]).makeTestClass(); - } - - public MakeTestClass(String className, String suiteFile)throws Exception { - this.className = className; - this.suiteFile = suiteFile; - Digester d = getDigester(); - InputStreamReader isr = new InputStreamReader(new FileInputStream(suiteFile)); - d.parse(isr); - } - - public void addTest(AjcTest test) { - tests.add(test); - } - - public void makeTestClass() throws Exception { - FileOutputStream fos = new FileOutputStream(className + ".java"); - PrintStream out = new PrintStream(fos); - out.print(HEADER); - out.print(className); - out.print(BODY_1); - out.print(className); - out.print(BODY_2); - out.print(suiteFile); - out.print(BODY_3); - out.println(); - int testNo = 1; - NumberFormat nf = NumberFormat.getInstance(); - nf.setMinimumIntegerDigits(3); - for (AjcTest test: tests) { - out.println(); - out.print(" public void test"); - out.print(nf.format(testNo++)); - out.println("(){"); - out.println(" runTest(\"" + test.getTitle() + "\");"); - out.println(" }"); - } - out.println(); - out.println(FOOTER); - out.close(); - } - - private Digester getDigester() { - Digester digester = new Digester(); - digester.push(this); - digester.addObjectCreate("suite/ajc-test",AjcTest.class); - digester.addSetProperties("suite/ajc-test"); - digester.addSetNext("suite/ajc-test","addTest","org.aspectj.testing.AjcTest"); - return digester; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/OutputLine.java b/testing/src/main/java/org/aspectj/testing/OutputLine.java deleted file mode 100644 index fc6fe4ce9..000000000 --- a/testing/src/main/java/org/aspectj/testing/OutputLine.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -/** - * @author Adrian Colyer - * @author Andy Clement - */ -public class OutputLine { - - // Expected text - private String text; - - // Comma separated list of vm versions on which this is expected - private String vm; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public String getVm() { - return vm; - } - - public void setVm(String vm) { - this.vm = vm; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/OutputSpec.java b/testing/src/main/java/org/aspectj/testing/OutputSpec.java deleted file mode 100644 index 9eab46098..000000000 --- a/testing/src/main/java/org/aspectj/testing/OutputSpec.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; -import java.util.StringTokenizer; - -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.util.LangUtil; - -public class OutputSpec { - - private List<String> expectedOutputLines = new ArrayList<String>(); - - public void addLine(OutputLine line) { - if (line.getVm() == null || matchesThisVm(line.getVm())) { - expectedOutputLines.add(line.getText()); - } - } - - /** - * For a test output line that has specified a vm version, check if it matches the vm we are running on. - * vm might be "1.2,1.3,1.4,1.5" or simply "9" or it may be a version with a '+' suffix indicating that - * level or later, e.g. "9+" should be ok on Java 10 - * @return true if the current vm version matches the spec - */ - private boolean matchesThisVm(String vm) { - // vm might be 1.2, 1.3, 1.4, 1.5 or 1.9 possibly with a '+' in there - // For now assume + is attached to there only being one version, like "9+" - if (vm.contains(LangUtil.getVmVersionString())) { - return true; - } - if (vm.endsWith("+")) { - double vmVersion = LangUtil.getVmVersion(); - double vmSpecified = Double.parseDouble(vm.substring(0,vm.length()-1)); - return vmVersion >= vmSpecified; - } - return false; - } - - public void matchAgainst(String output) { - matchAgainst(output, "yes"); - } - - public void matchAgainst(String output, String ordered) { - if (ordered != null && ordered.equals("no")) { - unorderedMatchAgainst(output); - return; - } - boolean matches = false; - int lineNo = 0; - StringTokenizer strTok = new StringTokenizer(output,"\n"); - if (strTok.countTokens() == expectedOutputLines.size()) { - matches = true; - for (String line: expectedOutputLines) { - lineNo++; - String outputLine = strTok.nextToken().trim(); - /* Avoid trying to match on ajSandbox source names that appear in messages */ - if (outputLine.indexOf(line) == -1) { - matches = false; - break; - } - } - } else { lineNo = -1; } - if (!matches) { - createFailureMessage(output, lineNo, strTok.countTokens()); - } - } - - public void unorderedMatchAgainst(String output) { - List<String> outputFound = getOutputFound(output); - if(outputFound.size() != expectedOutputLines.size()) { - createFailureMessage(output, -1, outputFound.size()); - return; - } - List<String> expected = new ArrayList<String>(); - expected.addAll(expectedOutputLines); - List<String> found = new ArrayList<String>(); - found.addAll(outputFound); - for (Iterator<String> iterator = outputFound.iterator(); iterator.hasNext();) { - String lineFound = (String) iterator.next(); - for (Iterator<String> iterator2 = expectedOutputLines.iterator(); iterator2.hasNext();) { - String lineExpected = (String) iterator2.next(); - if (lineFound.indexOf(lineExpected)!= -1) { - found.remove(lineFound); - expected.remove(lineExpected); - continue; - } - } - } - if (!found.isEmpty() || !expected.isEmpty()) { - createFailureMessage(output,-2,outputFound.size()); - } - } - - private void createFailureMessage(String output, int lineNo, int sizeFound) { - StringBuffer failMessage = new StringBuffer(); - failMessage.append("\n expecting output:\n"); - for (String line: expectedOutputLines) { - failMessage.append(line); - failMessage.append("\n"); - } - failMessage.append(" but found output:\n"); - failMessage.append(output); - failMessage.append("\n"); - if (lineNo==-1) { - failMessage.append("Expected "+expectedOutputLines.size()+" lines of output but there are "+sizeFound); - } else if (lineNo >= 0) { - failMessage.append("First difference is on line " + lineNo); - } - failMessage.append("\n"); - AjcTestCase.fail(failMessage.toString()); - } - - private List<String> getOutputFound(String output) { - List<String> found = new ArrayList<String>(); - StringTokenizer strTok = new StringTokenizer(output,"\n"); - while(strTok.hasMoreTokens()) { - String outputLine = strTok.nextToken().trim(); - found.add(outputLine); - } - return found; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/RunSpec.java b/testing/src/main/java/org/aspectj/testing/RunSpec.java deleted file mode 100644 index 62b93bcb0..000000000 --- a/testing/src/main/java/org/aspectj/testing/RunSpec.java +++ /dev/null @@ -1,262 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, Abraham Nevado (lucierna) - * ******************************************************************/ -package org.aspectj.testing; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; - -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.util.FileUtil; - -/** - * @author Adrian Colyer - */ -public class RunSpec implements ITestStep { - - private List<ExpectedMessageSpec> expected = new ArrayList<ExpectedMessageSpec>(); - private String classToRun; - private String moduleToRun; // alternative to classToRun on JDK9+ - private String baseDir; - private String options; - private String cpath; - private String mpath; - private String orderedStderr; - private AjcTest myTest; - private OutputSpec stdErrSpec; - private OutputSpec stdOutSpec; - private String ltwFile; - private String xlintFile; - private String vmargs; - private String usefullltw; - - @Override - public String toString() { - return "RunSpec: Running '"+classToRun+"' in directory '"+baseDir+"'. Classpath of '"+cpath+"'"; - } - public RunSpec() { - } - - @Override - public void execute(AjcTestCase inTestCase) { - if (!expected.isEmpty()) { - System.err.println("Warning, message spec for run command is currently ignored (org.aspectj.testing.RunSpec)"); - } - String[] args = buildArgs(); -// System.err.println("? execute() inTestCase='" + inTestCase + "', ltwFile=" + ltwFile); - boolean useLtw = copyLtwFile(inTestCase.getSandboxDirectory()); - - copyXlintFile(inTestCase.getSandboxDirectory()); - try { - setSystemProperty("test.base.dir", inTestCase.getSandboxDirectory().getAbsolutePath()); - - AjcTestCase.RunResult rr = inTestCase.run(getClassToRun(), getModuleToRun(), args, vmargs, getClasspath(), getModulepath(), useLtw, "true".equalsIgnoreCase(usefullltw)); - - if (stdErrSpec != null) { - stdErrSpec.matchAgainst(rr.getStdErr(), orderedStderr); - } - if (stdOutSpec != null) { - stdOutSpec.matchAgainst(rr.getStdOut()); - } - } finally { - restoreProperties(); - } - } - - /* - * Logic to save/restore system properties. Copied from LTWTests. As Matthew noted, need to refactor LTWTests to use this - */ - - private Properties savedProperties = new Properties(); - - public void setSystemProperty(String key, String value) { - Properties systemProperties = System.getProperties(); - copyProperty(key, systemProperties, savedProperties); - systemProperties.setProperty(key, value); - } - - private static void copyProperty(String key, Properties from, Properties to) { - String value = from.getProperty(key, NULL); - to.setProperty(key, value); - } - - private final static String NULL = "null"; - - protected void restoreProperties() { - Properties systemProperties = System.getProperties(); - for (Enumeration<Object> enu = savedProperties.keys(); enu.hasMoreElements();) { - String key = (String) enu.nextElement(); - String value = savedProperties.getProperty(key); - if (value == NULL) - systemProperties.remove(key); - else - systemProperties.setProperty(key, value); - } - } - - @Override - public void addExpectedMessage(ExpectedMessageSpec message) { - expected.add(message); - } - - @Override - public void setBaseDir(String dir) { - this.baseDir = dir; - } - - @Override - public void setTest(AjcTest test) { - this.myTest = test; - } - - public AjcTest getTest() { - return this.myTest; - } - - public String getOptions() { - return options; - } - - public void setOptions(String options) { - this.options = options; - } - - public String getClasspath() { - if (cpath == null) - return null; - return this.cpath.replace('/', File.separatorChar).replace(',', File.pathSeparatorChar); - } - - public String getModulepath() { - if (mpath == null) - return null; - return this.mpath.replace('/', File.separatorChar).replace(',', File.pathSeparatorChar); - } - - public void setModulepath(String mpath) { - this.mpath = mpath; - } - - public void setClasspath(String cpath) { - this.cpath = cpath; - } - - public void addStdErrSpec(OutputSpec spec) { - this.stdErrSpec = spec; - } - - public void addStdOutSpec(OutputSpec spec) { - this.stdOutSpec = spec; - } - - public void setOrderedStderr(String orderedStderr) { - this.orderedStderr = orderedStderr; - } - - public String getClassToRun() { - return classToRun; - } - - public void setClassToRun(String classToRun) { - this.classToRun = classToRun; - } - - public void setModuleToRun(String moduleToRun) { - this.moduleToRun = moduleToRun; - } - - public String getModuleToRun() { - return this.moduleToRun; - } - - public String getLtwFile() { - return ltwFile; - } - - public void setLtwFile(String ltwFile) { - this.ltwFile = ltwFile; - } - - private String[] buildArgs() { - if (options == null) - return new String[0]; - StringTokenizer strTok = new StringTokenizer(options, ","); - String[] ret = new String[strTok.countTokens()]; - for (int i = 0; i < ret.length; i++) { - ret[i] = strTok.nextToken(); - } - return ret; - } - - private boolean copyLtwFile(File sandboxDirectory) { - boolean useLtw = false; - - if (ltwFile != null) { - // TODO maw use flag rather than empty file name - if (ltwFile.trim().length() == 0) - return true; - - File from = new File(baseDir, ltwFile); - File to = new File(sandboxDirectory, "META-INF" + File.separator + "aop.xml"); - // System.out.println("RunSpec.copyLtwFile() from=" + from.getAbsolutePath() + " to=" + to.getAbsolutePath()); - try { - FileUtil.copyFile(from, to); - useLtw = true; - } catch (IOException ex) { - AjcTestCase.fail(ex.toString()); - } - } - - return useLtw; - } - - public String getXlintFile() { - return xlintFile; - } - - public void setXlintFile(String xlintFile) { - this.xlintFile = xlintFile; - } - - public void setVmargs(String vmargs) { - this.vmargs = vmargs; - } - - public String getVmargs() { - return vmargs; - } - - - public String getUsefullltw() { - return usefullltw; - } - - public void setUsefullltw(String usefullltw) { - this.usefullltw = usefullltw; - } - - private void copyXlintFile(File sandboxDirectory) { - if (xlintFile != null) { - File from = new File(baseDir, xlintFile); - File to = new File(sandboxDirectory, File.separator + xlintFile); - try { - FileUtil.copyFile(from, to); - } catch (IOException ex) { - AjcTestCase.fail(ex.toString()); - } - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/WeaveSpec.java b/testing/src/main/java/org/aspectj/testing/WeaveSpec.java deleted file mode 100644 index 2793b63ac..000000000 --- a/testing/src/main/java/org/aspectj/testing/WeaveSpec.java +++ /dev/null @@ -1,164 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2005 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.StringTokenizer; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; - -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.tools.ajc.CompilationResult; - -/** - * @author colyer - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Style - Code Templates - */ -public class WeaveSpec extends CompileSpec { - - private String classesFiles; - private String aspectsFiles; - private List<File> classFilesFromClasses; - - /* (non-Javadoc) - * @see org.aspectj.testing.ITestStep#execute(org.aspectj.tools.ajc.AjcTestCase) - */ - public void execute(AjcTestCase inTestCase) { - String failMessage = "test \"" + getTest().getTitle() + "\" failed"; - try { - File base = new File(getBaseDir()); - classFilesFromClasses = new ArrayList<File>(); - setFiles(classesFiles); - String[] args = buildArgs(); - CompilationResult result = inTestCase.ajc(base,args); - inTestCase.assertNoMessages(result,failMessage); - File sandbox = inTestCase.getSandboxDirectory(); - createJar(sandbox,"classes.jar",true); - - inTestCase.setShouldEmptySandbox(false); - setFiles(aspectsFiles); - String options = getOptions(); - if (options == null) { - setOptions(""); - } - setClasspath("classes.jar"); - args = buildArgs(); - result = inTestCase.ajc(base,args); - inTestCase.assertNoMessages(result,failMessage); - createJar(sandbox,"aspects.jar",false); - - args = buildWeaveArgs(); - inTestCase.setShouldEmptySandbox(false); - result = inTestCase.ajc(base,args); - AjcTestCase.MessageSpec messageSpec = buildMessageSpec(); - inTestCase.assertMessages(result,failMessage,messageSpec); - inTestCase.setShouldEmptySandbox(false); // so subsequent steps in same test see my results - } catch (IOException e) { - AjcTestCase.fail(failMessage + " " + e); - } - } - - public void setClassesFiles(String files) { - this.classesFiles = files; - } - - public void setAspectsFiles(String files) { - this.aspectsFiles = files; - } - - /** - * Find all the .class files under the dir, package them into a jar file, - * and then delete them. - * @param inDir - * @param name - */ - private void createJar(File inDir, String name, boolean isClasses) throws IOException { - File outJar = new File(inDir,name); - FileOutputStream fos = new FileOutputStream(outJar); - JarOutputStream jarOut = new JarOutputStream(fos); - List<File> classFiles = new ArrayList<File>(); - List<File> toExclude = isClasses ? Collections.<File>emptyList() : classFilesFromClasses; - collectClassFiles(inDir,classFiles,toExclude); - if (isClasses) classFilesFromClasses = classFiles; - String prefix = inDir.getPath() + File.separator; - for (File f: classFiles) { - String thisPath = f.getPath(); - if (thisPath.startsWith(prefix)) { - thisPath = thisPath.substring(prefix.length()); - } - JarEntry entry = new JarEntry(thisPath); - jarOut.putNextEntry(entry); - copyFile(f,jarOut); - jarOut.closeEntry(); - } - jarOut.flush(); - jarOut.close(); - } - - private void collectClassFiles(File inDir, List<File> inList, List<File> toExclude) { - File[] contents = inDir.listFiles(); - for (int i = 0; i < contents.length; i++) { - if (contents[i].getName().endsWith(".class")) { - if (!toExclude.contains(contents[i])) { - inList.add(contents[i]); - } - } else if (contents[i].isDirectory()) { - collectClassFiles(contents[i],inList, toExclude); - } - } - } - - private void copyFile(File f, OutputStream dest) throws IOException { - FileInputStream fis = new FileInputStream(f); - byte[] buf = new byte[4096]; - int read = -1; - while((read = fis.read(buf)) != -1) { - dest.write(buf,0,read); - } - fis.close(); - } - - private String[] buildWeaveArgs() { - StringBuffer args = new StringBuffer(); - if (getOptions() != null) { - StringTokenizer strTok = new StringTokenizer(getOptions(),","); - while (strTok.hasMoreTokens()) { - args.append(strTok.nextToken()); - args.append(" "); - } - } - args.append("-inpath "); - args.append("classes.jar"); - args.append(File.pathSeparator); - args.append("aspects.jar"); - args.append(" "); - args.append("-aspectpath "); - args.append("aspects.jar"); - String argumentString = args.toString(); - StringTokenizer strTok = new StringTokenizer(argumentString," "); - String[] ret = new String[strTok.countTokens()]; - for (int i = 0; i < ret.length; i++) { - ret[i] = strTok.nextToken(); - } - return ret; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCase.java b/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCase.java deleted file mode 100644 index 13bbf844e..000000000 --- a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCase.java +++ /dev/null @@ -1,522 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Adrian Colyer, - * ******************************************************************/ -package org.aspectj.testing; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - -import org.apache.commons.digester.Digester; -import org.aspectj.apache.bcel.classfile.Attribute; -import org.aspectj.apache.bcel.classfile.JavaClass; -import org.aspectj.apache.bcel.classfile.LocalVariable; -import org.aspectj.apache.bcel.classfile.LocalVariableTable; -import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; -import org.aspectj.tools.ajc.AjcTestCase; -import org.aspectj.tools.ajc.CompilationResult; -import org.aspectj.util.FileUtil; -import org.aspectj.weaver.AjAttribute; -import org.aspectj.weaver.ResolvedMember; -import org.aspectj.weaver.ResolvedType; -import org.aspectj.weaver.WeaverStateInfo; -import org.aspectj.weaver.AjAttribute.WeaverState; -import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; -import org.aspectj.weaver.bcel.BcelConstantPoolReader; - -import junit.extensions.TestSetup; -import junit.framework.Test; -import junit.framework.TestSuite; - -/** - * Root class for all Test suites that are based on an AspectJ XML test suite file. Extends AjcTestCase allowing a mix of - * programmatic and spec-file driven testing. See org.aspectj.systemtest.incremental.IncrementalTests for an example of this mixed - * style. - * <p> - * The class org.aspectj.testing.MakeTestClass will generate a subclass of this class for you, given a suite spec. file as input... - * </p> - */ -public abstract class XMLBasedAjcTestCase extends AjcTestCase { - - private static Map<String,AjcTest> testMap = new HashMap<String,AjcTest>(); - private static boolean suiteLoaded = false; - private AjcTest currentTest = null; - private Stack<Boolean> clearTestAfterRun = new Stack<Boolean>(); - - public XMLBasedAjcTestCase() { - } - - /** - * You must define a suite() method in subclasses, and return the result of calling this method. (Don't you hate static methods - * in programming models). For example: - * - * <pre> - * public static Test suite() { - * return XMLBasedAjcTestCase.loadSuite(MyTestCaseClass.class); - * } - * </pre> - * - * @param testCaseClass - * @return - */ - public static Test loadSuite(Class<?> testCaseClass) { - TestSuite suite = new TestSuite(testCaseClass.getName()); - suite.addTestSuite(testCaseClass); - TestSetup wrapper = new TestSetup(suite) { - /* - * (non-Javadoc) - * - * @see junit.extensions.TestSetup#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - suiteLoaded = false; - } - - /* - * (non-Javadoc) - * - * @see junit.extensions.TestSetup#tearDown() - */ - protected void tearDown() throws Exception { - super.tearDown(); - suiteLoaded = false; - } - }; - return wrapper; - } - - /** - * The file containing the XML specification for the tests. - */ - protected abstract File getSpecFile(); - - /* - * Return a map from (String) test title -> AjcTest - */ - protected Map<String,AjcTest> getSuiteTests() { - return testMap; - } - - protected WeaverStateInfo getWeaverStateInfo(JavaClass jc) { - WeaverStateInfo wsi = null; - try { - for (Attribute attribute : jc.getAttributes()) { - if (attribute.getName().equals("org.aspectj.weaver.WeaverState")) { - if (wsi != null) { - fail("Found two WeaverState attributes"); - } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - attribute.dump(new DataOutputStream(baos)); - baos.close(); - byte[] byteArray = baos.toByteArray(); - byte[] newbytes = new byte[byteArray.length-6]; - System.arraycopy(byteArray, 6, newbytes, 0, newbytes.length); - WeaverState read = (WeaverState) - AjAttribute.read(new WeaverVersionInfo(), WeaverState.AttributeName, - newbytes, null, null, - new BcelConstantPoolReader(jc.getConstantPool())); - wsi = read.reify(); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - return wsi; - } - - /** - * This helper method runs the test with the given title in the suite spec file. All tests steps in given ajc-test execute in - * the same sandbox. - */ - protected void runTest(String title, boolean print) { - try { - currentTest = (AjcTest) testMap.get(title); - final boolean clearTest = clearTestAfterRun(); - if (currentTest == null) { - if (clearTest) { - System.err.println("test already run: " + title); - return; - } else { - fail("No test '" + title + "' in suite."); - } - } - boolean run = currentTest.runTest(this); - assertTrue("Test not run", run); - if (clearTest) { - testMap.remove(title); - } - } finally { - if (print) { - System.out.println("SYSOUT"); - System.out.println(ajc.getLastCompilationResult().getStandardOutput()); - } - } - } - - protected void runTest(String title) { - runTest(title, false); - } - - /** - * Get the currently executing test. Useful for access to e.g. AjcTest.getTitle() etc.. - */ - protected AjcTest getCurrentTest() { - return currentTest; - } - - /** - * For use by the Digester. As the XML document is parsed, it creates instances of AjcTest objects, which are added to this - * TestCase by the Digester by calling this method. - */ - public void addTest(AjcTest test) { - testMap.put(test.getTitle(), test); - } - - protected final void pushClearTestAfterRun(boolean val) { - clearTestAfterRun.push(val ? Boolean.FALSE : Boolean.TRUE); - } - - protected final boolean popClearTestAfterRun() { - return clearTest(true); - } - - protected final boolean clearTestAfterRun() { - return clearTest(false); - } - - private boolean clearTest(boolean pop) { - if (clearTestAfterRun.isEmpty()) { - return false; - } - boolean result = clearTestAfterRun.peek().booleanValue(); - if (pop) { - clearTestAfterRun.pop(); - } - return result; - } - - /* - * The rules for parsing a suite spec file. The Digester using bean properties to match attributes in the XML document to - * properties in the associated classes, so this simple implementation should be very easy to maintain and extend should you - * ever need to. - */ - protected Digester getDigester() { - Digester digester = new Digester(); - digester.push(this); - digester.addObjectCreate("suite/ajc-test", AjcTest.class); - digester.addSetProperties("suite/ajc-test"); - digester.addSetNext("suite/ajc-test", "addTest", "org.aspectj.testing.AjcTest"); - digester.addObjectCreate("suite/ajc-test/compile", CompileSpec.class); - digester.addSetProperties("suite/ajc-test/compile"); - digester.addSetNext("suite/ajc-test/compile", "addTestStep", "org.aspectj.testing.ITestStep"); - digester.addObjectCreate("suite/ajc-test/file", FileSpec.class); - digester.addSetProperties("suite/ajc-test/file"); - digester.addSetNext("suite/ajc-test/file", "addTestStep", "org.aspectj.testing.ITestStep"); - digester.addObjectCreate("suite/ajc-test/run", RunSpec.class); - digester.addSetProperties("suite/ajc-test/run", "class", "classToRun"); - digester.addSetProperties("suite/ajc-test/run", "module", "moduleToRun"); - digester.addSetProperties("suite/ajc-test/run", "ltw", "ltwFile"); - digester.addSetProperties("suite/ajc-test/run", "xlintfile", "xlintFile"); - digester.addSetProperties("suite/ajc-test/run/stderr", "ordered", "orderedStderr"); - digester.addSetNext("suite/ajc-test/run", "addTestStep", "org.aspectj.testing.ITestStep"); - digester.addObjectCreate("*/message", ExpectedMessageSpec.class); - digester.addSetProperties("*/message"); - digester.addSetNext("*/message", "addExpectedMessage", "org.aspectj.testing.ExpectedMessageSpec"); - digester.addObjectCreate("suite/ajc-test/weave", WeaveSpec.class); - digester.addSetProperties("suite/ajc-test/weave"); - digester.addSetNext("suite/ajc-test/weave", "addTestStep", "org.aspectj.testing.ITestStep"); - - digester.addObjectCreate("suite/ajc-test/ant", AntSpec.class); - digester.addSetProperties("suite/ajc-test/ant"); - digester.addSetNext("suite/ajc-test/ant", "addTestStep", "org.aspectj.testing.ITestStep"); - digester.addObjectCreate("suite/ajc-test/ant/stderr", OutputSpec.class); - digester.addSetProperties("suite/ajc-test/ant/stderr"); - digester.addSetNext("suite/ajc-test/ant/stderr", "addStdErrSpec", "org.aspectj.testing.OutputSpec"); - digester.addObjectCreate("suite/ajc-test/ant/stdout", OutputSpec.class); - digester.addSetProperties("suite/ajc-test/ant/stdout"); - digester.addSetNext("suite/ajc-test/ant/stdout", "addStdOutSpec", "org.aspectj.testing.OutputSpec"); - - digester.addObjectCreate("suite/ajc-test/run/stderr", OutputSpec.class); - digester.addSetProperties("suite/ajc-test/run/stderr"); - digester.addSetNext("suite/ajc-test/run/stderr", "addStdErrSpec", "org.aspectj.testing.OutputSpec"); - digester.addObjectCreate("suite/ajc-test/run/stdout", OutputSpec.class); - digester.addSetProperties("suite/ajc-test/run/stdout"); - digester.addSetNext("suite/ajc-test/run/stdout", "addStdOutSpec", "org.aspectj.testing.OutputSpec"); - digester.addObjectCreate("*/line", OutputLine.class); - digester.addSetProperties("*/line"); - digester.addSetNext("*/line", "addLine", "org.aspectj.testing.OutputLine"); - return digester; - } - - /* - * (non-Javadoc) - * - * @see org.aspectj.tools.ajc.AjcTestCase#setUp() - */ - protected void setUp() throws Exception { - super.setUp(); - if (!suiteLoaded) { - testMap = new HashMap<String,AjcTest>(); - System.out.println("LOADING SUITE: " + getSpecFile().getPath()); - Digester d = getDigester(); - try { - InputStreamReader isr = new InputStreamReader(new FileInputStream(getSpecFile())); - d.parse(isr); - } catch (Exception ex) { - fail("Unable to load suite " + getSpecFile().getPath() + " : " + ex); - } - suiteLoaded = true; - } - } - - protected long nextIncrement(boolean doWait) { - long time = System.currentTimeMillis(); - if (doWait) { - try { - Thread.sleep(1000); - } catch (InterruptedException intEx) { - } - } - return time; - } - - protected void copyFile(String from, String to) throws Exception { - String dir = getCurrentTest().getDir(); - FileUtil.copyFile(new File(dir + File.separator + from), new File(ajc.getSandboxDirectory(), to)); - } - - protected void copyFileAndDoIncrementalBuild(String from, String to) throws Exception { - copyFile(from, to); - CompilationResult result = ajc.doIncrementalCompile(); - assertNoMessages(result, "Expected clean compile from test '" + getCurrentTest().getTitle() + "'"); - } - - protected void copyFileAndDoIncrementalBuild(String from, String to, MessageSpec expectedResults) throws Exception { - String dir = getCurrentTest().getDir(); - FileUtil.copyFile(new File(dir + File.separator + from), new File(ajc.getSandboxDirectory(), to)); - CompilationResult result = ajc.doIncrementalCompile(); - assertMessages(result, "Test '" + getCurrentTest().getTitle() + "' did not produce expected messages", expectedResults); - } - - protected void deleteFile(String file) { - new File(ajc.getSandboxDirectory(), file).delete(); - } - - protected void deleteFileAndDoIncrementalBuild(String file, MessageSpec expectedResult) throws Exception { - deleteFile(file); - CompilationResult result = ajc.doIncrementalCompile(); - assertMessages(result, "Test '" + getCurrentTest().getTitle() + "' did not produce expected messages", expectedResult); - } - - protected void deleteFileAndDoIncrementalBuild(String file) throws Exception { - deleteFileAndDoIncrementalBuild(file, MessageSpec.EMPTY_MESSAGE_SET); - } - - protected void assertAdded(String file) { - assertTrue("File " + file + " should have been added", new File(ajc.getSandboxDirectory(), file).exists()); - } - - protected void assertDeleted(String file) { - assertFalse("File " + file + " should have been deleted", new File(ajc.getSandboxDirectory(), file).exists()); - } - - protected void assertUpdated(String file, long sinceTime) { - File f = new File(ajc.getSandboxDirectory(), file); - assertTrue("File " + file + " should have been updated", f.lastModified() > sinceTime); - } - - public SyntheticRepository createRepos(File cpentry) { - ClassPath cp = new ClassPath(cpentry + File.pathSeparator + System.getProperty("java.class.path")); - return SyntheticRepository.getInstance(cp); - } - - protected byte[] loadFileAsByteArray(File f) { - try { - byte[] bs = new byte[100000]; - BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f)); - int pos = 0; - int len = 0; - while ((len=bis.read(bs, pos, 100000-pos))!=-1) { - pos+=len; - } - bis.close(); - return bs; - } catch (Exception e) { - return null; - } - } - - public JavaClass getClassFrom(File where, String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos(where); - return repos.loadClass(clazzname); - } - - protected Method getMethodStartsWith(JavaClass jc, String prefix) { - return getMethodStartsWith(jc,prefix,1); - } - - protected Attribute getAttributeStartsWith(Attribute[] attributes, String prefix) { - StringBuilder buf = new StringBuilder(); - for (Attribute a: attributes) { - if (a.getName().startsWith(prefix)) { - return a; - } - buf.append(a.toString()).append("\n"); - } - fail("Failed to find '"+prefix+"' in attributes:\n"+buf.toString()); - return null; - } - - protected Method getMethodStartsWith(JavaClass jc, String prefix, int whichone) { - Method[] meths = jc.getMethods(); - for (int i = 0; i < meths.length; i++) { - Method method = meths[i]; - System.out.println(method); - if (method.getName().startsWith(prefix)) { - whichone--; - if (whichone==0) { - return method; - } - } - } - return null; - } - - /** - * Sort it by name then start position - */ - public List<LocalVariable> sortedLocalVariables(LocalVariableTable lvt) { - List<LocalVariable> l = new ArrayList<LocalVariable>(); - LocalVariable lv[] = lvt.getLocalVariableTable(); - for (int i = 0; i < lv.length; i++) { - LocalVariable lvEntry = lv[i]; - l.add(lvEntry); - } - Collections.sort(l, new MyComparator()); - return l; - } - - public String stringify(LocalVariableTable lvt, int slotIndex) { - LocalVariable lv[] = lvt.getLocalVariableTable(); - LocalVariable lvEntry = lv[slotIndex]; - StringBuffer sb = new StringBuffer(); - sb.append(lvEntry.getSignature()).append(" ").append(lvEntry.getName()).append("(").append(lvEntry.getIndex()) - .append(") start=").append(lvEntry.getStartPC()).append(" len=").append(lvEntry.getLength()); - return sb.toString(); - } - - public String stringify(List<LocalVariable> l, int slotIndex) { - LocalVariable lvEntry = (LocalVariable) l.get(slotIndex); - StringBuffer sb = new StringBuffer(); - sb.append(lvEntry.getSignature()).append(" ").append(lvEntry.getName()).append("(").append(lvEntry.getIndex()) - .append(") start=").append(lvEntry.getStartPC()).append(" len=").append(lvEntry.getLength()); - return sb.toString(); - } - - public String stringify(LocalVariableTable lvt) { - if (lvt == null) { - return ""; - } - StringBuffer sb = new StringBuffer(); - sb.append("LocalVariableTable. Entries=#" + lvt.getTableLength()).append("\n"); - LocalVariable lv[] = lvt.getLocalVariableTable(); - for (int i = 0; i < lv.length; i++) { - LocalVariable lvEntry = lv[i]; - sb.append(lvEntry.getSignature()).append(" ").append(lvEntry.getName()).append("(").append(lvEntry.getIndex()) - .append(") start=").append(lvEntry.getStartPC()).append(" len=").append(lvEntry.getLength()).append("\n"); - } - - return sb.toString(); - } - - public static class CountingFilenameFilter implements FilenameFilter { - - private String suffix; - private int count; - - public CountingFilenameFilter(String s) { - this.suffix = s; - } - - public boolean accept(File dir, String name) { - if (name.endsWith(suffix)) { - count++; - } - return false; - } - - public int getCount() { - return count; - } - } - - public static class MyComparator implements Comparator<LocalVariable> { - public int compare(LocalVariable o1, LocalVariable o2) { - LocalVariable l1 = (LocalVariable) o1; - LocalVariable l2 = (LocalVariable) o2; - if (l1.getName().equals(l2.getName())) { - return l1.getStartPC() - l2.getStartPC(); - } else { - return l1.getName().compareTo(l2.getName()); - } - } - - } - - protected Method getMethodFromClass(JavaClass clazz, String methodName) { - Method[] meths = clazz.getMethods(); - for (int i = 0; i < meths.length; i++) { - Method method = meths[i]; - if (method.getName().equals(methodName)) { - return meths[i]; - } - } - return null; - } - - protected File getClassResource(String resourceName) { - return new File(getClass().getResource(resourceName).getFile()); - } - - protected Method findMethod(JavaClass jc, String string) { - for (Method m : jc.getMethods()) { - if (m.getName().equals(string)) { - return m; - } - } - return null; - } - - protected ResolvedMember findMethod(ResolvedType outerType, String string) { - for (ResolvedMember method: outerType.getDeclaredMethods()) { - if (method.getName().equals(string)) { - return method; - } - } - return null; - } - - -} diff --git a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava10OrLater.java b/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava10OrLater.java deleted file mode 100644 index 4a8c63f11..000000000 --- a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava10OrLater.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2018 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - * ******************************************************************/ -package org.aspectj.testing; - -import org.aspectj.util.LangUtil; - -/** - * Ensure sure tests are running on the right level of JDK. - * - * @author Andy Clement - */ -public abstract class XMLBasedAjcTestCaseForJava10OrLater extends XMLBasedAjcTestCase { - - @Override - public void runTest(String title) { - if (!LangUtil.is10VMOrGreater()) { - throw new IllegalStateException("These tests should be run on Java 10 or later"); - } - super.runTest(title); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava11OrLater.java b/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava11OrLater.java deleted file mode 100644 index b71fc19e9..000000000 --- a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava11OrLater.java +++ /dev/null @@ -1,31 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2018 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - * ******************************************************************/ -package org.aspectj.testing; - -/** - * Makes sure tests are running on the right level of JDK. - * - * @author Andy Clement - */ -public abstract class XMLBasedAjcTestCaseForJava11OrLater extends XMLBasedAjcTestCase { - - @Override - public void runTest(String title) { - // Check we are on Java11 - String property = System.getProperty("java.version"); - if (!property.startsWith("11")) { - throw new IllegalStateException("These tests should be run on Java 11 or later"); - } - super.runTest(title); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava9OrLater.java b/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava9OrLater.java deleted file mode 100644 index 205b55273..000000000 --- a/testing/src/main/java/org/aspectj/testing/XMLBasedAjcTestCaseForJava9OrLater.java +++ /dev/null @@ -1,32 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2018 Contributors - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Andy Clement - * ******************************************************************/ -package org.aspectj.testing; - -import org.aspectj.util.LangUtil; - -/** - * Makes sure tests are running on the right level of JDK. - * - * @author Andy Clement - */ -public abstract class XMLBasedAjcTestCaseForJava9OrLater extends XMLBasedAjcTestCase { - - @Override - public void runTest(String title) { - // Check we are on Java9 or later - if (!LangUtil.is19VMOrGreater()) { - throw new IllegalStateException("These tests should be run on Java 9 or later"); - } - super.runTest(title); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/ajde/CompileCommand.java b/testing/src/main/java/org/aspectj/testing/ajde/CompileCommand.java deleted file mode 100644 index 86c5fbaf7..000000000 --- a/testing/src/main/java/org/aspectj/testing/ajde/CompileCommand.java +++ /dev/null @@ -1,439 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * Helen Hawkins Converted to new interface (bug 148190) - * ******************************************************************/ - -package org.aspectj.testing.ajde; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.aspectj.ajde.core.AjCompiler; -import org.aspectj.ajde.core.IBuildMessageHandler; -import org.aspectj.ajde.core.IBuildProgressMonitor; -import org.aspectj.ajde.core.ICompilerConfiguration; -import org.aspectj.ajde.core.IOutputLocationManager; -import org.aspectj.ajde.core.JavaOptions; -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.ICommand; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessage.Kind; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.MessageHandler; -import org.aspectj.testing.harness.bridge.Globals; -import org.aspectj.util.FileUtil; - -/** - * This re-uses the same config file to setup ajde so that recompiles appear to be of the same configuration. - * - * @since Java 1.3 (uses dynamic proxies) - */ -public class CompileCommand implements ICommand { - // time out waiting for build at three minutes - long MAX_TIME = 180 * 1000; - // this proxy ignores calls - InvocationHandler proxy = new VoidInvocationHandler(); - InvocationHandler loggingProxy = new LoggingInvocationHandler(); - MyMessageHandler myHandler = new MyMessageHandler(); - long endTime; - boolean buildNextFresh; - File tempDir; - - private AjCompiler compiler; - - /** - * Clients call this before repeatCommand as a one-shot request for a full rebuild of the same configuration. (Requires a - * downcast from ICommand to CompileCommand.) - */ - public void buildNextFresh() { - buildNextFresh = true; - } - - // --------- ICommand interface - public boolean runCommand(String[] args, IMessageHandler handler) { - setup(args); - myHandler.start(); - long startTime = System.currentTimeMillis(); - try { - compiler.buildFresh(); - } finally { - runCommandCleanup(); - } - return !myHandler.hasError(); - } - - public boolean repeatCommand(IMessageHandler handler) { - myHandler.start(); - long startTime = System.currentTimeMillis(); - // System.err.println("recompiling..."); - if (buildNextFresh) { - buildNextFresh = false; - compiler.buildFresh(); - } else { - compiler.build(); - } - return !myHandler.hasError(); - } - - void runCommandCleanup() { - if (null != tempDir) { - FileUtil.deleteContents(tempDir); - tempDir.delete(); - } - } - - // set by build progress monitor when done - void setEndTime(long endTime) { - this.endTime = endTime; - } - - private void setup(String[] args) { - File config = writeConfig(args); - if (null == config) { - throw new Error("unable to write config file"); - } - IBuildProgressMonitor buildProgressMonitor = new MyBuildProgressMonitor(); - String classesDir = "../testing/bin/classes"; - for (int i = 0; i < args.length; i++) { - if ("-d".equals(args[i]) && ((1 + i) < args.length)) { - classesDir = args[1 + i]; - break; - } - } - MyCompilerConfig compilerConfig = new MyCompilerConfig(); - compiler = new AjCompiler("blah", compilerConfig, buildProgressMonitor, myHandler); - } - - private File writeConfig(String[] args) { - tempDir = FileUtil.getTempDir("CompileCommand"); - File result = new File(tempDir, "config.lst"); - OutputStream out = null; - try { - out = new FileOutputStream(result); - PrintStream outs = new PrintStream(out, true); - for (int i = 0; i < args.length; i++) { - outs.println(args[i]); - } - return result; - } catch (IOException e) { - return null; - } finally { - try { - out.close(); - } catch (IOException e) { - } - } - } - - // private Object makeLoggingProxy(Class interfac) { - // return Proxy.newProxyInstance( - // interfac.getClassLoader(), - // new Class[] { interfac }, - // loggingProxy); - // } - - private Object makeProxy(Class interfac) { - return Proxy.newProxyInstance(interfac.getClassLoader(), new Class[] { interfac }, proxy); - } -} - -class MyMessageHandler implements IBuildMessageHandler { - - boolean hasError; - boolean hasWarning; - - private MessageHandler messageHandler = new MessageHandler(false); - - public boolean handleMessage(IMessage message) throws AbortException { - maintainHasWarning(message.getKind()); - return messageHandler.handleMessage(message); - } - - private void maintainHasWarning(IMessage.Kind kind) { - if (!hasError) { - if (IMessage.ERROR.isSameOrLessThan(kind)) { - hasError = true; - hasWarning = true; - } - } - if (!hasWarning && IMessage.WARNING.isSameOrLessThan(kind)) { - hasWarning = true; - } - } - - public boolean hasWarning() { - return hasWarning; - } - - public boolean hasError() { - return hasError; - } - - public void start() { - hasWarning = false; - hasError = false; - messageHandler.init(true); - } - - public void dontIgnore(Kind kind) { - messageHandler.dontIgnore(kind); - } - - public void ignore(Kind kind) { - messageHandler.ignore(kind); - } - - public boolean isIgnoring(Kind kind) { - return messageHandler.isIgnoring(kind); - } - -} - -class MyBuildProgressMonitor implements IBuildProgressMonitor { - - public void begin() { - } - - public void finish(boolean wasFullBuild) { - } - - public boolean isCancelRequested() { - return false; - } - - public void setProgress(double percentDone) { - } - - public void setProgressText(String text) { - } - -} - -class VoidInvocationHandler implements InvocationHandler { - public Object invoke(Object me, Method method, Object[] args) throws Throwable { - // System.err.println("Proxying" - // // don't call toString on self b/c proxied - // // + " me=" + me.getClass().getName() - // + " method=" + method - // + " args=" + (LangUtil.isEmpty(args) - // ? "[]" : Arrays.asList(args).toString())); - return null; - } -} - -class LoggingInvocationHandler implements InvocationHandler { - public Object invoke(Object me, Method method, Object[] args) throws Throwable { - System.err.println("Proxying " + render(method, args)); - return null; - } - - public static String render(Class c) { - if (null == c) { - return "(Class) null"; - } - String result = c.getName(); - if (result.startsWith("java")) { - int loc = result.lastIndexOf("."); - if (-1 != loc) { - result = result.substring(loc + 1); - } - } - return result; - } - - public static String render(Method method, Object[] args) { - StringBuffer sb = new StringBuffer(); - sb.append(render(method.getReturnType())); - sb.append(" "); - sb.append(method.getName()); - sb.append("("); - Class[] parmTypes = method.getParameterTypes(); - int parmTypesLength = (null == parmTypes ? 0 : parmTypes.length); - int argsLength = (null == args ? 0 : args.length); - boolean doType = (parmTypesLength == argsLength); - for (int i = 0; i < argsLength; i++) { - if (i > 0) { - sb.append(", "); - } - if (doType) { - sb.append("("); - sb.append(render(parmTypes[i])); - sb.append(") "); - } - if (null == args[i]) { - sb.append("null"); - } else { // also don't recurse into proxied toString? - sb.append(args[i].toString()); - } - } - sb.append(")"); - return sb.toString(); - } -} - -class MyCompilerConfig implements ICompilerConfiguration { - - private Set inpath; - private Set aspectPath; - private String outJar; - private IOutputLocationManager locationMgr; - - public Set getAspectPath() { - return aspectPath; - } - - public void setAspectPath(Set path) { - aspectPath = path; - } - - public String getClasspath() { - return Globals.S_aspectjrt_jar; - } - - public Set getInpath() { - return inpath; - } - - public void setInpath(Set input) { - inpath = input; - } - - public Map getJavaOptionsMap() { - return JavaOptions.getDefaultJavaOptions(); - } - - public List getProjectXmlConfigFiles() { - return Collections.EMPTY_LIST; - } - - public String getOutJar() { - return outJar; - } - - public void configurationRead() { - } - - public void setOutJar(String input) { - outJar = input; - } - - public IOutputLocationManager getOutputLocationManager() { - if (locationMgr == null) { - locationMgr = new MyOutputLocationManager(); - } - return locationMgr; - } - - public String getNonStandardOptions() { - return null; - } - - public List getProjectSourceFiles() { - return null; - } - - public List getProjectSourceFilesChanged() { - return null; - } - - public Map getSourcePathResources() { - return null; - } - - public int getConfigurationChanges() { - return ICompilerConfiguration.EVERYTHING; - } - - public List getClasspathElementsWithModifiedContents() { - return null; - } - - public String getProjectEncoding() { - return null; - } - - public String getProcessor() { - return null; - } - - public String getProcessorPath() { - return null; - } - - @Override - public String getModulepath() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getModuleSourcepath() { - // TODO Auto-generated method stub - return null; - } - -} - -class MyOutputLocationManager implements IOutputLocationManager { - - public List getAllOutputLocations() { - return null; - } - - public File getDefaultOutputLocation() { - return null; - } - - public File getOutputLocationForClass(File compilationUnit) { - return null; - } - - public File getOutputLocationForResource(File resource) { - return null; - } - - public String getUniqueIdentifier() { - return null; - } - - public Map getInpathMap() { - return Collections.EMPTY_MAP; - } - - public String getSourceFolderForFile(File sourceFile) { - return null; - } - - public void reportFileWrite(String outputfile, int filetype) { - } - - public void reportFileRemove(String outputfile, int filetype) { - } - - public int discoverChangesSince(File dir, long buildtime) { - return 0; - } - - public String getProjectEncoding() { - return null; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/AbstractRunSpec.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/AbstractRunSpec.java deleted file mode 100644 index 4e61a512c..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/AbstractRunSpec.java +++ /dev/null @@ -1,918 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * Wes Isberg 2004 updates - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.Message; -import org.aspectj.bridge.MessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.util.BridgeUtil; -import org.aspectj.testing.util.options.Option; -import org.aspectj.testing.util.options.Option.InvalidInputException; -import org.aspectj.testing.util.options.Options; -import org.aspectj.testing.util.options.Values; -import org.aspectj.testing.xml.IXmlWritable; -import org.aspectj.testing.xml.SoftMessage; -import org.aspectj.testing.xml.XMLWriter; -import org.aspectj.util.LangUtil; - -/** - * Base class for initialization of components expecting messages, options, files/paths, and source locations (resolved files), and - * potentially containing child Spec. - * <p> - * <u>initialization</u>: This defines bean/xml setters for all. This converts String to IMessage using - * {@link MessageUtil#readMessage(String)} and String to ISourceLocation using {@link BridgeUtil#makeSourceLocation(input)}. See - * those APIs for input form and limitations. A Spec also accepts (or rejects) runtime configuration from a parent in {@link - * adoptParentValues(RT, IMessageHandler)}. Since some children Spec may balk but this parent Spec continue, use {@link - * getChildren()} to get the full list of children Spec, but {@link getWorkingChildren()} to get the list of children that are not - * being skipped in accordance with runtime configuration. - * <p> - * <u>subclassing</u>: subclasses wishing other than the default behavior for reading String input should override the corresponding - * (bean) setter. They can also override the add{foo} methods to get notice or modify objects constructed from the input. - * <p> - * <u>bean properties</u>: because this is designed to work by standard Java bean introspection, take care to follow bean rules when - * adding methods. In particular, a property is illegal if the setter takes a different type than the getter returns. That means, - * e.g., that all List and array[] getters should be named "get{property}[List|Array]". Otherwise the XML readers will silently fail - * to set the property (perhaps with trace information that the property had no write method or was read-only). - * <p> - * <u>Coordination with writers</u>: because this reads the contents of values written by IXmlWritable, they should ensure their - * values are readable. When flattening and unflattening lists, the convention is to use the {un}flattenList(..) methods in - * XMLWriter. - * - * @see XMLWriter@unflattenList(String) - * @see XMLWriter@flattenList(List) - */ -abstract public class AbstractRunSpec implements IRunSpec { - - /** true if we expect to use a staging directory */ - boolean isStaging; - - /** true if this spec permits bad input (e.g., to test error handling) */ - boolean badInput; - - protected String description; - - /** optional source location of the specification itself */ - protected ISourceLocation sourceLocation; - - private BitSet skipSet; - private boolean skipAll; - - protected String xmlElementName; // nonfinal only for clone() - protected final ArrayList<String> keywords; - protected final IMessageHolder /* IMessage */messages; - protected final ArrayList<String> options; - protected final ArrayList<String> paths; - // XXXXXunused protected final ArrayList /*ISourceLocation*/ sourceLocations; // XXX remove? - protected final ArrayList<IRunSpec> children; - protected final ArrayList<DirChanges.Spec> dirChanges; - protected XMLNames xmlNames; - protected String comment; - - /** These options are 1:1 with spec, but set at runtime (not saved) */ - public final RT runtime; - - /** if true, then any child skip causes this to skip */ - protected boolean skipIfAnyChildSkipped; // nonfinal only for cloning - - public AbstractRunSpec(String xmlElementName) { - this(xmlElementName, true); - } - - public AbstractRunSpec(String xmlElementName, boolean skipIfAnyChildSkipped) { - if (null == xmlElementName) { - xmlElementName = "spec"; - } - this.xmlElementName = xmlElementName; - messages = new MessageHandler(true); - options = new ArrayList<String>(); - paths = new ArrayList<String>(); - // XXXXXunused sourceLocations = new ArrayList(); - keywords = new ArrayList<String>(); - children = new ArrayList<IRunSpec>(); - dirChanges = new ArrayList(); - xmlNames = XMLNames.DEFAULT; - runtime = new RT(); - this.skipIfAnyChildSkipped = skipIfAnyChildSkipped; - } - - /** @param comment ignored if null */ - public void setComment(String comment) { - if (!LangUtil.isEmpty(comment)) { - this.comment = comment; - } - } - - public void setStaging(boolean staging) { - isStaging = staging; - } - - public void setBadInput(boolean badInput) { - this.badInput = badInput; - } - - boolean isStaging() { - return isStaging; - } - - // ------- description (title, label...) - public void setDescription(String description) { - this.description = description; - } - - public String getDescription() { - return description; - } - - // ------- source location of the spec - - public void setSourceLocation(ISourceLocation sourceLocation) { - this.sourceLocation = sourceLocation; - } - - public ISourceLocation getSourceLocation() { - return sourceLocation; - } - - // ------- keywords - /** @param keyword added after trimming if not empty */ - public void setKeyword(String keyword) { - addKeyword(keyword); - } - - /** @return ((null == s) || (0 == s.trim().length())); */ - public static boolean isEmptyTrimmed(String s) { - return ((null == s) || (0 == s.length()) || (0 == s.trim().length())); - } - - /** Add keyword if non-empty and not duplicate */ - public void addKeyword(String keyword) { - if (!isEmptyTrimmed(keyword)) { - keyword = keyword.trim(); - if (!keywords.contains(keyword)) { - keywords.add(keyword); - } - } - } - - public void setKeywords(String items) { - addKeywords(items); - } - - public void addKeywords(String items) { - if (null != items) { - addKeywords(XMLWriter.unflattenList(items)); - } - } - - public void addKeywords(String[] ra) { - if (null != ra) { - for (int i = 0; i < ra.length; i++) { - addKeyword(ra[i]); - } - } - } - - public ArrayList<String> getKeywordsList() { - return makeList(keywords); - } - - // ------- options - String args - - /** @return ArrayList of String options */ - public ArrayList<String> getOptionsList() { - return makeList(options); - } - - /** @return String[] of options */ - public String[] getOptionsArray() { - return (String[]) options.toArray(new String[0]); - } - - public void setOption(String option) { - addOption(option); - } - - public void addOption(String option) { - if ((null != option) && (0 < option.length())) { - options.add(option); - } - } - - /** add options (from XML/bean) - removes any existing options */ - public void setOptions(String items) { - this.options.clear(); - addOptions(items); - } - - /** - * Set options, removing any existing options. - * - * @param options String[] options to use - may be null or empty - */ - public void setOptionsArray(String[] options) { - this.options.clear(); - if (!LangUtil.isEmpty(options)) { - this.options.addAll(Arrays.asList(options)); - } - } - - public void addOptions(String items) { - if (null != items) { - addOptions(XMLWriter.unflattenList(items)); - } - } - - public void addOptions(String[] ra) { - if (null != ra) { - for (int i = 0; i < ra.length; i++) { - addOption(ra[i]); - } - } - } - - // --------------- (String) paths - /** @return ArrayList of String paths */ - public ArrayList<String> getPathsList() { - return makeList(paths); - } - - /** @return String[] of paths */ - public String[] getPathsArray() { - return (String[]) paths.toArray(new String[0]); - } - - public void setPath(String path) { - addPath(path); - } - - public void setPaths(String paths) { - addPaths(paths); - } - - public void addPath(String path) { - if (null != path) { - paths.add(path); - } - } - - public void addPaths(String items) { - if (null != items) { - addPaths(XMLWriter.unflattenList(items)); - } - } - - public void addPaths(String[] ra) { - if (null != ra) { - for (int i = 0; i < ra.length; i++) { - addPath(ra[i]); - } - } - } - - // --------------------- dir changes - public void addDirChanges(DirChanges.Spec dirChangesSpec) { - if (null != dirChangesSpec) { - dirChanges.add(dirChangesSpec); - } - } - - // --------------------- messages - public void setMessage(String message) { - addMessage(message); - } - - public void addMessage(IMessage message) { - if (null != message) { - if (!messages.handleMessage(message)) { - String s = "invalid message: " + message; - throw new IllegalArgumentException(s); - } - } - } - - public void addMessage(String message) { - if (null != message) { - addMessage(BridgeUtil.readMessage(message)); - } - } - - /** - * this can ONLY work if each item has no internal comma - */ - public void addMessages(String items) { - if (null != items) { - String[] ra = XMLWriter.unflattenList(items); - for (int i = 0; i < ra.length; i++) { - addMessage(ra[i]); - } - } - } - - public void addMessages(List messages) { - if (null != messages) { - for (Iterator iter = messages.iterator(); iter.hasNext();) { - Object o = iter.next(); - if (o instanceof IMessage) { - addMessage((IMessage) o); - } else { - String m = "not message: " + o; - addMessage(new Message(m, IMessage.WARNING, null, null)); - } - } - } - } - - /** @return int number of message of this kind (optionally or greater */ - public int numMessages(IMessage.Kind kind, boolean orGreater) { - return messages.numMessages(kind, orGreater); - } - - public IMessageHolder getMessages() { - return messages; - } - - public void addChild(IRunSpec child) { - // fyi, child is added when complete (depth-first), not when initialized, - // so cannot affect initialization of child here - if (null != child) { - children.add(child); - } - } - - /** @return copy of children list */ - public ArrayList<IRunSpec> getChildren() { - return makeList(children); - } - - /** @return copy of children list without children to skip */ - public ArrayList<IRunSpec> getWorkingChildren() { - if (skipAll) { - return new ArrayList<IRunSpec>(); - } - if (null == skipSet) { - return getChildren(); - } - ArrayList<IRunSpec> result = new ArrayList<IRunSpec>(); - int i = 0; - for (Iterator<IRunSpec> iter = children.listIterator(); iter.hasNext(); i++) { - IRunSpec child = iter.next(); - if (!skipSet.get(i)) { - result.add(child); - } - } - return result; - } - - /** - * Recursively absorb parent values if different. This implementation calls doAdoptParentValues(..) and then calls this for any - * children. This is when skipped children are determined. Children may elect to balk at this point, reducing the number of - * children or causing this spec to skip if skipIfAnyChildrenSkipped. For each test skipped, either this doAdoptParentValues(..) - * or the child's adoptParentValues(..) should add one info message with the reason this is being skipped. The only reason to - * override this would be to NOT invoke the same for children, or to do something similar for children which are not - * AbstractRunSpec. - * - * @param parentRuntime the RT values to adopt - ignored if null - * @param handler the IMessageHandler for info messages when skipping - * @return false if this wants to be skipped, true otherwise - */ - public boolean adoptParentValues(RT parentRuntime, IMessageHandler handler) { - boolean skipped = false; - skipAll = false; - skipSet = new BitSet(); - if (null != parentRuntime) { - skipped = !doAdoptParentValues(parentRuntime, handler); - if (skipped && skipIfAnyChildSkipped) { // no need to continue checking - skipAll = true; - return false; - } - int i = 0; - for (ListIterator iter = children.listIterator(); iter.hasNext(); i++) { - IRunSpec child = (IRunSpec) iter.next(); - if (child instanceof AbstractRunSpec) { - AbstractRunSpec arsChild = (AbstractRunSpec) child; - if (!arsChild.adoptParentValues(runtime, handler)) { - skipSet.set(i); - if (!skipped) { - skipped = true; - if (skipIfAnyChildSkipped) { // no need to continue checking - skipAll = true; - return false; - } - } - } - } - } - } - return true; - } - - /** - * Adopt parent values. This implementation makes a local copy. If we interpret (and absorb) any options, they should be removed - * from parentRuntime. This sets verbose if different (override) and directly adopts parentOptions if ours is null and otherwise - * adds any non-null options we don't already have. setting verbose and adding to parent options. Implementors override this to - * affect how parent values are adopted. Implementors should not recurse into children. This method may be called multiple - * times, so implementors should not destroy any spec information. Always add an info message when returning false to skip - * - * @param parentRuntime the RT values to adopt - never null - * @return false if this wants to be skipped, true otherwise - */ - protected boolean doAdoptParentValues(RT parentRuntime, IMessageHandler handler) { - if (runtime.verbose != parentRuntime.verbose) { - runtime.verbose = parentRuntime.verbose; - } - if (!LangUtil.isEmpty(runtime.parentOptions)) { - runtime.parentOptions.clear(); - } - if (!LangUtil.isEmpty(parentRuntime.parentOptions)) { - runtime.parentOptions.addAll(parentRuntime.parentOptions); - } - return true; - } - - /** - * Implementations call this when signalling skips to ensure consistency in message formatting - * - * @param handler the IMessageHandler sink - not null - * @param reason the String reason to skip - not null - */ - protected void skipMessage(IMessageHandler handler, String reason) { - LangUtil.throwIaxIfNull(handler, "handler"); - LangUtil.throwIaxIfNull(handler, "reason"); - // XXX for Runs, label does not identify the test - String label = toString(); - MessageUtil.info(handler, "skipping \"" + label + "\" because " + reason); - } - - // --------------------------- writing xml - would prefer castor.. - - /** - * Control XML output by renaming or suppressing output for attributes and subelements. Subelements are skipped by setting the - * XMLNames booleans to false. Attributes are skipped by setting their name to null. - * - * @param names XMLNames with new names and/or suppress flags. - */ - protected void setXMLNames(XMLNames names) { - if (null != names) { - xmlNames = names; - } - } - - // /** @return null if value is null or name="{value}" otherwise */ - // private String makeAttr(XMLWriter out, String name, String value) { - // if (null == value) { - // return null; - // } - // return XMLWriter.makeAttribute(name, value); - // } - // - // /** @return null if list is null or empty or name="{flattenedList}" otherwise */ - // private String makeAttr(XMLWriter out, String name, List list) { - // if (LangUtil.isEmpty(list)) { - // return null; - // } - // String flat = XMLWriter.flattenList(list); - // return XMLWriter.makeAttribute(name, flat); - // } - // - /** @return true if writeAttributes(..) will produce any output */ - protected boolean haveAttributes() { - return ((!LangUtil.isEmpty(xmlNames.descriptionName) && !LangUtil.isEmpty(description)) - || (!LangUtil.isEmpty(xmlNames.keywordsName) && !LangUtil.isEmpty(keywords)) - || (!LangUtil.isEmpty(xmlNames.optionsName) && !LangUtil.isEmpty(options)) || (!LangUtil - .isEmpty(xmlNames.pathsName) && !LangUtil.isEmpty(paths))); - } - - /** - * Write attributes without opening or closing elements/attributes. An attribute is written only if the value is not empty and - * the name in xmlNames is not empty - */ - protected void writeAttributes(XMLWriter out) { - if (!LangUtil.isEmpty(xmlNames.descriptionName) && !LangUtil.isEmpty(description)) { - out.printAttribute(xmlNames.descriptionName, description); - } - if (!LangUtil.isEmpty(xmlNames.keywordsName) && !LangUtil.isEmpty(keywords)) { - out.printAttribute(xmlNames.keywordsName, XMLWriter.flattenList(keywords)); - } - if (!LangUtil.isEmpty(xmlNames.optionsName) && !LangUtil.isEmpty(options)) { - out.printAttribute(xmlNames.optionsName, XMLWriter.flattenList(options)); - } - if (!LangUtil.isEmpty(xmlNames.pathsName) && !LangUtil.isEmpty(paths)) { - out.printAttribute(xmlNames.pathsName, XMLWriter.flattenList(paths)); - } - if (!LangUtil.isEmpty(xmlNames.commentName) && !LangUtil.isEmpty(comment)) { - out.printAttribute(xmlNames.commentName, comment); - } - if (isStaging && !LangUtil.isEmpty(xmlNames.stagingName)) { - out.printAttribute(xmlNames.stagingName, "true"); - } - if (badInput && !LangUtil.isEmpty(xmlNames.badInputName)) { - out.printAttribute(xmlNames.badInputName, "true"); - } - } - - /** - * The default implementation writes everything as attributes, then subelements for dirChanges, messages, then subelements for - * children. Subclasses that override may delegate back for any of these. Subclasses may also set XMLNames to name or suppress - * any attribute or subelement. - * - * @see writeMessages(XMLWriter) - * @see writeChildren(XMLWriter) - * @see IXmlWritable#writeXml(XMLWriter) - */ - public void writeXml(XMLWriter out) { - out.startElement(xmlElementName, false); - writeAttributes(out); - out.endAttributes(); - if (!xmlNames.skipMessages) { - writeMessages(out); - } - if (!xmlNames.skipChildren) { - writeChildren(out); - } - out.endElement(xmlElementName); - } - - /** - * Write messages. Assumes attributes are closed, can write child elements of current element. - */ - protected void writeMessages(XMLWriter out) { - if (0 < messages.numMessages(null, true)) { - SoftMessage.writeXml(out, messages); - } - - } - - /** - * Write children. Assumes attributes are closed, can write child elements of current element. - */ - protected void writeChildren(XMLWriter out) { - if (0 < children.size()) { - for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) { - IXmlWritable self = (IXmlWritable) iter.next(); - self.writeXml(out); - } - } - } - - // --------------------------- logging - - public void printAll(PrintStream out, String prefix) { - out.println(prefix + toString()); - for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) { - AbstractRunSpec child = (AbstractRunSpec) iter.next(); // IRunSpec - child.printAll(out, prefix + " "); - } - } - - /** - * default implementation returns the description if not empty or the unqualified class name otherwise. Subclasses should not - * call toString from here unless they reimplement it. - * - * @return name of this thing or type - */ - protected String getPrintName() { - if (!LangUtil.isEmpty(description)) { - return description; - } else { - return LangUtil.unqualifiedClassName(this); - } - } - - /** @return summary count of spec elements */ - public String toString() { - return getPrintName() + "(" + containedSummary() + ")"; - } - - /** @return String of the form (# [options|paths|locations|messages]).. */ - protected String containedSummary() { - StringBuffer result = new StringBuffer(); - addListCount("options", options, result); - addListCount("paths", paths, result); - // XXXXXunused addListCount("sourceLocations", sourceLocations, result); - List<IMessage> messagesList = messages.getUnmodifiableListView(); - addListCount("messages", messagesList, result); - - return result.toString().trim(); - } - - public String toLongString() { - String mssg = ""; - if (0 < messages.numMessages(null, true)) { - mssg = " expected messages (" + MessageUtil.renderCounts(messages) + ")"; - } - return getPrintName() + containedToLongString() + mssg.trim(); - } - - /** @return String of the form (# [options|paths|locations|messages]).. */ - protected String containedToLongString() { - StringBuffer result = new StringBuffer(); - addListEntries("options", options, result); - addListEntries("paths", paths, result); - // XXXXXunused addListEntries("sourceLocations", sourceLocations, result); - List<IMessage> messagesList = messages.getUnmodifiableListView(); - addListEntries("messages", messagesList, result); - - return result.toString(); - } - - protected void initClone(AbstractRunSpec spec) throws CloneNotSupportedException { - /* - * clone associated objects only if not (used as?) read-only. - */ - spec.badInput = badInput; - spec.children.clear(); - for (Iterator<IRunSpec> iter = children.iterator(); iter.hasNext();) { - // clone these... - IRunSpec child = iter.next(); - // require all child classes to support clone? - if (child instanceof AbstractRunSpec) { - spec.addChild((AbstractRunSpec) ((AbstractRunSpec) child).clone()); - } else { - throw new Error("unable to clone " + child); - } - } - spec.comment = comment; - spec.description = description; - spec.dirChanges.clear(); - spec.dirChanges.addAll(dirChanges); - spec.isStaging = spec.isStaging; - spec.keywords.clear(); - spec.keywords.addAll(keywords); - spec.messages.clearMessages(); - MessageUtil.handleAll(spec.messages, messages, false); - spec.options.clear(); - spec.options.addAll(options); - spec.paths.clear(); - spec.paths.addAll(paths); - spec.runtime.copy(runtime); - spec.skipAll = skipAll; - spec.skipIfAnyChildSkipped = skipIfAnyChildSkipped; - if (null != skipSet) { - spec.skipSet = new BitSet(); - spec.skipSet.or(skipSet); - } - // spec.sourceLocation = sourceLocation; - // spec.sourceLocations.clear(); - // XXXXXunused spec.sourceLocations.addAll(sourceLocations); - spec.xmlElementName = xmlElementName; - spec.xmlNames = ((AbstractRunSpec.XMLNames) xmlNames.clone()); - } - - private static void addListCount(String name, List<?> list, StringBuffer sink) { - int size = list.size(); - if ((null != list) && (0 < size)) { - sink.append(" " + size + " "); - sink.append(name); - } - } - - private static void addListEntries(String name, List<?> list, StringBuffer sink) { - if ((null != list) && (0 < list.size())) { - sink.append(" " + list.size() + " "); - sink.append(name); - sink.append(": "); - sink.append(list.toString()); - } - } - - private <T> ArrayList<T> makeList(List<T> list) { - ArrayList<T> result = new ArrayList<T>(); - if (null != list) { - result.addAll(list); - } - return result; - } - - /** - * Subclasses use this to rename attributes or omit attributes or subelements. To suppress output of an attribute, pass "" as - * the name of the attribute. To use default entries, pass null for that entry. XXX this really should be replaced with nested - * properties associated logical name with actual name (or placeholders for "unused" and "default"). - */ - public static class XMLNames { - public static final XMLNames DEFAULT = new XMLNames(null, "description", "sourceLocation", "keywords", "options", "paths", - "comment", "staging", "badInput", false, false, false); - final String descriptionName; - final String sourceLocationName; - final String keywordsName; - final String optionsName; - final String pathsName; - final String commentName; - final String stagingName; - final String badInputName; - final boolean skipDirChanges; - final boolean skipMessages; - final boolean skipChildren; - - protected Object clone() { - return new XMLNames(null, descriptionName, sourceLocationName, keywordsName, optionsName, pathsName, commentName, - stagingName, badInputName, skipDirChanges, skipMessages, skipChildren); - } - - // not runtime, skipAll, skipIfAnyChildSkipped, skipSet - // sourceLocations - /** - * reset all names/behavior or pass defaultNames as the defaults for any null elements - */ - XMLNames(XMLNames defaultNames, String descriptionName, String sourceLocationName, String keywordsName, String optionsName, - String pathsName, String commentName, String stagingName, String badInputName, boolean skipDirChanges, - boolean skipMessages, boolean skipChildren) { - this.skipDirChanges = skipDirChanges; - this.skipMessages = skipMessages; - this.skipChildren = skipChildren; - if (null != defaultNames) { - this.descriptionName = (null != descriptionName ? descriptionName : defaultNames.descriptionName); - this.sourceLocationName = (null != sourceLocationName ? sourceLocationName : defaultNames.sourceLocationName); - this.keywordsName = (null != keywordsName ? keywordsName : defaultNames.keywordsName); - this.optionsName = (null != optionsName ? optionsName : defaultNames.optionsName); - this.pathsName = (null != pathsName ? pathsName : defaultNames.pathsName); - this.commentName = (null != commentName ? commentName : defaultNames.commentName); - this.stagingName = (null != stagingName ? stagingName : defaultNames.stagingName); - this.badInputName = (null != badInputName ? badInputName : defaultNames.badInputName); - } else { - this.descriptionName = descriptionName; - this.sourceLocationName = sourceLocationName; - this.keywordsName = keywordsName; - this.optionsName = optionsName; - this.pathsName = pathsName; - this.commentName = commentName; - this.stagingName = stagingName; - this.badInputName = badInputName; - } - } - } - - /** subclasses implement this to create and set up a run */ - abstract public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator); - - /** segregate runtime-only state in spec */ - public static class RT { - /** true if we should emit verbose messages */ - private boolean verbose; - - /** null unless parent set options for children to consider */ - final private ArrayList<String> parentOptions; - - public RT() { - parentOptions = new ArrayList<String>(); - } - - public boolean isVerbose() { - return verbose; - } - - /** - * Set parent options - old options destroyed. Will result in duplicates if duplicates added. Null or empty entries are - * ignored - * - * @param options ignored if null or empty - */ - public void setOptions(String[] options) { - parentOptions.clear(); - if (!LangUtil.isEmpty(options)) { - for (int i = 0; i < options.length; i++) { - if (!LangUtil.isEmpty(options[i])) { - parentOptions.add(options[i]); - } - } - } - } - - /** - * Copy values from another RT - * - * @param toCopy the RT to copy from - * @throws IllegalArgumentException if toCopy is null - */ - public void copy(RT toCopy) { - LangUtil.throwIaxIfNull(toCopy, "parent"); - parentOptions.clear(); - parentOptions.addAll(toCopy.parentOptions); - verbose = toCopy.verbose; - } - - /** - * Return any parent option accepted by validOptions, optionally removing the parent option. - * - * @param validOptions String[] of options to extract - * @param remove if true, then remove any parent option matched - * @return String[] containing any validOptions[i] in parentOptions - * - */ - public Values extractOptions(Options validOptions, boolean remove, StringBuffer errors) { - Values result = Values.EMPTY; - if (null == errors) { - errors = new StringBuffer(); - } - if (null == validOptions) { - errors.append("null options"); - return result; - } - if (LangUtil.isEmpty(parentOptions)) { - return result; - } - // boolean haveOption = false; - String[] parents = (String[]) parentOptions.toArray(new String[0]); - try { - result = validOptions.acceptInput(parents); - } catch (InvalidInputException e) { - errors.append(e.getFullMessage()); - return result; - } - if (remove) { - Option.Value[] values = result.asArray(); - for (int i = 0; i < values.length; i++) { - Option.Value value = values[i]; - if (null == value) { - continue; - } - final int max = i + value.option.numArguments(); - if (max > i) { - if (max >= parents.length) { - errors.append("expecting more args for " + value.option + " at [" + i + "]: " + Arrays.asList(parents)); - return result; - } - // XXX verify - for (int j = i; j < max; j++) { - parentOptions.remove(parents[j]); - } - i = max - 1; - } - } - } - return result; - } - - /** - * Return any parent option which has one of validOptions as a prefix, optionally absorbing (removing) the parent option. - * - * @param validOptions String[] of options to extract - * @param absorb if true, then remove any parent option matched - * @return String[] containing any validOptions[i] in parentOptions (at most once) - */ - public String[] extractOptions(String[] validOptions, boolean absorb) { - if (LangUtil.isEmpty(validOptions) || LangUtil.isEmpty(parentOptions)) { - return new String[0]; - } - ArrayList<String> result = new ArrayList<String>(); - // boolean haveOption = false; - for (int i = 0; i < validOptions.length; i++) { - String option = validOptions[i]; - if (LangUtil.isEmpty(option)) { - continue; - } - for (ListIterator<String> iter = parentOptions.listIterator(); iter.hasNext();) { - String parentOption = iter.next(); - if (parentOption.startsWith(option)) { - result.add(parentOption); - if (absorb) { - iter.remove(); - } - } - } - } - return (String[]) result.toArray(new String[0]); - } - - /** Get ListIterator that permits removals */ - ListIterator<String> getListIterator() { - return parentOptions.listIterator(); - } - - /** - * Enable verbose logging - * - * @param verbose if true, do verbose logging - */ - public void setVerbose(boolean verbose) { - if (this.verbose != verbose) { - this.verbose = verbose; - } - } - } // class RT - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcMessageHandler.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcMessageHandler.java deleted file mode 100644 index f4a88c3b2..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcMessageHandler.java +++ /dev/null @@ -1,343 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.util.*; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.MessageHandler; -import org.aspectj.bridge.MessageUtil; -//import org.aspectj.bridge.IMessage.Kind; -import org.aspectj.testing.util.BridgeUtil; -import org.aspectj.testing.util.Diffs; -import org.aspectj.util.LangUtil; - -/** - * Handle messages during test and calculate differences - * between expected and actual messages. - */ -public class AjcMessageHandler extends MessageHandler { - - /** Comparator for enclosed IMessage diffs */ - public static final Comparator COMP_IMessage = - BridgeUtil.Comparators.MEDIUM_IMessage; - - /** Comparator for enclosed File diffs */ - public static final Comparator COMP_File = BridgeUtil.Comparators.WEAK_File; - - /** unmodifiable list of IMessage messages of any type */ - private final List expectedMessagesAsList; - - /** IMessageHolder variant of expectedMessagesAsList */ - private final IMessageHolder expectedMessages; - - /** number of messages FAIL or worse */ - private final int numExpectedFailed; - - /** true if there were no error or worse messages expected */ - private final boolean expectingCommandTrue; - - /** unmodifiable list of File expected to be recompiled */ - private final List expectedRecompiled; - // Unused now, but reinstate when supported - - /** if true, ignore warnings when calculating diffs and passed() */ - private final boolean ignoreWarnings; - - /** list of File actually recompiled */ - private List actualRecompiled; - - /** cache expected/actual diffs, nullify if any new message */ - private transient CompilerDiffs diffs; - - AjcMessageHandler(IMessageHolder expectedMessages) { - this(expectedMessages, false); - } - /** - * @param messages the (constant) IMessageHolder with expected messages - */ - AjcMessageHandler( - IMessageHolder expectedMessages, - boolean ignoreWarnings) { - LangUtil.throwIaxIfNull(messages, "messages"); - this.expectedMessages = expectedMessages; - expectedMessagesAsList = expectedMessages.getUnmodifiableListView(); - expectedRecompiled = Collections.EMPTY_LIST; - this.ignoreWarnings = ignoreWarnings; - int fails = 0; - int errors = 0; - for (Iterator iter = expectedMessagesAsList.iterator(); - iter.hasNext(); - ) { - IMessage m = (IMessage) iter.next(); - IMessage.Kind kind = m.getKind(); - if (IMessage.FAIL.isSameOrLessThan(kind)) { - fails++; - } else if (m.isError()) { - errors++; - } - } - expectingCommandTrue = (0 == (errors + fails)); - numExpectedFailed = fails; - } - - /** clear out any actual values to be re-run */ - public void init() { - super.init(); - actualRecompiled = null; - diffs = null; - } - - /** - * Return true if we have this kind of - * message for the same line and store all messages. - * @see bridge.tools.impl.ErrorHandlerAdapter#doShowMessage(IMessage) - * @return true if message handled (processing should abort) - */ - public boolean handleMessage(IMessage message) { - if (null == message) { - throw new IllegalArgumentException("null message"); - } - super.handleMessage(message); - return expecting(message); - } - - /** - * Set the actual files recompiled. - * @param List of File recompiled - may be null; adopted but not modified - * @throws IllegalStateException if they have been set already. - */ - public void setRecompiled(List list) { - if (null != actualRecompiled) { - throw new IllegalStateException("actual recompiled already set"); - } - this.actualRecompiled = LangUtil.safeList(list); - } - - /** Generate differences between expected and actual errors and warnings */ - public CompilerDiffs getCompilerDiffs() { - if (null == diffs) { - final List<IMessage> expected; - final List<IMessage> actual; - if (!ignoreWarnings) { - expected = expectedMessages.getUnmodifiableListView(); - actual = this.getUnmodifiableListView(); - } else { - expected = - Arrays.asList( - expectedMessages.getMessages(IMessage.ERROR, true)); - actual = Arrays.asList(this.getMessages(IMessage.ERROR, true)); - } - // we ignore unexpected info messages, - // but we do test for expected ones - final Diffs messages; - boolean usingNew = true; // XXX extract old API's after shake-out period - if (usingNew) { - final IMessage.Kind[] NOSKIPS = new IMessage.Kind[0]; - IMessage.Kind[] skipActual = new IMessage.Kind[] { IMessage.INFO }; - int expectedInfo - = MessageUtil.numMessages(expected, IMessage.INFO, false); - if (0 < expectedInfo) { - // fyi, when expecting any info messages, have to expect all - skipActual = NOSKIPS; - } - messages = Diffs.makeDiffs( - "message", - (IMessage[]) expected.toArray(new IMessage[0]), - (IMessage[]) actual.toArray(new IMessage[0]), - NOSKIPS, - skipActual); - } else { - messages = Diffs.makeDiffs( - "message", - expected, - actual, - COMP_IMessage, - Diffs.ACCEPT_ALL, - CompilerDiffs.SKIP_UNEXPECTED_INFO); - } - Diffs recompiled = - Diffs.makeDiffs( - "recompiled", - expectedRecompiled, - actualRecompiled, - COMP_File); - diffs = new CompilerDiffs(messages, recompiled); - } - return diffs; - } - - /** - * Get the (current) result of this run, - * ignoring differences in warnings on request. - * Note it may return passed (true) when there are expected error messages. - * @return false - * if there are any fail or abort messages, - * or if the expected errors, warnings, or recompiled do not match actual. - */ - public boolean passed() { - return !getCompilerDiffs().different; - } - - /** @return true if we are expecting the command to fail - i.e., any expected errors */ - public boolean expectingCommandTrue() { - return expectingCommandTrue; - } - - /** - * Report results to a handler, - * adding all messages - * and creating fail messages for each diff. - */ - public void report(IMessageHandler handler) { - if (null == handler) { - MessageUtil.debug(this, "report got null handler"); - } - // Report all messages except expected fail+ messages, - // which will cause the reported-to handler client to gack. - // XXX need some verbose way to report even expected fail+ - final boolean fastFail = false; // do all messages - if (0 == numExpectedFailed) { - MessageUtil.handleAll(handler, this, fastFail); - } else { - IMessage[] ra = getMessagesWithoutExpectedFails(); - MessageUtil.handleAll(handler, ra, fastFail); - } - - CompilerDiffs diffs = getCompilerDiffs(); - if (diffs.different) { - diffs.messages.report(handler, IMessage.FAIL); - diffs.recompiled.report(handler, IMessage.FAIL); - } - } - - /** @return String consisting of differences and any other messages */ - public String toString() { - CompilerDiffs diffs = getCompilerDiffs(); - StringBuffer sb = new StringBuffer(super.toString()); - final String EOL = "\n"; - sb.append(EOL); - render(sb, " unexpected message ", EOL, diffs.messages.unexpected); - render(sb, " missing message ", EOL, diffs.messages.missing); - render(sb, " fail ", EOL, getList(IMessage.FAIL)); - render(sb, " abort ", EOL, getList(IMessage.ABORT)); - render(sb, " info ", EOL, getList(IMessage.INFO)); - return sb.toString(); // XXX cache toString - } - - /** - * Check if the message was expected, and clear diffs if not. - * @return true if we expect a message of this kind with this line number - */ - private boolean expecting(IMessage message) { - boolean match = false; - if (null != message) { - for (Iterator iter = expectedMessagesAsList.iterator(); - iter.hasNext(); - ) { - // amc - we have to compare against all messages to consume multiple - // text matches on same line. Return true if any matches. - if (0 == COMP_IMessage.compare(message, iter.next())) { - match = true; - } - } - } - if (!match) { - diffs = null; - } - return match; - } - - private IMessage[] getMessagesWithoutExpectedFails() { - IMessage[] result = super.getMessages(null, true); - // remove all expected fail+ (COSTLY) - ArrayList<IMessage> list = new ArrayList<>(); - int leftToFilter = numExpectedFailed; - for (int i = 0; i < result.length; i++) { - if ((0 == leftToFilter) - || !IMessage.FAIL.isSameOrLessThan(result[i].getKind())) { - list.add(result[i]); - } else { - // see if this failure was expected - if (expectedMessagesHasMatchFor(result[i])) { - leftToFilter--; // ok, don't add - } else { - list.add(result[i]); - } - } - } - result = (IMessage[]) list.toArray(new IMessage[0]); - return result; - } - - /** - * @param actual the actual IMessage to seek a match for in expected messages - * @return true if actual message is matched in the expected messages - */ - private boolean expectedMessagesHasMatchFor(IMessage actual) { - for (Iterator iter = expectedMessagesAsList.iterator(); - iter.hasNext(); - ) { - IMessage expected = (IMessage) iter.next(); - if (0 == COMP_IMessage.compare(expected, actual)) { - return true; - } - } - return false; - } - - /** @return immutable list of a given kind - use null for all kinds */ - private List getList(IMessage.Kind kind) { - if ((null == kind) || (0 == numMessages(kind, IMessageHolder.EQUAL))) { - return Collections.EMPTY_LIST; - } - return Arrays.asList(getMessages(kind, IMessageHolder.EQUAL)); - } - - /** @return "" if no items or {prefix}{item}{suffix}... otherwise */ - private void render(// LangUtil instead? - StringBuffer result, String prefix, String suffix, List items) { - if ((null != items)) { - for (Iterator iter = items.iterator(); iter.hasNext();) { - result.append(prefix + iter.next() + suffix); - } - } - } - - /** compiler results for errors, warnings, and recompiled files */ - public static class CompilerDiffs { - /** Skip info messages when reporting unexpected messages */ - static final Diffs.Filter SKIP_UNEXPECTED_INFO = new Diffs.Filter() { - public boolean accept(Object o) { - return ((o instanceof IMessage) && !((IMessage) o).isInfo()); - } - }; - public final Diffs messages; - public final Diffs recompiled; - public final boolean different; - - public CompilerDiffs(Diffs messages, Diffs recompiled) { - this.recompiled = recompiled; - this.messages = messages; - different = (messages.different || recompiled.different); - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcTest.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcTest.java deleted file mode 100644 index bdebae02c..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/AjcTest.java +++ /dev/null @@ -1,586 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.*; -import java.io.File; -import java.util.*; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -//import org.aspectj.bridge.*; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.run.Runner; -import org.aspectj.testing.xml.XMLWriter; -import org.aspectj.util.LangUtil; - -/** - * An AjcTest has child subruns (compile, [inc-compile|run]*). - * XXX title keys shared between all instances - * (add Thread to key to restrict access?) - */ -public class AjcTest extends RunSpecIterator { - - /** Unwrap an AjcTest.Spec from an IRunStatus around an AjcTest */ - public static Spec unwrapSpec(IRunStatus status) { - if (null != status) { - Object id = status.getIdentifier(); - if (id instanceof Runner.IteratorWrapper) { - IRunIterator iter = ((Runner.IteratorWrapper) id).iterator; - if (iter instanceof AjcTest) { - return (Spec) ((AjcTest) iter).spec; - } - } - } - return null; - } - - /** Unwrap initial CompilerRun.Spec from an AjcTest.Spec */ - public static CompilerRun.Spec unwrapCompilerRunSpec(Spec spec) { - if (null != spec) { - List kids = spec.getChildren(); - if (0 < kids.size()) { - Object o = kids.get(0); - if (o instanceof CompilerRun.Spec) { - return (CompilerRun.Spec) o; - } - } - } - return null; - } - - /** The spec creates the sandbox, so we use it throughout */ - public AjcTest(Spec spec, Sandbox sandbox, Validator validator) { - super(spec, sandbox, validator, true); - } - - /** - * Clear the command from the sandbox, to avoid memory leaks. - * @see org.aspectj.testing.harness.bridge.RunSpecIterator#iterationCompleted() - */ - public void iterationCompleted() { - super.iterationCompleted(); - sandbox.clearCommand(this); - } - - - /** - * Specification for an ajc test. - * Keyword directives are global/parent options passed, e.g., as - * <pre>-ajctest[Require|Skip]Keywords=keyword{,keyword}..</pre>. - * See VALID_SUFFIXES for complete list. - */ - public static class Spec extends AbstractRunSpec { - public static final String XMLNAME = "ajc-test"; - /** - * do description as title, do sourceLocation, - * do keywords, do options, skip paths, do comment, - * skip staging, skip badInput, - * skip dirChanges, do messages and do children - * (though we do children directly). - */ - private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT, - "title", null, null, null, "", null, "", "", true, false, false); - - private static final String OPTION_PREFIX = "-ajctest"; - private static final String[] VALID_OPTIONS = new String[] { OPTION_PREFIX }; - - private static final String TITLE_LIST = "TitleList="; - private static final String TITLE_FAIL_LIST = "TitleFailList="; - private static final String TITLE_CONTAINS= "TitleContains="; - private static final String REQUIRE_KEYWORDS = "RequireKeywords="; - private static final String SKIP_KEYWORDS = "SkipKeywords="; - private static final String PICK_PR = "PR="; - private static final List<String> VALID_SUFFIXES - = Collections.unmodifiableList(Arrays.asList(new String[] - { TITLE_LIST, TITLE_FAIL_LIST, TITLE_CONTAINS, - REQUIRE_KEYWORDS, SKIP_KEYWORDS, PICK_PR })); - - /** Map String titlesName to List (String) of titles to accept */ - private static final Map<String,List<String>> TITLES = new HashMap<String,List<String>>(); - - private static List<String> getTitles(String titlesName) { - return getTitles(titlesName, false); - } - private static List<String> getTitles(String titlesName, boolean fail) { - if (LangUtil.isEmpty(titlesName)) { - return Collections.emptyList(); - } - List<String> result = (List<String>) TITLES.get(titlesName); - if (null == result) { - result = makeTitlesList(titlesName, fail); - TITLES.put(titlesName, result); - } - return result; - } - - /** - * Make titles list per titlesKey, either a path to a file - * containing "[PASS|FAIL] {title}(..)" entries, - * or a comma-delimited list of titles. - * @param titlesKey a String, either a path to a file - * containing "[PASS|FAIL] {title}(..)" entries, - * or a comma-delimited list of titles. - * @param fail if true, only read titles prefixed "FAIL" from files - * @return the unmodifiable List of titles (maybe empty, never null) - */ - private static List<String> makeTitlesList(String titlesKey, boolean fail) { - File file = new File(titlesKey); - return file.canRead() - ? readTitlesFile(file, fail) - : parseTitlesList(titlesKey); - } - - /** - * Parse list of titles from comma-delmited list - * titlesList, trimming each entry and permitting - * comma to be escaped with '\'. - * @param titlesList a comma-delimited String of titles - * @return the unmodifiable List of titles (maybe empty, never null) - */ - private static List<String> parseTitlesList(String titlesList) { - ArrayList<String> result = new ArrayList<String>(); - String last = null; - StringTokenizer st = new StringTokenizer(titlesList, ","); - while (st.hasMoreTokens()) { - String next = st.nextToken().trim(); - if (next.endsWith("\\")) { - next = next.substring(0, next.length()-1); - if (null == last) { - last = next; - } else { - last += next; - } - next = null; - } else if (null != last) { - next = (last + next).trim(); - last = null; - } else { - next = next.trim(); - } - if (!LangUtil.isEmpty(next)) { - result.add(next); - } - } - if (null != last) { - String m = "unterminated entry \"" + last; // XXX messages - System.err.println(m + "\" in " + titlesList); - result.add(last.trim()); - } - return Collections.unmodifiableList(result); - } - - /** - * Read titles from a test result file, accepting - * only those prefixed with [PASS|FAIL] and - * excluding the "[PASS|FAIL] Suite.Spec(.." entry. - * @param titlesFile the File containing a - * list of titles from test results, - * with some lines of the form - * <code>[PASS|FAIL] {title}()<code> (excluding - * <code>[PASS|FAIL] Suite.Spec(...<code>. - * @param titlesFile the File path to the file containing titles - * @param fail if true, only select titles prefixed "FAIL" - * @return the unmodifiable List of titles (maybe empty, never null) - */ - private static List<String> readTitlesFile(File titlesFile, boolean fail) { - ArrayList<String> result = new ArrayList<String>(); - Reader reader = null; - try { - reader = new FileReader(titlesFile); - BufferedReader lines = new BufferedReader(reader); - String line; - while (null != (line = lines.readLine())) { - if ((line.startsWith("FAIL ") - || (!fail && line.startsWith("PASS "))) - && (!line.substring(5).startsWith("Suite.Spec("))) { - String title = line.substring(5); - int loc = title.lastIndexOf("("); - if (-1 != loc) { - title = title.substring(0, loc); - } - result.add(title); - } - } - } catch (IOException e) { - System.err.println("ignoring titles in " + titlesFile); // XXX messages - e.printStackTrace(System.err); - } finally { - if (null != reader) { - try { - reader.close(); - } catch (IOException e) { - // ignore - } - } - } - return Collections.unmodifiableList(result); - } - - /** base directory of the test suite - set before making run */ - private File suiteDir; - - /** path offset from suite directory to base of test directory */ - String testDirOffset; // XXX revert to private after fixes - - /** id of bug - if 0, then no bug associated with this test */ - private int bugId; - - public Spec() { - super(XMLNAME); - setXMLNames(NAMES); - } - - protected void initClone(Spec spec) - throws CloneNotSupportedException { - super.initClone(spec); - spec.bugId = bugId; - spec.suiteDir = suiteDir; - spec.testDirOffset = testDirOffset; - } - - public Object clone() throws CloneNotSupportedException { - Spec result = new Spec(); - initClone(result); - return result; - } - - public void setSuiteDir(File suiteDir) { - this.suiteDir = suiteDir; - } - - public File getSuiteDir() { - return suiteDir; - } - - /** @param bugId 100..999999 */ - public void setBugId(int bugId) { - LangUtil.throwIaxIfFalse((bugId > 10) && (bugId < 1000000), "bad bug id: " + bugId); - this.bugId = bugId; - } - - public int getBugId() { - return bugId; - } - - public void setTestDirOffset(String testDirOffset) { - if (!LangUtil.isEmpty(testDirOffset)) { - this.testDirOffset = testDirOffset; - } - } - - public String getTestDirOffset() { - return (null == testDirOffset ? "" : testDirOffset); - } - - /** - * @param sandbox ignored - * @see org.aspectj.testing.harness.bridge.AbstractRunSpec#makeAjcRun(Sandbox, Validator) - */ - public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator) { - LangUtil.throwIaxIfNull(validator, "validator"); - - // if no one set suiteDir, see if we have a source location - if (null == suiteDir) { - ISourceLocation loc = getSourceLocation(); - if (!validator.nullcheck(loc, "suite file location") - || !validator.nullcheck(loc.getSourceFile(), "suite file")) { - return null; - } - File locDir = loc.getSourceFile().getParentFile(); - if (!validator.canReadDir(locDir, "source location dir")) { - return null; - } - suiteDir = locDir; - } - - // we make a new sandbox with more state for our subruns, keep that, - // in order to defer initialization to nextRun() - File testBaseDir; - String testDirOffset = getTestDirOffset(); - if (LangUtil.isEmpty(testDirOffset)) { - testBaseDir = suiteDir; - } else { - testBaseDir = new File(suiteDir, testDirOffset); - if (!validator.canReadDir(testBaseDir, "testBaseDir")) { - return null; - } - } - Sandbox childSandbox = null; - try { - childSandbox = new Sandbox(testBaseDir, validator); - validator.registerSandbox(childSandbox); - } catch (IllegalArgumentException e) { - validator.fail(e.getMessage()); - return null; - } - return new AjcTest(this, childSandbox, validator); - } - - /** @see IXmlWritable#writeXml(XMLWriter) */ - public void writeXml(XMLWriter out) { - out.println(""); - String value = (null == testDirOffset? "" : testDirOffset); - String attr = XMLWriter.makeAttribute("dir", value); - if (0 != bugId) { - attr += " " + XMLWriter.makeAttribute("pr", ""+bugId); - } - out.startElement(xmlElementName, attr, false); - super.writeAttributes(out); - out.endAttributes(); - super.writeChildren(out); - out.endElement(xmlElementName); - } - - /** - * AjcTest overrides this to skip if - * <ul> - * <li>the spec has a keyword the parent wants to skip</li> - * <li>the spec does not have a required keyword</li> - * <li>the spec does not have a required bugId</li> - * <li>the spec does not have a required title (description)n</li> - * </ul> - * When skipping, this issues a messages as to why skipped. - * Skip combinations are not guaranteed to work correctly. XXX - * @return false if this wants to be skipped, true otherwise - * @throws Error if selected option is not of the form - * <pre>-ajctest[Require|Skip]Keywords=keyword{,keyword}..</pre>. - */ - protected boolean doAdoptParentValues(RT parentRuntime, IMessageHandler handler) { - if (!super.doAdoptParentValues(parentRuntime, handler)) { - return false; - } - runtime.copy(parentRuntime); - - String[] globalOptions = runtime.extractOptions(VALID_OPTIONS, true); - for (int i = 0; i < globalOptions.length; i++) { - String option = globalOptions[i]; - if (!option.startsWith(OPTION_PREFIX)) { - throw new Error("only expecting " + OPTION_PREFIX + "..: " + option); - } - option = option.substring(OPTION_PREFIX.length()); - boolean keywordMustExist = false; - List<String> permittedTitles = null; - List<String> permittedTitleStrings = null; - String havePr = null; - if (option.startsWith(REQUIRE_KEYWORDS)) { - option = option.substring(REQUIRE_KEYWORDS.length()); - keywordMustExist = true; - } else if (option.startsWith(SKIP_KEYWORDS)) { - option = option.substring(SKIP_KEYWORDS.length()); - } else if (option.startsWith(TITLE_LIST)) { - option = option.substring(TITLE_LIST.length()); - permittedTitles = getTitles(option); - } else if (option.startsWith(TITLE_FAIL_LIST)) { - option = option.substring(TITLE_FAIL_LIST.length()); - permittedTitles = getTitles(option, true); - } else if (option.startsWith(TITLE_CONTAINS)) { - option = option.substring(TITLE_CONTAINS.length()); - permittedTitleStrings = getTitles(option); - } else if (option.startsWith(PICK_PR)) { - if (0 == bugId) { - skipMessage(handler, "bugId required, but no bugId for this test"); - return false; - } else { - havePr = "" + bugId; - } - option = option.substring(PICK_PR.length()); - } else { - throw new Error("unrecognized suffix: " + globalOptions[i] - + " (expecting: " + OPTION_PREFIX + VALID_SUFFIXES + "...)"); - } - if (null != permittedTitleStrings) { - boolean gotHit = false; - for (Iterator<String> iter = permittedTitleStrings.iterator(); - !gotHit && iter.hasNext(); - ) { - String substring = (String) iter.next(); - if (-1 != this.description.indexOf(substring)) { - gotHit = true; - } - } - if (!gotHit) { - String reason = "title " - + this.description - + " does not contain any of " - + option; - skipMessage(handler, reason); - return false; - } - } else if (null != permittedTitles) { - if (!permittedTitles.contains(this.description)) { - String reason = "titlesList " - + option - + " did not contain " - + this.description; - skipMessage(handler, reason); - return false; - } - } else { - // all other options handled as comma-delimited lists - List<String> specs = LangUtil.commaSplit(option); - // XXX also throw Error on empty specs... - for (Iterator<String> iter = specs.iterator(); iter.hasNext();) { - String spec = (String) iter.next(); - if (null != havePr) { - if (havePr.equals(spec)) { // String.equals() - havePr = null; - } - } else if (keywordMustExist != keywords.contains(spec)) { - String reason = "keyword " + spec - + " was " + (keywordMustExist ? "not found" : "found"); - skipMessage(handler, reason); - return false; - } - } - if (null != havePr) { - skipMessage(handler, "bugId required, but not matched for this test"); - return false; - } - } - } - return true; - } - - } // AjcTest.Spec - - /** - * A suite of AjcTest has children for each AjcTest - * and flows all options down as globals - */ - public static class Suite extends RunSpecIterator { - final Spec spec; - - /** - * Count the number of AjcTest in this suite. - * @param spec - * @return - */ - public static int countTests(Suite.Spec spec) { - return spec.children.size(); - } - - public static AjcTest.Spec[] getTests(Suite.Spec spec) { - if (null == spec) { - return new AjcTest.Spec[0]; - } - return (AjcTest.Spec[]) spec.children.toArray(new AjcTest.Spec[0]); - } - - public Suite(Spec spec, Sandbox sandbox, Validator validator) { - super(spec, sandbox, validator, false); - this.spec = spec; - } - - /** - * While being called to make the sandbox for the child, - * set up the child's suite dir based on ours. - * @param child must be instanceof AjcTest.Spec - * @see org.aspectj.testing.harness.bridge.RunSpecIterator#makeSandbox(IRunSpec, Validator) - * @return super.makeSandbox(child, validator) - */ - protected Sandbox makeSandbox( - IRunSpec child, - Validator validator) { - if (!(child instanceof AjcTest.Spec)) { - validator.fail("only expecting AjcTest children"); - return null; - } - if (!validator.canReadDir(spec.suiteDir, "spec.suiteDir")) { - return null; - } - ((AjcTest.Spec) child).setSuiteDir(spec.suiteDir); - return super.makeSandbox(child, validator); - } - - /** - * A suite spec contains AjcTest children. - * The suite dir or source location should be set - * if the tests do not each have a source location - * with a source file in the suite dir. - * XXX whether to write out suiteDir in XML? - */ - public static class Spec extends AbstractRunSpec { - public static final String XMLNAME = "suite"; - /** - * do description, do sourceLocation, - * do keywords, do options, skip paths, do comment, - * skip staging, skip badInput, - * skip dirChanges, skip messages and do children - * (though we do children directly). - */ -// private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT, -// null, null, null, null, "", null, "", "", true, true, false); - File suiteDir; - public Spec() { - super(XMLNAME, false); // do not skip this even if children skip - } - - public Object clone() throws CloneNotSupportedException { - Spec spec = new Spec(); - super.initClone(spec); - spec.suiteDir = suiteDir; - return spec; - } - - /** @param suiteDirPath the String path to the base suite dir */ - public void setSuiteDir(String suiteDirPath) { - if (!LangUtil.isEmpty(suiteDirPath)) { - this.suiteDir = new File(suiteDirPath); - } - } - - /** @param suiteDirFile the File for the base suite dir */ - public void setSuiteDirFile(File suiteDir) { - this.suiteDir = suiteDir; - } - - /** @return suiteDir from any set or source location if set */ - public File getSuiteDirFile() { - if (null == suiteDir) { - ISourceLocation loc = getSourceLocation(); - if (null != loc) { - File sourceFile = loc.getSourceFile(); - if (null != sourceFile) { - suiteDir = sourceFile.getParentFile(); - } - } - } - return suiteDir; - } - - /** - * @return - * @see org.aspectj.testing.harness.bridge.AbstractRunSpec#makeRunIterator(Sandbox, Validator) - */ - public IRunIterator makeRunIterator( - Sandbox sandbox, - Validator validator) { - return new Suite(this, sandbox, validator); - } - - public String toString() { - // removed nKids as misleading, since children.size() may change - //int nKids = children.size(); - //return "Suite.Spec(" + suiteDir + ", " + nKids + " tests)"; - return "Suite.Spec(" + suiteDir + ")"; - } - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/CompilerRun.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/CompilerRun.java deleted file mode 100644 index 8d6c587fe..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/CompilerRun.java +++ /dev/null @@ -1,1840 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC), - * 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * Wes Isberg 2003 updates - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.*; -import java.lang.reflect.Array; -import java.util.*; - -import org.aspectj.bridge.*; -import org.aspectj.testing.ajde.CompileCommand; -import org.aspectj.testing.run.*; -import org.aspectj.testing.taskdefs.AjcTaskCompileCommand; -import org.aspectj.testing.util.options.*; -import org.aspectj.testing.util.options.Option.*; -import org.aspectj.testing.xml.*; -import org.aspectj.util.*; - -/** - * Run the compiler once. - * The lifecycle is as follows: - * <ul> - * <li>Spec (specification) is created.</li> - * <li>This is created using the Spec.</li> - * <li>setupAjcRun(Sandbox, Validator) is invoked, - * at which point this populates the shared sandbox - * with values derived from the spec and also - * sets up internal state based on both the sandbox - * and the spec.</li> - * <li>run(IRunStatus) is invoked, and this runs the compiler - * based on internal state, the spec, and the sandbox.</li> - * </ul> - * Programmer notes: - * <ul> - * <li>Paths are resolved absolutely, which fails to test the - * compiler's ability to find files relative to a source base</li> - * <li>This does not enforce the lifecycle.</li> - * <li>This must be used as the initial compile - * before doing an incremental compile. - * In that case, staging must be enabled.</li> - * </ul> - */ -public class CompilerRun implements IAjcRun { - // static final String JAVAC_COMPILER - // = JavacCompileCommand.class.getName(); - - static final String[] RA_String = new String[0]; - - static final String[] JAR_SUFFIXES = new String[] { ".jar", ".zip" }; - - static final String[] SOURCE_SUFFIXES = - (String[]) FileUtil.SOURCE_SUFFIXES.toArray(new String[0]); - - /** specifications, set on construction */ - Spec spec; - - //------------ calculated during setup - /** get shared stuff during setup */ - Sandbox sandbox; - - /** - * During run, these String are passed as the source and arg files to compile. - * The list is set up in setupAjcRun(..), when arg files are prefixed with "@". - */ - final List /*String*/ - arguments; - - /** - * During run, these String are collapsed and passed as the injar option. - * The list is set up in setupAjcRun(..). - */ - final List /*String*/ - injars; - - /** - * During run, these String are collapsed and passed as the inpath option. - * The list is set up in setupAjcRun(..), - * which extracts only directories from the files attribute. - */ - final List inpaths; - - private CompilerRun(Spec spec) { - if (null == spec) { - throw new IllegalArgumentException("null spec"); - } - this.spec = spec; - arguments = new ArrayList(); - injars = new ArrayList(); - inpaths = new ArrayList(); - } - - - /** - * Select from input String[] if readable directories - * @param inputs String[] of input - null ignored - * @param baseDir the base directory of the input - * @return String[] of input that end with any input - */ - public static String[] selectDirectories(String[] inputs, File baseDir) { - if (LangUtil.isEmpty(inputs)) { - return new String[0]; - } - ArrayList result = new ArrayList(); - for (int i = 0; i < inputs.length; i++) { - String input = inputs[i]; - if (null == input) { - continue; - } - File inputFile = new File(baseDir, input); - if (inputFile.canRead() && inputFile.isDirectory()) { - result.add(input); - } - } - return (String[]) result.toArray(new String[0]); - } - - /** - * Select from input String[] based on suffix-matching - * @param inputs String[] of input - null ignored - * @param suffixes String[] of suffix selectors - null ignored - * @param ignoreCase if true, ignore case - * @return String[] of input that end with any input - */ - public static String[] endsWith(String[] inputs, String[] suffixes, boolean ignoreCase) { - if (LangUtil.isEmpty(inputs) || LangUtil.isEmpty(suffixes)) { - return new String[0]; - } - if (ignoreCase) { - String[] temp = new String[suffixes.length]; - for (int i = 0; i < temp.length; i++) { - String suff = suffixes[i]; - temp[i] = (null == suff ? null : suff.toLowerCase()); - } - suffixes = temp; - } - ArrayList result = new ArrayList(); - for (int i = 0; i < inputs.length; i++) { - String input = inputs[i]; - if (null == input) { - continue; - } - if (!ignoreCase) { - input = input.toLowerCase(); - } - for (int j = 0; j < suffixes.length; j++) { - String suffix = suffixes[j]; - if (null == suffix) { - continue; - } - if (input.endsWith(suffix)) { - result.add(input); - break; - } - } - } - return (String[]) result.toArray(new String[0]); - } - - /** - * This checks that the spec is reasonable and does setup: - * <ul> - * <li>calculate and set sandbox testBaseSrcDir as {Sandbox.testBaseDir}/ - * {Spec.testSrcDirOffset}/<li> - * <li>get the list of source File to compile as {Sandbox.testBaseSrcDir} / - * {Spec.getPaths..}</li> - * <li>get the list of extraClasspath entries to add to default classpath as - * {Sandbox.testBaseSrcDir} / {Spec.classpath..}</li> - * <li>get the list of aspectpath entries to use as the aspectpath as - * {Sandbox. testBaseSrcDir} / {Spec.aspectpath..}</li> - * </ul> - * All sources must be readable at this time, - * unless spec.badInput is true (for invalid-input tests). - * If staging, the source files and source roots are copied - * to a separate staging directory so they can be modified - * for incremental tests. Note that (as of this writing) the - * compiler only handles source roots for incremental tests. - * @param classesDir the File - * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File) - * @throws AbortException containing IOException or IllegalArgumentException - * if the staging operations fail - */ - public boolean setupAjcRun(Sandbox sandbox, Validator validator) { - - if (!validator.nullcheck(spec.getOptionsArray(), "localOptions") - || !validator.nullcheck(sandbox, "sandbox") - || !validator.nullcheck(spec.compiler, "compilerName") - || !validator.canRead(Globals.F_aspectjrt_jar, "aspectjrt.jar") - || !validator.canRead( - Globals.F_testingclient_jar, - "testing-client.jar")) { - return false; - } - - this.sandbox = sandbox; - - String rdir = spec.testSrcDirOffset; - File testBaseSrcDir; - if ((null == rdir) || (0 == rdir.length())) { - testBaseSrcDir = sandbox.testBaseDir; - } else { - testBaseSrcDir = new File(sandbox.testBaseDir, rdir); - // XXX what if rdir is two levels deep? - if (!validator - .canReadDir(testBaseSrcDir, "sandbox.testBaseSrcDir")) { - return false; - } - } - - // Sources come as relative paths - check read, copy if staging. - // This renders paths absolute before run(RunStatusI) is called. - // For a compile run to support relative paths + source base, - // change so the run calculates the paths (differently when staging) - - final String[] inpathPaths; - final String[] injarPaths; - final String[] srcPaths; - { - final String[] paths = spec.getPathsArray(); - srcPaths = - endsWith( - paths, - CompilerRun.SOURCE_SUFFIXES, - true); - injarPaths = - endsWith(paths, CompilerRun.JAR_SUFFIXES, true); - inpathPaths = - selectDirectories(paths, testBaseSrcDir); - if (!spec.badInput) { - int found = inpathPaths.length + injarPaths.length + srcPaths.length; - if (paths.length != found) { - validator.fail("found " + found + " of " + paths.length + " sources"); - } - } - } - - // validate readable for sources - if (!spec.badInput) { - if (!validator.canRead(testBaseSrcDir, srcPaths, "sources") - // see validation of inpathPaths below due to ambiguous base dir - || !validator.canRead( - testBaseSrcDir, - spec.argfiles, - "argfiles") - || !validator.canRead( - testBaseSrcDir, - spec.classpath, - "classpath") - || !validator.canRead( - testBaseSrcDir, - spec.aspectpath, - "aspectpath") - || !validator.canRead( - testBaseSrcDir, - spec.sourceroots, - "sourceroots") - || !validator.canRead( - testBaseSrcDir, - spec.extdirs, - "extdirs")) { - return false; - } - } - - int numSources = - srcPaths.length - + injarPaths.length - + inpathPaths.length - + spec.argfiles.length - + spec.sourceroots.length; - if (!spec.badInput && (numSources < 1)) { - validator.fail( - "no input jars, arg files, or source files or roots"); - return false; - } - - final File[] argFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, spec.argfiles); - final File[] injarFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, injarPaths); - final File[] inpathFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, inpathPaths); - final File[] aspectFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, spec.aspectpath); - final File[] extdirFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, spec.extdirs); - final File[] classFiles = - FileUtil.getBaseDirFiles(testBaseSrcDir, spec.classpath); - final File[] xlintFiles = (null == spec.xlintfile ? new File[0] - : FileUtil.getBaseDirFiles(testBaseSrcDir, new String[] {spec.xlintfile})); - - // injars might be outjars in the classes dir... - for (int i = 0; i < injarFiles.length; i++) { - if (!injarFiles[i].exists()) { - injarFiles[i] = new File(sandbox.classesDir, injarPaths[i]); - } - } - for (int i = 0; i < inpathFiles.length; i++) { - if (!inpathFiles[i].exists()) { - inpathFiles[i] = new File(sandbox.classesDir, inpathPaths[i]); - } - } - // moved after solving any injars that were outjars - if (!validator.canRead(injarFiles, "injars") - || !validator.canRead(injarFiles, "injars")) { - return false; - } - - // hmm - duplicates validation above, verifying getBaseDirFiles? - if (!spec.badInput) { - if (!validator.canRead(argFiles, "argFiles") - || !validator.canRead(injarFiles, "injarFiles") - || !validator.canRead(inpathFiles, "inpathFiles") - || !validator.canRead(aspectFiles, "aspectFiles") - || !validator.canRead(classFiles, "classFiles") - || !validator.canRead(xlintFiles, "xlintFiles")) { - return false; - } - } - - final File[] srcFiles; - File[] sourcerootFiles = new File[0]; - // source text files are copied when staging incremental tests - if (!spec.isStaging()) { - // XXX why this? was always? || (testBaseSrcDir != sandbox.stagingDir))) { - srcFiles = - FileUtil.getBaseDirFiles( - testBaseSrcDir, - srcPaths, - CompilerRun.SOURCE_SUFFIXES); - if (!LangUtil.isEmpty(spec.sourceroots)) { - sourcerootFiles = - FileUtil.getBaseDirFiles( - testBaseSrcDir, - spec.sourceroots, - null); - } - } else { // staging - copy files - if (spec.badInput) { - validator.info( - "badInput ignored - files checked when staging"); - } - try { - // copy all files, then remove tagged ones - // XXX make copyFiles support a filter? - srcFiles = - FileUtil.copyFiles( - testBaseSrcDir, - srcPaths, - sandbox.stagingDir); - if (!LangUtil.isEmpty(spec.sourceroots)) { - sourcerootFiles = - FileUtil.copyFiles( - testBaseSrcDir, - spec.sourceroots, - sandbox.stagingDir); - // delete incremental files in sourceroot after copying // XXX inefficient - // an incremental file has an extra "." in name - // most .java files don't, because they are named after - // the principle type they contain, and simple type names - // have no dots. - FileFilter pickIncFiles = new FileFilter() { - public boolean accept(File file) { - if (file.isDirectory()) { - // continue recursion - return true; - } - String path = file.getPath(); - // only source files are relevant to staging - if (!FileUtil.hasSourceSuffix(path)) { - return false; - } - int first = path.indexOf("."); - int last = path.lastIndexOf("."); - return (first != last); - } - }; - for (int i = 0; i < sourcerootFiles.length; i++) { - FileUtil.deleteContents( - sourcerootFiles[i], - pickIncFiles, - false); - } - if (0 < sourcerootFiles.length) { - FileUtil.sleepPastFinalModifiedTime( - sourcerootFiles); - } - } - File[] files = - FileUtil.getBaseDirFiles(sandbox.stagingDir, srcPaths); - if (0 < files.length) { - FileUtil.sleepPastFinalModifiedTime(files); - } - } catch (IllegalArgumentException e) { - validator.fail("staging - bad input", e); - return false; - } catch (IOException e) { - validator.fail("staging - operations", e); - return false; - } - } - if (!spec.badInput - && !validator.canRead(srcFiles, "copied paths")) { - return false; - } - arguments.clear(); - - if (!LangUtil.isEmpty(xlintFiles)) { - arguments.add("-Xlintfile"); - String sr = FileUtil.flatten(xlintFiles, null); - arguments.add(sr); - } - if (spec.outjar != null) { - arguments.add("-outjar"); - arguments.add(new File(sandbox.classesDir,spec.outjar).getPath()); - } - if (!LangUtil.isEmpty(extdirFiles)) { - arguments.add("-extdirs"); - String sr = FileUtil.flatten(extdirFiles, null); - arguments.add(sr); - } - if (!LangUtil.isEmpty(sourcerootFiles)) { - arguments.add("-sourceroots"); - String sr = FileUtil.flatten(sourcerootFiles, null); - arguments.add(sr); - } - if (!LangUtil.isEmpty(srcFiles)) { - arguments.addAll(Arrays.asList(FileUtil.getPaths(srcFiles))); - } - injars.clear(); - if (!LangUtil.isEmpty(injarFiles)) { - injars.addAll(Arrays.asList(FileUtil.getPaths(injarFiles))); - } - inpaths.clear(); - if (!LangUtil.isEmpty(inpathFiles)) { - inpaths.addAll(Arrays.asList(FileUtil.getPaths(inpathFiles))); - } - if (!LangUtil.isEmpty(argFiles)) { - String[] ra = FileUtil.getPaths(argFiles); - for (int j = 0; j < ra.length; j++) { - arguments.add("@" + ra[j]); - } - if (!spec.badInput && spec.isStaging) { - validator.fail( - "warning: files listed in argfiles not staged"); - } - } - - // save classpath and aspectpath in sandbox for this and other clients - final boolean checkReadable = !spec.badInput; - int size = spec.includeClassesDir ? 3 : 2; - File[] cp = new File[size + classFiles.length]; - System.arraycopy(classFiles, 0, cp, 0, classFiles.length); - int index = classFiles.length; - if (spec.includeClassesDir) { - cp[index++] = sandbox.classesDir; - } - cp[index++] = Globals.F_aspectjrt_jar; - cp[index++] = Globals.F_testingclient_jar; - sandbox.compilerRunInit(this, testBaseSrcDir, aspectFiles, - checkReadable, cp, checkReadable, null); - - // XXX todo set bootclasspath if set for forking? - return true; - } - - /** - * Setup result evaluation and command line, run, and evaluate result. - * <li>setup an AjcMessageHandler using the expected messages from - * {@link Spec#getMessages()}.<li> - * <li>heed any globals interpreted into a TestSetup by reading - * {@link Spec@getOptions()}. For a list of supported globals, see - * {@link setupArgs(ArrayList, IMessageHandler}.</li> - * <li>construct a command line, using as classpath - * {@link Sandbox.classpathToString()}<li> - * <li>construct a compiler using {@link Spec#compiler} - * or any overriding value set in TestSetup.<li> - * <li>Just before running, set the compiler in the sandbox using - * {@link Sandbox.setCompiler(ICommand)}.<li> - * <li>After running, report AjcMessageHandler results to the status parameter. - * If the AjcMessageHandler reports a failure, then send info messages - * for the Spec, TestSetup, and command line.<li> - * @see org.aspectj.testing.run.IRun#run(IRunStatus) - */ - public boolean run(IRunStatus status) { - if (null == spec.testSetup) { - MessageUtil.abort( - status, - "no test setup - adoptParentValues not called"); - return false; - } else if (!spec.testSetup.result) { - MessageUtil.abort(status, spec.testSetup.failureReason); - return false; - } - - AjcMessageHandler handler = - new AjcMessageHandler(spec.getMessages()); - handler.init(); - boolean handlerResult = false; - boolean result = false; - boolean commandResult = false; - ArrayList argList = new ArrayList(); - final Spec.TestSetup setupResult = spec.testSetup; - try { - if (spec.outjar == null) { - argList.add("-d"); - String outputDirPath = sandbox.classesDir.getAbsolutePath(); - try { // worth it to try for canonical? - outputDirPath = sandbox.classesDir.getCanonicalPath(); - } catch (IOException e) { - MessageUtil.abort( - status, - "canonical " + sandbox.classesDir, - e); - } - argList.add(outputDirPath); - } - String path = sandbox.classpathToString(this); - if (!LangUtil.isEmpty(path)) { - argList.add("-classpath"); - argList.add(path); - } - path = sandbox.getBootclasspath(this); - if (!LangUtil.isEmpty(path)) { - argList.add("-bootclasspath"); - argList.add(path); - } - - path = sandbox.aspectpathToString(this); - if (!LangUtil.isEmpty(path)) { - argList.add("-aspectpath"); - argList.add(path); - } - - if (0 < injars.size()) { - argList.add("-injars"); - argList.add( - FileUtil.flatten( - (String[]) injars.toArray(new String[0]), - null)); - } - - if (0 < inpaths.size()) { - argList.add("-inpath"); - argList.add( - FileUtil.flatten( - (String[]) inpaths.toArray(new String[0]), - null)); - } - - // put specified arguments last, for better badInput tests - argList.addAll(setupResult.commandOptions); - - // add both java/aspectj and argfiles - argList.addAll(arguments); - - // XXX hack - seek on request as a side effect. reimplement as listener - if (null != setupResult.seek) { - String slopPrefix = Spec.SEEK_MESSAGE_PREFIX + " slop - "; - PrintStream slop = - MessageUtil.handlerPrintStream( - status, - IMessage.INFO, - System.err, - slopPrefix); - List found = - FileUtil.lineSeek( - setupResult.seek, - arguments, - false, - slop); - if (!LangUtil.isEmpty(found)) { - for (Iterator iter = found.iterator(); - iter.hasNext(); - ) { - MessageUtil.info( - status, - Spec.SEEK_MESSAGE_PREFIX + iter.next()); - } - } - } - ICommand compiler = spec.reuseCompiler - // throws IllegalStateException if null - ? sandbox.getCommand(this) - : ReflectionFactory.makeCommand(setupResult.compilerName, status); - DirChanges dirChanges = null; - if (null == compiler) { - MessageUtil.fail( - status, - "unable to make compiler " + setupResult.compilerName); - return false; - } else { - if (setupResult.compilerName != Spec.DEFAULT_COMPILER) { - MessageUtil.info( - status, - "compiler: " + setupResult.compilerName); - } - if (status.aborted()) { - MessageUtil.debug( - status, - "aborted, but compiler valid?: " + compiler); - } else { - // same DirChanges handling for JavaRun, CompilerRun, IncCompilerRun - // XXX around advice or template method/class - if (!LangUtil.isEmpty(spec.dirChanges)) { - LangUtil.throwIaxIfFalse( - 1 == spec.dirChanges.size(), - "expecting 0..1 dirChanges"); - dirChanges = - new DirChanges( - (DirChanges.Spec) spec.dirChanges.get(0)); - if (!dirChanges - .start(status, sandbox.classesDir)) { - return false; // setup failed - } - } - MessageUtil.info( - status, - compiler + "(" + argList + ")"); - sandbox.setCommand(compiler, this); - String[] args = (String[]) argList.toArray(RA_String); - commandResult = compiler.runCommand(args, handler); - } - } - handlerResult = handler.passed(); - if (!handlerResult) { - return false; - } else { - result = (commandResult == handler.expectingCommandTrue()); - if (!result) { - String m = - commandResult - ? "compile did not fail as expected" - : "compile failed unexpectedly"; - MessageUtil.fail(status, m); - } else if (null != dirChanges) { - result = dirChanges.end(status, sandbox.testBaseDir); - } - } - return result; - } finally { - if (!handlerResult) { // more debugging context in case of failure - MessageUtil.info(handler, spec.toLongString()); - MessageUtil.info(handler, "" + argList); - if (null != setupResult) { - MessageUtil.info(handler, "" + setupResult); - } - } - handler.report(status); - // XXX weak - actual messages not reported in real-time, no fast-fail - } - } - - public String toString() { - return "CompilerRun(" + spec + ")"; - } - - /** - * Initializer/factory for CompilerRun - * any path or file is relative to this test base dir - */ - public static class Spec extends AbstractRunSpec { - public static final String XMLNAME = "compile"; - public static final String DEFAULT_COMPILER = - ReflectionFactory.ECLIPSE; - static final String SEEK_PREFIX = "-seek:"; - static final String SEEK_MESSAGE_PREFIX = "found: "; - - private static final CRSOptions CRSOPTIONS = new CRSOptions(); - /** - * Retitle description to title, paths to files, do comment, - * staging, badInput, - * do dirChanges, and print no chidren. - */ - private static final AbstractRunSpec.XMLNames NAMES = - new AbstractRunSpec.XMLNames( - AbstractRunSpec.XMLNames.DEFAULT, - "title", - null, - null, - null, - "files", - null, - null, - null, - false, - false, - true); - - /** - * If the source version warrants, add a -bootclasspath - * entry to the list of arguments to add. - * This will fail and return an error String if the - * required library is not found. - * @param sourceVersion the String (if any) describing the -source option - * (expecting one of [null, "1.3", "1.4", "1.5"]. - * @param compilerName the String name of the target compiler - * @param toAdd the ArrayList to add -bootclasspath to - * @return the String describing any errors, or null if no errors - */ - private static String updateBootclasspathForSourceVersion( - String sourceVersion, - String compilerName, - ArrayList toAdd) { - if (null == sourceVersion) { - return null; - } - if (3 != sourceVersion.length()) { - throw new IllegalArgumentException( - "bad version: " + sourceVersion); - } - if (null == toAdd) { - throw new IllegalArgumentException("null toAdd"); - } - int version = sourceVersion.charAt(2) - '0'; - switch (version) { - case (3) : - if (Globals.supportsJava("1.4")) { - if (!FileUtil.canReadFile(Globals.J2SE13_RTJAR)) { - return "no 1.3 libraries to handle -source 1.3"; - } - toAdd.add("-bootclasspath"); - toAdd.add(Globals.J2SE13_RTJAR.getAbsolutePath()); - } - break; - case (4) : - if (!Globals.supportsJava("1.4")) { - if (ReflectionFactory - .ECLIPSE - .equals(compilerName)) { - return "run eclipse under 1.4 to handle -source 1.4"; - } - if (!FileUtil.canReadFile(Globals.J2SE14_RTJAR)) { - return "no 1.4 libraries to handle -source 1.4"; - } - toAdd.add("-bootclasspath"); - toAdd.add(Globals.J2SE14_RTJAR.getAbsolutePath()); - } - break; - case (5) : - return "1.5 not supported in CompilerRun"; - case (0) : - // ignore - no version specified - break; - default : - throw new Error("unexpected version: " + version); - } - return null; - } - - static CRSOptions testAccessToCRSOptions() { - return CRSOPTIONS; - } - - static Options testAccessToOptions() { - return CRSOPTIONS.getOptions(); - } - - private static String[] copy(String[] input) { - if (null == input) { - return null; - } - String[] result = new String[input.length]; - System.arraycopy(input, 0, result, 0, input.length); - return result; - } - - protected String compiler; - - // use same command - see also IncCompiler.Spec.fresh - protected boolean reuseCompiler; - protected boolean permitAnyCompiler; - protected boolean includeClassesDir; - - protected TestSetup testSetup; - - protected String[] argfiles = new String[0]; - protected String[] aspectpath = new String[0]; - protected String[] classpath = new String[0]; - protected String[] sourceroots = new String[0]; - protected String[] extdirs = new String[0]; - - /** src path = {suiteParentDir}/{testBaseDirOffset}/{testSrcDirOffset}/{path} */ - protected String testSrcDirOffset; - protected String xlintfile; - protected String outjar; - - public Spec() { - super(XMLNAME); - setXMLNames(NAMES); - compiler = DEFAULT_COMPILER; - } - - protected void initClone(Spec spec) - throws CloneNotSupportedException { - super.initClone(spec); - spec.argfiles = copy(argfiles); - spec.aspectpath = copy(aspectpath); - spec.classpath = copy(classpath); - spec.compiler = compiler; - spec.includeClassesDir = includeClassesDir; - spec.reuseCompiler = reuseCompiler; - spec.permitAnyCompiler = permitAnyCompiler; - spec.sourceroots = copy(sourceroots); - spec.extdirs = copy(extdirs); - spec.outjar = outjar; - spec.testSetup = null; - if (null != testSetup) { - spec.testSetup = (TestSetup) testSetup.clone(); - } - spec.testSrcDirOffset = testSrcDirOffset; - } - - public Object clone() throws CloneNotSupportedException { - Spec result = new Spec(); - initClone(result); - return result; - } - - public void setIncludeClassesDir(boolean include) { - this.includeClassesDir = include; - } - public void setReuseCompiler(boolean reuse) { - this.reuseCompiler = reuse; - } - - public void setPermitAnyCompiler(boolean permitAny) { - this.permitAnyCompiler = permitAny; - } - - public void setCompiler(String compilerName) { - this.compiler = compilerName; - } - - public void setTestSrcDirOffset(String s) { - if (null != s) { - testSrcDirOffset = s; - } - } - - /** override to set dirToken to Sandbox.CLASSES and default suffix to ".class" */ - public void addDirChanges(DirChanges.Spec spec) { - if (null == spec) { - return; - } - spec.setDirToken(Sandbox.CLASSES_DIR); - spec.setDefaultSuffix(".class"); - super.addDirChanges(spec); - } - - public String toLongString() { - return getPrintName() + "(" + super.containedSummary() + ")"; - } - - public String toString() { - return getPrintName() + "(" + super.containedSummary() + ")"; - } - - /** bean mapping for writers */ - public void setFiles(String paths) { - addPaths(paths); - } - - /** - * Add to default classpath - * (which includes aspectjrt.jar and testing-client.jar). - * @param files comma-delimited list of classpath entries - ignored if - * null or empty - */ - public void setClasspath(String files) { - if (!LangUtil.isEmpty(files)) { - classpath = XMLWriter.unflattenList(files); - } - } - - /** - * Set source roots, deleting any old ones - * @param files comma-delimited list of directories - * - ignored if null or empty - */ - public void setSourceroots(String dirs) { - if (!LangUtil.isEmpty(dirs)) { - sourceroots = XMLWriter.unflattenList(dirs); - } - } - public void setXlintfile(String path) { - xlintfile = path; - } - - public void setOutjar(String path) { - outjar = path; - } - - /** - * Set extension dirs, deleting any old ones - * @param files comma-delimited list of directories - * - ignored if null or empty - */ - public void setExtdirs(String dirs) { - if (!LangUtil.isEmpty(dirs)) { - extdirs = XMLWriter.unflattenList(dirs); - } - } - - /** - * Set aspectpath, deleting any old ones - * @param files comma-delimited list of aspect jars - ignored if null or - * empty - */ - public void setAspectpath(String files) { - if (!LangUtil.isEmpty(files)) { - aspectpath = XMLWriter.unflattenList(files); - } - } - - /** - * Set argfiles, deleting any old ones - * @param files comma-delimited list of argfiles - ignored if null or empty - */ - public void setArgfiles(String files) { - if (!LangUtil.isEmpty(files)) { - argfiles = XMLWriter.unflattenList(files); - } - } - - /** @return String[] copy of argfiles array */ - public String[] getArgfilesArray() { - String[] argfiles = this.argfiles; - if (LangUtil.isEmpty(argfiles)) { - return new String[0]; - } - return (String[]) copy(argfiles); - } - - /** - * Make a copy of the array. - * @return an array with the same component type as source - * containing same elements, even if null. - * @throws IllegalArgumentException if source is null - */ - public static final Object[] copy(Object[] source) { - LangUtil.throwIaxIfNull(source, "source"); - final Class c = source.getClass().getComponentType(); - Object[] result = (Object[]) Array.newInstance(c, source.length); - System.arraycopy(source, 0, result, 0, result.length); - return result; - } - - /** - * This implementation skips if: - * <ul> - * <li>incremental test, but using ajc (not eclipse)</li> - * <li>usejavac, but javac is not available on the classpath</li> - * <li>eclipse, but -usejavac or -preprocess test</li> - * <li>-source 1.4, but running under 1.2 (XXX design)</li> - * <li>local/global option conflicts (-lenient/-strict)</li> - * <li>semantic conflicts (e.g., -lenient/-strict)</li> - * </ul> - * @return false if this wants to be skipped, true otherwise - */ - protected boolean doAdoptParentValues( - RT parentRuntime, - IMessageHandler handler) { - if (!super.doAdoptParentValues(parentRuntime, handler)) { - return false; - } - testSetup = setupArgs(handler); - if (!testSetup.result) { - skipMessage(handler, testSetup.failureReason); - } - return testSetup.result; - } - - private String getShortCompilerName() { - String compilerClassName = compiler; - if (null != testSetup) { - compilerClassName = testSetup.compilerName; - } - if (null != compilerClassName) { - int loc = compilerClassName.lastIndexOf("."); - if (-1 != loc) { - compilerClassName = - compilerClassName.substring(loc + 1); - } - } - return compilerClassName; - } - - /** @return a CompilerRun with this as spec if setup completes successfully. */ - public IRunIterator makeRunIterator( - Sandbox sandbox, - Validator validator) { - CompilerRun run = new CompilerRun(this); - if (run.setupAjcRun(sandbox, validator)) { - // XXX need name for compilerRun - return new WrappedRunIterator(this, run); - } - return null; - } - - protected String getPrintName() { - return "CompilerRun.Spec " + getShortCompilerName(); - } - - /** - * Each non-incremental run, fold the global flags in with - * the run flags, which may involve adding or removing from - * either list, depending on the flag prefix: - * <ul> - * <li>-foo: use -foo unless forced off.<li> - * <li>^foo: (force off) remove any -foo option from the run flags</li> - * <li>!foo: (force on) require the -foo flag </li> - * </ul> - * If there is a force conflict, then the test is skipped - * ("skipping" info message, TestSetup.result is false). - * This means an option local to the test which was specified - * without forcing may be overridden by a globally-forced option. - * <p> - * There are some flags which are interpreted by the test - * and removed from the list of flags passed to the command - * (see testFlag()): - * <ul> - * <li>eclipse: use the new eclipse compiler (can force)</li> - * <li>ajc: use the old ajc compiler (can force)</li> - * <li>ignoreWarnings: ignore warnings in result evaluations (no force)</li> - * </ul> - * <p> - * There are some flags which are inconsistent with each other. - * These are treated as conflicts and the test is skipped: - * <ul> - * <li>lenient, strict</li> - * </ul> - * <p> - * <p> - * This also interprets any relevant System properties, - * e.g., from <code>JavaRun.BOOTCLASSPATH_KEY</code>. - * <p> - * Finally, compiler limitations are enforced here by skipping - * tests which the compiler cannot do: - * <ul> - * <li>eclipse does not do -lenient, -strict, -usejavac, -preprocess, - * -XOcodeSize, -XSerializable, XaddSafePrefix, - * -XserializableAspects,-XtargetNearSource</li> - * <li>ajc does not run in incremental (staging) mode, - * nor with -usejavac if javac is not on the classpath</li> - * </ul> - * <u>Errors</u>:This will remove an arg not prefixed by [-|!|^] after - * providing an info message. - * <u>TestSetup Result</u>: - * If this completes successfully, then TestSetup.result is true, - * and commandOptions is not null, and any test flags (ignore warning, - * compiler) are reflected in the TestSetup. - * If this fails, then TestSetup.result is false, - * and a TestSetup.failreason is set. - * This means the test is skipped. - * @return TestSetup with results - * (TestSetup result=false if the run should not continue) - */ - protected TestSetup setupArgs(IMessageHandler handler) { - // warning: HarnessSelectionTest checks for specific error wording - final Spec spec = this; - final TestSetup result = new TestSetup(); - result.compilerName = spec.compiler; - // urk - s.b. null, but expected - Values values = gatherValues(result); - - if ((null == values) || (null != result.failureReason)) { - return checkResult(result); - } - - // send info messages about - // forced staging when -incremental - // or staging but no -incremental flag - Option.Family getFamily = - CRSOPTIONS.crsIncrementalOption.getFamily(); - final boolean haveIncrementalFlag = - (null != values.firstInFamily(getFamily)); - - if (spec.isStaging()) { - if (!haveIncrementalFlag) { - MessageUtil.info( - handler, - "staging but no -incremental flag"); - } - } else if (haveIncrementalFlag) { - spec.setStaging(true); - MessageUtil.info(handler, "-incremental forcing staging"); - } - - if (hasInvalidOptions(values, result)) { - return checkResult(result); - } - - // set compiler in result - getFamily = CRSOPTIONS.ajccompilerOption.getFamily(); - Option.Value compiler = values.firstInFamily(getFamily); - if (null != compiler) { - result.compilerName - = CRSOPTIONS.compilerClassName(compiler.option); - if (null == result.compilerName) { - result.failureReason = - "unable to get class name for " + compiler; - return checkResult(result); - } - } - String compilerName = - (null == result.compilerName - ? spec.compiler - : result.compilerName); - // check compiler semantics - if (hasCompilerSpecErrors(compilerName, values, result)) { - return checkResult(result); - } - // add toadd and finish result - ArrayList args = new ArrayList(); - String[] rendered = values.render(); - if (!LangUtil.isEmpty(rendered)) { - args.addAll(Arrays.asList(rendered)); - } - // update bootclasspath - getFamily = CRSOPTIONS.crsSourceOption.getFamily(); - Option.Value source = values.firstInFamily(getFamily); - if (null != source) { - String sourceVersion = source.unflatten()[1]; - ArrayList toAdd = new ArrayList(); - /*String err =*/ - updateBootclasspathForSourceVersion( - sourceVersion, - spec.compiler, - toAdd); - args.addAll(toAdd); - } - result.commandOptions = args; - result.result = true; - return checkResult(result); - } - - /** - * Ensure exit invariant: - * <code>result.result == (null == result.failureReason) - * == (null != result.commandOptions)</code> - * @param result the TestSetup to verify - * @return result - * @throws Error if invariant is not true - */ - TestSetup checkResult(TestSetup result) { - String err = null; - if (null == result) { - err = "null result"; - } else if (result.result != (null == result.failureReason)) { - err = - result.result - ? "expected no failure: " + result.failureReason - : "fail for no reason"; - } else if (result.result != (null != result.commandOptions)) { - err = - result.result - ? "expected command options" - : "unexpected command options"; - } - if (null != err) { - throw new Error(err); - } - return result; - } - - boolean hasInvalidOptions(Values values, TestSetup result) { - // not supporting 1.0 options any more - for (Iterator iter = CRSOPTIONS.invalidOptions.iterator(); - iter.hasNext(); - ) { - Option option = (Option) iter.next(); - if (null != values.firstOption(option)) { - result.failureReason = - "invalid option in harness: " + option; - return true; - } - } - return false; - } - - boolean hasCompilerSpecErrors( - String compilerName, - Values values, - TestSetup result) { - /* - * Describe any semantic conflicts between options. - * This skips: - * - old 1.0 options, including lenient v. strict - * - old ajc options, include !incremental and usejavac w/o javac - * - invalid eclipse options (mostly ajc) - * @param compilerName the String name of the target compiler - * @return a String describing any conflicts, or null if none - */ - if (!permitAnyCompiler - && (!(ReflectionFactory.ECLIPSE.equals(compilerName) - || ReflectionFactory.OLD_AJC.equals(compilerName) - || CRSOptions.AJDE_COMPILER.equals(compilerName) - || CRSOptions.AJCTASK_COMPILER.equals(compilerName) - || permitAnyCompiler - ))) { - //|| BUILDER_COMPILER.equals(compilerName)) - result.failureReason = - "unrecognized compiler: " + compilerName; - return true; - } - // not supporting ajc right now - if (null - != values.firstOption(CRSOPTIONS.ajccompilerOption)) { - result.failureReason = "ajc not supported"; - return true; - } - // not supporting 1.0 options any more - for (Iterator iter = CRSOPTIONS.ajc10Options.iterator(); - iter.hasNext(); - ) { - Option option = (Option) iter.next(); - if (null != values.firstOption(option)) { - result.failureReason = "old ajc 1.0 option: " + option; - return true; - } - } - - return false; - } - - protected Values gatherValues(TestSetup result) { - final Spec spec = this; - // ---- local option values - final Values localValues; - final Options options = CRSOPTIONS.getOptions(); - try { - String[] input = getOptionsArray(); - // this handles reading options, - // flattening two-String options, etc. - localValues = options.acceptInput(input); - // all local values should be picked up - String err = Options.missedMatchError(input, localValues); - if (!LangUtil.isEmpty(err)) { - result.failureReason = err; - return null; - } - } catch (InvalidInputException e) { - result.failureReason = e.getFullMessage(); - return null; - } - - // ---- global option values - StringBuffer errs = new StringBuffer(); - final Values globalValues = - spec.runtime.extractOptions(options, true, errs); - if (errs.length() > 0) { - result.failureReason = errs.toString(); - return null; - } - final Values combined = - Values.wrapValues( - new Values[] { localValues, globalValues }); - - String err = combined.resolve(); - if (null != err) { - result.failureReason = err; - return null; - } - - return handleTestArgs(combined, result); - } - - // final int len = globalValues.length() + localValues.length(); - // final Option.Value[] combinedValues = new Option.Value[len]; - // System.arraycopy( - // globalValues, - // 0, - // combinedValues, - // 0, - // globalValues.length()); - // System.arraycopy( - // localValues, - // 0, - // combinedValues, - // globalValues.length(), - // localValues.length()); - // - // result.compilerName = spec.compiler; - // if (0 < combinedValues.length) { - // // this handles option forcing, etc. - // String err = Options.resolve(combinedValues); - // if (null != err) { - // result.failureReason = err; - // return null; - // } - // if (!handleTestArgs(combinedValues, result)) { - // return null; - // } - // } - // return Values.wrapValues(combinedValues); - // } - /** - * This interprets and nullifies values for the test. - * @param values the Option.Value[] being processed - * @param result the TestSetup to modify - * @return false if error (caller should return), true otherwise - */ - Values handleTestArgs(Values values, final TestSetup result) { - final Option.Family compilerFamily = - CRSOPTIONS.ajccompilerOption.getFamily(); - Values.Selector selector = new Values.Selector() { - protected boolean accept(Option.Value value) { - if (null == value) { - return false; - } - Option option = value.option; - if (compilerFamily.sameFamily(option.getFamily())) { - if (value.prefix.isSet()) { - String compilerClass - = CRSOPTIONS.compilerClassName(option); - if (null == compilerClass) { - result.failureReason = - "unrecognized compiler: " + value; - throw Values.Selector.STOP; - } - if (!CRSOPTIONS.compilerIsLoadable(option)) { - result.failureReason = - "unable to load compiler: " + option; - throw Values.Selector.STOP; - } - result.compilerName = compilerClass; - } - return true; - } else if ( - CRSOPTIONS.crsIgnoreWarnings.sameOptionIdentifier( - option)) { - result.ignoreWarnings = value.prefix.isSet(); - result.ignoreWarningsSet = true; - return true; - } - return false; - } - }; - return values.nullify(selector); - } - - // /** - // * This interprets and nullifies values for the test. - // * @param values the Option.Value[] being processed - // * @param result the TestSetup to modify - // * @return false if error (caller should return), true otherwise - // */ - // boolean handleTestArgs(Option.Value[] values, TestSetup result) { - // if (!LangUtil.isEmpty(values)) { - // for (int i = 0; i < values.length; i++) { - // Option.Value value = values[i]; - // if (null == value) { - // continue; - // } - // Option option = value.option; - // if (option.sameOptionFamily(ECLIPSE_OPTION)) { - // if (!value.prefix.isSet()) { - // values[i] = null; - // continue; - // } - // String compilerClass = - // (String) COMPILER_OPTION_TO_CLASSNAME.get( - // option); - // if (null == compilerClass) { - // result.failureReason = - // "unrecognized compiler: " + value; - // return false; - // } - // result.compilerName = compilerClass; - // values[i] = null; - // } else if ( - // option.sameOptionFamily(crsIgnoreWarnings)) { - // result.ignoreWarnings = value.prefix.isSet(); - // result.ignoreWarningsSet = true; - // values[i] = null; - // } - // } - // } - // return true; - // } - - // XXX need keys, cache... - /** @return index of global in argList, ignoring first char */ - protected int indexOf(String global, ArrayList argList) { - int max = argList.size(); - for (int i = 0; i < max; i++) { - if (global - .equals(((String) argList.get(i)).substring(1))) { - return i; - } - } - return -1; - } - - /** - * Write this out as a compile element as defined in - * AjcSpecXmlReader.DOCTYPE. - * @see AjcSpecXmlReader#DOCTYPE - * @see IXmlWritable#writeXml(XMLWriter) - */ - public void writeXml(XMLWriter out) { - out.startElement(xmlElementName, false); - if (!LangUtil.isEmpty(testSrcDirOffset)) { - out.printAttribute("dir", testSrcDirOffset); - } - super.writeAttributes(out); - if (!DEFAULT_COMPILER.equals(compiler)) { - out.printAttribute("compiler", compiler); - } - if (reuseCompiler) { - out.printAttribute("reuseCompiler", "true"); - } -// test-only feature -// if (permitAnyCompiler) { -// out.printAttribute("permitAnyCompiler", "true"); -// } - if (includeClassesDir) { - out.printAttribute("includeClassesDir", "true"); - } - if (!LangUtil.isEmpty(argfiles)) { - out.printAttribute( - "argfiles", - XMLWriter.flattenFiles(argfiles)); - } - if (!LangUtil.isEmpty(aspectpath)) { - out.printAttribute( - "aspectpath", - XMLWriter.flattenFiles(aspectpath)); - } - if (!LangUtil.isEmpty(sourceroots)) { - out.printAttribute( - "sourceroots", - XMLWriter.flattenFiles(sourceroots)); - } - if (!LangUtil.isEmpty(extdirs)) { - out.printAttribute( - "extdirs", - XMLWriter.flattenFiles(extdirs)); - } - out.endAttributes(); - if (!LangUtil.isEmpty(dirChanges)) { - DirChanges.Spec.writeXml(out, dirChanges); - } - SoftMessage.writeXml(out, getMessages()); - out.endElement(xmlElementName); - } - - /** - * Encapsulate the directives that can be set using - * global arguments supplied in {@link Spec.getOptions()}. - * This supports changing the compiler and ignoring warnings. - */ - class TestSetup { - /** null unless overriding the compiler to be used */ - String compilerName; - /** - * true if we should tell AjcMessageHandler whether - * to ignore warnings in its result evaluation - */ - boolean ignoreWarningsSet; - - /** if telling AjcMessageHandler, what we tell it */ - boolean ignoreWarnings; - - /** false if setup failed */ - boolean result; - - /** if setup failed, this has the reason why */ - String failureReason; - - /** beyond running test, also seek text in sources */ - String seek; - - /** if setup completed, this has the combined global/local options */ - ArrayList commandOptions; - - public Object clone() { - TestSetup testSetup = new TestSetup(); - testSetup.compilerName = compilerName; - testSetup.ignoreWarnings = ignoreWarnings; - testSetup.ignoreWarningsSet = ignoreWarningsSet; - testSetup.result = result; - testSetup.failureReason = failureReason; - testSetup.seek = seek; - if (null != commandOptions) { - testSetup.commandOptions = new ArrayList(); - testSetup.commandOptions.addAll(commandOptions); - } - return testSetup; - } - public String toString() { - return "TestSetup(" - + (null == compilerName ? "" : compilerName + " ") - + (!ignoreWarningsSet - ? "" - : (ignoreWarnings ? "" : "do not ") - + "ignore warnings ") - + (result ? "" : "setup failed") - + ")"; - } - } - - /** - * Options-related stuff in the spec. - */ - static class CRSOptions { - // static final String BUILDER_COMPILER = - // "org.aspectj.ajdt.internal.core.builder.Builder.Command"; - static final String AJDE_COMPILER = - CompileCommand.class.getName(); - - static final String AJCTASK_COMPILER = - AjcTaskCompileCommand.class.getName(); - - private final Map compilerOptionToLoadable = new TreeMap(); - /* - * The options field in a compiler test permits some arbitrary - * command-line options to be set. It does not permit things - * like classpath, aspectpath, files, etc. which are set - * using other fields in the test specification, so the options - * permitted are a subset of those permitted on the command-line. - * - * Global options specified on the harness command-line are - * adopted for the compiler command-line if they are permitted - * in the options field. That means we have to detect each - * permitted option, rather than just letting all through - * for the compiler. - * - * Conversely, some options are targeted not at the compiler, - * but at the test itself (e.g., to ignore warnings, or to - * select a compiler. - * - * The harness can run many compilers, and they differ in - * which options are permitted. You can specify a compiler - * as an option (e.g., -eclipse). So the set of constraints - * on the list of permitted options can differ from test to test. - * - * The following code sets up the lists of permitted options - * and breaks out subsets for different compiler-variant checks. - * Most options are created but not named, but some options - * are named to detect corresponding values for further - * processing. e.g., the compiler options are saved so - * we can do per-compiler option verification. - * - */ - private final Options crsOptions; - private final Family compilerFamily; - private final Option crsIncrementalOption; - private final Option crsSourceOption; - // these are options handled/absorbed by CompilerRun - private final Option crsIgnoreWarnings; - private final Option eclipseOption; - private final Option buildercompilerOption; - private final Option ajdecompilerOption; - private final Option javacOption; - private final Option ajctaskcompilerOption; - private final Option ajccompilerOption; - private final Map compilerOptionToClassname; - private final Set compilerOptions; - // compiler verification - permit but flag ajc 1.0 options - private final List ajc10Options; - private final List invalidOptions; - - private CRSOptions() { - crsOptions = new Options(true); - Option.Factory factory = new Option.Factory("CompilerRun"); - // compiler options go in map - eclipseOption = - factory.create( - "eclipse", - "compiler", - Option.FORCE_PREFIXES, - false); - compilerFamily = eclipseOption.getFamily(); - buildercompilerOption = - factory.create( - "builderCompiler", - "compiler", - Option.FORCE_PREFIXES, - false); - ajctaskcompilerOption = - factory.create( - "ajctaskCompiler", - "compiler", - Option.FORCE_PREFIXES, - false); - ajdecompilerOption = - factory.create( - "ajdeCompiler", - "compiler", - Option.FORCE_PREFIXES, - false); - ajccompilerOption = - factory.create( - "ajc", - "compiler", - Option.FORCE_PREFIXES, - false); - javacOption = - factory.create( - "javac", - "compiler", - Option.FORCE_PREFIXES, - false); - - Map map = new TreeMap(); - map.put(eclipseOption, ReflectionFactory.ECLIPSE); - //map.put(BUILDERCOMPILER_OPTION, BUILDER_COMPILER); - map.put( - ajctaskcompilerOption, - AJCTASK_COMPILER); - map.put(ajdecompilerOption, AJDE_COMPILER); - map.put(ajccompilerOption, ReflectionFactory.OLD_AJC); - //map.put(JAVAC_OPTION, "XXX javac option not supported"); - compilerOptionToClassname = - Collections.unmodifiableMap(map); - - compilerOptions = - Collections.unmodifiableSet( - compilerOptionToClassname.keySet()); - // options not permitted in the harness - List list = new ArrayList(); - list.add(factory.create("workingdir")); - list.add(factory.create("argfile")); - list.add(factory.create("sourceroots")); - list.add(factory.create("outjar")); - invalidOptions = Collections.unmodifiableList(list); - - // other options added directly - crsIncrementalOption = factory.create("incremental"); - - crsIgnoreWarnings = factory.create("ignoreWarnings"); - - crsSourceOption = - factory - .create( - "source", - "source", - Option.FORCE_PREFIXES, - false, - new String[][] { new String[] { "1.3", "1.4", "1.5" } - }); - - // ajc 1.0 options - // workingdir above in invalid options - list = new ArrayList(); - list.add(factory.create("usejavac")); - list.add(factory.create("preprocess")); - list.add(factory.create("nocomment")); - list.add(factory.create("porting")); - list.add(factory.create("XOcodeSize")); - list.add(factory.create("XTargetNearSource")); - list.add(factory.create("XaddSafePrefix")); - list.add( - factory.create( - "lenient", - "lenient", - Option.FORCE_PREFIXES, - false)); - list.add( - factory.create( - "strict", - "lenient", - Option.FORCE_PREFIXES, - false)); - ajc10Options = Collections.unmodifiableList(list); - - // -warn:.. and -g/-g:.. are not exclusive - if (!(factory.setupFamily("debug", true) - && factory.setupFamily("warning", true))) { - System.err.println("CompilerRun debug/warning fail!"); - } - Option[] options = - new Option[] { - crsIncrementalOption, - crsIgnoreWarnings, - crsSourceOption, - factory.create( - "Xlint", - "XLint", - Option.FORCE_PREFIXES, - true), - factory.create("verbose"), - factory.create("emacssym"), - factory.create("referenceInfo"), - factory.create("nowarn"), - factory.create("deprecation"), - factory.create("noImportError"), - factory.create("proceedOnError"), - factory.create("preserveAllLocals"), - factory.create( - "warn", - "warning", - Option.STANDARD_PREFIXES, - true), - factory.create( - "g", - "debug", - Option.STANDARD_PREFIXES, - false), - factory.create( - "g:", - "debug", - Option.STANDARD_PREFIXES, - true), - factory.create( - "1.3", - "compliance", - Option.FORCE_PREFIXES, - false), - factory.create( - "1.4", - "compliance", - Option.FORCE_PREFIXES, - false), - factory.create( - "1.5", - "compliance", - Option.FORCE_PREFIXES, - false), - factory - .create( - "target", - "target", - Option.FORCE_PREFIXES, - false, - new String[][] { new String[] { - "1.1", - "1.2", - "1.3", - "1.4", - "1.5" }}), - factory.create("XnoInline"), - factory.create("XterminateAfterCompilation"), - factory.create("Xreweavable"), - factory.create("XnotReweavable"), - factory.create("XserializableAspects") - }; - - // among options not permitted: extdirs... - - for (int i = 0; i < options.length; i++) { - crsOptions.addOption(options[i]); - } - for (Iterator iter = compilerOptions.iterator(); - iter.hasNext(); - ) { - crsOptions.addOption((Option) iter.next()); - } - // these are recognized but records with them are skipped - for (Iterator iter = ajc10Options.iterator(); - iter.hasNext(); - ) { - crsOptions.addOption((Option) iter.next()); - } - crsOptions.freeze(); - } - - Options getOptions() { - return crsOptions; - } - - /** - * @return unmodifiable Set of options sharing the - * family "compiler". - */ - Set compilerOptions() { - return compilerOptions; - } - - /** - * @param option the compiler Option to get name for - * @return null if option is null or not a compiler option, - * or the fully-qualified classname of the ICommand - * implementing the compiler. - */ - String compilerClassName(Option option) { - if ((null == option) - || (!compilerFamily.sameFamily(option.getFamily()))) { - return null; - } - return (String) compilerOptionToClassname.get(option); - } - - /** - * Check that the compiler class associated with a compiler - * option can be loaded. This check only happens once; - * the result is cached (by compilerOption key) for later calls. - * @param compilerOption the Option (family compiler) to check - * @return true if compiler class for this option can be loaded - */ - boolean compilerIsLoadable(Option compilerOption) { - LangUtil.throwIaxIfNull(compilerOption, "compilerName"); - synchronized (compilerOptionToLoadable) { - Boolean result = - (Boolean) compilerOptionToLoadable.get( - compilerOption); - if (null == result) { - MessageHandler sink = new MessageHandler(); - String compilerClassname = - (String) compilerOptionToClassname.get( - compilerOption); - if (null == compilerClassname) { - result = Boolean.FALSE; - } else { - ICommand c = - ReflectionFactory.makeCommand( - compilerClassname, - sink); - - if ((null == c) - || sink.hasAnyMessage( - IMessage.ERROR, - true)) { - result = Boolean.FALSE; - } else { - result = Boolean.TRUE; - } - } - compilerOptionToLoadable.put( - compilerOption, - result); - } - return result.booleanValue(); - } - } - } // CompilerRun.Spec.CRSOptions - } // CompilerRun.Spec -} // CompilerRun
\ No newline at end of file diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/DirChanges.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/DirChanges.java deleted file mode 100644 index 13281607b..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/DirChanges.java +++ /dev/null @@ -1,614 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.testing.util.TestUtil; -import org.aspectj.testing.xml.IXmlWritable; -import org.aspectj.testing.xml.XMLWriter; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * Calculate changes in a directory tree. - * This implements two different specification styles: - * <ul> - * <li>Specify files added, removed, updated, and/or a component - * to check any existing files</li> - * <li>Specify expected directory. When complete this checks that - * any files in expected directory are matched in the actual. - * (.class files are dissassembled before comparison.) - * </li> - * </ul> - * Usage: - * <ul> - * <li>Set up with any expected changes and/or an expected directory</li> - * <li>Set up with any file checker</li> - * <li>start(..) before changes. - * This issues messages for any removed files not found, - * which represent an error in the expected changes.</li> - * <li>Do whatever operations will change the directory</li> - * <li>end(..). - * This issues messages for any files not removed, added, or updated, - * and, if any checker was set, any checker messages for matching - * added or updated files</li> - * </ul> - * When comparing directories, this ignores any paths containing "CVS". - */ -public class DirChanges { - - public static final String DELAY_NAME = "dir-changes.delay"; - private static final long DELAY; - static { - long delay = 10l; - try { - delay = Long.getLong(DELAY_NAME).longValue(); - if ((delay > 40000) || (delay < 0)) { - delay = 10l; - } - } catch (Throwable t) { - // ignore - } - DELAY = delay; - } - - private static final boolean EXISTS = true; - - final Spec spec; - - /** start time, in milliseconds - valid only from start(..)..end(..) */ - long startTime; - - /** base directory of actual files - valid only from start(..)..end(..) */ - File baseDir; - - /** if set, this is run against any resulting existing files - * specified in added/updated lists. - * This does not affect expected-directory comparison. - */ - IFileChecker fileChecker; - - /** handler valid from start..end of start(..) and end(..) methods */ - IMessageHandler handler; - - /** - * Constructor for DirChanges. - */ - public DirChanges(Spec spec) { - LangUtil.throwIaxIfNull(spec, "spec"); - this.spec = spec; - } - - /** - * Inspect the base dir, and issue any messages for - * removed files not present. - * @param baseDir File for a readable directory - * @return true if this started without sending messages - * for removed files not present. - */ - public boolean start(IMessageHandler handler, File baseDir) { - FileUtil.throwIaxUnlessCanReadDir(baseDir, "baseDir"); - final IMessageHandler oldHandler = this.handler; - this.handler = handler; - this.baseDir = baseDir; - startTime = 0l; - final boolean doCompare = false; - boolean result - = exists("at start, did not expect added file to exist", !EXISTS, spec.added, doCompare); - result &= exists("at start, expected unchanged file to exist", EXISTS, spec.unchanged, doCompare); - result &= exists("at start, expected updated file to exist", EXISTS, spec.updated, doCompare); - result &= exists("at start, expected removed file to exist", EXISTS, spec.removed, doCompare); - startTime = System.currentTimeMillis(); - // ensure tests don't complete in < 1 second, otherwise can confuse fast machines. - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - this.handler = oldHandler; - return result; - } - - - /** - * Inspect the base dir, issue any messages for - * files not added, files not updated, and files not removed, - * and compare expected/actual files added or updated. - * This sleeps before checking until at least DELAY milliseconds after start. - * @throws IllegalStateException if called before start(..) - */ - public boolean end(IMessageHandler handler, File srcBaseDir) { - FileUtil.throwIaxUnlessCanReadDir(baseDir, "baseDir"); - if (0l == startTime) { - throw new IllegalStateException("called before start"); - } - final long targetTime = startTime + spec.delayInMilliseconds; - do { - long curTime = System.currentTimeMillis(); - if (curTime >= targetTime) { - break; - } - try { - Thread.sleep(targetTime-curTime); - } catch (InterruptedException e) { - break; - } - } while (true); - final IMessageHandler oldHandler = this.handler; - this.handler = handler; - try { - // variant 1: check specified files - // deferring comparison to end... - final boolean doCompare = (null != fileChecker); - final boolean fastFail = spec.fastFail; - boolean result - = exists("at end, expected file was not added", EXISTS, spec.added, doCompare); - if (result || !fastFail) { - result &= exists("at end, expected file was not unchanged", EXISTS, spec.unchanged, doCompare, false); - } - if (result || !fastFail) { - result &= exists("at end, expected file was not updated", EXISTS, spec.updated, doCompare); - } - if (result || !fastFail) { - result &= exists("at end, file exists, was not removed", !EXISTS, spec.removed, doCompare); - } -// if (result || !fastFail) { -// // XXX validate that unchanged mod-time did not change -// } - // variant 1: compare expected directory - if (result || !fastFail) { - result &= compareDir(srcBaseDir); - } - return result; - } finally { - this.handler = oldHandler; - baseDir = null; - startTime = 0l; - } - } - - /** - * Verify that all files in any specified expected directory - * have matching files in the base directory, putting any messages - * in the handler (only one if the spec indicates fast-fail). - * @param srcBaseDir the File for the base directory of the test sources - * (any expected dir is specified relative to this directory) - * @return true if the same, false otherwise - */ - private boolean compareDir(File srcBaseDir) { - if (null == spec.expDir) { - return true; - } - File expDir = new File(srcBaseDir, spec.expDir); - File actDir = baseDir; - //System.err.println("XXX comparing actDir=" + actDir + " expDir=" + expDir); - return TestUtil.sameDirectoryContents(handler, expDir, actDir, spec.fastFail); - } - - - /** @param comp FileMessageComparer (if any) given matching messages to compare */ - protected void setFileComparer(IFileChecker comp) { - this.fileChecker = comp; - } - - - - /** - * Signal fail if any files do {not} exist or do {not} have last-mod-time after startTime - * @param handler the IMessageHandler sink for messages - * @param label the String infix for the fail message - * @param exists if true, then file must exist and be modified after start time; - * if false, then the file must not exist or must be modified before start time. - * @param pathList the List of path (without any Spec.defaultSuffix) of File - * in Spec.baseDir to find (or not, if !exists) - */ - protected boolean exists( - String label, - boolean exists, - List pathList, - boolean doCompare) { -// boolean expectStartEarlier = true; - return exists(label, exists, pathList,doCompare, true); - } - protected boolean exists( - String label, - boolean exists, - List pathList, - boolean doCompare, - boolean expectStartEarlier) { - boolean result = true; - if (!LangUtil.isEmpty(pathList)) { -// final File expDir = ((!doCompare || (null == spec.expDir)) -// ? null -// : new File(baseDir, spec.expDir)); - for (Iterator iter = pathList.iterator(); iter.hasNext();) { - final String entry = (String) iter.next() ; - String path = entry ; - if (null != spec.defaultSuffix) { - if (".class".equals(spec.defaultSuffix)) { - path = path.replace('.', '/'); - } - path = path + spec.defaultSuffix; - } - File actualFile = new File(baseDir, path); - if (exists != (actualFile.canRead() && actualFile.isFile() - && (expectStartEarlier - ? startTime <= actualFile.lastModified() - : startTime > actualFile.lastModified() - ))) { - failMessage(handler, exists, label, path, actualFile); - if (result) { - result = false; - } - } else if (exists && doCompare && (null != fileChecker)) { - if (!fileChecker.checkFile(handler, path, actualFile) && result) { - result = false; - } - } - } - } - return result; - } - - /** - * Generate fail message "{un}expected {label} file {path} in {baseDir}". - * @param handler the IMessageHandler sink - * @param label String message infix - * @param path the path to the file - */ - protected void failMessage( - IMessageHandler handler, - boolean exists, - String label, - String path, - File file) { - MessageUtil.fail(handler, label + " \"" + path + "\" in " + baseDir); - } - - /** Check actual File found at a path, usually to diff expected/actual contents */ - public static interface IFileChecker { - /** - * Check file found at path. - * Implementations should return false when adding fail (or worse) - * message to the handler, and true otherwise. - * @param handler IMessageHandler sink for messages, esp. fail. - * @param path String for normalized path portion of actualFile.getPath() - * @param actualFile File to file found - * @return false if check failed and messages added to handler - */ - boolean checkFile(IMessageHandler handler, String path, File actualFile); - } -// File-comparison code with a bit more generality -- too unweildy -// /** -// * Default FileChecker compares files literally, transforming any -// * with registered normalizers. -// */ -// public static class FileChecker implements IFileChecker { -// final File baseExpectedDir; -// NormalizedCompareFiles fileComparer; -// -// public FileChecker(File baseExpectedDir) { -// this.baseExpectedDir = baseExpectedDir; -// fileComparer = new NormalizedCompareFiles(); -// } -// public boolean checkFile(IMessageHandler handler, String path, File actualFile) { -// if (null == baseExpectedDir) { -// MessageUtil.error(handler, "null baseExpectedDir set on construction"); -// } else if (!baseExpectedDir.canRead() || !baseExpectedDir.isDirectory()) { -// MessageUtil.error(handler, "bad baseExpectedDir: " + baseExpectedDir); -// } else { -// File expectedFile = new File(baseExpectedDir, path); -// if (!expectedFile.canRead()) { -// MessageUtil.fail(handler, "cannot read expected file: " + expectedFile); -// } else { -// return doCheckFile(handler, expectedFile, actualFile, path); -// } -// } -// return false; -// } -// -// protected boolean doCheckFile( -// IMessageHandler handler, -// File expectedFile, -// File actualFile, -// String path) { -// fileComparer.setHandler(handler); -// FileLine[] expected = fileComparer.diff(); -// return false; -// } -// } - -// /** -// * CompareFiles implementation that pre-processes input -// * to normalize it. Currently it reads all files except -// * .class files, which it disassembles first. -// */ -// public static class NormalizedCompareFiles extends CompareFiles { -// private final static String[] NO_PATHS = new String[0]; -// private static String normalPath(File file) { // XXX util -// if (null == file) { -// return ""; -// } -// return file.getAbsolutePath().replace('\\', '/'); -// } -// -// private String[] baseDirs; -// private IMessageHandler handler; -// -// public NormalizedCompareFiles() { -// } -// -// void init(IMessageHandler handler, File[] baseDirs) { -// this.handler = handler; -// if (null == baseDirs) { -// this.baseDirs = NO_PATHS; -// } else { -// this.baseDirs = new String[baseDirs.length]; -// for (int i = 0; i < baseDirs.length; i++) { -// this.baseDirs[i] = normalPath(baseDirs[i]) + "/"; -// } -// } -// } -// -// private String getClassName(File file) { -// String result = null; -// String path = normalPath(file); -// if (!path.endsWith(".class")) { -// MessageUtil.error(handler, -// "NormalizedCompareFiles expected " -// + file -// + " to end with .class"); -// } else { -// path = path.substring(0, path.length()-6); -// for (int i = 0; i < baseDirs.length; i++) { -// if (path.startsWith(baseDirs[i])) { -// return path.substring(baseDirs[i].length()).replace('/', '.'); -// } -// } -// MessageUtil.error(handler, -// "NormalizedCompareFiles expected " -// + file -// + " to start with one of " -// + LangUtil.arrayAsList(baseDirs)); -// } -// -// return result; -// } -// -// /** -// * Read file as normalized lines, sending handler any messages -// * ERROR for input failures and FAIL for processing failures. -// * @return NOLINES on error or normalized lines from file otherwise -// */ -// public FileLine[] getFileLines(File file) { -// FileLineator capture = new FileLineator(); -// InputStream in = null; -// try { -// if (!file.getPath().endsWith(".class")) { -// in = new FileInputStream(file); -// FileUtil.copyStream( -// new BufferedReader(new InputStreamReader(in)), -// new PrintWriter(capture)); -// } else { -// String name = getClassName(file); -// if (null == name) { -// return new FileLine[0]; -// } -// String path = normalPath(file); -// path = path.substring(0, path.length()-name.length()); -// // XXX sole dependency on bcweaver/bcel -// LazyClassGen.disassemble(path, name, capture); -// } -// } catch (IOException e) { -// MessageUtil.fail(handler, -// "NormalizedCompareFiles IOException reading " + file, e); -// return null; -// } finally { -// if (null != in) { -// try { in.close(); } -// catch (IOException e) {} // ignore -// } -// capture.flush(); -// capture.close(); -// } -// String missed = capture.getMissed(); -// if (!LangUtil.isEmpty(missed)) { -// MessageUtil.fail(handler, -// "NormalizedCompareFiles missed input: " -// + missed); -// return null; -// } else { -// return capture.getFileLines(); -// } -// } -// -// -// } - - /** - * Specification for a set of File added, removed, or updated - * in a given directory, or for a directory base for a tree of expected files. - * If defaultSuffix is specified, entries may be added without it. - * Currently the directory tree - * only is used to verify files that are expected - * and found after the process completes. - */ - public static class Spec implements IXmlWritable { - /** XML element name */ - public static final String XMLNAME = "dir-changes"; - - /** a symbolic name for the base directory */ - String dirToken; // XXX default to class? - - /** if set, then append to specified paths when seeking files */ - String defaultSuffix; - - /** relative path of dir with expected files for comparison */ - String expDir; - - long delayInMilliseconds = DELAY; - - /** if true, fail on first mis-match */ - boolean fastFail; - - /** relative paths (String) of expected files added */ - final ArrayList<String> added; - - /** relative paths (String) of expected files removed/deleted */ - final ArrayList<String> removed; - - /** relative paths (String) of expected files updated/changed */ - final ArrayList<String> updated; - - /** relative paths (String) of expected files NOT - * added, removed, or changed - * XXX unchanged unimplemented - */ - final ArrayList<String> unchanged; - - public Spec() { - added = new ArrayList<>(); - removed = new ArrayList<>(); - updated = new ArrayList<>(); - unchanged = new ArrayList<>(); - } - - /** - * @param dirToken the symbol name of the base directory (classes, run) - */ - public void setDirToken(String dirToken) { - this.dirToken = dirToken; - } - - /** - * Set the directory containing the expected files. - * @param expectedDirRelativePath path relative to the test base - * of the directory containing expected results for the output dir. - */ - public void setExpDir(String expectedDirRelativePath) { - expDir = expectedDirRelativePath; - } - - public void setDelay(String delay) { - if (null != delay) { - // let NumberFormatException propogate up - delayInMilliseconds = Long.parseLong(delay); - if (delayInMilliseconds < 0l) { - delayInMilliseconds = 0l; - } - } - } - - /** - * @param clipSuffix the String suffix, if any, to clip automatically - */ - public void setDefaultSuffix(String defaultSuffix) { - this.defaultSuffix = defaultSuffix; - } - - public void setAdded(String items) { - XMLWriter.addFlattenedItems(added, items); - } - - public void setRemoved(String items) { - XMLWriter.addFlattenedItems(removed, items); - } - - public void setUpdated(String items) { - XMLWriter.addFlattenedItems(updated, items); - } - - public void setUnchanged(String items) { - XMLWriter.addFlattenedItems(unchanged, items); - } - public void setFastfail(boolean fastFail) { - this.fastFail = fastFail; - } - - /** @return true if some list was specified */ - private boolean hasFileList() { - return (!LangUtil.isEmpty(added) - || !LangUtil.isEmpty(removed) - || !LangUtil.isEmpty(updated) - || !LangUtil.isEmpty(unchanged) - ); - } - - /** - * Emit specification in XML form if not empty. - * This writes nothing if there is no expected dir - * and there are no added, removed, or changed. - * fastFail is written only if true, since the default is false. - */ - public void writeXml(XMLWriter out) { - if (!hasFileList() && LangUtil.isEmpty(expDir)) { - return; - } - // XXX need to permit defaults here... - out.startElement(XMLNAME, false); - if (!LangUtil.isEmpty(dirToken)) { - out.printAttribute("dirToken", dirToken.trim()); - } - if (!LangUtil.isEmpty(defaultSuffix)) { - out.printAttribute("defaultSuffix", defaultSuffix.trim()); - } - if (!LangUtil.isEmpty(expDir)) { - out.printAttribute("expDir", expDir.trim()); - } - if (!LangUtil.isEmpty(added)) { - out.printAttribute("added", XMLWriter.flattenList(added)); - } - if (!LangUtil.isEmpty(removed)) { - out.printAttribute("removed", XMLWriter.flattenList(removed)); - } - if (!LangUtil.isEmpty(updated)) { - out.printAttribute("updated", XMLWriter.flattenList(updated)); - } - if (!LangUtil.isEmpty(unchanged)) { - out.printAttribute("unchanged", XMLWriter.flattenList(unchanged)); - } - if (fastFail) { - out.printAttribute("fastFail", "true"); - } - out.endElement(XMLNAME); - } - - /** - * Write list as elements to XMLWriter. - * @param out XMLWriter output sink - * @param dirChanges List of DirChanges.Spec to write - */ - public static void writeXml(XMLWriter out, List<DirChanges.Spec> dirChanges) { - if (LangUtil.isEmpty(dirChanges)) { - return; - } - LangUtil.throwIaxIfNull(out, "out"); - for (Iterator<DirChanges.Spec> iter = dirChanges.iterator(); iter.hasNext();) { - DirChanges.Spec spec = iter.next(); - if (null == spec) { - continue; - } - spec.writeXml(out); - } - } - -} // class Spec - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/FlatSuiteReader.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/FlatSuiteReader.java deleted file mode 100644 index 8d75d5620..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/FlatSuiteReader.java +++ /dev/null @@ -1,376 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.Message; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.bridge.SourceLocation; -import org.aspectj.bridge.IMessage.Kind; -import org.aspectj.testing.util.BridgeUtil; -import org.aspectj.testing.util.ObjectChecker; -import org.aspectj.testing.util.SFileReader; -import org.aspectj.testing.util.StandardObjectChecker; -import org.aspectj.testing.util.UtilLineReader; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * SFileReader.Maker implementation to read tests - * XXX supports iterative but not yet incremental compiles - */ -public class FlatSuiteReader implements SFileReader.Maker { - public static final String[] RA_String = new String[0]; - public static final FlatSuiteReader ME = new FlatSuiteReader(); - private static final SFileReader READER = new SFileReader(ME); - - static boolean isNumber(String s) { // XXX costly - if ((null == s) || (0 == s.length())) { - return false; - } - try { - Integer.valueOf(s); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - /** if true, clean up records before returning from make */ - public boolean clean; - - private FlatSuiteReader() { - } - - /** - * @see org.aspectj.testing.harness.bridge.SFileReader.Maker#getType() - */ - public Class getType() { - return AjcTest.Spec.class; - } - - /** - * This constructs an AjcTest.Spec assuming we are at the start of a - * test definition in reader and taking the parent directory of - * the reader as the base directory for the test suite root. - * @return the next AjcTest in reader, or null - * @see org.aspectj.testing.harness.bridge.SFileReader.Maker#make(UtilLineReader) - */ - public Object make(final UtilLineReader reader) - throws AbortException, IOException { - final AjcTest.Spec result = new AjcTest.Spec(); - boolean usingEclipse = false; // XXX - /** handle read errors by throwing AbortException with context info */ - class R { - public String read(String context) throws IOException { - return read(context, true); - } - public String read(String context, boolean required) - throws IOException { - final boolean skipEmpties = false; - String result = reader.nextLine(skipEmpties); - if ((null != result) && (0 == result.length())) { - result = null; - } - if ((null == result) && required) { - String s = "expecting " + context + " at " + reader; - throw new AbortException(s); - } - return result; - } - } - - final R r = new R(); - //final String baseDir = reader.getFile().getParent(); - String line; - String[] words; -// boolean isRequired = true; - - final int startLine = reader.getLineNumber() - 1; - - // description first - get from last line read - // XXX permits exactly one blank line between test records? - result.description = reader.lastLine(); - if (null == result.description) { - throw new AbortException("expecting description at " + reader); - } - - // next line is baseDir {option..} - line = r.read("baseDir {option..}"); - words = LangUtil.split(line); - if ((null == words) || (0 == words.length)) { - throw new AbortException( - "expecting dir {option..} at " + reader); - } - // XXX per-test (shared) root - //final File sourceRoot = new File(baseDir, words[0]); - result.setTestDirOffset(words[0]); - - String[] compileOptions = new String[words.length - 1]; - System.arraycopy(words, 1, compileOptions, 0, words.length - 1); - - // next are 1..n source lines: source... - CompilerRun.Spec lastCompileSpec = null; - // save last source file as default for error/warning line - File lastFile = null; // XXX per-compiler-run errors - while (null != (line = r.read("source.."))) { - words = LangUtil.split(line); - if (0 == FileUtil.sourceSuffixLength(words[0])) { // XXX - break; - } else { - lastCompileSpec = new CompilerRun.Spec(); - lastCompileSpec.testSrcDirOffset = null; - // srcs are in test base for old - lastCompileSpec.addOptions(compileOptions); - lastCompileSpec.addPaths(words); - lastFile = new File(words[words.length - 1]); - result.addChild(lastCompileSpec); - } - } - if (null == lastCompileSpec) { - throw new AbortException("expected sources at " + reader); - } - - ArrayList<Message> exp = new ArrayList<>(); - // !compile || noerrors || className {runOption..} - String first = words[0]; - if ("!compile".equals(first)) { - //result.className = words[0]; - //result.runOptions = new String[words.length-1]; - //System.arraycopy(words, 0, result.runOptions, 0, words.length-1); - } else if ("noerrors".equals(first)) { - // className is null, but no errors expected - // so compile succeeds but run not attempted - //result.errors = Main.RA_ErrorLine; - // result.runOptions = Main.RA_String; - } else if (isNumber(first) || (-1 != first.indexOf(":"))) { - exp.addAll(makeMessages(IMessage.ERROR, words, 0, lastFile)); - } else { - String[] args = new String[words.length - 1]; - System.arraycopy(words, 0, args, 0, args.length); - JavaRun.Spec spec = new JavaRun.Spec(); - spec.className = first; - spec.addOptions(args); - //XXXrun.runDir = sourceRoot; - result.addChild(spec); - } - - // optional: warnings, eclipse.warnings, eclipse.errors - // XXX unable to specify error in eclipse but not ajc - boolean gotErrors = false; - while (null - != (line = - r.read( - " errors, warnings, eclipse.warnings, eclipse.error", - false))) { - words = LangUtil.split(line); - first = words[0]; - if ("eclipse.warnings:".equals(first)) { - if (usingEclipse) { - exp.addAll( - makeMessages( - IMessage.WARNING, - words, - 0, - lastFile)); - } - } else if ("eclipse.errors:".equals(first)) { - if (usingEclipse) { - exp.addAll( - makeMessages(IMessage.ERROR, words, 0, lastFile)); - } - } else if ("warnings:".equals(first)) { - exp.addAll( - makeMessages(IMessage.WARNING, words, 0, lastFile)); - } else if (gotErrors) { - exp.addAll( - makeMessages(IMessage.WARNING, words, 0, lastFile)); - } else { - exp.addAll( - makeMessages(IMessage.ERROR, words, 0, lastFile)); - gotErrors = true; - } - } - lastCompileSpec.addMessages(exp); - - int endLine = reader.getLineNumber(); - File sourceFile = reader.getFile(); - ISourceLocation sl = - new SourceLocation(sourceFile, startLine, endLine, 0); - result.setSourceLocation(sl); - - if (clean) { - cleanup(result, reader); - } - return result; - } - - /** post-process result - * - use file name as keyword - * - clip / for dir offsets - * - extract purejava keyword variants - * - extract bugID - * - convert test options to force-options - * - detect illegal xml characters - */ - private void cleanup(AjcTest.Spec result, UtilLineReader lineReader) { - LangUtil.throwIaxIfNull(result, "result"); - LangUtil.throwIaxIfNull(lineReader, "lineReader"); - - File suiteFile = lineReader.getFile(); - String name = suiteFile.getName(); - if (!name.endsWith(".txt")) { - throw new Error("unexpected name: " + name); - } - result.addKeyword("from-" + name.substring(0,name.length()-4)); - - final String dir = result.testDirOffset; - if (dir.endsWith("/")) { - result.testDirOffset = dir.substring(0,dir.length()-1); - } - - StringBuffer description = new StringBuffer(result.description); - if (strip(description, "PUREJAVA")) { - result.addKeyword("purejava"); - } - if (strip(description, "PUREJAVE")) { - result.addKeyword("purejava"); - } - if (strip(description, "[purejava]")) { - result.addKeyword("purejava"); - } - String input = description.toString(); - int loc = input.indexOf("PR#"); - if (-1 != loc) { - String prefix = input.substring(0, loc).trim(); - String pr = input.substring(loc+3, loc+6).trim(); - String suffix = input.substring(loc+6).trim(); - description.setLength(0); - description.append((prefix + " " + suffix).trim()); - try { - result.setBugId(Integer.valueOf(pr).intValue()); - } catch (NumberFormatException e) { - throw new Error("unable to convert " + pr + " for " + result - + " at " + lineReader); - } - } - input = description.toString(); - String error = null; - if (-1 != input.indexOf("&")) { - error = "char &"; - } else if (-1 != input.indexOf("<")) { - error = "char <"; - } else if (-1 != input.indexOf(">")) { - error = "char >"; - } else if (-1 != input.indexOf("\"")) { - error = "char \""; - } - if (null != error) { - throw new Error(error + " in " + input + " at " + lineReader); - } - result.description = input; - - ArrayList<String> newOptions = new ArrayList<>(); - ArrayList<String> optionsCopy = result.getOptionsList(); - for (String option: optionsCopy) { - if (option.startsWith("-")) { - newOptions.add("!" + option.substring(1)); - } else { - throw new Error("non-flag option? " + option); - } - } - result.setOptionsArray((String[]) newOptions.toArray(new String[0])); - } - - private boolean strip(StringBuffer sb, String infix) { - String input = sb.toString(); - int loc = input.indexOf(infix); - if (-1 != loc) { - String prefix = input.substring(0, loc); - String suffix = input.substring(loc+infix.length()); - input = (prefix.trim() + " " + suffix.trim()).trim(); - sb.setLength(0); - sb.append(input); - return true; - } - return false; - } - - /** - * Generate list of expected messages of this kind. - * @param kind any non-null kind, but s.b. IMessage.WARNING or ERROR - * @param words - * @param start index in words where to start - * @param lastFile default file for source location if the input does not specify - * @return List - */ - private List<Message> makeMessages(// XXX weak - also support expected exceptions, etc. - Kind kind, String[] words, int start, File lastFile) { - ArrayList<Message> result = new ArrayList<>(); - for (int i = start; i < words.length; i++) { - ISourceLocation sl = - BridgeUtil.makeSourceLocation(words[i], lastFile); - if (null == sl) { // XXX signalling during make - // System.err.println(...); - //MessageUtil.debug(handler, "not a source location: " + words[i]); - } else { - String text = - (("" + sl.getLine()).equals(words[i]) ? "" : words[i]); - result.add(new Message(text, kind, null, sl)); - } - } - return (0 == result.size() ? Collections.<Message>emptyList() : result); - } - - /** - * Read suite spec from a flat .txt file. - * @throws AbortException on failure - * @return AjcTest.Suite.Spec with any AjcTest.Spec as children - */ - public AjcTest.Suite.Spec readSuite(File suiteFile) { - LangUtil.throwIaxIfNull(suiteFile, "suiteFile"); - if (!suiteFile.isAbsolute()) { - suiteFile = suiteFile.getAbsoluteFile(); - } - final AjcTest.Suite.Spec result = new AjcTest.Suite.Spec(); - result.setSuiteDirFile(suiteFile.getParentFile()); - ObjectChecker collector = new StandardObjectChecker(IRunSpec.class) { - public boolean doIsValid(Object o) { - result.addChild((IRunSpec) o); - return true; - } - }; - boolean abortOnError = true; - try { - READER.readNodes( - suiteFile, - collector, - abortOnError, - System.err); - } catch (IOException e) { - IMessage m = MessageUtil.fail("reading " + suiteFile, e); - throw new AbortException(m); - } - - return result; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/Globals.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/Globals.java deleted file mode 100644 index ad62c9735..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/Globals.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC) - * 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * Wes Isberg removed unused globals. - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - */ -public class Globals { - - /** map from String version to String class implemented in that version or later */ - private static final Map VM_CLASSES; - - public static final String FORK_NAME = "harness.fork"; - // XXX in testing-drivers/../package.htm - /** name/key of the System property to set to define library dir */ - public static final String LIBDIR_NAME = "harness.libdir"; - - /** name/key of the System property to set to define J2SE_HOME dir */ - public static final String J2SE14_RTJAR_NAME = "j2se14.rtjar"; - public static final String J2SE13_RTJAR_NAME = "j2se13.rtjar"; - - /** assumed relative location of a library with required jars */ - public static final String LIBDIR = - getSystemProperty(LIBDIR_NAME, "../lib/test"); - - /** Path to J2SE_HOME */ - public static final File J2SE14_RTJAR; - // XXX used only by 1.0 compiler tests - deprecate? - public static final File J2SE13_RTJAR; - - /** array of parameter types for main(String[]) */ - public static final Class[] MAIN_PARM_TYPES = - new Class[] { String[].class }; - public static final String S_testingclient_jar = - LIBDIR + "/testing-client.jar"; - public static final String S_aspectjrt_jar = LIBDIR + "/aspectjrt.jar"; - public static final File F_testingclient_jar = - new File(S_testingclient_jar); - public static final File F_aspectjrt_jar = new File(S_aspectjrt_jar); - public static final boolean globalsValid; - - static { - J2SE13_RTJAR = - getRtJarFor(J2SE13_RTJAR_NAME, "c:/home/apps/jdk13"); - J2SE14_RTJAR = - getRtJarFor(J2SE14_RTJAR_NAME, "c:/home/apps/jdk14"); - -// String forkSpec = getSystemProperty(FORK_NAME, null); - globalsValid = - (FileUtil.canReadFile(F_testingclient_jar) - && FileUtil.canReadFile(F_aspectjrt_jar) - && FileUtil.canReadFile(J2SE13_RTJAR) - && FileUtil.canReadFile(J2SE14_RTJAR)); - HashMap map = new HashMap(); - map.put("1.2", "java.lang.ref.Reference"); - map.put("1.3", "java.lang.reflect.Proxy"); - map.put("1.4", "java.nio.Buffer"); - map.put("1.5", "java.lang.annotation.Annotation"); - - VM_CLASSES = Collections.unmodifiableMap(map); - } - - private static File getRtJarFor( - String propertyName, - String defaultLocation) { - File j2seJar = null; - try { - String path = getSystemProperty(propertyName, defaultLocation); - File file = new File(path); - if (file.exists()) { - File rtjar = null; - if (path.endsWith("rt.jar")) { - rtjar = file; - } else if (file.isDirectory()) { - path = file.getAbsolutePath() + "/jre/lib/rt.jar"; - rtjar = new File(path); - } - if (rtjar.canRead() && rtjar.isFile()) { - j2seJar = rtjar; - } - } - } catch (Throwable t) { // avoid at all costs during static init - try { - t.printStackTrace(System.err); - } catch (Throwable x) { - // unable to log, better to just fail... - } - } - return j2seJar; - } - - /** - * - * @return null if not found, or - * String with class path for compiler to load J2SE 1.4 classes from. - */ - public static String get14Bootclasspath() { - return null; - } - - /** - * Get System property completely safely. - * @param propertyName the String name of the property to get - * @param defaultValue the String default value to return value is null or empty - * @return String value or defaultValue if not available. - */ - static String getSystemProperty( - String propertyName, - String defaultValue) { - String result = defaultValue; - try { - String value = System.getProperty(propertyName); - if (!LangUtil.isEmpty(value)) { - result = value; - } - } catch (Throwable t) { - } - return result; - } - - - /** - * Detect whether Java version is supported. - * @param version String "1.2" or "1.3" or "1.4" - * @return true if the currently-running VM supports the version - * @throws IllegalArgumentException if version is not known - */ - public static final boolean supportsJava(String version) { - LangUtil.throwIaxIfNull(version, "version"); - String className = (String) VM_CLASSES.get(version); - if (null == className) { - throw new IllegalArgumentException("unknown version: " + version); - } - try { - Class.forName(className); - return true; - } catch (Throwable t) { - return false; - } - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/IAjcRun.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/IAjcRun.java deleted file mode 100644 index e685df5dd..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/IAjcRun.java +++ /dev/null @@ -1,44 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import org.aspectj.testing.run.IRun; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.xml.XMLWriter; - -// XXX candidate to be subsumed in class/constructors, since inner spec does setup -// at the same time it constructs the run. -public interface IAjcRun extends IRun { - boolean setupAjcRun(Sandbox sandbox, Validator validator); - // XXX add for result eval? ArrayList getExpectedMessages(); - - /** this IAjcRun does nothing, returning true always */ - public static final IAjcRun NULLRUN = new IAjcRun() { - public boolean setupAjcRun(Sandbox sandbox, Validator validator) { - return true; - } - public boolean run(IRunStatus status) { - if (!status.started()) { - status.start(); - } - status.finish(IRunStatus.PASS); - return true; - } - - public void writeXml(XMLWriter out) { - throw new UnsupportedOperationException("unimplemented"); - } - public String toString() { return "IAjcRun.NULLRUN"; } - }; - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/IRunSpec.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/IRunSpec.java deleted file mode 100644 index dc35b493d..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/IRunSpec.java +++ /dev/null @@ -1,24 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.xml.IXmlWritable; - -/** - * A run spec can make a run iterator and write itself as XML. - */ -public interface IRunSpec extends IXmlWritable { - IRunIterator makeRunIterator(Sandbox sandbox, Validator validator); -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/IncCompilerRun.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/IncCompilerRun.java deleted file mode 100644 index 7c7f2c54e..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/IncCompilerRun.java +++ /dev/null @@ -1,503 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.ICommand; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.testing.ajde.CompileCommand; -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.run.WrappedRunIterator; -import org.aspectj.testing.util.StructureModelUtil; -import org.aspectj.testing.util.StructureModelUtil.ModelIncorrectException; -import org.aspectj.testing.xml.AjcSpecXmlReader; -import org.aspectj.testing.xml.IXmlWritable; -import org.aspectj.testing.xml.SoftMessage; -import org.aspectj.testing.xml.XMLWriter; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * An incremental compiler run takes an existing compiler commmand - * from the sandbox, updates the staging directory, and recompiles. - * The staging directory is updated by prefix/suffix rules applied - * to files found below Sandbox.testBaseSrcDir. - * Files with suffix .{tag}.java are owned by this run - * and are copied to the staging directory - * unless they are prefixed "delete.", in which case the - * corresponding file is deleted. Any "owned" file is passed to - * the compiler as the list of changed files. - * The files entry contains the expected files recompiled. XXX underinclusive - * XXX prefer messages for expected files? - * XXX later: also support specified paths, etc. - */ -public class IncCompilerRun implements IAjcRun { - - final Spec spec; // nonfinal later to make re-runnable - Sandbox sandbox; - - /** - * @param handler must not be null, but may be reused in the same thread - */ - public IncCompilerRun(Spec spec) { - LangUtil.throwIaxIfNull(spec, "spec"); - this.spec = spec; - } - - /** - * Initialize this from the sandbox, using compiler and changedFiles. - * @param sandbox the Sandbox setup for this test, including copying - * any changed files, etc. - * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File) - * @throws AbortException containing IOException or IllegalArgumentException - * if the staging operations fail - */ - public boolean setupAjcRun(Sandbox sandbox, Validator validator) { - LangUtil.throwIaxIfNull(validator, "validator"); - if (!validator.nullcheck(sandbox, "sandbox") - || !validator.nullcheck(spec, "spec") - || !validator.nullcheck(spec.tag, "fileSuffix")) { - return false; - } - File srcDir = sandbox.getTestBaseSrcDir(this); - File destDir = sandbox.stagingDir; - if (!validator.canReadDir(srcDir, "testBaseSrcDir") - || !validator.canReadDir(destDir, "stagingDir")) { - return false; - } - - this.sandbox = sandbox; - return doStaging(validator); - } - - /** - * Handle copying and deleting of files per tag. - * This returns false unless - * (1) tag is "same", or - * (2) some file was copied or deleted successfully - * and there were no failures copying or deleting files. - * @return true if staging completed successfully - */ - boolean doStaging(final Validator validator) { - if ("same".equals(spec.tag)) { - return true; - } - boolean result = false; - try { - final String toSuffix = ".java"; - final String fromSuffix = "." + spec.tag + toSuffix; - // copy our tagged generation of files to the staging directory, - // deleting any with ChangedFilesCollector.DELETE_SUFFIX - // sigh - delay until after last last-mod-time - intHolder holder = new intHolder(); - List copied = new ArrayList(); - doStaging(validator,".java",holder,copied); - doStaging(validator,".jar",holder,copied); - doStaging(validator,".class",holder,copied); - doStaging(validator,".properties",holder,copied); // arbitrary resource extension - doStaging(validator,".xml",holder,copied); // arbitrary resource extension - if ((0 == holder.numCopies) && (0 == holder.numDeletes)) { - validator.fail("no files changed??"); - } else { - result = (0 == holder.numFails); - } - if (0 < copied.size()) { - File[] files = (File[]) copied.toArray(new File[0]); - FileUtil.sleepPastFinalModifiedTime(files); - } - } catch (NullPointerException npe) { - validator.fail("staging - input", npe); - } catch (IOException e) { - validator.fail("staging - operations", e); - } - return result; - } - - - private void doStaging(final Validator validator, final String toSuffix, - final intHolder holder,final List copied) - throws IOException - { - final String fromSuffix = "." + spec.tag + toSuffix; - final String clip = ".delete" + toSuffix; - FileFilter deleteOrCount = new FileFilter() { - /** do copy unless file should be deleted */ - public boolean accept(File file) { - boolean doCopy = true; - String path = file.getAbsolutePath(); - if (!path.endsWith(clip)) { - holder.numCopies++; - validator.info("copying file: " + path); - copied.add(file); - } else { - doCopy = false; - path = path.substring(0, path.length()-clip.length()) + toSuffix; - File toDelete = new File(path); - if (toDelete.delete()) { - validator.info("deleted file: " + path); - holder.numDeletes++; - } else { - validator.fail("unable to delete file: " + path); - holder.numFails++; - } - } - return doCopy; - } - - }; - File srcDir = sandbox.getTestBaseSrcDir(this); - File destDir = sandbox.stagingDir; - FileUtil.copyDir(srcDir, destDir, fromSuffix, toSuffix, deleteOrCount); - } - - private static class intHolder { - int numCopies; - int numDeletes; - int numFails; - } - - /** - * @see org.aspectj.testing.run.IRun#run(IRunStatus) - */ - public boolean run(IRunStatus status) { - - ICommand compiler = sandbox.getCommand(this); - if (null == compiler) { - MessageUtil.abort(status, "null compiler"); - } - -// // This is a list of expected classes (in File-normal form -// // relative to base class/src dir, without .class suffix -// // -- like "org/aspectj/tools/ajc/Main") -// // A preliminary list is generated in doStaging. -// ArrayList expectedClasses = doStaging(status); -// if (null == expectedClasses) { -// return false; -// } -// -// // now add any (additional) expected-class entries listed in the spec -// // normalize to a similar file path (and do info messages for redundancies). -// -// List alsoChanged = spec.getPathsAsFile(sandbox.stagingDir); -// for (Iterator iter = alsoChanged.iterator(); iter.hasNext();) { -// File f = (File) iter.next(); -// -// if (expectedClasses.contains(f)) { -// // XXX remove old comment changed.contains() works b/c getPathsAsFile producing both File -// // normalizes the paths, and File.equals(..) compares these lexically -// String s = "specification of changed file redundant with tagged file: "; -// MessageUtil.info(status, s + f); -// } else { -// expectedClasses.add(f); -// } -// } -// -// // now can create handler, use it for reporting -// List errors = spec.getMessages(IMessage.ERROR); -// List warnings = spec.getMessages(IMessage.WARNING); -// AjcMessageHandler handler = new AjcMessageHandler(errors, warnings, expectedClasses); - - // same DirChanges handling for JavaRun, CompilerRun, IncCompilerRun - // XXX around advice or template method/class - DirChanges dirChanges = null; - if (!LangUtil.isEmpty(spec.dirChanges)) { - LangUtil.throwIaxIfFalse(1 == spec.dirChanges.size(), "expecting only 1 dirChanges"); - dirChanges = new DirChanges((DirChanges.Spec) spec.dirChanges.get(0)); - if (!dirChanges.start(status, sandbox.classesDir)) { - return false; // setup failed - } - } - AjcMessageHandler handler = new AjcMessageHandler(spec.getMessages()); - boolean handlerResult = false; - boolean commandResult = false; - boolean result = false; - boolean report = false; - try { - handler.init(); - if (spec.fresh) { - if (compiler instanceof CompileCommand) { // urk - ((CompileCommand) compiler).buildNextFresh(); - } else { - MessageUtil.info(handler, "fresh not supported by compiler: " + compiler); - } - } -// final long startTime = System.currentTimeMillis(); - commandResult = compiler.repeatCommand(handler); - if (!spec.checkModel.equals("")) { - StructureModelUtil.checkModel(spec.checkModel); - } - // XXX disabled LangUtil.throwIaxIfNotAllAssignable(actualRecompiled, File.class, "recompiled"); - report = true; - // handler does not verify sandbox... - handlerResult = handler.passed(); - if (!handlerResult) { - result = false; - } else { - result = (commandResult == handler.expectingCommandTrue()); - if (! result) { - String m = commandResult - ? "incremental compile command did not return false as expected" - : "incremental compile command returned false unexpectedly"; - MessageUtil.fail(status, m); - } else if (null != dirChanges) { - result = dirChanges.end(status, sandbox.testBaseDir); - } - } - } catch (ModelIncorrectException e) { - MessageUtil.fail(status,e.getMessage()); - } finally { - if (!result || spec.runtime.isVerbose()) { // more debugging context in case of failure - MessageUtil.info(handler, "spec: " + spec.toLongString()); - MessageUtil.info(handler, "sandbox: " + sandbox); - String[] classes = FileUtil.listFiles(sandbox.classesDir); - MessageUtil.info(handler, "sandbox.classes: " + Arrays.asList(classes)); - } - // XXX weak - actual messages not reported in real-time, no fast-fail - if (report) { - handler.report(status); - } - } - return result; - } - -// private boolean hasFile(ArrayList changed, File f) { -// return changed.contains(f); // d -// } - - - public String toString() { - return "" + spec; - // return "IncCompilerRun(" + spec + ")"; // XXX - } - - /** - * initializer/factory for IncCompilerRun. - */ - public static class Spec extends AbstractRunSpec { - public static final String XMLNAME = "inc-compile"; - - protected boolean fresh; - protected ArrayList classesAdded; - protected ArrayList classesRemoved; - protected ArrayList classesUpdated; - - protected String checkModel; - - /** - * skip description, skip sourceLocation, - * do keywords, skip options, do paths as classes, do comment, - * skip staging (always true), skip badInput (irrelevant) - * do dirChanges, do messages but skip children. - */ -// private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT, -// "", "", null, "", "classes", null, "", "", false, false, true); -// - /** identifies files this run owns, so {name}.{tag}.java maps to {name}.java */ - String tag; - - public Spec() { - super(XMLNAME); - setStaging(true); - classesAdded = new ArrayList(); - classesRemoved = new ArrayList(); - classesUpdated = new ArrayList(); - checkModel=""; - } - - protected void initClone(Spec spec) - throws CloneNotSupportedException { - super.initClone(spec); - spec.fresh = fresh; - spec.tag = tag; - spec.classesAdded.clear(); - spec.classesAdded.addAll(classesAdded); - spec.classesRemoved.clear(); - spec.classesRemoved.addAll(classesRemoved); - spec.classesUpdated.clear(); - spec.classesUpdated.addAll(classesUpdated); - } - - public Object clone() throws CloneNotSupportedException { - Spec result = new Spec(); - initClone(result); - return result; - } - - - public void setFresh(boolean fresh) { - this.fresh = fresh; - } - - public void setTag(String input) { - tag = input; - } - - public void setCheckModel(String thingsToCheck) { - this.checkModel=thingsToCheck; - } - - public String toString() { - return "IncCompile.Spec(" + tag + ", " + super.toString() + ",["+checkModel+"])"; - } - - /** override to set dirToken to Sandbox.CLASSES and default suffix to ".class" */ - public void addDirChanges(DirChanges.Spec spec) { // XXX copy/paste of CompilerRun.Spec... - if (null == spec) { - return; - } - spec.setDirToken(Sandbox.CLASSES_DIR); - spec.setDefaultSuffix(".class"); - super.addDirChanges(spec); - } - - /** @return a IncCompilerRun with this as spec if setup completes successfully. */ - public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator) { - IncCompilerRun run = new IncCompilerRun(this); - if (run.setupAjcRun(sandbox, validator)) { - // XXX need name - return new WrappedRunIterator(this, run); - } - return null; - } - - /** - * Write this out as a compile element as defined in - * AjcSpecXmlReader.DOCTYPE. - * @see AjcSpecXmlReader#DOCTYPE - * @see IXmlWritable#writeXml(XMLWriter) - */ - public void writeXml(XMLWriter out) { - String attr = XMLWriter.makeAttribute("tag", tag); - out.startElement(xmlElementName, attr, false); - if (fresh) { - out.printAttribute("fresh", "true"); - } - super.writeAttributes(out); - out.endAttributes(); - if (!LangUtil.isEmpty(dirChanges)) { - DirChanges.Spec.writeXml(out, dirChanges); - } - SoftMessage.writeXml(out, getMessages()); - out.endElement(xmlElementName); - } - - public void setClassesAdded(String items) { - addItems(classesAdded, items); - } - - public void setClassesUpdated(String items) { - addItems(classesUpdated, items); - } - - public void setClassesRemoved(String items) { - addItems(classesRemoved, items); - } - - private void addItems(ArrayList list, String items) { - if (null != items) { - String[] classes = XMLWriter.unflattenList(items); - if (!LangUtil.isEmpty(classes)) { - for (int i = 0; i < classes.length; i++) { - if (!LangUtil.isEmpty(classes[i])) { - list.add(classes[i]); - } - } - } - } - } - } // class IncCompilerRun.Spec -} -// // XXX replaced with method-local class - revisit if useful -// -// /** -// * This class collects the list of all changed files and -// * deletes the corresponding file for those prefixed "delete." -// */ -// static class ChangedFilesCollector implements FileFilter { -// static final String DELETE_SUFFIX = ".delete.java"; -// static final String REPLACE_SUFFIX = ".java"; -// final ArrayList changed; -// final Validator validator; -// /** need this to generate paths by clipping */ -// final File destDir; -// -// /** @param changed the sink for all files changed (full paths) */ -// public ChangedFilesCollector(ArrayList changed, File destDir, Validator validator) { -// LangUtil.throwIaxIfNull(validator, "ChangedFilesCollector - handler"); -// this.changed = changed; -// this.validator = validator; -// this.destDir = destDir; -// } -// -// /** -// * This converts the input File to normal String path form -// * (without any source suffix) and adds it to the list changed. -// * If the name of the file is suffixed ".delete..", then -// * delete the corresponding file, and return false (no copy). -// * Return true otherwise (copy file). -// * @see java.io.FileFilter#accept(File) -// */ -// public boolean accept(File file) { -// final String aname = file.getAbsolutePath(); -// String name = file.getName(); -// boolean doCopy = true; -// boolean failed = false; -// if (name.endsWith(DELETE_SUFFIX)) { -// name = name.substring(0,name.length()-DELETE_SUFFIX.length()); -// file = file.getParentFile(); -// file = new File(file, name + REPLACE_SUFFIX); -// if (!file.canWrite()) { -// validator.fail("file to delete is not writable: " + file); -// failed = true; -// } else if (!file.delete()) { -// validator.fail("unable to delete file: " + file); -// failed = true; -// } -// doCopy = false; -// } -// if (!failed && doCopy) { -// int clip = FileUtil.sourceSuffixLength(file); -// if (-1 != clip) { -// name.substring(0, name.length()-clip); -// } -// if (null != destDir) { -// String path = destDir.getPath(); -// if (!LangUtil.isEmpty(path)) { -// // XXX incomplete -// if (name.startsWith(path)) { -// } else { -// int loc = name.lastIndexOf(path); -// if (-1 == loc) { // sigh -// -// } else { -// -// } -// } -// } -// } -// name = FileUtil.weakNormalize(name); -// changed.add(file); -// } -// return doCopy; -// } -// }; - diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/JavaRun.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/JavaRun.java deleted file mode 100644 index aade35f48..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/JavaRun.java +++ /dev/null @@ -1,899 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.testing.Tester; -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.run.WrappedRunIterator; -import org.aspectj.testing.util.TestClassLoader; -import org.aspectj.testing.util.TestUtil; -import org.aspectj.testing.xml.SoftMessage; -import org.aspectj.testing.xml.XMLWriter; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; -import org.aspectj.weaver.loadtime.WeavingURLClassLoader; - -import java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.security.Permission; -import java.util.*; - -/** - * Run a class in this VM using reflection. - * Forked mode supported, but through system properties: - * - javarun.fork: anything to enable forking - * - javarun.java: path to java executable (optional) - * - javarun.java.home: JAVA_HOME for java (optional) - * (normally requires javarun.java) - * - javarun.classpath: a prefix to the run classpath (optional) - */ -public class JavaRun implements IAjcRun { - - private static void appendClasspath(StringBuffer cp, Object[] entries) { - if (!LangUtil.isEmpty(entries)) { - for (int i = 0; i < entries.length; i++) { - Object entry = entries[i]; - if (entry instanceof String) { - cp.append((String) entry); - cp.append(File.pathSeparator); - } else if (entry instanceof File) { - String s = FileUtil.getBestPath((File) entry); - if (null != s) { - cp.append(s); - cp.append(File.pathSeparator); - } - } - } - } - } - - Spec spec; - private Sandbox sandbox; - - /** programmatic initialization per spec */ - public JavaRun(Spec spec) { - this.spec = spec; - } - // XXX init(Spec) - - /** - * This checks the spec for a class name - * and checks the sandbox for a readable test source directory, - * a writable run dir, and (non-null, possibly-empty) lists - * of readable classpath dirs and jars, - * and, if fork is enabled, that java can be read. - * @return true if all checks pass - * @see org.aspectj.testing.harness.bridge.AjcTest.IAjcRun#setup(File, File) - */ - public boolean setupAjcRun(Sandbox sandbox, Validator validator) { - this.sandbox = sandbox; - sandbox.javaRunInit(this); - return (validator.nullcheck(spec.className, "class name") - && validator.nullcheck(sandbox, "sandbox") - && validator.canReadDir(sandbox.getTestBaseSrcDir(this), "testBaseSrc dir") - && validator.canWriteDir(sandbox.runDir, "run dir") - && validator.canReadFiles(sandbox.getClasspathJars(true, this), "classpath jars") - && validator.canReadDirs(sandbox.getClasspathDirectories(true, this, true), "classpath dirs") - && (!spec.forkSpec.fork - || validator.canRead(spec.forkSpec.java, "java")) - ); - - } - - /** caller must record any exceptions */ - public boolean run(IRunStatus status) - throws IllegalAccessException, - InvocationTargetException, - ClassNotFoundException, - NoSuchMethodException { - boolean completedNormally = false; - boolean passed = false; - if (!LangUtil.isEmpty(spec.dirChanges)) { - MessageUtil.info(status, "XXX dirChanges not implemented in JavaRun"); - } - try { - final boolean readable = true; - File[] libs = sandbox.getClasspathJars(readable, this); - boolean includeClassesDir = true; - File[] dirs = sandbox.getClasspathDirectories(readable, this, includeClassesDir); - completedNormally = (spec.forkSpec.fork) - ? runInOtherVM(status, libs, dirs) - : runInSameVM(status, libs, dirs); - passed = completedNormally; - } finally { - if (!passed || !status.runResult()) { - MessageUtil.info(status, spec.toLongString()); - MessageUtil.info(status, "sandbox: " + sandbox); - } - } - return passed; - } - protected boolean runInSameVM(IRunStatus status, File[] libs, File[] dirs) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { - ClassLoader loader = null; - boolean completedNormally = false; - boolean passed = false; - ByteArrayOutputStream outSnoop = null; - PrintStream oldOut = null; - ByteArrayOutputStream errSnoop = null; - PrintStream oldErr = null; - if (spec.outStreamIsError) { - outSnoop = new ByteArrayOutputStream(); - oldOut = System.out; - System.setOut(new PrintStream(outSnoop, true)); - } - if (spec.errStreamIsError) { - errSnoop = new ByteArrayOutputStream(); - oldErr = System.err; - System.setErr(new PrintStream(errSnoop, true)); - } - Class targetClass = null; - try { - final URL[] clAndLibs; - { - File[] files = sandbox.findFiles(spec.classpath); - URL[] clURLs = FileUtil.getFileURLs(files); - URL[] libURLs = FileUtil.getFileURLs(libs); - clAndLibs = new URL[clURLs.length + libURLs.length]; - System.arraycopy(clURLs, 0, clAndLibs , 0, clURLs.length); - System.arraycopy(libURLs, 0, clAndLibs, clURLs.length, libURLs.length); - } - if (!spec.isLTW()) { - loader = new TestClassLoader(clAndLibs, dirs); - } else { - final URL[] aspectURLs; - { - File[] files = sandbox.findFiles(spec.aspectpath); - aspectURLs = FileUtil.getFileURLs(files); - } - ArrayList classpath = new ArrayList(); - classpath.addAll(Arrays.asList(aspectURLs)); - final URL[] classURLs; - { - classpath.addAll(Arrays.asList(clAndLibs)); - URL[] urls = FileUtil.getFileURLs(dirs); - classpath.addAll(Arrays.asList(urls)); - classpath.add(FileUtil.getFileURL(Globals.F_aspectjrt_jar)); - classpath.add(FileUtil.getFileURL(Globals.F_testingclient_jar)); - classURLs = (URL[]) classpath.toArray(new URL[0]); - } - - ClassLoader parent = JavaRun.class.getClassLoader(); - loader = new WeavingURLClassLoader(classURLs, aspectURLs, parent); - } - // make the following load test optional - // Class testAspect = loader.loadClass("org.aspectj.lang.JoinPoint"); - targetClass = loader.loadClass(spec.className); - Method main = targetClass.getMethod("main", Globals.MAIN_PARM_TYPES); - setupTester(sandbox.getTestBaseSrcDir(this), loader, status); - RunSecurityManager.ME.setJavaRunThread(this); - main.invoke(null, new Object[] { spec.getOptionsArray() }); - completedNormally = true; - boolean snoopFailure = - ((null != errSnoop) && 0 < errSnoop.size()) - || ((null != outSnoop) && 0 < outSnoop.size()); - passed = !snoopFailure && (null == spec.expectedException); - } catch (AbortException e) { - if (expectedException(e)) { - passed = true; - } else { - throw e; - } - } catch (InvocationTargetException e) { - // this and following clauses catch ExitCalledException - Throwable thrown = LangUtil.unwrapException(e); - if (null == thrown) { - throw e; - } - if (thrown instanceof RunSecurityManager.ExitCalledException) { - int i = ((RunSecurityManager.ExitCalledException) thrown).exitCode; - status.finish(new Integer(i)); - } else if (thrown instanceof RunSecurityManager.AwtUsedException) { - MessageUtil.fail(status, "test code should not use the AWT event queue"); - throw (RunSecurityManager.AwtUsedException) thrown; - // same as: status.thrown(thrown); - } else if (expectedException(thrown)) { - passed = true; - } else if (thrown instanceof RuntimeException) { - throw (RuntimeException) thrown; - } else if (thrown instanceof Error) { - throw (Error) thrown; - } else { - throw e; - } - } catch (RunSecurityManager.ExitCalledException e) { - // XXX need to update run validator (a) to accept null result or (b) to require zero result, and set 0 if completed normally - status.finish(new Integer(e.exitCode)); - } catch (ClassNotFoundException e) { - String[] classes = FileUtil.listFiles(sandbox.classesDir); - MessageUtil.info(status, "sandbox.classes: " + Arrays.asList(classes)); - MessageUtil.fail(status, null, e); - } finally { - if (null != oldOut) { - System.setOut(oldOut); - } - if (null != oldErr) { - System.setErr(oldErr); - } - RunSecurityManager.ME.releaseJavaRunThread(this); - if (!completedNormally) { - MessageUtil.info(status, "targetClass: " + targetClass); - MessageUtil.info(status, "loader: " + loader); - } - } - return passed; - } - - /** - * Run in another VM by grabbing Java, bootclasspath, classpath, etc. - * This assumes any exception or output to System.err is a failure, - * and any normal completion is a pass. - * @param status - * @param libs - * @param dirs - * @return - */ - protected boolean runInOtherVM(IRunStatus status, File[] libs, File[] dirs) { - // assert spec.fork || !LangUtil.isEmpty(spec.aspectpath); - ArrayList cmd = new ArrayList(); - cmd.add(FileUtil.getBestPath(spec.forkSpec.java)); - if (!LangUtil.isEmpty(spec.forkSpec.vmargs)) { - cmd.addAll(Arrays.asList(spec.forkSpec.vmargs)); - } - final String classpath; - { - StringBuffer cp = new StringBuffer(); - appendClasspath(cp, spec.forkSpec.bootclasspath); - appendClasspath(cp, dirs); - appendClasspath(cp, libs); - File[] classpathFiles = sandbox.findFiles(spec.classpath); - int cpLength = (null == classpathFiles ? 0 : classpathFiles.length); - int spLength = (null == spec.classpath ? 0 : spec.classpath.length); - if (cpLength != spLength) { - throw new Error("unable to find " + Arrays.asList(spec.classpath) - + " got " + Arrays.asList(classpathFiles)); - } - appendClasspath(cp, classpathFiles); - File[] stdlibs = {Globals.F_aspectjrt_jar, Globals.F_testingclient_jar}; - appendClasspath(cp, stdlibs); - classpath = cp.toString(); - } - if (!spec.isLTW()) { - cmd.add("-classpath"); - cmd.add(classpath); - } else { - // verify 1.4 or above, assuming same vm as running this - if (!Globals.supportsJava("1.4")) { - throw new Error("load-time weaving test requires Java 1.4+"); - } - cmd.add("-Djava.system.class.loader=org.aspectj.weaver.WeavingURLClassLoader"); - // assume harness VM classpath has WeavingURLClassLoader (but not others) - cmd.add("-classpath"); - cmd.add(System.getProperty("java.class.path")); - - File[] aspectJars = sandbox.findFiles(spec.aspectpath); - if (aspectJars.length != spec.aspectpath.length) { - throw new Error("unable to find " + Arrays.asList(spec.aspectpath)); - } - StringBuffer cp = new StringBuffer(); - appendClasspath(cp, aspectJars); - cmd.add("-Daj.aspect.path=" + cp.toString()); - cp.append(classpath); // appendClasspath writes trailing delimiter - cmd.add("-Daj.class.path=" + cp.toString()); - } - cmd.add(spec.className); - cmd.addAll(spec.options); - String[] command = (String[]) cmd.toArray(new String[0]); - - final IMessageHandler handler = status; - // setup to run asynchronously, pipe streams through, and report errors - class DoneFlag { - boolean done; - boolean failed; - int code; - } - final StringBuffer commandLabel = new StringBuffer(); - final DoneFlag doneFlag = new DoneFlag(); - LangUtil.ProcessController controller - = new LangUtil.ProcessController() { - protected void doCompleting(Thrown ex, int result) { - if (!ex.thrown && (0 == result)) { - doneFlag.done = true; - return; // no errors - } - // handle errors - String context = spec.className - + " command \"" - + commandLabel - + "\""; - if (null != ex.fromProcess) { - if (!expectedException(ex.fromProcess)) { - String m = "Exception running " + context; - MessageUtil.abort(handler, m, ex.fromProcess); - doneFlag.failed = true; - } - } else if (0 != result) { - doneFlag.code = result; - } - if (null != ex.fromInPipe) { - String m = "Error processing input pipe for " + context; - MessageUtil.abort(handler, m, ex.fromInPipe); - doneFlag.failed = true; - } - if (null != ex.fromOutPipe) { - String m = "Error processing output pipe for " + context; - MessageUtil.abort(handler, m, ex.fromOutPipe); - doneFlag.failed = true; - } - if (null != ex.fromErrPipe) { - String m = "Error processing error pipe for " + context; - MessageUtil.abort(handler, m, ex.fromErrPipe); - doneFlag.failed = true; - } - doneFlag.done = true; - } - }; - controller.init(command, spec.className); - if (null != spec.forkSpec.javaHome) { - controller.setEnvp(new String[] {"JAVA_HOME=" + spec.forkSpec.javaHome}); - } - commandLabel.append(Arrays.asList(controller.getCommand()).toString()); - final ByteArrayOutputStream errSnoop - = new ByteArrayOutputStream(); - final ByteArrayOutputStream outSnoop - = new ByteArrayOutputStream(); - controller.setErrSnoop(errSnoop); - controller.setOutSnoop(outSnoop); - controller.start(); - // give it 3 minutes... - long maxTime = System.currentTimeMillis() + 3 * 60 * 1000; - boolean waitingForStop = false; - while (!doneFlag.done) { - if (maxTime < System.currentTimeMillis()) { - if (waitingForStop) { // hit second timeout - bail - break; - } - MessageUtil.fail(status, "timeout waiting for process"); - doneFlag.failed = true; - controller.stop(); - // wait 1 minute to evaluate results of stopping - waitingForStop = true; - maxTime = System.currentTimeMillis() + 1 * 60 * 1000; - } - try { - Thread.sleep(300); - } catch (InterruptedException e) { - // ignore - } - } - - boolean foundException = false; - if (0 < errSnoop.size()) { - if (expectedException(errSnoop)) { - foundException = true; - } else if (spec.errStreamIsError) { - MessageUtil.error(handler, errSnoop.toString()); - if (!doneFlag.failed) { - doneFlag.failed = true; - } - } else { - MessageUtil.info(handler, "Error stream: " + errSnoop.toString()); - } - } - if (0 < outSnoop.size()) { - if (expectedException(outSnoop)) { - foundException = true; - } else if (spec.outStreamIsError) { - MessageUtil.error(handler, outSnoop.toString()); - if (!doneFlag.failed) { - doneFlag.failed = true; - } - } else { - MessageUtil.info(handler, "Output stream: " + outSnoop.toString()); - } - } - if (!foundException) { - if (null != spec.expectedException) { - String m = " expected exception " + spec.expectedException; - MessageUtil.fail(handler, m); - doneFlag.failed = true; - } else if (0 != doneFlag.code) { - String m = doneFlag.code + " result from " + commandLabel; - MessageUtil.fail(handler, m); - doneFlag.failed = true; - } - } - if (doneFlag.failed) { - MessageUtil.info(handler, "other-vm command-line: " + commandLabel); - } - return !doneFlag.failed; - } - - protected boolean expectedException(Throwable thrown) { - if (null != spec.expectedException) { - String cname = thrown.getClass().getName(); - if (-1 != cname.indexOf(spec.expectedException)) { - return true; // caller sets value for returns normally - } - } - return false; - } - - protected boolean expectedException(ByteArrayOutputStream bout) { - return ((null != spec.expectedException) - && (-1 != bout.toString().indexOf(spec.expectedException))); - } - - /** - * Clear (static) testing state and setup base directory, - * unless spec.skipTesting. - * @return null if successful, error message otherwise - */ - protected void setupTester(File baseDir, ClassLoader loader, IMessageHandler handler) { - if (null == loader) { - setupTester(baseDir, handler); - return; - } - File baseDirSet = null; - try { - if (!spec.skipTester) { - Class tc = loader.loadClass("org.aspectj.testing.Tester"); - // Tester.clear(); - Method m = tc.getMethod("clear", new Class[0]); - m.invoke(null, new Object[0]); - // Tester.setMessageHandler(handler); - m = tc.getMethod("setMessageHandler", new Class[] {IMessageHandler.class}); - m.invoke(null, new Object[] { handler}); - - //Tester.setBASEDIR(baseDir); - m = tc.getMethod("setBASEDIR", new Class[] {File.class}); - m.invoke(null, new Object[] { baseDir}); - - //baseDirSet = Tester.getBASEDIR(); - m = tc.getMethod("getBASEDIR", new Class[0]); - baseDirSet = (File) m.invoke(null, new Object[0]); - - if (!baseDirSet.equals(baseDir)) { - String l = "AjcScript.setupTester() setting " - + baseDir + " returned " + baseDirSet; - MessageUtil.debug(handler, l); - } - } - } catch (Throwable t) { - MessageUtil.abort(handler, "baseDir=" + baseDir, t); - } - } - - /** - * Clear (static) testing state and setup base directory, - * unless spec.skipTesting. - * This implementation assumes that Tester is defined for the - * same class loader as this class. - * @return null if successful, error message otherwise - */ - protected void setupTester(File baseDir, IMessageHandler handler) { - File baseDirSet = null; - try { - if (!spec.skipTester) { - Tester.clear(); - Tester.setMessageHandler(handler); - Tester.setBASEDIR(baseDir); - baseDirSet = Tester.getBASEDIR(); - if (!baseDirSet.equals(baseDir)) { - String l = "AjcScript.setupTester() setting " - + baseDir + " returned " + baseDirSet; - MessageUtil.debug(handler, l); - } - } - } catch (Throwable t) { - MessageUtil.abort(handler, "baseDir=" + baseDir, t); - } - } - public String toString() { - return "JavaRun(" + spec + ")"; - } - - /** - * Struct class for fork attributes and initialization. - * This supports defaults for forking using system properties - * which will be overridden by any specification. - * (It differs from CompilerRun, which supports option - * overriding by passing values as harness arguments.) - */ - public static class ForkSpec { - /** - * key for system property for default value for forking - * (true if set to true) - */ - public static String FORK_KEY = "javarun.fork"; - public static String JAVA_KEY = "javarun.java"; - public static String VM_ARGS_KEY = "javarun.vmargs"; - public static String JAVA_HOME_KEY = "javarun.java.home"; - public static String BOOTCLASSPATH_KEY = "javarun.bootclasspath"; - static final ForkSpec FORK; - static { - ForkSpec fork = new ForkSpec(); - fork.fork = Boolean.getBoolean(FORK_KEY); - fork.java = getFile(JAVA_KEY); - if (null == fork.java) { - fork.java = LangUtil.getJavaExecutable(); - } - fork.javaHome = getFile(JAVA_HOME_KEY); - fork.bootclasspath = XMLWriter.unflattenList(getProperty(BOOTCLASSPATH_KEY)); - fork.vmargs = XMLWriter.unflattenList(getProperty(VM_ARGS_KEY)); - FORK = fork; - } - private static File getFile(String key) { - String path = getProperty(key); - if (null != path) { - File result = new File(path); - if (result.exists()) { - return result; - } - } - return null; - } - private static String getProperty(String key) { - try { - return System.getProperty(key); - } catch (Throwable t) { - return null; - } - } - private boolean fork; - private String[] bootclasspath; - private File java; - private File javaHome; - private String[] vmargs; - - private ForkSpec() { - copy(FORK); - } - - private void copy(ForkSpec forkSpec) { - if (null != forkSpec) { - fork = forkSpec.fork; - bootclasspath = forkSpec.bootclasspath; - java = forkSpec.java; - javaHome = forkSpec.javaHome; - vmargs = forkSpec.vmargs; - } - } - - /** - * @return "" or bootclasspath with File.pathSeparator internal delimiters - */ - String getBootclasspath() { - if (LangUtil.isEmpty(bootclasspath)) { - return ""; - } - return FileUtil.flatten(bootclasspath, null); - } - } - - /** - * Initializer/factory for JavaRun. - * The classpath is not here but precalculated in the Sandbox. - */ - public static class Spec extends AbstractRunSpec { - static { - try { - System.setSecurityManager(RunSecurityManager.ME); - } catch (Throwable t) { - System.err.println("JavaRun: Security manager set - no System.exit() protection"); - } - } - public static final String XMLNAME = "run"; - /** - * skip description, skip sourceLocation, - * do keywords, do options, skip paths, do comment, - * skip staging, skip badInput, - * do dirChanges, do messages but skip children. - */ - private static final XMLNames NAMES = new XMLNames(XMLNames.DEFAULT, - "", "", null, null, "", null, "", "", false, false, true); - - /** fully-qualified name of the class to run */ - protected String className; - - /** Alternative to classname for specifying what to run modulename/type */ - protected String module; - - /** minimum required version of Java, if any */ - protected String javaVersion; - - /** if true, skip Tester setup (e.g., if Tester n/a) */ - protected boolean skipTester; - - /** if true, report text to output stream as error */ - protected boolean outStreamIsError; - - /** if true, report text to error stream as error */ - protected boolean errStreamIsError = true; - - protected final ForkSpec forkSpec; - protected String[] aspectpath; - protected boolean useLTW; - protected String[] classpath; - protected String expectedException; - - public Spec() { - super(XMLNAME); - setXMLNames(NAMES); - forkSpec = new ForkSpec(); - } - - protected void initClone(Spec spec) - throws CloneNotSupportedException { - super.initClone(spec); - spec.className = className; - spec.errStreamIsError = errStreamIsError; - spec.javaVersion = javaVersion; - spec.outStreamIsError = outStreamIsError; - spec.skipTester = skipTester; - spec.forkSpec.copy(forkSpec); - } - - public Object clone() throws CloneNotSupportedException { - Spec result = new Spec(); - initClone(result); - return result; - } - - public boolean isLTW() { - return useLTW || (null != aspectpath); - } - - /** - * @param version "1.1", "1.2", "1.3", "1.4" - * @throws IllegalArgumentException if version is not recognized - */ - public void setJavaVersion(String version) { - Globals.supportsJava(version); - this.javaVersion = version; - } - - /** @className fully-qualified name of the class to run */ - public void setClassName(String className) { - this.className = className; - } - - public void setModule(String module) { - this.module = module; - } - - public void setLTW(String ltw) { - useLTW = TestUtil.parseBoolean(ltw); - } - - public void setAspectpath(String path) { - this.aspectpath = XMLWriter.unflattenList(path); - } - public void setException(String exception) { - this.expectedException = exception; - } - - public void setClasspath(String path) { - this.classpath = XMLWriter.unflattenList(path); - } - public void setErrStreamIsError(String errStreamIsError) { - this.errStreamIsError = TestUtil.parseBoolean(errStreamIsError); - } - - public void setOutStreamIsError(String outStreamIsError) { - this.outStreamIsError = TestUtil.parseBoolean(outStreamIsError); - } - - /** @param skip if true, then do not set up Tester */ - public void setSkipTester(boolean skip) { - skipTester = skip; - } - - public void setFork(boolean fork) { - forkSpec.fork = fork; - } - - /** - * @param vmargs comma-delimited list of arguments for java, - * typically -Dname=value,-DanotherName="another value" - */ - public void setVmArgs(String vmargs) { - forkSpec.vmargs = XMLWriter.unflattenList(vmargs); - } - - /** override to set dirToken to Sandbox.RUN_DIR */ - public void addDirChanges(DirChanges.Spec spec) { - if (null == spec) { - return; - } - spec.setDirToken(Sandbox.RUN_DIR); - super.addDirChanges(spec); - } - - /** @return a JavaRun with this as spec if setup completes successfully. */ - public IRunIterator makeRunIterator(Sandbox sandbox, Validator validator) { - JavaRun run = new JavaRun(this); - if (run.setupAjcRun(sandbox, validator)) { - // XXX need name for JavaRun - return new WrappedRunIterator(this, run); - } - return null; - } - - /** - * Write this out as a run element as defined in - * AjcSpecXmlReader.DOCTYPE. - * @see AjcSpecXmlReader#DOCTYPE - * @see IXmlWritable#writeXml(XMLWriter) - */ - public void writeXml(XMLWriter out) { - String attr = XMLWriter.makeAttribute("class", className); - out.startElement(xmlElementName, attr, false); - if (skipTester) { - out.printAttribute("skipTester", "true"); - } - if (null != javaVersion) { - out.printAttribute("vm", javaVersion); - } - if (outStreamIsError) { - out.printAttribute("outStreamIsError", "true"); - } - if (!errStreamIsError) { // defaults to true - out.printAttribute("errStreamIsError", "false"); - } - super.writeAttributes(out); - out.endAttributes(); - if (!LangUtil.isEmpty(dirChanges)) { - DirChanges.Spec.writeXml(out, dirChanges); - } - SoftMessage.writeXml(out, getMessages()); - out.endElement(xmlElementName); - } - public String toLongString() { - return toString() + "[" + super.toLongString() + "]"; - } - - public String toString() { - if (skipTester) { - return "JavaRun(" + className + ", skipTester)"; - } else { - return "JavaRun(" + className + ")"; - } - } - - /** - * This implementation skips if: - * <ul> - * <li>current VM is not at least any specified javaVersion </li> - * </ul> - * @return false if this wants to be skipped, true otherwise - */ - protected boolean doAdoptParentValues(RT parentRuntime, IMessageHandler handler) { - if (!super.doAdoptParentValues(parentRuntime, handler)) { - return false; - } - if ((null != javaVersion) && (!Globals.supportsJava(javaVersion))) { - skipMessage(handler, "requires Java version " + javaVersion); - return false; - } - return true; - } - } - /** - * This permits everything but System.exit() in the context of a - * thread set by JavaRun. - * XXX need to update for thread spawned by that thread - * XXX need to update for awt thread use after AJDE wrapper doesn't - */ - public static class RunSecurityManager extends SecurityManager { - public static RunSecurityManager ME = new RunSecurityManager(); - private Thread runThread; - private RunSecurityManager(){} - private synchronized void setJavaRunThread(JavaRun run) { - LangUtil.throwIaxIfNull(run, "run"); - runThread = Thread.currentThread(); - } - private synchronized void releaseJavaRunThread(JavaRun run) { - LangUtil.throwIaxIfNull(run, "run"); - runThread = null; - } - /** @throws ExitCalledException if called from the JavaRun-set thread */ - public void checkExit(int exitCode) throws ExitCalledException { - if ((null != runThread) && runThread.equals(Thread.currentThread())) { - throw new ExitCalledException(exitCode); - } - } - public void checkAwtEventQueueAccess() { - if ((null != runThread) && runThread.equals(Thread.currentThread())) { - throw new AwtUsedException(); - } - } - public void checkSystemClipboardAccess() { - // permit - } - // used by constrained calls - public static class ExitCalledException extends SecurityException { - public final int exitCode; - public ExitCalledException(int exitCode) { - this.exitCode = exitCode; - } - } - public static class AwtUsedException extends SecurityException { - public AwtUsedException() { } - } - // permit everything else - public void checkAccept(String arg0, int arg1) { - } - public void checkAccess(Thread arg0) { - } - public void checkAccess(ThreadGroup arg0) { - } - public void checkConnect(String arg0, int arg1) { - } - public void checkConnect(String arg0, int arg1, Object arg2) { - } - public void checkCreateClassLoader() { - } - public void checkDelete(String arg0) { - } - public void checkExec(String arg0) { - } - public void checkLink(String arg0) { - } - public void checkListen(int arg0) { - } - public void checkMemberAccess(Class arg0, int arg1) { - } - public void checkMulticast(InetAddress arg0) { - } - public void checkMulticast(InetAddress arg0, byte arg1) { - } - public void checkPackageAccess(String arg0) { - } - public void checkPackageDefinition(String arg0) { - } - public void checkPermission(Permission arg0) { - } - public void checkPermission(Permission arg0, Object arg1) { - } - public void checkPrintJobAccess() { - } - public void checkPropertiesAccess() { - } - public void checkPropertyAccess(String arg0) { - } - public void checkRead(FileDescriptor arg0) { - } - public void checkRead(String arg0) { - } - public void checkRead(String arg0, Object arg1) { - } - public void checkSecurityAccess(String arg0) { - } - public void checkSetFactory() { - } - public boolean checkTopLevelWindow(Object arg0) { - return true; - } - public void checkWrite(FileDescriptor arg0) { - } - public void checkWrite(String arg0) { - } - - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/RunSpecIterator.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/RunSpecIterator.java deleted file mode 100644 index e5792236b..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/RunSpecIterator.java +++ /dev/null @@ -1,256 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.util.ArrayList; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.Message; -import org.aspectj.testing.run.IRun; -import org.aspectj.testing.run.IRunIterator; -import org.aspectj.testing.run.Runner; -import org.aspectj.testing.run.WrappedRunIterator; -import org.aspectj.util.LangUtil; - - -/** - * This wraps an AbstractRunSpec, which has children that - * return IRunIterator, the results of which we return - * from nextRun(..) - * We extract global options from the AbstractRunSpec options - * and set the global options in the AbstractRunSpec, - * which is responsible for setting them in any children - * during makeRun(..). - */ -public class RunSpecIterator implements IRunIterator { - /* - * When constructed, this gets its own spec - * and a sandbox to be used for making all children. - * In nextRun() this uses the spec's child specs - * and the sandbox to create the next child run iterator. - * This returns all the run provided by that child iterator - * before going to the next child. - */ - - /** spec for this test */ - public final AbstractRunSpec spec; // XXX reconsider public after debugging - - /** current sandbox by default shared by all children */ - Sandbox sandbox; - - /** keep our copy to avoid recopying */ - ArrayList childSpecs; - - /** index into child specs of next run */ - int specIndex; - - /** child creation until the start of each run */ - final Validator validator; - - /** current child iterator */ - IRunIterator childIterator; - - final boolean haltOnFailure; - - private int numIncomplete; - - private final IMessage.Kind failureKind; - -// private boolean didCleanup; - - /** - * Create a RunSpecIterator. - * Failure messages are of type IMessage.ABORT if abortOnFailure is true, - * or IMessage.ERROR otherwise. - * @param spec the AbstractRunSpec whose children we iterate - not null - * @param sandbox the default Sandbox to use for children to make runs - may be null - * @param haltOnFailure if true, stop after any failure in providing runs - */ - public RunSpecIterator( - AbstractRunSpec spec, - Sandbox sandbox, - Validator validator, - boolean haltOnFailure) { - this(spec, sandbox, validator, haltOnFailure, - (haltOnFailure ? IMessage.ABORT : IMessage.ERROR)); - } - - /** - * Create a RunSpecIterator, specifying any failure message kind. - * @param spec the AbstractRunSpec whose children we iterate - not null - * @param sandbox the default Sandbox to use for children to make runs - may be null - * @param haltOnFailure if true, stop after any failure in providing runs - * @param failureKind the IMessage.Kind for any failure messages - if null, no messages sent - */ - public RunSpecIterator( - AbstractRunSpec spec, - Sandbox sandbox, - Validator validator, - boolean haltOnFailure, - IMessage.Kind failureKind) { - LangUtil.throwIaxIfNull(spec, "spec"); - LangUtil.throwIaxIfNull(sandbox, "sandbox"); - LangUtil.throwIaxIfNull(validator, "validator"); - this.sandbox = sandbox; - this.spec = spec; - this.validator = validator; - this.haltOnFailure = haltOnFailure; - this.failureKind = failureKind; - reset(); - } - - /** - * @return value set on construction for abortOnError - * @see org.aspectj.testing.run.IRunIterator#abortOnFailure() - */ - public boolean abortOnFailure() { - return haltOnFailure; - } - - /** reset to start at the beginning of the child specs. */ - public void reset() { - specIndex = 0; - childSpecs = spec.getWorkingChildren(); - childIterator = null; - numIncomplete = 0; - } - - /** @return int number of child run attempts that did not produce IRun */ - public int getNumIncomplete() { - return numIncomplete; - } - - /** - * @see org.aspectj.testing.run.IRunIterator#hasNextRun() - */ - public boolean hasNextRun() { - return ((specIndex < childSpecs.size()) - || ((null != childIterator) - && childIterator.hasNextRun())); - } - - /** - * Get the next child IRunIterator as an IRun. - * In case of failure to get the next child, - * numIncomplete is incremented, and - * a message of type failureKind is passed to the handler - * (if failureKind was defined in the contructor). - * @return next child IRunIterator wrapped as an IRun - */ - public IRun nextRun(final IMessageHandler handler, Runner runner) { - validator.pushHandler(handler); - try { - IRun result = null; - IRunSpec childSpec = null; - String error = null; - String specLabel = "getting run for child of \"" + spec + "\" "; - while ((null == result) && hasNextRun() && (null == error)) { - if (null == childIterator) { - childSpec = (IRunSpec) childSpecs.get(specIndex++); - if (null == childSpec) { - error = "unexpected - no more child specs at " + --specIndex; - } else { - Sandbox sandbox = makeSandbox(childSpec, validator); - if (null == sandbox) { - error = "unable to make sandbox for \"" + childSpec + "\""; - childIterator = null; - } else { - IRunIterator iter = childSpec.makeRunIterator(sandbox, validator); - if (null == iter) { - // client should read reason why from validator - error = "child \"" + childSpec + "\".makeRunIterator(..) returned null"; - } else { - // hoist: result not wrapped but single IRun - if ((iter instanceof WrappedRunIterator)) { - if (!iter.hasNextRun()) { - error = "child \"" + childSpec + "\".hasNextRun()" - + " is not true - should be exactly one run"; - } else { - result = iter.nextRun(handler, runner); - if (null == result) { - error = "child \"" + childSpec + "\".nextRun()" - + " returned null - should be exactly one run"; - } else { - childIterator = null; - return result; - } - } - } else { - childIterator = iter; - } - } - } - } - } - if (null != childIterator) { - result = runner.wrap(childIterator, null); - childIterator = null; - } else if (null != error) { - numIncomplete++; - if (null != failureKind) { - handler.handleMessage(new Message(specLabel + error, failureKind, null, null)); - } - if (!haltOnFailure) { - error = null; - } else if (result != null) { - result = null; // do not return result if halting due to failure - } - } - } - return result; - } finally { - validator.popHandler(handler); - } - } - - /** - * @see org.aspectj.testing.run.IRunIterator#iterationCompleted() - */ - public void iterationCompleted() { - } - - public String toString() { - return "" + spec; - //return "RunSpecIterator(" + specIndex + ", " + spec + ")" ; - } - - /* - * Subclasses may: - * - set the sandbox on construction - * - lazily set it on first use - * - set it for each child - */ - - /** - * Create the sandbox used for each child. - * This implementation always uses the sandbox set on construction. - * Subclasses may decide to create one sandbox per child iterator. - */ - protected Sandbox makeSandbox(IRunSpec child, Validator validator) { - return getSandbox(); - } - - /** Get the sandbox currently in use */ - protected Sandbox getSandbox() { - return sandbox; - } - - /** Set the sandbox currently in use */ - protected void setSandbox(Sandbox sandbox) { - LangUtil.throwIaxIfNull(sandbox, "sandbox"); - this.sandbox = sandbox; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/Sandbox.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/Sandbox.java deleted file mode 100644 index f7f4df31e..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/Sandbox.java +++ /dev/null @@ -1,575 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.Arrays; - -import org.aspectj.bridge.ICommand; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.testing.taskdefs.AjcTaskCompileCommand; -import org.aspectj.testing.util.Diffs; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * A sandbox holds state shared by AjcTest sub-runs, - * mostly directories relevant to testing. - * It permits a limited amount of coordination and - * setup/cleanup operations (todo XXX). - * <p> - * AjcTest creates the Sandbox and initializes the final fields. - * To coordinate with each other, run components may set and get values, - * with the sources running first and the sinks second. - * To make the interactions clear - * (and to avoid accidentally violating these semantics), - * setters/getters for a coordinated property are constrained two ways: - * <li>Both have an extra (typed) "caller" parameter which must not - * be null, authenticating that the caller is known & valid.</li> - * <li>A getter throws IllegalStateException if called before the setter</li> - * <li>A setter throws IllegalStateException if called after the getter<li> - * XXX subclass more general sandbox? - */ -public class Sandbox { - /** classes directory token for DirChanges.Spec */ - public static final String RUN_DIR = "run"; - - /** run directory token for DirChanges.Spec */ - public static final String CLASSES_DIR = "classes"; - - private static boolean canRead(File dir) { - return ((null != dir) && dir.isDirectory() && dir.canRead()); - } - - private static boolean canWrite(File dir) { - return ((null != dir) && dir.isDirectory() && dir.canWrite()); - } - - private static void iaxWrite(File dir, String label) { - if (!canWrite(dir)) { - throw new IllegalArgumentException(label + " - " + dir); - } - } - - private static void iaxRead(File dir, String label) { - if (!canRead(dir)) { - throw new IllegalArgumentException(label + " - " + dir); - } - } - - /** @throws IllegalStateException(message) if test */ - private static void assertState(boolean test, String message) { - if (!test) { - throw new IllegalStateException(message); - } - } - - /** - * The (read-only) base of the test sources (which may or may not - * be the base of the java sources) - */ - public final File testBaseDir; - - /** the parent of a temporary workspace, probably includes some others */ - public final File sandboxDir; - - /** a shared working dir */ - public final File workingDir; - - /** a shared classes dir */ - public final File classesDir; - - /** a run dir (which will be ignored in non-forking runs) */ - public final File runDir; - - /** staging directory for IAjcRun requiring files be copied, deleted, etc. */ - public final File stagingDir; - - /** - * This manages creation and deletion of temporary directories. - * We hold a reference so that our clients can signal whether - * this should be deleted. - */ - private final Validator validator; // XXX required after completing tests? - - /** original base of the original java sources, set by CompileRun.setup(..) */ - private File testBaseSrcDir; - - /** directories and libraries on the classpath, set by CompileRun.setup(..) */ - private File[] compileClasspath; - - private String bootClasspath; - - /** aspectpath entries, set by CompileRun.setup(..) */ - private File[] aspectpath; - - /** track whether classpath getter ran */ - private boolean gotClasspath; - - /** command shared between runs using sandbox - i.e., compiler */ - private ICommand command; - - /** track whether command getter ran */ - private boolean gotCommand; - - /** cache results of rendering final fields */ - private transient String toStringLeader; - - private transient boolean compilerRunInit; - - /** @throws IllegalArgumentException unless validator validates - * testBaseDir as readable - */ - public Sandbox(File testBaseDir, Validator validator) { - LangUtil.throwIaxIfNull(validator, "validator"); - this.validator = validator; - Sandbox.iaxRead(testBaseDir, "testBaseDir"); - this.testBaseDir = testBaseDir; - { - File baseDir = FileUtil.getTempDir("Sandbox"); - if (!baseDir.isAbsolute()) { - baseDir = baseDir.getAbsoluteFile(); - } - sandboxDir = baseDir; - } - Sandbox.iaxWrite(sandboxDir, "sandboxDir"); // XXX not really iax - - workingDir = FileUtil.makeNewChildDir(sandboxDir, "workingDir"); - Sandbox.iaxWrite(workingDir, "workingDir"); - - classesDir = FileUtil.makeNewChildDir(sandboxDir, "classes"); - Sandbox.iaxWrite(classesDir, "classesDir"); - - runDir = FileUtil.makeNewChildDir(sandboxDir, "run"); - Sandbox.iaxWrite(runDir, "runDir"); - - stagingDir = FileUtil.makeNewChildDir(sandboxDir, "staging"); - Sandbox.iaxWrite(stagingDir, "stagingDir"); - - validator.registerSandbox(this); - } - - private String getToStringLeader() { - if (null == toStringLeader) { - toStringLeader = "Sandbox(" + sandboxDir.getName() - + ", " + testBaseSrcDir.getName(); - } - return toStringLeader; - } - - /** @return "Sandbox(sandbox, src, classes)" with names only */ - public String toString() { - return getToStringLeader() + ", " + classesDir.getName() + ")"; - } - - /** @return "Sandbox(sandbox, src, classes)" with paths */ - public String toLongString() { - return getToStringLeader() + ", " + classesDir.getPath() - + (null == command ? ", (null command)" : ", " + command) + ")"; - } - - void setCommand(ICommand command, CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - LangUtil.throwIaxIfNull(command, "command"); - LangUtil.throwIaxIfFalse(!gotCommand, "no command"); - this.command = command; - } - - /** When test is completed, clear the compiler to avoid memory leaks */ - void clearCommand(AjcTest caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - if (null != command) { // need to add ICommand.quit() - if (command instanceof AjcTaskCompileCommand) { // XXX urk! - ((AjcTaskCompileCommand) command).quit(); - } - command = null; - } - // also try to clear sandbox/filesystem. - // If locked by suite, we can't. - if (null != validator) { - validator.deleteTempFiles(true); - } - } - -// /** -// * Populate the staging directory by copying any files in the -// * source directory ending with fromSuffix -// * to the staging directory, after renaming them with toSuffix. -// * If the source file name starts with "delete", then the -// * corresponding file in the staging directory is deleting. -// * @return a String[] of the files copied or deleted -// * (path after suffix changes and relative to staging dir) -// * @throws Error if no File using fromSuffix are found -// */ -// String[] populateStagingDir(String fromSuffix, String toSuffix, IAjcRun caller) { -// LangUtil.throwIaxIfNull(fromSuffix, "fromSuffix"); -// LangUtil.throwIaxIfNull(toSuffix, "toSuffix"); -// LangUtil.throwIaxIfNull(caller, "caller"); -// -// ArrayList result = new ArrayList(); -// FileUtil.copyDir( -// srcBase, -// targetSrc, -// fromSuffix, -// toSuffix, -// collector); -// -// final String canonicalFrom = srcBase.getCanonicalPath(); -// final Definition[] defs = getDefinitions(srcBase); -// if ((null == defs) || (defs.length < 9)) { -// throw new Error("did not get definitions"); -// } -// MessageHandler compilerMessages = new MessageHandler(); -// StringBuffer commandLine = new StringBuffer(); -// for (int i = 1; result && (i < 10); i++) { -// String fromSuffix = "." + i + "0.java"; -// // copy files, collecting as we go... -// files.clear(); -// if (0 == files.size()) { // XXX detect incomplete? -// break; -// } -// -// -// return (String[]) result.toArray(new String[0]); -// } - - // XXX move to more general in FileUtil - void reportClassDiffs( - final IMessageHandler handler, - IncCompilerRun caller, - long classesDirStartTime, - String[] expectedSources) { - LangUtil.throwIaxIfFalse(0 < classesDirStartTime, "0 >= " + classesDirStartTime); - boolean acceptPrefixes = true; - Diffs diffs = org.aspectj.testing.util.FileUtil.dirDiffs( - "classes", - classesDir, - classesDirStartTime, - ".class", - expectedSources, - acceptPrefixes); - diffs.report(handler, IMessage.ERROR); - } - -// // XXX replace with IMessage-based implementation -// // XXX move to more general in FileUtil -// void reportClassesDirDiffs(final IMessageHandler handler, IncCompilerRun caller, -// String[] expectedSources) { -// // normalize sources to ignore -// final ArrayList sources = new ArrayList(); -// if (!LangUtil.isEmpty(expectedSources)) { -// for (int i = 0; i < expectedSources.length; i++) { -// String srcPath = expectedSources[i]; -// int clip = FileUtil.sourceSuffixLength(srcPath); -// if (0 != clip) { -// srcPath = srcPath.substring(0, srcPath.length() - clip); -// sources.add(FileUtil.weakNormalize(srcPath)); -// } else if (srcPath.endsWith(".class")) { -// srcPath = srcPath.substring(0, srcPath.length() - 6); -// sources.add(FileUtil.weakNormalize(srcPath)); -// } else { -// MessageUtil.info(handler, "not source file: " + srcPath); -// } -// } -// } -// -// // gather, normalize paths changed -// final ArrayList changed = new ArrayList(); -// FileFilter touchedCollector = new FileFilter() { -// public boolean accept(File file) { -// if (file.lastModified() > classesDirTime) { -// String path = file.getPath(); -// if (!path.endsWith(".class")) { -// MessageUtil.info(handler, "changed file not a class: " + file); -// } else { -// String classPath = path.substring(0, path.length() - 6); -// classPath = FileUtil.weakNormalize(classPath); -// if (sources.contains(classPath)) { -// sources.remove(classPath); -// } else { -// changed.add(classPath); -// } -// } -// } -// return false; -// } -// }; -// classesDir.listFiles(touchedCollector); -// -// // report any unexpected changes -// Diffs diffs = new Diffs("classes", sources, changed, String.CASE_INSENSITIVE_ORDER); -// diffs.report(handler, IMessage.ERROR); -// } - - ICommand getCommand(CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(null != command, "command never set"); - return command; - } - - ICommand getCommand(IncCompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(null != command, "command never set"); - return command; - } - - File getTestBaseSrcDir(IncCompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return testBaseSrcDir; - } - - /** - * Get the files with names (case-sensitive) - * under the staging or test base directories. - * @param names - * @return - */ - File[] findFiles(final String[] names) { - ArrayList result = new ArrayList(); - NamesFilter filter = new NamesFilter(names); - File[] bases = { testBaseDir, sandboxDir }; - for (int i = 0; i < bases.length; i++) { - File base = bases[i]; - if ((null == base) || !base.canRead()) { - continue; - } - result.addAll(Arrays.asList(FileUtil.listFiles(base, filter))); - } - return (File[]) result.toArray(new File[0]); - } - File getTestBaseSrcDir(JavaRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return testBaseSrcDir; - } - - void defaultTestBaseSrcDir(JavaRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - if (null != testBaseSrcDir) { - throw new IllegalStateException("testBaseSrcDir not null"); - } - testBaseSrcDir = testBaseDir; - } - - static boolean readableDir(File dir) { - return ((null != dir) && dir.isDirectory() && dir.canRead()); - } - - void compilerRunInit(CompilerRun caller, File testBaseSrcDir, - File[] aspectPath, boolean aspectpathReadable, - File[] classPath, boolean classpathReadable, - String bootclassPath - ) { - if (null != testBaseSrcDir) { - setTestBaseSrcDir(testBaseSrcDir, caller); - } - if ((null != aspectPath) && (0 < aspectPath.length)) { - setAspectpath(aspectPath, aspectpathReadable, caller); - } - if ((null != classPath) && (0 < classPath.length)) { - setClasspath(classPath, classpathReadable, caller); - } - - setBootclasspath(bootclassPath, caller); - compilerRunInit = true; - } - void javaRunInit(JavaRun caller) { - if (!compilerRunInit) { - testBaseSrcDir = testBaseDir; - // default to aspectjrt.jar? - compileClasspath = new File[0]; - - } - } - - /** @throws IllegalArgumentException unless a readable directory */ - private void setTestBaseSrcDir(File dir, CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - if ((null == dir) || !dir.isDirectory() || !dir.canRead()) { - throw new IllegalArgumentException("bad test base src dir: " + dir); - } - testBaseSrcDir = dir; - } - - /** - * Set aspectpath. - * @param readable if true, then throw IllegalArgumentException if not readable - */ - private void setAspectpath(File[] files, boolean readable, CompilerRun caller) { - LangUtil.throwIaxIfNull(files, "files"); - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(null == aspectpath, "aspectpath already written"); - aspectpath = new File[files.length]; - for (int i = 0; i < files.length; i++) { - LangUtil.throwIaxIfNull(files[i], "files[i]"); - if (readable && !files[i].canRead()) { - throw new IllegalArgumentException("bad aspectpath entry: " + files[i]); - } - aspectpath[i] = files[i]; - } - } - - /** - * Set bootclasspath, presumed to be delimited by - * File.pathSeparator and have valid entries. - * @param bootClasspath - * @param caller - */ - private void setBootclasspath(String bootClasspath, CompilerRun caller) { - this.bootClasspath = bootClasspath; - } - - /** - * Set compile classpath. - * @param readable if true, then throw IllegalArgumentException if not readable - */ - private void setClasspath(File[] files, boolean readable, CompilerRun caller) { - LangUtil.throwIaxIfNull(files, "files"); - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(!gotClasspath, "classpath already read"); - compileClasspath = new File[files.length]; - for (int i = 0; i < files.length; i++) { - LangUtil.throwIaxIfNull(files[i], "files[i]"); - if (readable && !files[i].canRead()) { - throw new IllegalArgumentException("bad classpath entry: " + files[i]); - } - compileClasspath[i] = files[i]; - } - } - -// /** -// * Get run classpath -// * @param caller unused except to restrict usage to non-null JavaRun. -// * @throws IllegalStateException if compileClasspath was not set. -// * @throws IllegalArgumentException if caller is null -// */ -// File[] getRunClasspath(JavaRun caller) { -// LangUtil.throwIaxIfNull(caller, "caller"); -// assertState(null != compileClasspath, "classpath not set"); -// int compilePathLength = compileClasspath.length; -// int aspectPathLength = (null == aspectpath ? 0 : aspectpath.length); -// File[] result = new File[aspectPathLength + compilePathLength]; -// System.arraycopy(compileClasspath, 0, result, 0, compilePathLength); -// if (0 < aspectPathLength) { -// System.arraycopy(aspectpath, 0, result, compilePathLength, aspectPathLength); -// } -// return result; -// } - - /** - * Get directories for the run classpath by selecting them - * from the compile classpath. - * This ignores aspectpath since it may contain only jar files. - * @param readable if true, omit non-readable directories - */ - File[] getClasspathDirectories( - boolean readable, - JavaRun caller, - boolean includeOutput) { - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(null != compileClasspath, "classpath not set"); - ArrayList result = new ArrayList(); - File[] src = compileClasspath; - for (int i = 0; i < src.length; i++) { - File f = src[i]; - if ((null != f) && (f.isDirectory()) && (!readable || f.canRead())) { - result.add(f); - } - } - if (includeOutput && (null != classesDir) - && (!readable || classesDir.canRead())) { - result.add(classesDir); - } - return (File[]) result.toArray(new File[0]); - } - - /** - * Get the jars belonging on the run classpath, including classpath - * and aspectpath entries. - * @param readable if true, omit non-readable directories - */ - File[] getClasspathJars(boolean readable, JavaRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - assertState(null != compileClasspath, "classpath not set"); - ArrayList result = new ArrayList(); - File[][] src = new File[][] { compileClasspath, aspectpath }; - for (int i = 0; i < src.length; i++) { - File[] paths = src[i]; - int len = (null == paths ? 0 : paths.length); - for (int j = 0; j < len; j++) { - File f = paths[j]; - if (FileUtil.isZipFile(f) && (!readable || f.canRead())) { - result.add(f); - } - } - } - return (File[]) result.toArray(new File[0]); - } - - /** - * Get the list of aspect jars as a String. - * @return String of classpath entries delimited internally by File.pathSeparator - */ - String aspectpathToString(CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return FileUtil.flatten(aspectpath, File.pathSeparator); - } - - /** - * Get the compile classpath as a String. - * @return String of classpath entries delimited internally by File.pathSeparator - */ - String classpathToString(CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return FileUtil.flatten(compileClasspath, File.pathSeparator); - } - - /** - * Get the bootClasspath as a String. - * @return String of bootclasspath entries delimited internally by File.pathSeparator - */ - String getBootclasspath(CompilerRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return bootClasspath; - } - - /** - * Get the bootClasspath as a String. - * @return String of bootclasspath entries delimited internally by File.pathSeparator - */ - String getBootclasspath(JavaRun caller) { - LangUtil.throwIaxIfNull(caller, "caller"); - return bootClasspath; - } - private static class NamesFilter implements FileFilter { - private final String[] names; - private NamesFilter(String[] names) { - this.names = names; - } - public boolean accept(File file) { - if (null != file) { - String name = file.getName(); - if ((null != name) && (null != names)) { - for (int i = 0; i < names.length; i++) { - if (name.equals(names[i])) { - return true; - } - } - } - } - return false; - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/harness/bridge/Validator.java b/testing/src/main/java/org/aspectj/testing/harness/bridge/Validator.java deleted file mode 100644 index 37ddd005e..000000000 --- a/testing/src/main/java/org/aspectj/testing/harness/bridge/Validator.java +++ /dev/null @@ -1,564 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.harness.bridge; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.ListIterator; -import java.util.Stack; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * Check input and implement defaults. - * This handles failure messaging and collecting temp directories - * for later cleanup. - * The default behavior is to send a fail message to the message - * handler. Clients may instead: - * <li>Toggle abortOnException to throw AbortException on failure</li> - * <li>push their own message handler to redirect messages - * (pop to remove if any pushed)</li> - * <li>subclass this to reimplement <code>fail(String)</code> - * <p> - * A component given this to do validation should - * not change the reporting scheme established by the caller, - * so the caller may lock and unlock the error handling policy. - * When the policy is locked, this silently ignores attempts - * to toggle exceptions, or delete temporary files. - * XXX callers cannot prevent others from pushing other error handlers. - */ -public class Validator { - - /** stack of handlers */ - private final Stack handlers; - - /** list of File registered for deletion on demand */ - private final ArrayList tempFiles; // deleteTempFiles requires ListIterator.remove() - - /** list of Sandboxes registered for cleanup on demand */ - private final ArrayList sandboxes; - - /** if true, throw AbortException on failure */ - boolean abortOnFailure; - - /** this object prevents any changes to error-handling policy */ - private Object locker; - - public Validator(IMessageHandler handler) { - tempFiles = new ArrayList(); - sandboxes = new ArrayList(); - handlers = new Stack(); - pushHandler(handler); - } - - /** - * Push IMessageHandler onto stack, - * so it will be used until the next push or pop - * @param handler not null - * - */ - public void pushHandler(IMessageHandler handler) { - LangUtil.throwIaxIfNull(handler, "handler"); - handlers.push(handler); - } - - /** @throws IllegalStateException if handler is not on top */ - public void popHandler(IMessageHandler handler) { - LangUtil.throwIaxIfNull(handler, "handler"); - if (handler != handlers.peek()) { - throw new IllegalStateException("not current handler"); - } - handlers.pop(); - } - - /** @return true if this requestor now has locked the error handling policy */ - public boolean lock(Object requestor) { - if (null == locker) { - locker = requestor; - } - return (locker == requestor); - } - - /** @return true if the error handling policy is now unlocked */ - public boolean unlock(Object requestor) { - if (requestor == locker) { - locker = null; - } - return (locker == null); - } - - public void setAbortOnFailure(boolean abortOnFailure) { - if (null == locker) { - if (this.abortOnFailure != abortOnFailure) { - this.abortOnFailure = abortOnFailure; - } - } - } - - /** - * May fail with any of the messages - * <li>{null check} array<li> - * <li>{null check} {message}[#}<li> - */ - public boolean nullcheck(Object[] ra, String message) { - return ((nullcheck((Object) ra, message + " array")) - && nullcheck(Arrays.asList(ra), message)); - } - - /** - * Like nullcheck(Collection, message), except adding lower and upper bound - * @param atLeast fail if list size is smaller than this - * @param atMost fail if list size is greater than this - */ - public boolean nullcheck(Collection list, int atLeast, int atMost, String message) { - if (nullcheck(list, message)) { - int size = list.size(); - if (size < atLeast) { - fail(message + ": " + size + "<" + atLeast); - } else if (size > atMost) { - fail(message + ": " + size + ">" + atMost); - } else { - return true; - } - } - return false; - } - - /** - * May fail with any of the messages - * <li>{null check} list<li> - * <li>{null check} {message}[#}<li> - */ - public boolean nullcheck(Collection list, String message) { - if (nullcheck((Object) list, message + " list")) { - int i = 0; - for (Iterator iter = list.iterator(); iter.hasNext();) { - if (!nullcheck(iter.next(), message + "[" + i++ + "]")) { - return false; - } - } - return true; - } - return false; - } - - /** - * May fail with the message "null {message}" - * if o and the def{ault} are null - * @return o if not null or default otherwise - */ - public Object nulldefault(Object o, String message, Object def) { - if (null == o) { - o = def; - } - nullcheck(o, message); - return o; - } - - /** may fail with the message "null {message}" */ - public boolean nullcheck(Object o, String message) { - if (null == o) { - if (null == message) message = "object"; - fail("null " + message); - return false; - } - return true; - } - - /** - * Verify that all paths are readable relative to baseDir. - * may fail with the message "cannot read {file}" - */ - public boolean canRead(File baseDir, String[] paths, String message) { - if (!canRead(baseDir, "baseDir - " + message) - || !nullcheck(paths, "paths - " + message)) { - return false; - } - final String dirPath = baseDir.getPath(); - File[] files = FileUtil.getBaseDirFiles(baseDir, paths); - for (int j = 0; j < files.length; j++) { - if (!canRead(files[j], "{" + dirPath + "} " + files[j])) { - return false; - } - } - return true; - } - - /** - * Verify that all paths are readable relative to baseDir. - * may fail with the message "cannot read {file}" - */ - public boolean canRead(File[] files, String message) { - if (!nullcheck(files, message)) { - return false; - } - for (int j = 0; j < files.length; j++) { - if (!canRead(files[j], files[j].getPath())) { - return false; - } - } - return true; - } - - /** may fail with the message "cannot read {file}" */ - public boolean canRead(File file, String message) { - if (nullcheck(file, message)) { - if (file.canRead()) { - return true; - } else { - fail("cannot read " + file); - } - } - return false; - } - - /** may fail with the message "cannot write {file}" */ - public boolean canWrite(File file, String message) { - if (nullcheck(file, message)) { - if (file.canRead()) { - return true; - } else { - fail("cannot write " + file); - } - } - return false; - } - - /** may fail with the message "not a directory {file}" */ - public boolean canReadDir(File file, String message) { - if (canRead(file, message)) { - if (file.isDirectory()) { - return true; - } else { - fail("not a directory " + file); - } - } - return false; - } - - /** may fail with the message "not a directory {file}" */ - public boolean canWriteDir(File file, String message) { - if (canWrite(file, message)) { - if (file.isDirectory()) { - return true; - } else { - fail("not a directory " + file); - } - } - return false; - } - - /** - * May fail with any of the messages - * <li>{null check} dir array<li> - * <li>"#: not a File {file}"<li> - * <li>{canRead} {message}[#}<li> - */ - public boolean canReadFiles(Object[] dirs, String message) { - return ((nullcheck((Object) dirs, message + " dir array")) - && canReadFiles(Arrays.asList(dirs), message)); - } - - /** - * May fail with any of the messages - * <li>{null check} files<li> - * <li>"#: not a File {file}"<li> - * <li>{canRead} {message}[#}<li> - */ - public boolean canReadFiles(Collection dirs, String message) { - if (nullcheck((Object) dirs, message + " files")) { - int i = 0; - for (Iterator iter = dirs.iterator(); iter.hasNext();) { - Object o = iter.next(); - if (! (o instanceof File)) { - fail(i + ": not a file " + o); - } - if (!canRead((File) o, message + "[" + i++ + "]")) { - return false; - } - } - return true; - } - return false; - } - /** - * May fail with any of the messages - * <li>{null check} dir array<li> - * <li>"#: not a File {file}"<li> - * <li>{canReadDir} {message}[#}<li> - */ - public boolean canReadDirs(Object[] dirs, String message) { - return ((nullcheck((Object) dirs, message + " dir array")) - && canReadDirs(Arrays.asList(dirs), message)); - } - - /** - * May fail with any of the messages - * <li>{null check} dirs<li> - * <li>"#: not a File {file}"<li> - * <li>{canReadDir} {message}[#}<li> - */ - public boolean canReadDirs(Collection dirs, String message) { - if (nullcheck((Object) dirs, message + " dirs")) { - int i = 0; - for (Iterator iter = dirs.iterator(); iter.hasNext();) { - Object o = iter.next(); - if (! (o instanceof File)) { - fail(i + ": not a file " + o); - } - if (!canReadDir((File) o, message + "[" + i++ + "]")) { - return false; - } - } - return true; - } - return false; - } - - /** - * May fail with any of the messages - * <li>{null check} dir array<li> - * <li>"#: not a File {file}"<li> - * <li>{canWrite} {message}[#}<li> - */ - public boolean canWriteFiles(Object[] dirs, String message) { - return ((nullcheck((Object) dirs, message + " dir array")) - && canWriteFiles(Arrays.asList(dirs), message)); - } - - /** - * May fail with any of the messages - * <li>{null check} files<li> - * <li>"#: not a File {file}"<li> - * <li>{canWrite} {message}[#}<li> - */ - public boolean canWriteFiles(Collection dirs, String message) { - if (nullcheck((Object) dirs, message + " files")) { - int i = 0; - for (Iterator iter = dirs.iterator(); iter.hasNext();) { - Object o = iter.next(); - if (! (o instanceof File)) { - fail(i + ": not a file " + o); - } - if (!canWrite((File) o, message + "[" + i++ + "]")) { - return false; - } - } - return true; - } - return false; - } - - /** - * May fail with any of the messages - * <li>{null check} dir array<li> - * <li>"#: not a File {file}"<li> - * <li>{canWriteDir} {message}[#}<li> - */ - public boolean canWriteDirs(Object[] dirs, String message) { - return ((nullcheck((Object) dirs, message + " dir array")) - && canWriteDirs(Arrays.asList(dirs), message)); - } - - /** - * May fail with any of the messages - * <li>{null check} dirs<li> - * <li>"#: not a File {file}"<li> - * <li>{canWriteDir} {message}[#}<li> - */ - public boolean canWriteDirs(Collection dirs, String message) { - if (nullcheck((Object) dirs, message + " dirs")) { - int i = 0; - for (Iterator iter = dirs.iterator(); iter.hasNext();) { - Object o = iter.next(); - if (! (o instanceof File)) { - fail(i + ": not a file " + o); - } - if (!canWriteDir((File) o, message + "[" + i++ + "]")) { - return false; - } - } - return true; - } - return false; - } - - /** - * Send an info message to any underlying handler - * @param message ignored if null - */ - public void info(String message) { - if (null != message) { - IMessageHandler handler = getHandler(); - MessageUtil.info(handler, message); - } - } - - /** Fail via message or AbortException */ - public void fail(String message) { - fail(message, (Throwable) null); - } - - /** - * Fail via message or AbortException. - * All failure messages go through here, - * so subclasses may override to control - * failure-handling. - */ - public void fail(String message, Throwable thrown) { - if ((null == message) && (null == thrown)) { - message = "<Validator:no message>"; - } - IMessage m = MessageUtil.fail(message, thrown); - if (abortOnFailure) { - throw new AbortException(m); - } else { - IMessageHandler handler = getHandler(); - handler.handleMessage(m); - } - } - - /** - * Register a file temporary, i.e., to be - * deleted on completion. The file need not - * exist (yet or ever) and may be a duplicate - * of existing files registered. - */ - public void registerTempFile(File file) { - if (null != file) { - tempFiles.add(file); - } - } - - /** - * Get a writable {possibly-empty} directory. - * If the input dir is null, then try to create a temporary - * directory using name. - * If the input dir is not null, this tries to - * create it if it does not exist. - * Then if name is not null, - * it tries to get a temporary directory - * under this using name. - * If name is null, "Validator" is used. - * If deleteContents is true, this will try to delete - * any existing contents. If this is unable to delete - * the contents of the input directory, this may return - * a new, empty temporary directory. - * If register is true, then any directory returned is - * saved for later deletion using <code>deleteTempDirs()</code>, - * including the input directory. - * When this is unable to create a result, if failMessage - * is not null then this will fail; otherwise it returns false; - */ - public File getWritableDir(File dir, String name, - boolean deleteContents, boolean register, String failMessage) { - // check dir - if (null == dir) { - if (null == name) { - name = "Validator"; - } - dir = FileUtil.getTempDir(name); - } else { - if (!dir.exists()) { - dir.mkdirs(); - } - } - // fail if necessary - if ((null == dir) || (!dir.exists())) { - if (null != failMessage) { - fail(failMessage + ": unable to get parent " + dir); - } - } else { - FileUtil.makeNewChildDir(dir, name); - if (deleteContents) { - FileUtil.deleteContents(dir); - } - if (register) { - tempFiles.add(dir); - } - } - return dir; - } - - /** - * Delete any temp sandboxes, files or directories saved, - * optionally reporting failures in the normal way. - * This will be ignored unless the failure policy - * is unlocked. - */ - public void deleteTempFiles(boolean reportFailures) { - if (null == locker) { - for (ListIterator iter = tempFiles.listIterator(); iter.hasNext();) { - if (deleteFile((File) iter.next(), reportFailures)) { - iter.remove(); - } - } - for (ListIterator iter = sandboxes.listIterator(); iter.hasNext();) { - Sandbox sandbox = (Sandbox) iter.next(); - // XXX assumes all dirs are in sandboxDir - if (deleteFile(sandbox.sandboxDir, reportFailures)) { - iter.remove(); - } - } - } - } - - /** - * Manage temp files and directories of registered sandboxes. - * Note that a sandbox may register before it is initialized, - * so this must do nothing other than save the reference. - * @param sandbox the uninitialized Sandbox to track - */ - public void registerSandbox(Sandbox sandbox) { - sandboxes.add(sandbox); - } - - - private boolean deleteFile(File file, boolean reportFailures) { - if (null == file) { - if (reportFailures) { - fail("unable to delete null file"); - } - return true; // null file - skip - } - FileUtil.deleteContents(file); - if (file.exists()) { - file.delete(); - } - if (!file.exists()) { - return true; - } else if (reportFailures) { - fail("unable to delete " + file); - } - return false; - } - - /** @throws IllegalStateException if handler is null */ - private IMessageHandler getHandler() { - IMessageHandler handler = (IMessageHandler) handlers.peek(); - if (null == handler) { - throw new IllegalStateException("no handler"); - } - return handler; - } - -} // class Validator - diff --git a/testing/src/main/java/org/aspectj/testing/run/IRun.java b/testing/src/main/java/org/aspectj/testing/run/IRun.java deleted file mode 100644 index 57639016b..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/IRun.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -/** - * A run is a Runnable that may know how to set its own status. - * @author isberg - */ -public interface IRun { - public static final IRun[] RA_IRun = new IRun[0]; - - /** Positive wrapper for the status parameter */ - public static final IRun OK - = new IRun() { - /** This returns false when the status is null - * or runResult is false */ - public boolean run(IRunStatus status) { - return ((null != status) && status.runResult()); - } - public IRunStatus makeStatus() { return null; } - }; - - /** Negative wrapper for the status parameter */ - public static final IRun NOTOK - = new IRun() { - public boolean run(IRunStatus status) { - return ((null == status) || !status.runResult()); - } - public IRunStatus makeStatus() { return null; } - }; - - /** - * Run process, setting any known status. - * Normally the caller starts the process - * and the callee completes it, so that - * status.isCompleted() returns true after - * the call completes. However, responsible - * callees ensure starting, and responsible - * callers ensure completed after the call. - * Anyone setting completion should ensure it - * is set recursively for all children, - * and anyone starting child runs should - * ensure children are registered and initialized - * appropriately. - * @param status the IRunStatus representing the - * outcome of the process (collecting parameter). - * @see Runners - */ - boolean run(IRunStatus status) throws Exception; // IMessageHandler? -} diff --git a/testing/src/main/java/org/aspectj/testing/run/IRunIterator.java b/testing/src/main/java/org/aspectj/testing/run/IRunIterator.java deleted file mode 100644 index 5035b216f..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/IRunIterator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import org.aspectj.bridge.IMessageHandler; - -/** - * Iterator for IRun. - * IRunIterator are useful if the underlying components - * can use a generic IRunStatus and a single listener. - * It is a requirement of any component runnin the IRunIterator - * that they call iterationCompleted() when done, to permit - * the IRunIterator to clean up. - * @see Runner#runIterator(IRunIterator, IRunStatus, IRunListener) - */ -public interface IRunIterator { - - /** - * @return true if nextRun() would return something non-null - * @throws IllegalStateException if called after - * <code>iterationCompleted()</code> - */ - boolean hasNextRun(); - - /** - * Get the next run. - * IRunIterator which contains child IRunIterator may either return - * the children IRun or wrap them using - * Runner.wrap(IRunIterator, IRunListener) - * @param handler the IMessageHandler to use for error and other messages - * @param runnere the Runner to use to wrap any nested IRunIterator as IRun. - * @return the next run, or null if there are no more. - * @throws IllegalStateException if called after - * <code>iterationCompleted()</code> - * @see Runner#wrap(IRunIterator, IRunListener) - */ - IRun nextRun(IMessageHandler handler, Runner runner); - - /** - * Signal a runner that further runs should be aborted. Runners - * should check this after each failure. - * @return true if the runner should stop iterating when an IRun fails - * @throws IllegalStateException if called after - * <code>iterationCompleted()</code> - */ - boolean abortOnFailure(); // XXX supply IRun or IRunStatus? - - /** called when hasNextRun() and nextRun() will no longer be called */ - void iterationCompleted(); -} diff --git a/testing/src/main/java/org/aspectj/testing/run/IRunListener.java b/testing/src/main/java/org/aspectj/testing/run/IRunListener.java deleted file mode 100644 index 4318d618f..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/IRunListener.java +++ /dev/null @@ -1,38 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -/** - * Listen to events in the run lifecycle - - * birth, death, and procreation. - * @author isberg - */ -public interface IRunListener { - - /** - * Called when run is about to be started. - */ - void runStarting(IRunStatus run); - - /** - * Called when run is has completed. - */ - void runCompleted(IRunStatus run); - - /** - * Called when adding a child to a parent run - */ - void addingChild(IRunStatus parent, IRunStatus child); -} diff --git a/testing/src/main/java/org/aspectj/testing/run/IRunStatus.java b/testing/src/main/java/org/aspectj/testing/run/IRunStatus.java deleted file mode 100644 index 9c8665728..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/IRunStatus.java +++ /dev/null @@ -1,195 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.MessageUtil; - -/** - * Encapsulate status and results for a run. - * A run starts and then completes normally - * (finished(Object result)), - * abruptly (thrown(Throwable thrown)), - * or by user request (abort(Object request)). - * @author isberg - */ -public interface IRunStatus extends IMessageHolder { - /** clients use this when signalling completion without a specific result */ - public static final Object VOID = Boolean.TRUE; - - /** result object for successful (unset) boolean run result */ - public static final Boolean PASS = Boolean.TRUE; - - /** result object for failed (unset) boolean run result */ - public static final Boolean FAIL = Boolean.FALSE; - - /** clients use this when signalling abort without any specific request */ - public static final Object ABORT = Boolean.FALSE; - - /** clients use this when signalling abort because no object to run */ - public static final Object ABORT_NORUN = MessageUtil.ABORT_NOTHING_TO_RUN; - - /** returned from getChildren when there are no children */ - public static final IRunStatus[] EMPTY_NEST = new IRunStatus[0]; - - //------------------- process controls - /** - * Set identifier associated with this run, if any - * @throws IllegalArgumentException if id is null - * @throws IllegalStateException if id has already been set - */ - void setIdentifier(Object id); - - //------------------- process controls - /** - * Call before any start() or after isCompleted() would return true - * to reset this to its pre-start state - * @throws IllegalStateException if start() has been called - * and isCompleted() is not true. - */ - void reset(); - - /** - * Call only once to signal this run has started. - * @throws IllegalStateException if start() has been called - */ - void start(); - - /** - * Call this or thrown only once after start() - * to signal this run has ended. - * If this represents a void process, use VOID. - * @param result the Object returned by this run. - * @throws IllegalStateException if start() was not called first - * or if either completed(Object) or thrown(Throwable) have been called. - */ - void finish(Object result); - - /** - * Call to signal this run is ending by request. - * If there is no message, use ABORT. - * @param request the Object request to abort, - * or ABORT if none is available. - * @throws IllegalStateException if start() was not called first - * or if either completed(Object) or thrown(Throwable) have been called. - */ - void abort(Object request); - - /** - * Call this or completed only once after start() - * to signal this run has ended. - * @throws IllegalStateException if start() was not called first - * or if either completed(Object) or thrown(Throwable) have been called. - */ - void thrown(Throwable thrown); - - - /** - * Call this for the status to throw an unchecked exception - * of the type that its controller understands. - * It is an error for a IRunStatus to continue normally - * after this is invoked. - */ - void completeAbruptly(); - //------------------- process messages - /** - * Detect whether a message of a given kind has been handled. - * @param kind the IMessage.Kind of the message to detect - * @param orGreater if true, then also accept any message of a greater kind - * @param includeChildren if true, then also search in any child IRunStatus - * @return true if any such message is detected - */ - boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater, boolean includeChildren); - - /** - * Get all messages or those of a specific kind, optionally in children as well - * Pass null to get all kinds. - * @param kind the IMessage.Kind expected, or null for all messages - * @param orGreater if true, also get any greater than the target kind - * as determined by IMessage.Kind.COMPARATOR - * @param includeChildren if true, then also search in any child IRunStatus - * @return IMessage[] of messages of the right kind, or IMessage.NONE - */ - IMessage[] getMessages(IMessage.Kind kind, boolean orGreater, boolean includeChildren); - - /** - * Call this any time to signal any messages. - * (In particular, the IRun caller may use this to register messages - * about the mishandling of the run by the ResultStatusI by the callee.) - * This is a shortcut for getMessageHandler().handleMessage(..); - */ - //boolean handleMessage(IMessage message); - - //------------------- process display - /** @return true if this run has started */ - boolean started(); - - /** @return true if one of the result, abort request, or thrown is available */ - boolean isCompleted(); - - /** @return true if this got an abort request */ - boolean aborted(); - - /** - * @return true if completed and not aborted and no thrown - * or messages with kind ABORT or FAIL or ERROR - */ - boolean runResult(); - - /** get the invoker for any subruns */ - Runner getRunner(); - - /** @return the Object result, if any, of this run */ - Object getResult(); - - /** @return the Object abort request, if any, of this run */ - Object getAbortRequest(); - - /** @return the Throwable thrown, if any, by this run */ - Throwable getThrown(); - - /** @return any Message[] signalled, or SILENCE if none */ - IMessage[] getMessages(); - - /** @return the identifier set for this run, if any */ - Object getIdentifier(); - - //------------------- subprocess - /** - * Add a record for a child run - * and install self as parent. - * @throws IllegalArgumentException if child is null - */ - void addChild(IRunStatus child); - - /** - * Register this as the run parent. - * (Any run that does addChild(IRunStatus) should register as parent.) - * @throws IllegalArgumentException if parent is null - * @throws IllegalStateException if parent exists already - */ - void registerParent(IRunStatus parent); - - /** - * @return the current children of this run, or EMPTY_NEST if none - */ - IRunStatus[] getChildren(); - - /** - * @return the currently-registered parent, or null if none - */ - IRunStatus getParent(); -} diff --git a/testing/src/main/java/org/aspectj/testing/run/IRunValidator.java b/testing/src/main/java/org/aspectj/testing/run/IRunValidator.java deleted file mode 100644 index a341aa167..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/IRunValidator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -/** - * These check whether particular runs have passed. - * @author isberg - */ -public interface IRunValidator { - /** - * Evaluate whether a run has passed. - * @param run the IRunStatus to see if it passed. - * @return true if run has passed - */ - boolean runPassed(IRunStatus run); -} diff --git a/testing/src/main/java/org/aspectj/testing/run/RunIterator.java b/testing/src/main/java/org/aspectj/testing/run/RunIterator.java deleted file mode 100644 index 1b5c8f307..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/RunIterator.java +++ /dev/null @@ -1,136 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import java.util.Arrays; -import java.util.List; -import java.util.ListIterator; - -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.util.LangUtil; - -/** - * Adapt IRun or Run[] or List or ListIterator to RunIteratorI. - */ -public class RunIterator implements IRunIterator { - - protected String name; - protected ListIterator iter; - protected IRun run; - - public RunIterator(String name, IRun run) { - init(name, run); - } - - public RunIterator(String name, List list) { - init(name, list); - } - - public RunIterator(String name, IRun[] runs) { - init(name, Arrays.asList(runs).listIterator()); - } - - public RunIterator(String name, ListIterator iterator) { - init(name, iterator); - } - - public void init(String name, List list) { - init(name, list.listIterator()); - } - - public void init(String name, IRun[] runs) { - init(name, Arrays.asList(runs).listIterator()); - } - - /** @return true if the first IRun from nextRun can be the sole IRun */ - public boolean isHoistable() { - return (null != run); - } - - /** - * @param name if null, use iterator.toString(); - * @param iterator not null - * @throws IllegalArgumentException if iterator is null - */ - public void init(String name, ListIterator iterator) { - LangUtil.throwIaxIfNull(iterator, "iterator"); - iter = iterator; - name = (null != name? name : iterator.toString()); - run = null; - } - - /** - * @param name if null, use run(); - * @param run not null - * @throws IllegalArgumentException if iterator is null - */ - public void init(String name, IRun run) { - LangUtil.throwIaxIfNull(run, "run"); - this.run = run; - name = (null != name? name : run.toString()); - iter = null; - } - - /** - * @return false always - * @see org.aspectj.testing.run.IRunIterator#abortOnFailure() - */ - public boolean abortOnFailure() { - return false; - } - - /** - * @see org.aspectj.testing.run.RunIteratorI#hasNextRun() - */ - public boolean hasNextRun() { - return ((null != run) || ((null != iter) && (iter.hasNext()))); - } - - /** - * @see org.aspectj.testing.run.IRunIterator#iterationCompleted() - */ - public void iterationCompleted() { - } - - - /** - * @see org.aspectj.testing.run.RunIteratorI#nextRun(IMessageHandler, Runner) - */ - public IRun nextRun(IMessageHandler handler, Runner runner) { - if (null != run) { - IRun result = run; - run = null; - return result; - } - if (null != iter) { - for (Object o = iter.next(); iter.hasNext();) { - if (o instanceof IRunIterator) { - return runner.wrap((IRunIterator) o, null); - } else if (o instanceof IRun) { - return (IRun) o; - } else { - MessageUtil.error(handler, "not IRun or IRunIterator: " + o); - } - } - } - return null; - } - - /** @return name */ - public String toString() { - return name; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/run/RunListener.java b/testing/src/main/java/org/aspectj/testing/run/RunListener.java deleted file mode 100644 index 0d7c9fc76..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/RunListener.java +++ /dev/null @@ -1,116 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import java.io.PrintWriter; -import java.util.List; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.MessageUtil; - -/** - * A generic RunListener for easier partial implementations. - * It can take a RunI selector (called on completion) - * and/or a List to accumulate complete IRunStatus - * (if the selector is null or returns true). - * It can also take a PrintWriter and String to print traces of each event - * as "{prefix} [addingChild|runStarting|runCompleted]({IRunStatus})" - */ -public class RunListener implements IRunListener { - protected final List list; - protected final IRun selector; - protected final PrintWriter writer; - protected final String prefix; - - protected RunListener() { - this((List) null, (IRun) null, (PrintWriter) null, (String) null); - } - - /** - * @param sink the List sink for any IRunStatus if the selector is null - * or returns true for run(IRunStatus) - ignored if null. - * @param selector the IRun called on completion, - * perhaps to select those to be accumulated - * (should NOT throw Exception) - */ - public RunListener(List sink, IRun selector) { - this(sink, selector, (PrintWriter) null, (String) null); - } - - /** - * @param writer the PrintWriter to print events to - may be null - * @param prefix the String prefixing any printing - if null, "" - */ - public RunListener(PrintWriter writer, String prefix) { - this((List) null, (IRun) null, writer, prefix); - } - - /** - * @param sink the List sink for any IRunStatus if the selector is null - * or returns true for run(IRunStatus) - ignored if null. - * @param selector the IRun called on completion, - * perhaps to select those to be accumulated - * (should NOT throw Exception) - * @param writer the PrintWriter to print events to - may be null - * @param prefix the String prefixing any printing - if null, "" - */ - public RunListener(List sink, IRun selector, PrintWriter writer, String prefix) { - this.prefix = (null == prefix ? "" : prefix); - this.writer = writer; - this.selector = selector; - list = sink; - } - - /** - * @see org.aspectj.testing.harness.run.IRunListener#addingChild(IRunStatus, IRunStatus) - */ - public void addingChild(IRunStatus parent, IRunStatus child) { - if (null != writer) { - writer.println(prefix + " addingChild(\"" + parent - + "\", \"" + child + "\")"); - } - } - - /** - * @see org.aspectj.testing.harness.run.IRunListener#runStarting(IRunStatus) - */ - public void runStarting(IRunStatus run) { - if (null != writer) { - writer.println(prefix + " runStarting(\"" + run + "\")"); - } - } - - /** - * Print to writer (if any), run selector (if any), and add to list - * (if any and if selector is null or returns true). - * @see org.aspectj.testing.harness.run.IRunListener#runCompleted(IRunStatus) - * @throws AbortException wrapping any Exception thrown by any selector - * (error for selector to throw Exception) - */ - public void runCompleted(IRunStatus run) { - if (null != writer) { - writer.println(prefix + " runCompleted(\"" + run + "\")"); - } - try { - if (((null == selector) || selector.run(run)) && (null != list)) { - list.add(run); - } - } catch (Throwable e) { - String m = "Selectors should not throw exceptions!"; - throw new AbortException(MessageUtil.abort(m, e)); - } - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/run/RunListeners.java b/testing/src/main/java/org/aspectj/testing/run/RunListeners.java deleted file mode 100644 index 4eb8e7a74..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/RunListeners.java +++ /dev/null @@ -1,89 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import java.util.ArrayList; -import java.util.Iterator; - -/** - * Aggregate listeners into one and run synchronously in order added. - * @author isberg - */ -public class RunListeners extends RunListener implements IRunListener { - - ArrayList listeners; - public RunListeners() { - listeners = new ArrayList(); - } - - public void addListener(IRunListener listener) { - if (null != listener) { - listeners.add(listener); - } - } - - public void removeListener(IRunListener listener) { - if (null != listener) { - listeners.remove(listener); - } - } - - - /** - * Run all listeners with the given status. - * @see org.aspectj.testing.harness.run.IRunListener#runStarting(IRunStatus) - */ - public final void runStarting(IRunStatus status) { - if (null == status) { - throw new IllegalArgumentException("null RunStatusI"); - } - Iterator iter = listeners.iterator(); - while(!status.aborted() && iter.hasNext()) { - IRunListener element = (IRunListener) iter.next(); - element.runStarting(status); - } - } - - /** - * Signal all listeners with the given status. - * @see org.aspectj.testing.harness.run.IRunListener#runCompleted(IRunStatus) - */ - public final void runCompleted(IRunStatus status) { - if (null == status) { - throw new IllegalArgumentException("null RunStatusI"); - } - Iterator iter = listeners.iterator(); - while(!status.aborted() && iter.hasNext()) { - IRunListener element = (IRunListener) iter.next(); - element.runCompleted(status); - } - } - /** - * @see org.aspectj.testing.harness.run.IRunListener#addingChild(IRunStatus, IRunStatus) - */ - public final void addingChild(IRunStatus parent, IRunStatus child) { - if (null == child) { - throw new IllegalArgumentException("null child"); - } - if (null == parent) { - throw new IllegalArgumentException("null parent"); - } - Iterator iter = listeners.iterator(); - while(!parent.aborted() && ! child.aborted() && iter.hasNext()) { - IRunListener element = (IRunListener) iter.next(); - element.addingChild(parent, child); - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/run/RunStatus.java b/testing/src/main/java/org/aspectj/testing/run/RunStatus.java deleted file mode 100644 index ac22280ba..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/RunStatus.java +++ /dev/null @@ -1,442 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.run; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.MessageHandler; -import org.aspectj.testing.util.BridgeUtil; -import org.aspectj.util.LangUtil; - -/** - * Default implementation of {@link IRunStatus}. - * - * @author isberg - */ -public class RunStatus implements IRunStatus { - private static int INDEX; - - private final String name = "RunStatus[" + INDEX++ + "]"; - - /** true after isCompleted() evaluated true */ - private boolean evaluated; - - /** true after starting() called */ - private boolean started; // set only in starting() - - /** true after finished(int) or thrown(Throwable) called */ - private boolean completed; // set only in completed(boolean) - - /** contains any id set */ - private Object id; - - /** after finished(Object) called, contains that parameter */ - private Object result; - - /** after aborted(Object) called, contains that parameter */ - private Object abortRequest; - - /** use to set exception thrown, if any */ - private Throwable thrown; - - /** list of any messages submitted */ - private IMessageHolder messageHolder; - - /** list of any child status */ - private ArrayList children; - - /** parent of this status */ - private IRunStatus parent; - - /** invoker for any subruns */ - private Runner runner; - - /** controls runResult() */ - private IRunValidator validator; - - // public RunStatus() { - // reset(); - // validator = RunValidator.NORMAL; - // } - - public RunStatus(IMessageHolder holder, Runner runner) { - reset(holder, runner); - validator = RunValidator.NORMAL; - } - - // ------------------- process controls - - /** - * Set identifier associated with this run, if any - * - * @throws IllegalArgumentException if id is null - * @throws IllegalStateException if id has already been set - */ - public void setIdentifier(Object id) { - if (null == id) { - throw new IllegalArgumentException("null id"); - } else if ((null != this.id) && (id != this.id)) { - throw new IllegalStateException("attempt to set id " + this.id + " to " + id); - } - this.id = id; - } - - /** - * Set the current validator. - * - * @param delegate the RunValidatorI to use when calculating runStatus - * @throws IllegalArgumentException if delegate is null - */ - public void setValidator(IRunValidator delegate) { - if (null == delegate) { - throw new IllegalArgumentException("null delegate"); - } - if (validator != delegate) { - validator = delegate; - } - } - - /** - * Call before any start() or after isCompleted() would return true to reset this to its pre-start state - * - * @throws IllegalStateException if start() has been called and isCompleted() is not true. - */ - public void reset() { - reset((IMessageHolder) null, (Runner) null); - } - - /** - * Call before any start() or after isCompleted() would return true to reset this to its pre-start state. Does not affect - * validator. - * - * @param holder the IMessageHolder to use after resetting. - * @throws IllegalStateException if start() has been called and isCompleted() is not true. - */ - public void reset(IMessageHolder holder, Runner runner) { - if (null == runner) { - throw new IllegalArgumentException("null runner"); - } - if (started && (!isCompleted())) { - throw new IllegalStateException("no reset() until isCompleted"); - } - started = false; - completed = false; - result = null; - abortRequest = null; - thrown = null; - parent = null; - id = null; - messageHolder = (null != holder ? holder : new MessageHandler()); - if (null != children) { - children.clear(); - } - this.runner = runner; - evaluated = false; - } - - /** - * Call only once to signal this run has started. - * - * @throws IllegalStateException if start() has been called - */ - public void start() { - if (started) { - throw new IllegalStateException("started already"); - } else if (isCompleted()) { - throw new IllegalStateException("start after completed (do reset)"); - } - started = true; - } - - /** - * Call this or thrown only once after start() to signal this run has ended. If this represents a void process, use VOID. - * - * @param result the Object returned by this run. - * @throws IllegalStateException if start() was not called first or if either completed(Object) or thrown(Throwable) have been - * called. - */ - public void finish(Object result) { - if (null == result) { - throw new IllegalArgumentException("null result"); - } else if (isCompleted()) { - throw new IllegalStateException("completed then finish " + result); - } - this.result = result; - } - - /** - * Call to signal this run is ending by request. If this represents a void process, use VOID. If there is no message, use ABORT. - * - * @param request the Object request to abort, or ABORT if none is available. - * @throws IllegalStateException if start() was not called first or if either completed(Object) or thrown(Throwable) have been - * called. - */ - public void abort(Object request) { - if (null == request) { - throw new IllegalArgumentException("null request"); - } else if (isCompleted()) { - throw new IllegalStateException("completed then abort " + request); - } - this.abortRequest = request; - } - - /** - * Call this or completed only once after start() to signal this run has ended. - * - * @throws IllegalStateException if start() was not called first or if either completed(Object) or thrown(Throwable) have been - * called. - */ - public void thrown(Throwable thrown) { - if (null == thrown) { - throw new IllegalArgumentException("null thrown"); - } else if (isCompleted()) { - throw new IllegalStateException("completed then thrown " + thrown); - } - this.thrown = thrown; - } - - public void completeAbruptly() { - throw new Error("completing abruptly"); // XXX configurable - } - - /** - * @return true if completed, not aborted, no thrown, no messages of kind ERROR, FAIL or ABORT, and result object is not - * IRunStatus.FAIL. - * @see org.aspectj.testing.run.IRunStatus#runResult() - */ - public boolean runResult() { - return validator.runPassed(this); - } - - public boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater, boolean includeChildren) { - if (messageHolder.hasAnyMessage(kind, orGreater)) { - return true; - } - if (includeChildren) { - IRunStatus[] kids = getChildren(); - for (int i = 0; i < kids.length; i++) { - if (kids[i].hasAnyMessage(kind, orGreater, true)) { - return true; - } - } - } - return false; - } - - public IMessage[] getMessages(IMessage.Kind kind, boolean orGreater, boolean includeChildren) { - IMessage[] result = getMessages(kind, orGreater); - if (!includeChildren) { - return result; - } - ArrayList sink = new ArrayList(); - if (!LangUtil.isEmpty(result)) { - sink.addAll(Arrays.asList(result)); - } - - IRunStatus[] kids = getChildren(); - for (int i = 0; i < kids.length; i++) { - result = kids[i].getMessages(kind, orGreater, includeChildren); - if (!LangUtil.isEmpty(result)) { - sink.addAll(Arrays.asList(result)); - } - } - return (IMessage[]) sink.toArray(new IMessage[0]); - } - - // ------------------- process messages - /** - * Call this any time before isCompleted() would return true to signal any messages. - * - * @throws IllegalStateException if isCompleted(). - */ - public boolean handleMessage(IMessage message) { - return messageHolder.handleMessage(message); - } - - public boolean isIgnoring(IMessage.Kind kind) { - return messageHolder.isIgnoring(kind); - } - - public void dontIgnore(IMessage.Kind kind) { - messageHolder.dontIgnore(kind); - } - - public void ignore(IMessage.Kind kind) { - messageHolder.ignore(kind); - } - - /** - * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(org.aspectj.bridge.IMessage.Kind, boolean) - */ - public boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater) { - return messageHolder.hasAnyMessage(kind, orGreater); - } - - /** - * @see org.aspectj.bridge.IMessageHolder#getMessages(org.aspectj.bridge.IMessage.Kind, boolean) - */ - public IMessage[] getMessages(IMessage.Kind kind, boolean orGreater) { - return messageHolder.getMessages(kind, orGreater); - } - - /** - * @see org.aspectj.bridge.IMessageHolder#numMessages(org.aspectj.bridge.IMessage.Kind, boolean) - */ - public int numMessages(IMessage.Kind kind, boolean orGreater) { - return messageHolder.numMessages(kind, orGreater); - } - - // ------------------- process display - /** @return true if this run has started */ - public boolean started() { - return started; - } - - /** @return true if one of the result, abort request, or thrown is available */ - public boolean isCompleted() { - if (!evaluated) { - if (started && ((null != thrown) || (null != result) || (null != abortRequest))) { - completed = true; - evaluated = true; - } - } - return completed; - } - - /** @return true if this got an abort request */ - public boolean aborted() { - return (completed && (null != abortRequest)); - } - - /** @return the Object result, if any, of this run */ - public Object getResult() { - return result; - } - - /** @return the Object abort request, if any, of this run */ - public Object getAbortRequest() { - return abortRequest; - } - - /** @return the Throwable thrown, if any, by this run */ - public Throwable getThrown() { - return thrown; - } - - /** - * @see org.aspectj.bridge.IMessageHolder#getUnmodifiableListView() - */ - public List<IMessage> getUnmodifiableListView() { - return messageHolder.getUnmodifiableListView(); - } - - /** @return any Message[] signalled, or IMessage.NONE if none */ - public IMessage[] getMessages() { - return messageHolder.getMessages(null, IMessageHolder.EQUAL); - } - - /** @return the identifier set for this run, if any */ - public Object getIdentifier() { - return id; - } - - /** - * @see org.aspectj.bridge.IMessageHolder#clearMessages() - * @throws UnsupportedOperationException always - */ - public void clearMessages() throws UnsupportedOperationException { - throw new UnsupportedOperationException("use reset"); - } - - // ------------------- subprocess - - /** get the invoker for any subrunners */ - public Runner getRunner() { - return runner; - } - - /** - * Add a record for a child run and install self as parent. - * - * @throws IllegalArgumentException if child is null - */ - public void addChild(IRunStatus child) { - if (null == child) { - throw new IllegalArgumentException("null child"); - } - if (null == children) { - children = new ArrayList(); - } - children.add(child); - } - - /** - * Register this as the run parent. (Any run that does addChild(IRunStatus) should register as parent.) - * - * @throws IllegalArgumentException if parent is null - * @throws IllegalStateException if parent exists already - */ - public void registerParent(IRunStatus parent) { - if (null == parent) { - throw new IllegalArgumentException("null parent"); - } else if (null != this.parent) { - throw new IllegalStateException("adding parent " + parent + " to parent " + this.parent); - } - this.parent = parent; - } - - /** - * @return the current children of this run, or EMPTY_NEST if none - */ - public IRunStatus[] getChildren() { - if ((null == children) || (0 == children.size())) { - return EMPTY_NEST; - } else { - return (IRunStatus[]) children.toArray(EMPTY_NEST); - } - } - - /** - * @return the currently-registered parent, or null if none - */ - public IRunStatus getParent() { - return parent; - } - - public String toString() { - return BridgeUtil.toShortString(this); - } - - public String toLongString() { - StringBuffer sb = new StringBuffer(); - sb.append(BridgeUtil.toShortString(this)); - if ((null != children) && (0 < children.size())) { - String label = "### --------- " + name; - int index = 0; - for (Iterator iter = children.iterator(); iter.hasNext();) { - IRunStatus childStatus = (IRunStatus) iter.next(); - String childLabel = "\n" + label + " child[" + index++ + "] " + childStatus.getIdentifier(); - sb.append(childLabel + " ---- start\n"); - sb.append(childStatus.toString()); - sb.append(childLabel + " ---- end\n"); - } - } - return sb.toString(); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/run/RunValidator.java b/testing/src/main/java/org/aspectj/testing/run/RunValidator.java deleted file mode 100644 index 70131f71a..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/RunValidator.java +++ /dev/null @@ -1,210 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.testing.util.IntRange; -import org.aspectj.testing.util.ObjectChecker; - -/** - * This checks if a run status passes, as follows: - * <li>state: fail unless completed and not aborted</li> - * <li>messages: fail if any of type ABORT, FAIL - permit ERROR, WARNING, DEBUG... - * (which permits expected compiler errors and warnings) </li> - * <li>thrown: if type required, fail unless type thrown; - * if type permitted, fail if wrong type thrown</li> - * <li>result: fail unless no ObjectChecker or it validates - * and the result is not IRunStatus.FAIL.</li> - * <li>otherwise delegates to any subclass doPassed()<li> - * Client setup the expected and permitted exception classes - * and the result object checker, and may also subclass to - * query the IRunStatus more carefully. - * <p> - * Note that IRunStatus states can be out of sync with messages, - * e.g., as underlying components signal ABORT without using abort(...). - */ -public class RunValidator implements IRunValidator { - /** expect normal completion with any non-null result object, - * except that Integer Objects must have value 0 */ - public static final IRunValidator NORMAL - = new RunValidator(ObjectChecker.ANY_ZERO); - /** expect normal completion with any non-null result object */ - public static final IRunValidator ORIGINAL_NORMAL - = new RunValidator(ObjectChecker.ANY); - - /** expect normal completion and Integer result object with value 0 */ - public static final IRunValidator ZERO_STATUS - = new RunValidator(IntRange.ZERO); - - /** expect finished(IRunStatus.PASS) and no thrown, fail, etc. */ - public static final IRunValidator PASS - = new RunValidator(new ObjectChecker() { - public boolean isValid(Object o) { - return (o == IRunStatus.PASS); - } - }); - - /** expect finished(IRunStatus.FAIL) */ - public static final IRunValidator FAIL - = new RunValidator(new ObjectChecker() { - public boolean isValid(Object o) { - return (o == IRunStatus.FAIL); - } - }); - - /** range of status values required for passing */ - private ObjectChecker resultChecker; - - // XXX replace two exc. classes with one, plus boolean for how to interpret? - /** if non-null, passed() permits any thrown assignable to this class */ - private Class permittedExceptionsClass; - - /** if non-null, passed() requires some thrown assignable to this class */ - private Class requiredExceptionsClass; - - /** Create result validator that expects a certain int status */ - public RunValidator(ObjectChecker resultChecker) { - this(resultChecker, null, null); - } - - /** - * Create result validator that passes only when completed abruptly by - * a Throwable assignable to the specified class. - * @throws illegalArgumentException if requiredExceptionsClass is not Throwable - */ - public RunValidator(Class requiredExceptionsClass) { - this(null, null, requiredExceptionsClass); - } - - /** - * Create a result handler than knows how to evaluate {@link #passed()}. - * You cannot specify both permitted and required exception class, - * and any exception class specified must be assignable to throwable. - * - * @param resultChecker {@link #passed()} will return false if - * the int status is not accepted by this int validator - if null, - * any int status result is accepted. - * @param fastFailErrorClass an Error subclass with a (String) constructor to use to - * construct and throw Error from fail(String). If null, then fail(String) - * returns normally. - * @param permittedExceptionsClass if not null and any exceptions thrown are - * assignable to this class, {@link #passed()} will not return - * false as it normally does when exceptions are thrown. - * @param requiredExceptionsClass if not null, {@link #passed()} will return false - * unless some exception was thrown that is assignable to this class. - * @throws illegalArgumentException if any exception class is not Throwable - * or if fast fail class is illegal (can't make String constructor) - */ - protected RunValidator( - ObjectChecker resultChecker, - Class permittedExceptionsClass, - Class requiredExceptionsClass) { - init(resultChecker,permittedExceptionsClass, requiredExceptionsClass); - } - - /** same as init with existing values */ - protected void reset() { - init(resultChecker, permittedExceptionsClass, - requiredExceptionsClass); - } - - /** subclasses may use this to re-initialize this for re-use */ - protected void init( - ObjectChecker resultChecker, - Class permittedExceptionsClass, - Class requiredExceptionsClass) { - this.permittedExceptionsClass = permittedExceptionsClass; - this.requiredExceptionsClass = requiredExceptionsClass; - - if (null != resultChecker) { - this.resultChecker = resultChecker; - } else { - this.resultChecker = IntRange.ANY; - } - - if (null != permittedExceptionsClass) { - if (!Throwable.class.isAssignableFrom(permittedExceptionsClass)) { - String e = "permitted not throwable: " + permittedExceptionsClass; - throw new IllegalArgumentException(e); - } - } - if (null != requiredExceptionsClass) { - if (!Throwable.class.isAssignableFrom(requiredExceptionsClass)) { - String e = "required not throwable: " + requiredExceptionsClass; - throw new IllegalArgumentException(e); - } - } - if ((null != permittedExceptionsClass) - && (null != requiredExceptionsClass) ) { - String e = "define at most one of required or permitted exceptions"; - throw new IllegalArgumentException(e); - } - } - - /** @return true if this result passes per this validator */ - public final boolean runPassed(IRunStatus result) { - if (null == result) { - throw new IllegalArgumentException("null result"); - } - // After the result has completed, the result is stored. - if (!result.isCompleted()) { - return false; - } - if (result.aborted()) { - return false; - } - if (null != result.getAbortRequest()) { - return false; - } - Object resultObject = result.getResult(); - if (!resultChecker.isValid(resultObject)) { - return false; - } - if (resultObject == IRunStatus.FAIL) { - return false; - } - // need MessageHandler.getMessage(...) - if (result.hasAnyMessage(IMessage.FAIL, IMessageHolder.ORGREATER)) { - return false; - } - Throwable thrown = result.getThrown(); - if (null == thrown) { - if (null != requiredExceptionsClass) { - return false; - } - } else { - Class c = thrown.getClass(); - // at most one of the ExceptionsClass set - if (null != requiredExceptionsClass) { - if (!requiredExceptionsClass.isAssignableFrom(c)) { - return false; - } - } else if (null != permittedExceptionsClass) { - if (!permittedExceptionsClass.isAssignableFrom(c)) { - return false; - } - } else { - return false; - } - } - return dopassed(); - } - - /** subclasses implement subclass-specific behavior for passed() here */ - protected boolean dopassed() { - return true; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/run/Runner.java b/testing/src/main/java/org/aspectj/testing/run/Runner.java deleted file mode 100644 index 58860be6f..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/Runner.java +++ /dev/null @@ -1,510 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.run; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.Message; -import org.aspectj.bridge.MessageHandler; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.util.LangUtil; - -/** - * Run IRun, setting status and invoking listeners - * for simple and nested runs. - * <p> - * This manages baseline IRun status reporting: - * any throwables are caught and reported, and - * the status is started before running and - * (if not already completed) completed after. - * <p> - * This runs any IRunListeners specified directly in the - * run*(..., IRunListener) methods - * as well as any specified indirectly by registering listeners per-type - * in {@link registerListener(Class, IRunListener)} - * <p> - * For correct handling of nested runs, this sets up - * status parent/child relationships. - * It uses the child result object supplied directly in the - * runChild(..., IRunStatus childStatus,..) methods, - * or (if that is null) one obtained from the child IRun itself, - * or (if that is null) a generic IRunStatus. - * <p> - * For IRunIterator, this uses IteratorWrapper to wrap the - * iterator as an IRun. Runner and IteratorWrapper coordinate - * to handle fast-fail (aborting further iteration when an IRun fails). - * The IRunIterator itself may specify fast-fail by returning true - * from {@link IRunIterator#abortOnFailure()}, or clients can - * register IRunIterator by Object or type for fast-failure using - * {@link registerFastFailIterator(IRunIterator)} or - * {@link registerFastFailIterator(Class)}. - * This also ensures that - * {@link IRunIterator#iterationCompleted()} is - * called after the iteration process has completed. - */ -public class Runner { - // XXX need to consider wiring in a logger - sigh - - private static final IMessage FAIL_NORUN - = MessageUtil.fail("Null IRun parameter to Runner.run(IRun..)"); -// private static final IMessage FAIL_NORUN_ITERATOR -// = MessageUtil.fail("Null IRunterator parameter to Runner.run(IRunterator...)"); - - public Runner() { - } - - /** - * Do the run, setting run status, invoking - * listener, and aborting as necessary. - * If the run is null, the status is - * updated, but the listener is never run. - * If the listener is null, then the runner does a lookup - * for the listeners of this run type. - * Any exceptions thrown by the listener(s) are added - * to the status messages and processing continues. - * unless the status is aborted. - * The status will be completed when this method completes. - * @param run the IRun to run - if null, issue a FAIL message - * to that effect in the result. - * @throws IllegalArgumentException if status is null - * @return boolean result returned from IRun - * or false if IRun did not complete normally - * or status.runResult() if aborted. - */ - /* XXX later permit null status - * If the status is null, this tries to complete - * the run without a status. It ignores exceptions - * from the listeners, but does not catch any from the run. - */ - public boolean run(IRun run, IRunStatus status, - IRunListener listener) { - return run(run, status, listener, (Class) null); - } - - public boolean run(IRun run, IRunStatus status, - IRunListener listener, Class exceptionClass) { - if (!precheck(run, status)) { - return false; - } - RunListeners listeners = getListeners(run, listener); - return runPrivate(run, status, listeners, exceptionClass); - - } - - /** - * Run child of parent, handling interceptor registration, etc. - * @throws IllegalArgumentException if parent or child status is null - */ - public boolean runChild(IRun child, - IRunStatus parentStatus, - IRunStatus childStatus, - IRunListener listener) { - return runChild(child, parentStatus, childStatus, listener, null); - } - - /** - * Run child of parent, handling interceptor registration, etc. - * If the child run is supposed to throw an exception, then pass - * the exception class. - * After this returns, the childStatus is guaranteed to be completed. - * If an unexpected exception is thrown, an ABORT message - * is passed to childStatus. - * @param parentStatus the IRunStatus for the parent - must not be null - * @param childStatus the IRunStatus for the child - default will be created if null - * @param exceptionClass the Class of any expected exception - * @throws IllegalArgumentException if parent status is null - */ - public boolean runChild(IRun child, - IRunStatus parentStatus, - IRunStatus childStatus, - IRunListener listener, - Class exceptionClass) { - if (!precheck(child, parentStatus)) { - return false; - } - if (null == childStatus) { - childStatus = new RunStatus(new MessageHandler(), this); - } - installChildStatus(child, parentStatus, childStatus); - if (!precheck(child, childStatus)) { - return false; - } - RunListeners listeners = getListeners(child, listener); - if (null != listeners) { - try { - listeners.addingChild(parentStatus, childStatus); - } catch (Throwable t) { - String m = "RunListenerI.addingChild(..) exception " + listeners; - parentStatus.handleMessage(MessageUtil.abort(m, t)); // XXX - } - } - boolean result = false; - try { - result = runPrivate(child, childStatus, listeners, exceptionClass); - } finally { - if (!childStatus.isCompleted()) { - childStatus.finish(result ? IRunStatus.PASS : IRunStatus.FAIL); - childStatus.handleMessage(MessageUtil.debug("XXX parent runner set completion")); - } - } - boolean childResult = childStatus.runResult(); - if (childResult != result) { - childStatus.handleMessage(MessageUtil.info("childResult != result=" + result)); - } - return childResult; - } - - public IRunStatus makeChildStatus(IRun run, IRunStatus parent, IMessageHolder handler) { - return installChildStatus(run, parent, new RunStatus(handler, this)); - } - - /** - * Setup the child status before running - * @param run the IRun of the child process (not null) - * @param parent the IRunStatus parent of the child status (not null) - * @param child the IRunStatus to install - if null, a generic one is created - * @return the IRunStatus child status (as passed in or created if null) - */ - public IRunStatus installChildStatus(IRun run, IRunStatus parent, IRunStatus child) { - if (null == parent) { - throw new IllegalArgumentException("null parent"); - } - if (null == child) { - child = new RunStatus(new MessageHandler(), this); - } - child.setIdentifier(run); // XXX leak if ditching run... - parent.addChild(child); - return child; - } - - /** - * Do a run by running all the subrunners provided by the iterator, - * creating a new child status of status for each. - * If the iterator is null, the result is - * updated, but the interceptor is never run. - * @param iterator the IRunteratorI for all the IRun to run - * - if null, abort (if not completed) or message to status. - * @throws IllegalArgumentException if status is null - */ - public boolean runIterator(IRunIterator iterator, IRunStatus status, - IRunListener listener) { - LangUtil.throwIaxIfNull(status, "status"); - if (status.aborted()) { - return status.runResult(); - } - if (null == iterator) { - if (!status.isCompleted()) { - status.abort(IRunStatus.ABORT_NORUN); - } else { - status.handleMessage(FAIL_NORUN); - } - return false; - } - IRun wrapped = wrap(iterator, listener); - return run(wrapped, status, listener); - } - - /** - * Signal whether to abort on failure for this run and iterator, - * based on the iterator and any fast-fail registrations. - * @param iterator the IRunIterator to stop running if this returns true - * @param run the IRun that failed - * @return true to halt further iterations - */ - private boolean abortOnFailure(IRunIterator iterator, IRun run) { - return ((null == iterator) || iterator.abortOnFailure()); // XxX not complete - } - - - /** - * Tell Runner to stop iterating over IRun for an IRunIterator - * if any IRun.run(IRunStatus) fails. - * This overrides a false result from IRunIterator.abortOnFailure(). - * @param iterator the IRunIterator to fast-fail - ignored if null. - * @see IRunIterator#abortOnFailure() - */ - public void registerFastFailIterator(IRunIterator iterator) { // XXX unimplemented - throw new UnsupportedOperationException("ignoring " + iterator); - } - - /** - * Tell Runner to stop iterating over IRun for an IRunIterator - * if any IRun.run(IRunStatus) fails, - * if the IRunIterator is assignable to iteratorType. - * This overrides a false result from IRunIterator.abortOnFailure(). - * @param iteratorType the IRunIterator Class to fast-fail - * - ignored if null, must be assignable to IRunIterator - * @see IRunIterator#abortOnFailure() - */ - public void registerFastFailIteratorTypes(Class iteratorType) { // XXX unimplemented - throw new UnsupportedOperationException("ignoring " + iteratorType); - } - - /** - * Register a run listener for any run assignable to type. - * @throws IllegalArgumentException if either is null - */ - public void registerListener(Class type, IRunListener listener) { // XXX unregister - if (null == type) { - throw new IllegalArgumentException("null type"); - } - if (null == listener) { - throw new IllegalArgumentException("null listener"); - } - ClassListeners.addListener(type, listener); - } - - /** - * Wrap this IRunIterator. - * This wrapper takes care of calling - * <code>iterator.iterationCompleted()</code> when done, so - * after running this, clients should not invoker IRunIterator - * methods on this iterator. - * @return the iterator wrapped as a single IRun - */ - public IRun wrap(IRunIterator iterator, IRunListener listener) { - LangUtil.throwIaxIfNull(iterator, "iterator"); - return new IteratorWrapper(this, iterator, listener); - } - - /** - * This gets any listeners registered for the run - * based on the class of the run (or of the wrapped iterator, - * if the run is an IteratorWrapper). - * @return a listener with all registered listener and parm, - * or null if parm is null and there are no listeners - */ - protected RunListeners getListeners(IRun run, IRunListener listener) { - if (null == run) { - throw new IllegalArgumentException("null run"); - } - Class runClass = run.getClass(); - if (runClass == IteratorWrapper.class) { - IRunIterator it = ((IteratorWrapper) run).iterator; - if (null != it) { - runClass = it.getClass(); - } - // fyi expecting: listener == ((IteratorWrapper) run).listener - } - RunListeners listeners = ClassListeners.getListeners(runClass); - if (null != listener) { - listeners.addListener(listener); - } - return listeners; // XXX implement registration - } - - /** check status and run before running */ - private boolean precheck(IRun run, IRunStatus status) { - if (null == status) { - throw new IllegalArgumentException("null status"); - } - // check abort request coming in - if (status.aborted()) { - return status.runResult(); - } else if (status.isCompleted()) { - throw new IllegalStateException("status completed before starting"); - } - - if (!status.started()) { - status.start(); - } - return true; - } - - /** This assumes precheck has happened and listeners have been obtained */ - private boolean runPrivate(IRun run, IRunStatus status, - RunListeners listeners, Class exceptionClass) { - IRunListener listener = listeners; - if (null != listener) { - try { - listener.runStarting(status); - } catch (Throwable t) { - String m = listener + " RunListenerI.runStarting(..) exception"; - IMessage mssg = new Message(m, IMessage.WARNING, t, null); - // XXX need IMessage.EXCEPTION - WARNING is ambiguous - status.handleMessage(mssg); - } - } - // listener can set abort request - if (status.aborted()) { - return status.runResult(); - } - if (null == run) { - if (!status.isCompleted()) { - status.abort(IRunStatus.ABORT_NORUN); - } else { - status.handleMessage(MessageUtil.FAIL_INCOMPLETE); - } - return false; - } - - boolean result = false; - try { - result = run.run(status); - if (!status.isCompleted()) { - status.finish(result?IRunStatus.PASS: IRunStatus.FAIL); - } - } catch (Throwable thrown) { - if (!status.isCompleted()) { - status.thrown(thrown); - } else { - String m = "run status completed but run threw exception"; - status.handleMessage(MessageUtil.abort(m, thrown)); - result = false; - } - } finally { - if (!status.isCompleted()) { - // XXX should never get here... - hides errors to set result - status.finish(result ? IRunStatus.PASS : IRunStatus.FAIL); - if (!status.isCompleted()) { - status.handleMessage(MessageUtil.debug("child set of status failed")); - } - } - } - - - try { - if ((null != listener) && !status.aborted()) { - listener.runCompleted(status); - } - } catch (Throwable t) { - String m = listener + " RunListenerI.runCompleted(..) exception"; - status.handleMessage(MessageUtil.abort(m, t)); - } - return result; - } - - //---------------------------------- nested classes - /** - * Wrap an IRunIterator as a IRun, coordinating - * fast-fail IRunIterator and Runner - */ - public static class IteratorWrapper implements IRun { - final Runner runner; - public final IRunIterator iterator; - final IRunListener listener; - - public IteratorWrapper(Runner runner, IRunIterator iterator, IRunListener listener) { - LangUtil.throwIaxIfNull(iterator, "iterator"); - LangUtil.throwIaxIfNull(runner, "runner"); - this.runner = runner; - this.iterator = iterator; - this.listener = listener; - } - - /** @return null */ - public IRunStatus makeStatus() { - return null; - } - - /** @return true unless one failed */ - public boolean run(IRunStatus status) { - boolean result = true; - try { - int i = 0; - int numMessages = status.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER); - while (iterator.hasNextRun()) { - IRun run = iterator.nextRun((IMessageHandler) status, runner); - if (null == run) { - MessageUtil.debug(status, "null run " + i + " from " + iterator); - continue; - } - - int newMessages = status.numMessages(IMessage.FAIL, IMessageHolder.ORGREATER); - if (newMessages > numMessages) { - numMessages = newMessages; - String m = "run " + i + " from " + iterator - + " not invoked, due to fail(+) message(s) "; - MessageUtil.debug(status, m); - continue; - } - RunStatus childStatus = null; // let runChild create - if (!runner.runChild(run, status, childStatus, listener)) { - if (result) { - result = false; - } - if (iterator.abortOnFailure() - || runner.abortOnFailure(iterator, run)) { - break; - } - } - i++; - } - return result; - } finally { - iterator.iterationCompleted(); - } - } - - /** @return iterator, clipped to 75 char */ - public String toString() { - String s = "" + iterator; - if (s.length() > 75) { - s = s.substring(0, 72) + "..."; - } - return s; - } - } - - /** per-class collection of IRun */ - static class ClassListeners extends RunListeners { - private static final Hashtable known = new Hashtable(); - - static RunListeners getListeners(Class c) { // XXX costly and stupid - Enumeration keys = known.keys(); - RunListeners many = new RunListeners(); - while (keys.hasMoreElements()) { - Class kc = (Class) keys.nextElement(); - if (kc.isAssignableFrom(c)) { - many.addListener((IRunListener) known.get(kc)); - } - } - return many; - } - - private static RunListeners makeListeners(Class c) { - RunListeners result = (ClassListeners) known.get(c); - if (null == result) { - result = new ClassListeners(c); - known.put(c, result); - } - return result; - } - - static void addListener(Class c, IRunListener listener) { - if (null == listener) { - throw new IllegalArgumentException("null listener"); - } - if (null == c) { - c = IRun.class; - } - makeListeners(c).addListener(listener); - } - - Class clazz; - - ClassListeners(Class clazz) { - this.clazz = clazz; - } - - public String toString() { - return clazz.getName() + " ClassListeners: " + super.toString(); - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/run/WrappedRunIterator.java b/testing/src/main/java/org/aspectj/testing/run/WrappedRunIterator.java deleted file mode 100644 index 75be92cb7..000000000 --- a/testing/src/main/java/org/aspectj/testing/run/WrappedRunIterator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.run; - -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.util.LangUtil; - -/** Adapt IRun to IRunIterator in a way that can be detected for hoisting. */ -public class WrappedRunIterator implements IRunIterator { - protected final Object id; - protected IRun run; - - /** - * @param id the Object used for toString(), if set - * @param run the IRun returned from the first call to - * nextRun(IMessageHandler handler, Runner runner) - */ - public WrappedRunIterator(Object id, IRun run) { - LangUtil.throwIaxIfNull(run, "run"); - this.id = id; - this.run = run; - } - - /** @return false always - we run only once anyway */ - public boolean abortOnFailure() { - return false; - } - - /** - * @return true until nextRun() completes - * @see org.aspectj.testing.run.RunIteratorI#hasNextRun() - */ - public boolean hasNextRun() { - return (null != run); - } - - /** - * @see org.aspectj.testing.run.IRunIterator#iterationCompleted() - */ - public void iterationCompleted() { - } - - /** - * @return the only IRun we have, and null thereafter - * @see org.aspectj.testing.run.RunIteratorI#nextRun(IMessageHandler, Runner) - */ - public IRun nextRun(IMessageHandler handler, Runner runner) { - if (null == run) { - return null; - } else { - IRun result = run; - run = null; - return result; - } - } - - /** @return name */ - public String toString() { - return (null == id ? run : id).toString(); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/taskdefs/AjcTaskCompileCommand.java b/testing/src/main/java/org/aspectj/testing/taskdefs/AjcTaskCompileCommand.java deleted file mode 100644 index 1f5325e82..000000000 --- a/testing/src/main/java/org/aspectj/testing/taskdefs/AjcTaskCompileCommand.java +++ /dev/null @@ -1,294 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.taskdefs; - -//import java.awt.Frame; -import java.io.*; -//import java.lang.reflect.*; -import java.util.*; -//import java.util.List; - -import org.apache.tools.ant.*; -import org.apache.tools.ant.Project; -import org.aspectj.bridge.*; -import org.aspectj.tools.ant.taskdefs.AjcTask; -import org.aspectj.util.*; -import org.aspectj.util.FileUtil; - -/** - * Drive tests using the Ant taskdef. - * The non-incremental case is quite easy to implement, - * but incremental compiles require running the compiler - * in another thread using an incremental tag file. - * This is imprecise because it assumes - * incremental compiles are complete - * when messages stop coming from the compiler. - * Also, the client should call quit() when done compiling - * to halt the process. - * XXX build up ICommand with quit (and done-with-last-invocation?) - * to avoid the kludge workarounds - */ -public class AjcTaskCompileCommand implements ICommand { - /** - * 20 seconds of quiet in message holder - * before we assume incremental compile is done - */ - public static int COMPILE_SECONDS_WITHOUT_MESSAGES = 20; - - /** 5 minutes maximum time to wait for a compile to complete */ - public static int COMPILE_MAX_SECONDS = 300; - - /** - * Wait until this holder has not changed the number of messages - * in secs seconds, as a weak form of determining when the - * compile has completed. - * XXX implement "compile-complete" message instead. - * @param holder the IMessageHolder to wait for - * @param seconds the number of seconds that the messages should be the same - * @param timeoutSeconds the int number of seconds after which to time out - * @return true if the messages quiesced before the timeout - * false if parameters are 0 or negative or if - * seconds => timeoutSeconds - */ - static boolean waitUntilMessagesQuiet( - IMessageHolder holder, - int seconds, - int timeoutSeconds) { - LangUtil.throwIaxIfNull(holder, "holder"); - if ((0 >= timeoutSeconds) || (0 >= seconds) - || (timeoutSeconds <= seconds)) { - return false; - } - long curTime = System.currentTimeMillis(); - final long timeout = curTime + (timeoutSeconds*1000); -// final Thread thread = Thread.currentThread(); - final long targetQuietTime = 1000 * seconds; - int numMessages = holder.numMessages(null, true); - long numMessagesTime = curTime; - // check for new messages every .5 to 3 seconds - final long checkInterval; - { - long interval = seconds / 10; - if (interval > 3000) { - interval = 3000; - } else if (interval < 200) { - interval = 500; - } - checkInterval = interval; - } - while ((curTime < timeout) - && (curTime < (numMessagesTime + targetQuietTime))) { - // delay until next check - long nextCheck = curTime + checkInterval; - while (nextCheck > curTime) { - try { - Thread.sleep(nextCheck - curTime); - } catch (InterruptedException e) { - // ignore - } - curTime = System.currentTimeMillis(); - } - int newNumMessages = holder.numMessages(null, true); - if (newNumMessages != numMessages) { - numMessages = newNumMessages; - numMessagesTime = curTime; - } - } - return (curTime >= (numMessagesTime + targetQuietTime)); - } - - // single-threaded driver - MessageHandler messages = new MessageHandler(); - AjcTask ajcTask; - File incrementalFile; - Thread incrementalCompileThread; - - /** - * Stop waiting for any further incremental compiles. - * Safe to call in non-incremental modes. - */ - public void quit() { // XXX requires downcast from ICommand, need validator,IMessageHandler interface - AjcTask task = ajcTask; - if (null != task) { - task.quit(); // signal task to quit, thread to die - ajcTask = null; // XXX need for cleanup? - } - updateIncrementalFile(false, true); - Thread thread = incrementalCompileThread; - if (null != thread) { - if (thread.isAlive()) { - try { - thread.join(3000); - } catch (InterruptedException e) { - // ignore - } - if (thread.isAlive()) { - String s = "WARNING: abandoning undying thread "; - System.err.println(s + thread.getName()); - } - } - incrementalCompileThread = null; - } - } - - // --------- ICommand interface - public boolean runCommand(String[] args, IMessageHandler handler) { - return (makeAjcTask(args, handler) - && doCommand(handler, false)); - } - - /** - * Fails if called before runCommand or if - * not in incremental mode or if the command - * included an incremental file entry. - * @return - */ - public boolean repeatCommand(IMessageHandler handler) { - return doCommand(handler, true); - } - - protected boolean doCommand(IMessageHandler handler, boolean repeat) { - messages.clearMessages(); - if (null == ajcTask) { - MessageUtil.fail(messages, "ajcTask null - repeat without do"); - } - try { - // normal, non-incremental case - if (!repeat && (null == incrementalFile)) { - ajcTask.execute(); - // rest is for incremental mode - } else if (null == incrementalFile) { - MessageUtil.fail(messages, "incremental mode not specified"); - } else if (!updateIncrementalFile(false, false)) { - MessageUtil.fail(messages, "can't update incremental file"); - } else if (!repeat) { // first incremental compile - incrementalCompileThread = new Thread( - new Runnable() { - public void run() { - ajcTask.execute(); - } - }, "AjcTaskCompileCommand-incremental"); - incrementalCompileThread.start(); - waitUntilMessagesQuiet(messages, 10, 180); - } else { - Thread thread = incrementalCompileThread; - if (null == thread) { - MessageUtil.fail(messages, "incremental process stopped"); - } else if (!thread.isAlive()) { - MessageUtil.fail(messages, "incremental process dead"); - } else { - waitUntilMessagesQuiet(messages, 10, 180); - } - } - } catch (BuildException e) { - Throwable t = e.getCause(); - while (t instanceof BuildException) { - t = ((BuildException) t).getCause(); - } - if (null == t) { - t = e; - } - MessageUtil.abort(messages, "BuildException " + e.getMessage(), t); - } finally { - MessageUtil.handleAll(handler, messages, false); - } - return (0 == messages.numMessages(IMessage.ERROR, true)); - } - - - protected boolean makeAjcTask(String[] args, IMessageHandler handler) { - ajcTask = null; - incrementalFile = null; - AjcTask result = null; - try { - result = new AjcTask(); - Project project = new Project(); - project.setName("AjcTaskCompileCommand"); - result.setProject(project); - result.setMessageHolder(messages); - // XXX argh - have to strip out "-incremental" - // because tools.ajc.Main privileges it over tagfile - ArrayList newArgs = new ArrayList(); - boolean incremental = false; - for (int i = 0; i < args.length; i++) { - if ("-incremental".equals(args[i])) { - incremental = true; - } else if ("-XincrementalFile".equals(args[i])) { - // CommandController.TAG_FILE_OPTION = "-XincrementalFile"; - incremental = true; - i++; - } else { - newArgs.add(args[i]); - } - } - if (incremental) { - args = (String[]) newArgs.toArray(new String[0]); - } - - result.readArguments(args); - - if (incremental || result.isInIncrementalMode()) { - // these should be impossible... - if (result.isInIncrementalFileMode()) { - String m = "incremental file set in command"; - MessageUtil.fail(handler, m); - return false; - } else if (null != incrementalFile) { - String m = "incremental file set already"; - MessageUtil.fail(handler, m); - return false; - } - String prefix = "AjcTaskCompileCommand_makeAjcTask"; - File tmpDir = FileUtil.getTempDir(prefix); - incrementalFile = new File(tmpDir, "tagfile.tmp"); - boolean create = true; - boolean delete = false; - updateIncrementalFile(create, delete); - result.setTagFile(incrementalFile); - } - // do not throw BuildException on error - result.setFailonerror(false); - ajcTask = result; - } catch (BuildException e) { - MessageUtil.abort(handler,"setting up AjcTask", e); - } - return (null != ajcTask); - } - - protected boolean updateIncrementalFile(boolean create, boolean delete) { - File file = incrementalFile; - if (delete) { - try { - return (null == file) - || !file.exists() - || file.delete(); - } finally { - incrementalFile = null; - } - } - if (null == file) { - return false; - } - if (file.exists()) { - return file.setLastModified(System.currentTimeMillis()); - } else { - try { - return create && file.createNewFile(); - } catch (IOException e) { // XXX warn in verbose mode? - return false; - } - } - } - -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/AccumulatingFileFilter.java b/testing/src/main/java/org/aspectj/testing/util/AccumulatingFileFilter.java deleted file mode 100644 index e01f71874..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/AccumulatingFileFilter.java +++ /dev/null @@ -1,53 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.File; -import java.util.Vector; - -/** - * A FileFilter that accumulates the results when called if they exist. - * Subclasses override accumulate to determine whether it should be - * accumulated. - */ -public class AccumulatingFileFilter extends ValidFileFilter { - Vector files = new Vector(); - public final boolean accept(File f) { - if (super.accept(f) && (accumulate(f))) { - files.add(f); - } - return true; - } - - /** - * This implementation accumulates everything. - * Subclasses should override to implement filter - * @param file a File guaranteed to exist - * @return true if file should be accumulated. - */ - public boolean accumulate(File f) { - return true; - } - /** - * @return list of files currently accumulated - */ - public File[] getFiles() { - int numFiles = files.size(); - File[] result = new File[numFiles]; - if (0 < numFiles) { - files.copyInto(result); - } - return result; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/BridgeUtil.java b/testing/src/main/java/org/aspectj/testing/util/BridgeUtil.java deleted file mode 100644 index f06e93850..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/BridgeUtil.java +++ /dev/null @@ -1,517 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.File; -import java.util.Comparator; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.Message; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.bridge.SourceLocation; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.run.RunValidator; -import org.aspectj.util.FileUtil; - -/** - * - */ -public class BridgeUtil { - -// private static final String INDENT = " "; - - /** result value when writeMessage is passed null */ - private static final String NULL_MESSAGE_OUTPUT = "<null message output>"; - - /** result value when readMessage is passed null */ - private static final IMessage NULL_MESSAGE_INPUT = null; - - private static final String KIND_DELIM = ": \""; - private static final String MESSAGE_DELIM = "\" - "; - - - public static ISourceLocation makeSourceLocation(UtilLineReader reader) { - LangUtil.throwIaxIfNull(reader, "reader"); - int line = reader.getLineNumber(); - - return new SourceLocation(reader.getFile(), line, line, 0); - } - - - /** - * Method readSourceLocation. - * @param sourceLocStr - * @return ISourceLocation - */ - private static ISourceLocation readSourceLocation(String sourceLocStr) { - return BridgeUtil.makeSourceLocation(sourceLocStr); - } -// public static IMessage makeMessage(String message, IMessage.Kind kind, -// Throwable thrown, LineReader reader) { -// ISourceLocation sl = (null == reader ? null : MessageUtil.makeSourceLocation(reader)); -// if (null == kind) kind = IMessage.INFO; -// return new Message(message, kind, thrown, sl); -// } - - /** - * Read a message from a string written by writeMessage(IMessage). - * Does not handle exceptions at all or source location well. XXX - * @param message the String representation of a message - * @return IMessage - */ - public static IMessage readMessage(String message) { - if (null == message) { - return NULL_MESSAGE_INPUT; - } - if (NULL_MESSAGE_OUTPUT.equals(message)) { - return null; - } - int kindEnd = message.indexOf(KIND_DELIM); - int messageEnd = message.indexOf(MESSAGE_DELIM); - int messageStart = kindEnd+KIND_DELIM.length(); - int sourceLocStart = messageEnd+MESSAGE_DELIM.length(); - String kindStr = message.substring(0, kindEnd); - String text = message.substring(messageStart, messageEnd); - String sourceLocStr = message.substring(sourceLocStart); - IMessage.Kind kind = MessageUtil.getKind(kindStr); - ISourceLocation loc = readSourceLocation(sourceLocStr); - return new Message(text, kind, null, loc); - } - - - /** - * Write a message to a string to be read by readMessage(String) - * @param message the String representation of a message - * @return IMessage - */ - public static String writeMessage(IMessage message) { - if (null == message) { - return NULL_MESSAGE_OUTPUT; - } - return message.getKind() - + KIND_DELIM - + message.getMessage() - + MESSAGE_DELIM - + message.getSourceLocation(); // XXX implement - } - - - public static class Comparators { - /** - * Compare based solely on null-inequality: - * -1 if one is not null and two is null, - * 1 if one is null and two is not null, - * 0 otherwise. - */ - static int compareNull(Object one, Object two) { - return (null == one - ? (null == two ? 0 : 1) - : (null == two ? -1 : 0)); - } - - /** - * Soft comparison of String returns 0 if either is empty - * or a substring of the other, and the case-insensitive - * ordering otherwise. - * @param lhs_s - * @param rhs_s - * @return - */ - static int compareStringsSoftly(String lhs_s, String rhs_s) { - if (LangUtil.isEmpty(lhs_s) - || LangUtil.isEmpty(rhs_s)) { - return 0; - } - if ((-1 != lhs_s.indexOf(rhs_s)) - || (-1 != rhs_s.indexOf(lhs_s))) { - return 0; - } - return String.CASE_INSENSITIVE_ORDER.compare(lhs_s, rhs_s); - } - - /** - * This returns 0 if one file path is a suffix of the other - * or a case-insensitive string comparison otherwise. - * WARNING: it returns 0 if either file is - * ISourceLocation.NO_FILE to permit tests to - * not specify file paths. - * - * Use only for sorts, not to maintain maps. - */ - public static final Comparator WEAK_File = new Comparator() { - public int compare(Object o1, Object o2) { - if ((o1 == o2) - || (o1 == ISourceLocation.NO_FILE) - || (o2 == ISourceLocation.NO_FILE) ) { - return 0; - } - int result = compareNull(o1, o2); - if (0 != result) { - return result; - } - File one = (File) o1; - File two = (File) o2; - String s1 = one.getPath(); - String s2 = two.getPath(); - // check if normalize needed - if (s1.endsWith(s2) || s2.endsWith(s1)) { - return 0; - } - s1 = FileUtil.weakNormalize(s1); - s2 = FileUtil.weakNormalize(s2); - if (s1.endsWith(s2) || s2.endsWith(s1)) { - return 0; - } - return String.CASE_INSENSITIVE_ORDER.compare(s1, s2); - - } - }; - /** - * Ordering only uses line number. - * Use only for sorts, not to maintain maps. - */ - public static final Comparator WEAK_ISourceLocation = new Comparator() { - public int compare(Object o1, Object o2) { - if (o1 == o2) { - return 0; - } - int result = compareNull(o1, o2); - if (0 != result) { - return result; - } - ISourceLocation one = (ISourceLocation) o1; - ISourceLocation two = (ISourceLocation) o2; - int i1 = one.getLine(); - int i2 = two.getLine(); - return i1 - i2; - } - }; - - /** - * Like WEAK_ISourceLocation, except it also - * uses WEAK_FILE on the sourceFile. - * Use only for sorts, not to maintain maps. - */ - public static final Comparator MEDIUM_ISourceLocation = new Comparator() { - public int compare(Object o1, Object o2) { - int result = WEAK_ISourceLocation.compare(o1, o2); - if (0 != result) { - return result; - } - ISourceLocation one = (ISourceLocation) o1; - ISourceLocation two = (ISourceLocation) o2; - result = compareNull(one, two); - if (0 != result) { // one but not other is null - return result; - } - if (null == one) { // both null - return 0; - } - // neither null - return WEAK_File.compare(one.getSourceFile(), two.getSourceFile()); - } - }; - - /** - * Ordering uses kind and weak source location, - * and ignores message - * so use only for sorts, not to maintain maps - */ - public static final Comparator WEAK_IMessage = new Comparator() { - public int compare(Object o1, Object o2) { - if (o1 == o2) { - return 0; - } - int result = compareNull(o1, o2); - if (0 != result) { - return result; - } - IMessage one = (IMessage) o1; - IMessage two = (IMessage) o2; - IMessage.Kind kind1 = one.getKind(); - IMessage.Kind kind2= two.getKind(); - result = IMessage.Kind.COMPARATOR.compare(kind1, kind2); - if (0 != result) { - return result; - } - ISourceLocation sl1 = one.getSourceLocation(); - ISourceLocation sl2 = two.getSourceLocation(); - return WEAK_ISourceLocation.compare(sl1, sl2); - } - }; - - /** - * Ordering uses line and weak filename and message - * (message matches if either is a substring of the other, - * or if either is empty, i.e., none specified). - * so use only for sorts, not to maintain maps - */ - public static final Comparator MEDIUM_IMessage = new Comparator() { - public int compare(Object o1, Object o2) { - int result = WEAK_IMessage.compare(o1, o2); - if (0 != result) { - return result; - } - IMessage rhs_m= (IMessage) o1; - IMessage lhs_m = (IMessage) o2; - ISourceLocation rhs_sl = rhs_m.getSourceLocation(); - ISourceLocation lhs_sl = lhs_m.getSourceLocation(); - result = MEDIUM_ISourceLocation.compare(lhs_sl, rhs_sl); - if (0 != result) { - return result; - } - String lhs_s =lhs_m.getMessage(); - String rhs_s = rhs_m.getMessage(); - return compareStringsSoftly(lhs_s, rhs_s); - } - }; -} - public static SourceLocation makeSourceLocation(String input) { // XXX only for testing, not production - return makeSourceLocation(input, (File) null); - } - - public static SourceLocation makeSourceLocation(String input, String path) { - return makeSourceLocation(input, (null == path ? null : new File(path))); - } - - /** attempt to create a source location from the input */ - public static SourceLocation makeSourceLocation(String input, File defaultFile) { - /* - * Forms interpreted: - * # - line - * file - file - * file:# - file, line - * #:# - if defaultFile is not null, then file, line, column - * file:#:# - file, line, column - * file:#:#:? - file, line, column, message - */ -// SourceLocation result = null; - if ((null == input) || (0 == input.length())) { - if (null == defaultFile) { - return null; - } else { - return new SourceLocation(defaultFile, 0, 0, 0); - } - } - input = input.trim(); - - String path = null; - int line = 0; - int endLine = 0; - int column = 0; -// String message = null; - - // first try line only - line = convert(input); - if (-1 != line) { - return new SourceLocation(defaultFile, line, line, 0); - } - - // if not a line - must be > 2 characters - if (3 > input.length()) { - return null; // throw new IllegalArgumentException("too short: " + input); - } - final String fixTag = "FIXFIX"; - if (input.charAt(1) == ':') { // windows drive ambiguates ":" file:line:col separator - input = fixTag + input.substring(0,1) + input.substring(2); - } - // expecting max: path:line:column:message - // if 1 colon, delimits line (to second colon or end of string) - // if 2 colon, delimits column (to third colon or end of string) - // if 3 colon, delimits column (to fourth colon or end of string) - // todo: use this instead?? - final int colon1 = input.indexOf(":",2); // 2 to get past windows drives... - final int colon2 = (-1 == colon1?-1:input.indexOf(":", colon1+1)); - final int colon3 = (-1 == colon2?-1:input.indexOf(":", colon2+1)); - String s; - if (-1 == colon1) { // no colon; only path (number handled above) - path = input; - } else { // 1+ colon => file:line // XXX later or line:column - path = input.substring(0, colon1); - s = input.substring(colon1+1,(-1!=colon2?colon2:input.length())).trim(); - line = convert(s); - if (-1 == line) { - return null; - //line = "expecting line(number) at \"" + line + "\" in " + input; - //throw new IllegalArgumentException(line); - } else if (-1 != colon2) { // 2+ colon => col - s = input.substring(colon2+1,(-1!=colon3?colon3:input.length())).trim(); - column = convert(s); - if (-1 == column) { - return null; - //col = "expecting col(number) at \"" + col + "\" in " + input; - //throw new IllegalArgumentException(col); - } else if (-1 != colon3) { // 3 colon => message - input.substring(colon3+1); // do not trim message - } - } - } - - if (path.startsWith(fixTag)) { - int len = fixTag.length(); - path = path.substring(len, 1+len) + ":" + - path.substring(1+len); - } - if ((endLine == 0) && (line != 0)) { - endLine = line; - } - // XXX removed message/comment - return new SourceLocation(new File(path), line, endLine, column); - } - - // XXX reconsider convert if used in production code - /** - * Convert String to int using ascii and optionally - * tolerating text - * @param s the String to convert - * @param permitText if true, pick a sequence of numbers - * within a possibly non-numeric String - * @param last if permitText, then if this is true the - * last sequence is used - otherwise the first is used - * XXX only default u.s. encodings.. - * @return -1 or value if a valid, totally-numeric positive string 0..MAX_WIDTH - */ - private static int convert(String s) { - return convert(s, false, false); - } - - // XXX reconsider convert if used in production code - /** - * Convert String to int using ascii and optionally - * tolerating text - * @param s the String to convert - * @param permitText if true, pick a sequence of numbers - * within a possibly non-numeric String - * @param last if permitText, then if this is true the - * last sequence is used - otherwise the first is used - * XXX only default u.s. encodings.. - * @return -1 or value if a valid, positive string 0..MAX_WIDTH - */ - private static int convert(String s, boolean permitText, - boolean first) { - int result = -1; - int last = -1; - int max = s.length(); - boolean reading = false; - for (int i = 0; i < max; i++) { - char c = s.charAt(i); - if ((c >= '0') && (c <= '9')) { - if (-1 == result) { // prefix loop - result = 0; - reading = true; - } - result = ((result * 10) + (c - '0')); - } else if (!permitText) { - return -1; - } else if (reading) { // from numeric -> non-numeric - if (first) { - return result; - } else { - last = result; - } - reading = false; - } - } - if (permitText && !first && (-1 != last) && (-1 == result)) { - result = last; - } - return ((0 < result) && (result < ISourceLocation.MAX_LINE) ? result : -1); - } - - private BridgeUtil() {} - - /** @return String for status header, counting children passed/failed */ - public static String childString(IRunStatus runStatus, int numSkips, int numIncomplete) { - if (null == runStatus) { - return "((RunStatus) null)"; - } - if (0 > numSkips) { - numSkips = 0; - } - if (0 > numIncomplete) { - numIncomplete = 0; - } - StringBuffer sb = new StringBuffer(); - if (RunValidator.NORMAL.runPassed(runStatus)) { - sb.append("PASS "); - } else { - sb.append("FAIL "); - } - Object id = runStatus.getIdentifier(); - if (null != id) { - sb.append(id.toString() + " "); - } - IRunStatus[] children = runStatus.getChildren(); - final int numChildren = (null == children ? 0 : children.length); - final int numTests = numIncomplete + numChildren + numSkips; - int numFails = 0; - if (!LangUtil.isEmpty(children)) { - for (int i = 0; i < children.length; i++) { - if (!RunValidator.NORMAL.runPassed(children[i])) { - numFails++; - } - } - } - final int numPass = children.length - numFails; - sb.append(numTests + " tests"); - if (0 < numTests) { - sb.append(" ("); - } - if (0 < numSkips) { - sb.append(numSkips + " skipped"); - if (0 < (numFails + numPass + numIncomplete)) { - sb.append(", "); - } - } - if (0 < numIncomplete) { - sb.append(numIncomplete + " incomplete"); - if (0 < (numFails + numPass)) { - sb.append(", "); - } - } - if (0 < numFails) { - sb.append(numFails + " failed"); - if (0 < numPass) { - sb.append(", "); - } - } - if (0 < numPass) { - sb.append(numPass + " passed)"); - } else if (0 < numTests) { - sb.append(")"); - } - return sb.toString().trim(); - } - - /** @return String for status header */ - public static String toShortString(IRunStatus runStatus) { - if (null == runStatus) { - return "((RunStatus) null)"; - } - StringBuffer sb = new StringBuffer(); - if (RunValidator.NORMAL.runPassed(runStatus)) { - sb.append("PASS "); - } else { - sb.append("FAIL "); - } - Object id = runStatus.getIdentifier(); - if (null != id) { - sb.append(id.toString() + " "); - } - sb.append(MessageUtil.renderCounts(runStatus)); - return sb.toString().trim(); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/util/CollectorFileFilter.java b/testing/src/main/java/org/aspectj/testing/util/CollectorFileFilter.java deleted file mode 100644 index 7c63c3b6c..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/CollectorFileFilter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Wrap FileFilter to collect any accepted - */ -public class CollectorFileFilter implements FileFilter { - /** returned from getFiles() when there are no files to get */ - public static final List EMPTY - = Collections.unmodifiableList(new ArrayList(0)); - - /** used for collecting filters */ - protected ArrayList files; - - /** filter delegate - may be null */ - protected final FileFilter filter; - - /** return false from accept only when !alwaysTrue - * and filter is null or fails - */ - protected final boolean alwaysTrue; - - /** this(null, true) */ - public CollectorFileFilter() { - this(null, true); - } - - /* - * @param filter the FileFilter delegate - may be null - * @param alwaysTrue return false from accept only when !alwaysTrue - * and filter is null or fails - */ - public CollectorFileFilter(FileFilter filter, boolean alwaysTrue){ - this.filter = filter; - this.alwaysTrue = alwaysTrue; - } - - /** - * Accept file into collection if filter is null or passes. - * @return false only when !alwaysTrue and filter fails. - */ - public boolean accept(File f) { - if ((null == filter) || filter.accept(f)) { - add(f); - return true; - } - return alwaysTrue; - } - - /** gather files */ - protected synchronized void add(File f) { - if (null != f) { - if (null == files) { - files = new ArrayList(); - } - files.add(f); - } - } - - /** - * return clone of gathered-files - * @return EMPTY if no files or a clone of the collection otherwise - */ - public synchronized List getFiles() { - if ((null == files) || (0 == files.size())) { - return EMPTY; - } - return (List) files.clone(); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/Diffs.java b/testing/src/main/java/org/aspectj/testing/util/Diffs.java deleted file mode 100644 index a6edf0d87..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/Diffs.java +++ /dev/null @@ -1,547 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.File; -import java.util.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.util.FileUtil; -import org.aspectj.util.LangUtil; - -/** - * Result struct for expected/actual diffs for Collection - */ -public class Diffs { - - /** - * Compare IMessage.Kind based on kind priority. - */ - public static final Comparator KIND_PRIORITY = new Comparator() { - /** - * Compare IMessage.Kind based on kind priority. - * @throws NullPointerException if anything is null - */ - public int compare(Object lhs, Object rhs) { - return ((IMessage.Kind) lhs).compareTo((IMessage.Kind) rhs); - } - }; - /** - * Sort ISourceLocation based on line, file path. - */ - public static final Comparator SORT_SOURCELOC = new Comparator() { - /** - * Compare ISourceLocation based on line, file path. - * @throws NullPointerException if anything is null - */ - public int compare(Object lhs, Object rhs) { - ISourceLocation l = (ISourceLocation) lhs; - ISourceLocation r = (ISourceLocation) rhs; - int result = getLine(l) - getLine(r); - if (0 != result) { - return result; - } - String lp = getSourceFile(l).getPath(); - String rp = getSourceFile(r).getPath(); - return lp.compareTo(rp); - } - }; - - /** - * Compare IMessages based on kind and source location line (only). - */ - public static final Comparator MESSAGE_LINEKIND = new Comparator() { - /** - * Compare IMessages based on kind and source location line (only). - * @throws NullPointerException if anything is null - */ - public int compare(Object lhs, Object rhs) { - IMessage lm = (IMessage) lhs; - IMessage rm = (IMessage) rhs; - ISourceLocation ls = (lm == null ? null : lm.getSourceLocation()); - ISourceLocation rs = (rm == null ? null : rm.getSourceLocation()); - int left = (ls == null ? -1 : ls.getLine()); - int right = (rs == null ? -1 : rs.getLine()); - int result = left - right; - if (0 == result) { - result = lm.getKind().compareTo(rm.getKind()); - } - return result; - } - }; - public static final Filter ACCEPT_ALL = new Filter() { - public boolean accept(Object o) { - return true; - } - }; - // // XXX List -> Collection b/c comparator orders - // public static final Diffs NONE - // = new Diffs("NONE", Collections.EMPTY_LIST, Collections.EMPTY_LIST); - - public static Diffs makeDiffs( - String label, - List expected, - List actual, - Comparator comparator) { - return makeDiffs( - label, - expected, - actual, - comparator, - ACCEPT_ALL, - ACCEPT_ALL); - } - - public static Diffs makeDiffs( - String label, - IMessage[] expected, - IMessage[] actual) { - return makeDiffs(label, expected, actual, null, null); - } - - private static int getLine(ISourceLocation loc) { - int result = -1; - if (null != loc) { - result = loc.getLine(); - } - return result; - } - private static int getLine(IMessage message) { - int result = -1; - if ((null != message)) { - result = getLine(message.getSourceLocation()); - } - return result; - } - - private static File getSourceFile(ISourceLocation loc) { - File result = ISourceLocation.NO_FILE; - if (null != loc) { - result = loc.getSourceFile(); - } - return result; - } - - public static Diffs makeDiffs( - String label, - IMessage[] expected, - IMessage[] actual, - IMessage.Kind[] ignoreExpectedKinds, - IMessage.Kind[] ignoreActualKinds) { - ArrayList exp = getExcept(expected, ignoreExpectedKinds); - ArrayList act = getExcept(actual, ignoreActualKinds); - - ArrayList missing = new ArrayList(); - List unexpected = new ArrayList(); - - if (LangUtil.isEmpty(expected)) { - unexpected.addAll(act); - } else if (LangUtil.isEmpty(actual)) { - missing.addAll(exp); - } else { - ListIterator expectedIterator = exp.listIterator(); - int lastLine = Integer.MIN_VALUE + 1; - ArrayList expectedFound = new ArrayList(); - ArrayList expectedForLine = new ArrayList(); - for (ListIterator iter = act.listIterator(); iter.hasNext();) { - IMessage actualMessage = (IMessage) iter.next(); - int actualLine = getLine(actualMessage); - if (actualLine != lastLine) { - // new line - get all messages expected for it - if (lastLine > actualLine) { - throw new Error("sort error"); - } - lastLine = actualLine; - expectedForLine.clear(); - while (expectedIterator.hasNext()) { - IMessage curExpected = - (IMessage) expectedIterator.next(); - int curExpectedLine = getLine(curExpected); - if (actualLine == curExpectedLine) { - expectedForLine.add(curExpected); - } else { - expectedIterator.previous(); - break; - } - } - } - // now check actual against all expected on that line - boolean found = false; - IMessage expectedMessage = null; - for (Iterator iterator = expectedForLine.iterator(); - !found && iterator.hasNext(); - ) { - expectedMessage = (IMessage) iterator.next(); - found = expectingMessage(expectedMessage, actualMessage); - } - if (found) { - iter.remove(); - if (expectedFound.contains(expectedMessage)) { - // XXX warn: expected message matched two actual - } else { - expectedFound.add(expectedMessage); - } - } else { - // unexpected: any actual result not found - unexpected.add(actualMessage); - } - } - // missing: all expected results not found - exp.removeAll(expectedFound); - missing.addAll(exp); - } - return new Diffs(label, missing, unexpected); - } - - public static Diffs makeDiffs( - String label, - List expected, - List actual, - Comparator comparator, - Filter missingFilter, - Filter unexpectedFilter) { - label = label.trim(); - if (null == label) { - label = ": "; - } else if (!label.endsWith(":")) { - label += ": "; - } - final String thisLabel = " " + label; - ArrayList miss = new ArrayList(); - ArrayList unexpect = new ArrayList(); - - org.aspectj.testing.util.LangUtil.makeSoftDiffs( - expected, - actual, - miss, - unexpect, - comparator); - if (null != missingFilter) { - for (ListIterator iter = miss.listIterator(); iter.hasNext();) { - if (!missingFilter.accept(iter.next())) { - iter.remove(); - } - } - } - if (null != unexpectedFilter) { - for (ListIterator iter = unexpect.listIterator(); - iter.hasNext(); - ) { - if (!unexpectedFilter.accept(iter.next())) { - iter.remove(); - } - } - } - return new Diffs(thisLabel, miss, unexpect); - } - - // /** - // * Shift over elements in sink if they are of one of the specified kinds. - // * @param sink the IMessage[] to shift elements from - // * @param kinds - // * @return length of sink after shifting - // * (same as input length if nothing shifted) - // */ - // public static int removeKinds(IMessage[] sink, IMessage.Kind[] kinds) { - // if (LangUtil.isEmpty(kinds)) { - // return sink.length; - // } else if (LangUtil.isEmpty(sink)) { - // return 0; - // } - // int from = -1; - // int to = -1; - // for (int j = 0; j < sink.length; j++) { - // from++; - // if (null == sink[j]) { - // continue; - // } - // boolean remove = false; - // for (int i = 0; !remove && (i < kinds.length); i++) { - // IMessage.Kind kind = kinds[i]; - // if (null == kind) { - // continue; - // } - // if (0 == kind.compareTo(sink[j].getKind())) { - // remove = true; - // } - // } - // if (!remove) { - // to++; - // if (to != from) { - // sink[to] = sink[from]; - // } - // } - // } - // return to+1; - // } - - /** - * @param expected the File from the expected source location - * @param actual the File from the actual source location - * @return true if exp is ISourceLocation.NO_FILE - * or exp path is a suffix of the actual path - * (after using FileUtil.weakNormalize(..) on both) - */ - static boolean expectingFile(File expected, File actual) { - if (null == expected) { - return (null == actual); - } else if (null == actual) { - return false; - } - if (expected != ISourceLocation.NO_FILE) { - String expPath = FileUtil.weakNormalize(expected.getPath()); - String actPath = FileUtil.weakNormalize(actual.getPath()); - if (!actPath.endsWith(expPath)) { - return false; - } - } - return true; - } - - /** - * Soft comparison for expected message will not check a corresponding - * element in the actual message unless defined in the expected message. - * <pre> - * message - * kind must match (constant/priority) - * message only requires substring - * thrown ignored - * column ignored - * endline ignored - * details only requires substring - * sourceLocation - * line must match, unless expected < 0 - * file ignored if ISourceLocation.NOFILE - * matches if expected is a suffix of actual - * after changing any \ to / - * extraSourceLocation[] - * if any are defined in expected, then there - * must be exactly the actual elements as are - * defined in expected (so it is an error to - * not define all if you define any) - * <pre> - * @param expected - * @param actual - * @return true if we are expecting the line, kind, file, message, - * details, and any extra source locations. - * (ignores column/endline, thrown) XXX - */ - static boolean expectingMessage(IMessage expected, IMessage actual) { - if (null == expected) { - return (null == actual); - } else if (null == actual) { - return false; - } - if (0 != expected.getKind().compareTo(actual.getKind())) { - return false; - } - if (!expectingSourceLocation(expected.getSourceLocation(), - actual.getSourceLocation())) { - return false; - } - if (!expectingText(expected.getMessage(), actual.getMessage())) { - return false; - } - if (!expectingText(expected.getDetails(), actual.getDetails())) { - return false; - } - ISourceLocation[] esl = - (ISourceLocation[]) expected.getExtraSourceLocations().toArray( - new ISourceLocation[0]); - ISourceLocation[] asl = - (ISourceLocation[]) actual.getExtraSourceLocations().toArray( - new ISourceLocation[0]); - - Arrays.sort(esl, SORT_SOURCELOC); - Arrays.sort(asl, SORT_SOURCELOC); - if (!expectingSourceLocations(esl, asl)) { - return false; - } - return true; - } - - /** - * This returns true if no ISourceLocation are specified - * (i.e., it ignored any extra source locations if no expectations stated). - * XXX need const like NO_FILE. - * @param expected the sorted ISourceLocation[] expected - * @param expected the actual sorted ISourceLocation[] - * @return true if any expected element is expected by the corresponding actual element. - */ - static boolean expectingSourceLocations( - ISourceLocation[] expected, - ISourceLocation[] actual) { - if (LangUtil.isEmpty(expected)) { - return true; - } else if (LangUtil.isEmpty(actual)) { - return false; - } else if (actual.length != expected.length) { - return false; - } - for (int i = 0; i < actual.length; i++) { - if (!expectingSourceLocation(expected[i], actual[i])) { - return false; - } - } - - return true; - } - - /** - * @param expected - * @param actual - * @return true if any expected line/file matches the actual line/file, - * accepting a substring as a file match - */ - static boolean expectingSourceLocation( - ISourceLocation expected, - ISourceLocation actual) { - int eline = getLine(expected); - int aline = getLine(actual); - if ((-1 < eline) && (eline != aline)) { - return false; - } - if (!expectingFile(getSourceFile(expected), getSourceFile(actual))) { - return false; - } - return true; - } - - /** - * @param expected the String in the expected message - * @param actual the String in the actual message - * @return true if both are null or actual contains expected - */ - static boolean expectingText(String expected, String actual) { - if (null == expected) { - return true; // no expectations - } else if (null == actual) { - return false; // expected something - } else { - return (-1 != actual.indexOf(expected)); - } - } - - private static ArrayList getExcept( - IMessage[] source, - IMessage.Kind[] skip) { - ArrayList sink = new ArrayList(); - if (LangUtil.isEmpty(source)) { - return sink; - } - - if (LangUtil.isEmpty(skip)) { - sink.addAll(Arrays.asList(source)); - Collections.sort(sink, MESSAGE_LINEKIND); - return sink; - } - for (int i = 0; i < source.length; i++) { - IMessage message = source[i]; - IMessage.Kind mkind = message.getKind(); - boolean skipping = false; - for (int j = 0; !skipping && (j < skip.length); j++) { - if (0 == mkind.compareTo(skip[j])) { - skipping = true; - } - } - if (!skipping) { - sink.add(message); - } - } - Collections.sort(sink, MESSAGE_LINEKIND); - return sink; - } - - private static List harden(List list) { - return ( - LangUtil.isEmpty(list) - ? Collections.EMPTY_LIST - : Collections.unmodifiableList(list)); - } - - /** name of the thing being diffed - used only for reporting */ - public final String label; - - /** immutable List */ - public final List missing; - - /** immutable List */ - public final List unexpected; - - /** true if there are any missing or unexpected */ - public final boolean different; - - /** - * Struct-constructor stores these values, - * wrapping the lists as unmodifiable. - * @param label the String label for these diffs - * @param missing the List of missing elements - * @param unexpected the List of unexpected elements - */ - public Diffs(String label, List missing, List unexpected) { - this.label = label; - this.missing = harden(missing); - this.unexpected = harden(unexpected); - different = - ((0 != this.missing.size()) || (0 != this.unexpected.size())); - } - - /** - * Report missing and extra items to handler. - * For each item in missing or unexpected, this creates a {kind} IMessage with - * the text "{missing|unexpected} {label}: {message}" - * where {message} is the result of - * <code>MessageUtil.renderMessage(IMessage)</code>. - * @param handler where the messages go - not null - * @param kind the kind of message to construct - not null - * @param label the prefix for the message text - if null, "" used - * @see MessageUtil#renderMessage(IMessage) - */ - public void report(IMessageHandler handler, IMessage.Kind kind) { - LangUtil.throwIaxIfNull(handler, "handler"); - LangUtil.throwIaxIfNull(kind, "kind"); - if (different) { - for (Iterator iter = missing.iterator(); iter.hasNext();) { - String s = MessageUtil.renderMessage((IMessage) iter.next()); - MessageUtil.fail(handler, "missing " + label + ": " + s); - } - for (Iterator iter = unexpected.iterator(); iter.hasNext();) { - String s = MessageUtil.renderMessage((IMessage) iter.next()); - MessageUtil.fail(handler, "unexpected " + label + ": " + s); - } - } - } - - /** @return "{label}: (unexpected={#}, missing={#})" */ - public String toString() { - return label - + "(unexpected=" - + unexpected.size() - + ", missing=" - + missing.size() - + ")"; - } - public static interface Filter { - /** @return true to keep input in list of messages */ - boolean accept(Object input); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/FileUtil.java b/testing/src/main/java/org/aspectj/testing/util/FileUtil.java deleted file mode 100644 index db77cbd10..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/FileUtil.java +++ /dev/null @@ -1,745 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringBufferInputStream; -import java.io.StringWriter; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Vector; -import java.util.jar.Attributes; -import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -/** - * misc file utilities - */ -public class FileUtil { - - /** default filename if URL has none (i.e., a directory URL): index.html */ - public static final String DEFAULT_URL_FILENAME = "index.html"; - - /** - * @param args the String[] - * <code>{ "-copy", "-srcFile" | "-srcUrl", {src}, "-destFile", {destFile} }</code> - */ - public static void main (String[] args) { - if (null == args) return; - for (int i = 0; (i+4) < args.length; i++) { - if ("-copy".equals(args[i])) { - String arg = args[++i]; - String src = null; - String destFile = null; - boolean srcIsFile = ("-srcFile".equals(arg)); - if (srcIsFile) { - src = args[++i]; - } else if ("-srcUrl".equals(arg)) { - src = args[++i]; - } - if ((null != src) && ("-destFile".equals(args[++i]))) { - destFile = args[++i]; - StringBuffer errs = new StringBuffer(); - if (srcIsFile) { - copyFile(new File(src), new File(destFile), errs); - } else { - URL url = null; - try { url = new URL(src) ; } - catch (MalformedURLException e) { render(e, errs); } - if (null != url) { - copyURL(url, new File(destFile), errs); - } - } - if (0 < errs.length()) { - System.err.println("Error copying " + src + " to " + destFile); - System.err.println(errs.toString()); - - } - } - } // ("-copy".equals(args[i])){ - } - } // end of main () - - /** - * Generate a list of missing and extra files by comparison to a - * timestamp, optionally excluding certain files. - * This is a call to select all files after a given time: - * - * <pre>Diffs d = dirDiffs(dir, givenTime, null, null, null);</pre> - * - * Given files - * <pre>classes/Foo.class - * classes/bar/Bash.class - * classes/Old.class - * classes/one/Unexpected.class - * classes/start.gif</pre> - * where only Old.class predated startTime, this is a call that - * reports "one/Unexpected.class" as unexpected and "Foo" - * as missing: - * <pre>String requireSuffix = ".class"; - * String[] expectedPaths = new String[] { "Foo", "bar/Bas" }; - * File file = new File("classes"); - * Diffs d = dirDiffs(dir, startTime, requireSuffix,expectedPaths, true);</pre> - * - * @param label the String to use for the Diffs label - * @param dir the File for the dir to search - * @param startTime collect files modified after this time - * (ignored if less than 0) - * @param requireSuffix ignore all actual files without this suffix - * (ignored if null) - * @param expectedPaths paths (relative to dir) of the expected files - * (if null, none expected) - * @param acceptFilePrefix if true, then accept a file which - * differs from an expected file name only by a suffix - * (which need not begin with "."). - */ - public static Diffs dirDiffs( // XXX too complicated, weak prefix checking - final String label, - final File dir, - final long startTime, - final String requiredSuffix, - final String[] expectedPaths, - final boolean acceptFilePrefix) { - - LangUtil.throwIaxIfNull(dir, "dir"); - final boolean checkExpected = !LangUtil.isEmpty(expectedPaths); - - // normalize sources to ignore - final ArrayList expected = (!checkExpected ? null : new ArrayList()); - if (checkExpected) { - for (int i = 0; i < expectedPaths.length; i++) { - String srcPath = expectedPaths[i]; - if (!LangUtil.isEmpty(srcPath)) { - expected.add(org.aspectj.util.FileUtil.weakNormalize(srcPath)); - } - } - } - - // gather, normalize paths changed - FileFilter touchedCollector = new FileFilter() { - /** - * For files complying with time and suffix rules, - * return true (accumulate - unexpected) - * unless they match expected files, - * (deleting any matches from sources - * so the remainder is missing). - * @return true for unexpected files after date */ - public boolean accept(File file) { - if (file.isFile() - && ((0 > startTime) - || (startTime < file.lastModified()))) { - String path = file.getPath(); - if ((null == requiredSuffix) || path.endsWith(requiredSuffix)) { - path = org.aspectj.util.FileUtil.weakNormalize(path); - if (checkExpected) { - if (!acceptFilePrefix) { - // File.equals(..) does lexical compare - if (expected.contains(path)) { - expected.remove(path); - // found - do not add to unexpected - return false; - } - } else { - for (Iterator iter = expected.iterator(); - iter.hasNext(); - ) { - String exp = (String) iter.next(); - if (path.startsWith(exp)) { - String suffix = path.substring(exp.length()); - if (-1 == suffix.indexOf("/")) { // normalized... - expected.remove(path); - // found - do not add to unexpected - return false; - } - } - } - } - } - // add if is file, right time, and have or don't need suffix - return true; - } - } - // skip if not file or not right time - return false; - } - }; - ArrayList unexp = new ArrayList(); - unexp.addAll(Arrays.asList(dir.listFiles(touchedCollector))); - - // report any unexpected changes - return Diffs.makeDiffs(label, expected, unexp, String.CASE_INSENSITIVE_ORDER); - } - - - /** - * Visit the entries in a zip file, halting when visitor balks. - * Errors are silently ignored. - * @throws IllegalArgumentException if zipfile or visitor is null - */ - public static void visitZipEntries(ZipFile zipfile, StringVisitor visitor) { - visitZipEntries(zipfile, visitor, (StringBuffer) null); - } - - /** - * Visit the entries in a zip file, halting when visitor balks. - * Errors are reported in errs, if not null. - * @throws IllegalArgumentException if zipfile or visitor is null - */ - public static void visitZipEntries(ZipFile zipfile, StringVisitor visitor, - StringBuffer errs) { - if (null == zipfile) throw new IllegalArgumentException("null zipfile"); - if (null == visitor) throw new IllegalArgumentException("null visitor"); - int index = 0; - try { - Enumeration enu = zipfile.entries(); - while (enu.hasMoreElements()) { - ZipEntry entry = (ZipEntry) enu.nextElement(); - index++; - if (! visitor.accept(entry.getName())) { - break; - } - } - } catch (Throwable e) { - if (null != errs) { - errs.append("FileUtil.visitZipEntries error accessing entry " + index - + ": " + e.getMessage()); - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - errs.append(sw.toString()); - } - } finally { - if (null != zipfile) { - try { zipfile.close(); } - catch (IOException x) {} // ignore - } - } - } - - /** - * descend filesystem tree, invoking FileFilter.accept() on files. - * E.g., To list files from current directory: - * <code><pre>descendFileTree(new File("."), new FileFilter() { - * public boolean accept(File f){ - * System.out.println(f.getAbsolutePath()); - * return true; - * }});</code></pre> - * @param file root/starting point. If a file, the only one visited. - * @param filter supplies accept(File) routine - */ - public static void descendFileTree(File file, FileFilter filter) { - descendFileTree(file, filter, false); - } - - /** - * Descend filesystem tree, invoking FileFilter.accept() on files - * and, if userRecursion, on dirs. If userRecursion, accept() must - * call descendFileTree() again to recurse down directories. - * This calls fileFilter.accept(File) on all files before doing any dirs. - * E.g., To list only files from Unix root: - * <code><pre>descendFileTree(new File("/"), new FileFilter() { - * public boolean run(File f){ - * System.out.println(f.getAbsolutePath()); - * return true; - * }}, false);</code></pre> - * To list files/dir from root using user recursion: - * <code><pre>descendFileTree(new File("/"), new FileFilter() { - * public boolean run(File f){ - * System.out.println(f.getAbsolutePath()); - * if (f.isDirectory() && (-1 == f.getName().indexOf("CVS"))) - * return descendFileTree(f, this, true); - * return true; - * }}, true);</code></pre> - * @param file root/starting point. If a file, the only one visited. - * @param filter supplies boolean accept(File) method - * @param userRecursion - if true, do accept() on dirs; else, recurse - * @return false if any fileFilter.accept(File) did. - * @throws IllegalArgumentException if file or fileFilter is null - */ - public static boolean descendFileTree(File file, FileFilter fileFilter, - boolean userRecursion) { - if (null == file) {throw new IllegalArgumentException("parm File"); } - if (null == fileFilter){throw new IllegalArgumentException("parm FileFilter");} - - if (!file.isDirectory()) { - return fileFilter.accept(file); - } else if (file.canRead()) { - // go through files first - File[] files = file.listFiles(ValidFileFilter.FILE_EXISTS); - if (null != files) { - for (int i = 0; i < files.length; i++) { - if (!fileFilter.accept(files[i])) { - return false; - } - } - } - // now recurse to handle directories - File[] dirs = file.listFiles(ValidFileFilter.DIR_EXISTS); - if (null != dirs) { - for (int i = 0; i < dirs.length; i++) { - if (userRecursion) { - if (!fileFilter.accept(dirs[i])) { - return false; - } - } else { - if (!descendFileTree(dirs[i], fileFilter,userRecursion)) { - return false; - } - } - } - } - } // readable directory (ignore unreadable ones) - return true; - } // descendFiles - - /** - * Return the names of all files below a directory. - * If file is a directory, then all files under the directory - * are returned. If file is absolute or relative, all the files are. - * If file is a zip or jar file, then all entries in the zip or jar - * are listed. Entries inside those jarfiles/zipfiles are not listed. - * There are no guarantees about ordering. - * @param dir the File to list for - * @param results the Collection to use for the results (may be null) - * @throws IllegalArgumentException if null == dir - * @return a Collection of String of paths, including paths inside jars - */ - public static Collection directoryToString(File dir, Collection results) { - if (null == dir) throw new IllegalArgumentException("null dir"); - final Collection result = (results != null? results : new Vector()); - if (isZipFile(dir)) { - zipFileToString(dir, result); - } else if (!dir.isDirectory()) { - throw new IllegalArgumentException("not a dir: " + dir); - } else { - AccumulatingFileFilter acFilter = new AccumulatingFileFilter() { - public boolean accumulate(File file) { - String name = file.getPath(); - result.add(name); - if (isZipFile(file)) { - zipFileToString(file, result); - } - return true; - } - }; - descendFileTree(dir, acFilter, false); - } - return result; - } // directoryToString - - /** - * Render as String the entries in a zip or jar file, - * converting each to String beforehand (as jarpath!jarentry) - * applying policies for whitespace, etc. - * @param file the File to enumerate ZipEntry for - * @param results the Colection to use to return the FileLine - may be null - * @return FileLines with string as text and - * canonical as string modified by any canonicalizing policies. - */ - public static Collection zipFileToString(final File zipfile, Collection results) { - Collection result = (results != null ? results : new Vector()); - ZipFile zip = null; - try { - zip = new ZipFile(zipfile); // ZipFile.OPEN_READ| ZipFile.OPEN_DELETE); delete is 1.3 only - Enumeration enu = zip.entries(); - while (enu.hasMoreElements()) { - results.add(renderZipEntry(zipfile, (ZipEntry) enu.nextElement())); - } - zip.close(); - zip = null; - } catch (Throwable t) { - String err = "Error opening " + zipfile + " attempting to continue..."; - System.err.println(err); - t.printStackTrace(System.err); - } finally { - if (null != zip) { - try { zip.close(); } - catch (IOException e) { - e.printStackTrace(System.err); - } - } - } - return result; - } - - /** - * @return true if file represents an existing file with a zip extension - */ - public static boolean isZipFile(File f) { - String s = null; - if ((null == f) || (null == (s = f.getPath()))) { - return false; - } else { - return (f.canRead() && !f.isDirectory() - && (s.endsWith(".zip") - || (s.endsWith(".jar")))); - } - } - - /** - * Render a zip/entry combination to String - */ - public static String renderZipEntry(File zipfile, ZipEntry entry) { - String filename = (null == zipfile ? "null File" : zipfile.getName()); - String entryname = (null == entry ? "null ZipEntry" : entry.getName()); - return filename + "!" + entryname; - } - - /** - * Write all files in directory out to jarFile - * @param jarFile the File to create and write to - * @param directory the File representing the directory to read - * @param mainClass the value of the main class attribute - may be null - */ - public static boolean createJarFile(File jarFile, File directory, - String mainClass, FileFilter filter) { - String label = "createJarFile("+jarFile - +","+directory +","+mainClass +","+filter + "): "; - Log.signal(label + " start"); - if (null == directory) - throw new IllegalArgumentException("null directory"); - Manifest manifest = createManifest(mainClass); - Log.signal(label + " manifest=" + manifest); - JarOutputStream out = null; - try { - File jarFileDir = jarFile.getParentFile(); - if (null == jarFileDir) { - Log.signal(label + " null jarFileDir"); - } else if (!jarFileDir.exists() && !jarFileDir.mkdirs()) { // XXX convert to Error - Log.signal(label + " unable to create jarFileDir: " + jarFileDir); - } - OutputStream os = new FileOutputStream(jarFile); - out = (null == manifest ? new JarOutputStream(os) - : new JarOutputStream(os, manifest)); - Log.signal(label + " out=" + out); - ZipAccumulator reader = new ZipAccumulator(directory, out, filter); - Log.signal(label + " reader=" + reader); - FileUtil.descendFileTree(directory, reader); - out.closeEntry(); - return true; - } catch (IOException e) { - e.printStackTrace(System.err); // todo - } finally { - if (null != out) { - try { out.close();} - catch (IOException e) {} // todo ignored - } - } - - return false; - } - - protected static Manifest createManifest(String mainClass) { - final String mainKey = "Main-Class"; - Manifest result = null; - if (null != mainClass) { - String entry = "Manifest-Version: 1.0\n" - + mainKey + ": " + mainClass + "\n"; - try { - result = new Manifest(new StringBufferInputStream(entry)); - Attributes attributes = result.getMainAttributes(); - String main = attributes.getValue(mainKey); - if (null == main) { - attributes.putValue(mainKey, mainClass); - main = attributes.getValue(mainKey); - if (null == main) { - Log.signal("createManifest unable to set main " - + mainClass); - } - } - } catch (IOException e) { // todo ignoring - Log.signal(e, " IOException creating manifest with " + mainClass); - } - } - return result; - } - - - /** read a file out to the zip stream */ - protected static void addFileToZip(File in, File parent, - ZipOutputStream out) - throws IOException { - String path = in.getCanonicalPath(); - String parentPath = parent.getCanonicalPath(); - if (!path.startsWith(parentPath)) { - throw new Error("not parent: " + parentPath + " of " + path); - } else { - path = path.substring(1+parentPath.length()); - path = path.replace('\\', '/'); // todo: use filesep - } - ZipEntry entry = new ZipEntry(path); - entry.setTime(in.lastModified()); - // todo: default behavior is DEFLATED - - out.putNextEntry(entry); - - InputStream input = null; - try { - input = new FileInputStream(in); - byte[] buf = new byte[1024]; - int count; - while (0 < (count = input.read(buf, 0, buf.length))) { - out.write(buf, 0, count); - } - } finally { - if (null != input) input.close(); - } - } - - - public static void returnTempDir(File dir) { - deleteDirectory(dir); - } - - /** @return true if path ends with gif, properties, jpg */ - public static boolean isResourcePath(String path) { - if (null == path) return false; - path = path.toLowerCase(); - return (path.endsWith(".gif") - || path.endsWith(".properties") - || path.endsWith(".jpg") - || path.endsWith(".jpeg") - || path.endsWith(".props") - ); - } - - public static void render(Throwable t, StringBuffer err) { // todo: move - String name = t.getClass().getName(); - int loc = name.lastIndexOf("."); - name = name.substring(1+loc); - err.append(name + ": " + t.getMessage() + "\n"); // todo - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - err.append(sw.toString()); - } - - private static boolean report(StringBuffer err, String context, String status, - Throwable throwable) { - boolean failed = ((null != status) || (null != throwable)); - if ((null != err) && (failed)) { - if (null != context) { - err.append(context); - } - if (null != status) { - err.append(status); - } - if (null != throwable) { - render(throwable, err); - } - } - return failed; - } - - /** - * Copy file. - * @param src the File to copy - must exist - * @param dest the File for the target file or directory (will not create directories) - * @param err the StringBuffer for returning any errors - may be null - **/ - public static boolean copyFile(File src, File dest, StringBuffer err) { - boolean result = false; - String label = "start"; - Throwable throwable = null; - try { - if (!ValidFileFilter.FILE_EXISTS.accept(src)) { - label = "src file does not exist"; - } else { - if (dest.isDirectory()) { - dest = new File(dest, src.getName()); - } - if (ValidFileFilter.FILE_EXISTS.accept(dest)) { - label = "dest file exists"; - } - boolean closeWhenDone = true; - result = copy(new FileInputStream(src), - new FileOutputStream(dest), - closeWhenDone); - } - label = null; - } catch (Throwable t) { - throwable = t; - } - String context = "FileUtil.copyFile(src, dest, err)"; - boolean report = report(err, context, label, throwable); - return (result && !report); - } - - /** - * Copy URL to file. - * @param src the URL to copy - must exist - * @param dest the File for the target file or directory (will not create directories) - * @param err the StringBuffer for returning any errors - may be null - **/ - public static boolean copyURL(URL url, File dest, StringBuffer err) { // todo untested. - boolean result = false; - String label = "start"; - Throwable throwable = null; - try { - if (dest.isDirectory()) { - String filename = url.getFile(); - if ((null == filename) || (0 == filename.length())) { - filename = DEFAULT_URL_FILENAME; - } - dest = new File(dest, filename); - } - if (ValidFileFilter.FILE_EXISTS.accept(dest)) { - label = "dest file exists"; - } - boolean closeWhenDone = true; - result = copy(url.openConnection().getInputStream(), - new FileOutputStream(dest), - closeWhenDone); - label = null; - } catch (Throwable t) { - throwable = t; - } - String context = "FileUtil.copyURL(src, dest, err)"; // add actual parm to labels? - boolean report = report(err, context, label, throwable); - return (result && report); - } - - /** - * Copy input to output - does not close either - * @param src the InputStream to copy - must exist - * @param dest the OutputStream for the target - * @param close if true, close when done - */ - public static boolean copy(InputStream src, OutputStream dest, - boolean close) - throws IOException { - boolean result = false; - IOException throwable = null; - try { - byte[] buf = new byte[8*1024]; - int count; - while (0 < (count = src.read(buf, 0, buf.length))) { - dest.write(buf, 0, count); - } - result = true; - } catch (IOException t) { - throwable = t; - } finally { - if (close) { - try { if (null != src) src.close(); } - catch (IOException e) { - if (null == throwable) { throwable = e; } - } - try { if (null != dest) dest.close(); } - catch (IOException i) { - if (null == throwable) { throwable = i; } - } - } - } - if (null != throwable) throw throwable; - return result; - } - - /** - * @return true if dir was an existing directory that is now deleted - */ - protected static boolean deleteDirectory(File dir) { - return ((null != dir) - && dir.exists() - && dir.isDirectory() - && FileUtil.descendFileTree(dir, DELETE_FILES, false) - && FileUtil.descendFileTree(dir, DELETE_DIRS, true) - && dir.delete()); - } - - public static String[] getPaths(File[] files) { // util - String[] result = new String[files.length]; - for (int i = 0; i < result.length; i++) { - result[i] = files[i].getPath(); // preserves absolute? - } - return result; - } - - //-------- first-order, input and visible interface - - protected static final FileFilter DELETE_DIRS = new FileFilter() { - public boolean accept(File file) { - return ((null != file) && file.isDirectory() - && file.exists() && file.delete()); - } - }; - protected static final FileFilter DELETE_FILES = new FileFilter() { - public boolean accept(File file) { - return ((null != file) && !file.isDirectory() - && file.exists() && file.delete()); - } - }; - -} // class FileUtil - -/** - * Localize FileUtil log/signals for now - * ordinary signals are ignored, - * but exceptions are printed to err - * and errors are thrown as Error - */ -class Log { - /** ordinary logging - may be suppressed */ - public static final void signal(String s) { - //System.err.println(s); - } - /** print stack trace to System.err */ - public static final void signal(Throwable t, String s) { - System.err.println(s); - t.printStackTrace(System.err); - } - /** @throws Error(s) always */ - public static final void error(String s) { - throw new Error(s); - } -} - -/** read each file out to the zip file */ -class ZipAccumulator implements FileFilter { - final File parentDir; - final ZipOutputStream out; - final FileFilter filter; - public ZipAccumulator(File parentDir, ZipOutputStream out, - FileFilter filter) { - this.parentDir = parentDir; - this.out = out; - this.filter = filter; - } - public boolean accept(File f) { - if ((null != filter) && (!filter.accept(f))) { - return false; - } - try { - FileUtil.addFileToZip(f, parentDir, out); - return true; - } catch (IOException e) { - e.printStackTrace(System.err); // todo - } - return false; - } -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/IntRange.java b/testing/src/main/java/org/aspectj/testing/util/IntRange.java deleted file mode 100644 index 1f44f69bd..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/IntRange.java +++ /dev/null @@ -1,118 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - - -import java.io.Serializable; - -/** - * imutable class to enforce an integer range - */ -public class IntRange implements IntValidator, ObjectChecker, Serializable { - /** no values permitted */ - public static final IntRange NONE = new IntRange(0, 0); - /** 0 permitted */ - public static final IntRange ZERO = new IntRange(0, 1); - /** 1 permitted */ - public static final IntRange ONE = new IntRange(1, 2); - /** 0..1 permitted */ - public static final IntRange OPTIONAL = new IntRange(0, 2); - /** 1..1000 permitted */ - public static final IntRange MANY = new IntRange(1, 1001); - - /** all positive numbers permitted except Integer.MAX_VALUE */ - public static final IntRange POSITIVE = new IntRange(1, Integer.MAX_VALUE); - /** all negative numbers permitted */ - public static final IntRange NEGATIVE = new IntRange(Integer.MIN_VALUE, 0); - /** any int number permitted except Integer.MAX_VALUE */ - public static final IntRange ANY = new IntRange(Integer.MIN_VALUE, Integer.MAX_VALUE); - - /** - * Make an IntRange that accepts this value - * (using existing if available). - * @throws IllegalArgumentException if value is Integer.MAX_VALUE. - */ - public static final IntRange make(int value) { - switch (value) { - case (1) : return ONE; - case (0) : return ZERO; - case (Integer.MAX_VALUE) : - throw new IllegalArgumentException("illegal " + value); - default : - return new IntRange(value, value + 1); - } - } - - public final int min; - public final int max; - private transient String cache; - - /** use only for serialization - * @deprecated IntRange(int, int) - */ - protected IntRange() { - min = 0; - max = 0; - } - - /** - * @param min minimum permitted value, inclusive - * @param max maximum permitted value, exclusive - */ - public IntRange(int min, int max) { - this.min = min; - this.max = max; - if (min > max) { - throw new IllegalArgumentException( min + " > " + max); - } - toString(); // create cache to view during debugging - } - - /** @return true if integer instanceof Integer with acceptable intValue */ - public final boolean isValid(Object integer) { - return ((integer instanceof Integer) - && (acceptInt(((Integer) integer).intValue()))); - } - - /** @return true if min <= value < max */ - public final boolean acceptInt(int value) { - return ((value >= min) && (value < max)); - } - - - /** - * @deprecated acceptInt(int) - * @return true if min <= value < max - */ - public final boolean inRange(int value) { - return acceptInt(value); - } - /** - * @return true if, for any int x s.t. other.inRange(x) - * is true, this.inRange(x) is also true - */ - public final boolean inRange(IntRange other) { - return ((null != other) && (other.min >= min) - && (other.max <= max)); - } - - // XXX equals(Object) - - public String toString() { - if (null == cache) { - cache = "IntRange [" + min + ".." + max + "]"; - } - return cache; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/IntValidator.java b/testing/src/main/java/org/aspectj/testing/util/IntValidator.java deleted file mode 100644 index e3697d1aa..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/IntValidator.java +++ /dev/null @@ -1,21 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -/** - * @author isberg - */ -public interface IntValidator { - /** @return true if this is a valid value */ - public boolean acceptInt(int value); -} diff --git a/testing/src/main/java/org/aspectj/testing/util/IteratorWrapper.java b/testing/src/main/java/org/aspectj/testing/util/IteratorWrapper.java deleted file mode 100644 index 5b7c13af9..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/IteratorWrapper.java +++ /dev/null @@ -1,147 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.util.Iterator; -import java.util.List; - -/** - * This iterates in order through the permutations of Lists. - * Order and numericity depend on the underlying list iterators - * and the order in which the lists are supplied to the constructor. - * @author isberg - */ -public class IteratorWrapper implements Iterator { - - final List[] lists; - final Iterator[] iterators; - final Object[] current; - Object[] next; - - /** number of elements in each array */ - final int maxDepth; - - /** - * Current level being iterated. - * Set to 0 whenever depth is incremented. - * Incremented when iterator for the level has no more elements. - */ - int currentLevel; - - /** - * Maximum depth iterated-to thus far. - * Set to 0 on initialization. - * Incremented when incrementing currentLevel brings it past depth. - * Run completes when depth = maxDepth or any new iterator has no elements - */ - int depth; - - - /** @throws IllegalArgumentException if lists or any element null */ - public IteratorWrapper(List[] lists) { - if (null == lists) { - throw new IllegalArgumentException("null lists"); - } - maxDepth = lists.length; - currentLevel = 0; - depth = 0; - List[] temp = new List[maxDepth]; - System.arraycopy(lists, 0, temp, 0, temp.length); - for (int i = 0; i < maxDepth; i++) { - if (null == temp[i]) { - throw new IllegalArgumentException("null List[" + i + "]"); - } - } - this.lists = temp; - current = new Object[maxDepth]; - iterators = new Iterator[maxDepth]; - reset(); - } - - /** Reset to the initial state of the iterator */ - public void reset() { - next = null; - for (int i = 0; i < lists.length; i++) { - iterators[i] = lists[i].iterator(); - if (!iterators[i].hasNext()) { // one iterator is empty - never go - depth = maxDepth; - break; - } else { - current[i] = iterators[i].next(); - } - } - if (depth < maxDepth) { - next = getCurrent(); - } - } - - /** @throws UnsupportedOperationException always */ - public void remove() { - throw new UnsupportedOperationException("operation ambiguous"); - } - - public boolean hasNext() { - return (null != next); - } - - /** - * @return Object[] with each element from the iterator of the - * corresponding list which was passed to the constructor for this. - */ - public Object next() { - Object result = next; - next = getNext(); - return result; - } - - private Object[] getCurrent() { - Object[] result = new Object[maxDepth]; - System.arraycopy(current, 0, result, 0, maxDepth); - return result; - } - - private Object[] getNext() { - int initialLevel = currentLevel; - while (depth < maxDepth) { - if (iterators[currentLevel].hasNext()) { - current[currentLevel] = iterators[currentLevel].next(); - if (currentLevel > initialLevel) { - currentLevel = 0; - } - return getCurrent(); - } else { // pop - // reset this level - iterators[currentLevel] = lists[currentLevel].iterator(); - if (!iterators[currentLevel].hasNext()) { // empty iterator - quit - depth = maxDepth; - return null; - } - current[currentLevel] = iterators[currentLevel].next(); - - // do the next level - currentLevel++; - if (currentLevel > depth) { - depth++; - } - } - } - return null; - } - /** @return "IteratorWrapper({{field}={value}}..)" for current, ceiling, and max */ - public String toString() { - return "IteratorWrapper(currentLevel=" + currentLevel - + ", maxLevel=" + depth - + ", size=" + maxDepth + ")"; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/LangUtil.java b/testing/src/main/java/org/aspectj/testing/util/LangUtil.java deleted file mode 100644 index 2baf81c48..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/LangUtil.java +++ /dev/null @@ -1,1271 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.StringTokenizer; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; - - -/** - * misc lang utilities - */ -public class LangUtil { - - /** Delimiter used by split(String) (and ArrayList.toString()?) */ - public static final String SPLIT_DELIM = ", "; - - /** prefix used by split(String) (and ArrayList.toString()?) */ - public static final String SPLIT_START = "["; - - /** suffix used by split(String) (and ArrayList.toString()?) */ - public static final String SPLIT_END = "]"; - - /** system-dependent classpath separator */ - public static final String CLASSPATH_SEP; - - private static final String[] NONE = new String[0]; - - /** bad: hard-wired unix, windows, mac path separators */ - private static final char[] SEPS = new char[] { '/', '\\', ':' }; - - static { - // XXX this has to be the wrong way to get system-dependent classpath separator - String ps = ";"; - try { - ps = System.getProperty("path.separator"); - if (null == ps) { - ps = ";"; - String cp = System.getProperty("java.class.path"); - if (null != cp) { - if (-1 != cp.indexOf(";")) { - ps = ";"; - } else if (-1 != cp.indexOf(":")) { - ps = ":"; - } - // else warn? - } - } - } catch (Throwable t) { // ignore - } finally { - CLASSPATH_SEP = ps; - } - } - - /** - * @return input if any are empty or no target in input, - * or input with escape prefixing all original target - */ - public static String escape(String input, String target, String escape) { - if (isEmpty(input) || isEmpty(target) || isEmpty(escape)) { - return input; - } - StringBuffer sink = new StringBuffer(); - escape(input, target, escape, sink); - return sink.toString(); - } - - - /** - * Append escaped input to sink. - * Cheap form of arbitrary escaping does not escape the escape String - * itself, but unflatten treats it as significant only before the target. - * (so this fails with input that ends with target). - */ - public static void escape(String input, String target, String escape, StringBuffer sink) { - if ((null == sink) || isEmpty(input) || isEmpty(target) || isEmpty(escape)) { - return; - } else if (-1 == input.indexOf(target)) { // avoid StringTokenizer construction - sink.append(input); - return; - } - throw new Error("unimplemented"); - } - - /** flatten list per spec to sink */ - public static void flatten(List list, FlattenSpec spec, StringBuffer sink) { - throwIaxIfNull(spec, "spec"); - final FlattenSpec s = spec; - flatten(list, s.prefix, s.nullFlattened, s.escape, s.delim, s.suffix, sink); - } - - /** - * Flatten a List to String by first converting to String[] - * (using toString() if the elements are not already String) - * and calling flatten(String[]...). - */ - public static void flatten( - List list, - String prefix, - String nullFlattened, - String escape, - String delim, - String suffix, - StringBuffer sink) { - throwIaxIfNull(list, "list"); - Object[] ra = list.toArray(); - String[] result; - if (String.class == ra.getClass().getComponentType()) { - result = (String[]) ra; - } else { - result = new String[ra.length]; - for (int i = 0; i < result.length; i++) { - if (null != ra[i]) { - result[i] = ra[i].toString(); - } - } - } - flatten(result, prefix, nullFlattened, escape, delim, suffix, sink); - } - - - - - /** flatten String[] per spec to sink */ - public static void flatten(String[] input, FlattenSpec spec, StringBuffer sink) { - throwIaxIfNull(spec, "spec"); - final FlattenSpec s = spec; - flatten(input, s.prefix, s.nullFlattened, s.escape, s.delim,s.suffix, sink); - } - - - - - /** - * Flatten a String[] to String by writing strings to sink, - * prefixing with leader (if not null), - * using nullRendering for null entries (skipped if null), - * escaping any delim in entry by prefixing with escape (if not null), - * separating entries with delim (if not null), - * and suffixing with trailer (if not null). - * Note that nullFlattened is not processed for internal delim, - * and strings is not copied before processing. - * @param strings the String[] input - not null - * @param prefix the output starts with this if not null - * @param nullFlattened the output of a null entry - entry is skipped (no delim) if null - * @param escape any delim in an item will be prefixed by escape if not null - * @param delim two items in the output will be separated by delim if not null - * @param suffix the output ends with this if not null - * @param sink the StringBuffer to use for output - * @return null if sink is not null (results added to sink) or rendering otherwise - */ - public static void flatten( - String[] strings, - String prefix, - String nullFlattened, - String escape, - String delim, - String suffix, - StringBuffer sink) { - throwIaxIfNull(strings, "strings"); - if (null == sink) { - return; - } - final boolean haveDelim = (!isEmpty(delim)); - final boolean haveNullFlattened = (null != nullFlattened); - final boolean escaping = (haveDelim && (null != escape)); - final int numStrings = (null == strings ? 0 : strings.length); - if (null != prefix) { - sink.append(prefix); - } - for (int i = 0; i < numStrings; i++) { - String s = strings[i]; - if (null == s) { - if (!haveNullFlattened) { - continue; - } - if (haveDelim && (i > 0)) { - sink.append(delim); - } - sink.append(nullFlattened); - } else { - if (haveDelim && (i > 0)) { - sink.append(delim); - } - - if (escaping) { - escape(s, delim, escape, sink); - } else { - sink.append(s); - } - } - } - if (null != suffix) { - sink.append(suffix); - } - } - - /** - * Get indexes of any invalid entries in array. - * @param ra the Object[] entries to check - * (if null, this returns new int[] { -1 }) - * @param superType the Class, if any, to verify that - * any entries are assignable. - * @return null if all entries are non-null, assignable to superType - * or comma-delimited error String, with components - * <code>"[#] {null || not {superType}"</code>, - * e.g., "[3] null, [5] not String" - */ - public static String invalidComponents(Object[] ra, Class superType) { - if (null == ra) { - return "null input array"; - } else if (0 == ra.length) { - return null; - } - StringBuffer result = new StringBuffer(); - final String cname = LangUtil.unqualifiedClassName(superType); -// int index = 0; - for (int i = 0; i < ra.length; i++) { - if (null == ra[i]) { - result.append(", [" + i + "] null"); - } else if ((null != superType) - && !superType.isAssignableFrom(ra[i].getClass())) { - result.append(", [" + i + "] not " + cname); - } - } - if (0 == result.length()) { - return null; - } else { - return result.toString().substring(2); - } - } - - /** @return ((null == ra) || (0 == ra.length)) */ - public static boolean isEmpty(Object[] ra) { - return ((null == ra) || (0 == ra.length)); - } - - /** @return ((null == s) || (0 == s.length())); */ - public static boolean isEmpty(String s) { - return ((null == s) || (0 == s.length())); - } - - - /** - * Throw IllegalArgumentException if any component in input array - * is null or (if superType is not null) not assignable to superType. - * The exception message takes the form - * <code>{name} invalid entries: {invalidEntriesResult}</code> - * @throws IllegalArgumentException if any components bad - * @see #invalidComponents(Object[], Class) - */ - public static final void throwIaxIfComponentsBad( - final Object[] input, - final String name, - final Class superType) { - String errs = invalidComponents(input, superType); - if (null != errs) { - String err = name + " invalid entries: " + errs; - throw new IllegalArgumentException(err); - } - } - /** - * Shorthand for "if false, throw IllegalArgumentException" - * @throws IllegalArgumentException "{message}" if test is false - */ - public static final void throwIaxIfFalse(final boolean test, final String message) { - if (!test) { - throw new IllegalArgumentException(message); - } - } - - /** - * Shorthand for "if null, throw IllegalArgumentException" - * @throws IllegalArgumentException "null {name}" if o is null - */ - public static final void throwIaxIfNull(final Object o, final String name) { - if (null == o) { - String message = "null " + (null == name ? "input" : name); - throw new IllegalArgumentException(message); - } - } - - public static ArrayList unflatten(String input, FlattenSpec spec) { - throwIaxIfNull(spec, "spec"); - final FlattenSpec s = spec; - return unflatten(input,s.prefix, s.nullFlattened, s.escape, s.delim, s.suffix, s.emptyUnflattened); - } - - /** - * Unflatten a String to String[] by separating elements at delim, - * handling prefixes, suffixes, escapes, etc. - * Any prefix or suffix is stripped from the input - * (or, if not found, an IllegalArgumentException is thrown). - * If delim is null or empty or input contains no delim, - * then return new String[] {stripped input}. - * - * XXX fix comments - * prefixing with leader (if not null), - * using nullRendering for null entries (skipped if null), - * escaping any delim in entry by prefixing with escape (if not null), - * separating entries with delim (if not null), - * and suffixing with trailer (if not null). - * Note that nullRendering is not processed for internal delim, - * and strings is not copied before processing. - * @param strings the String[] input - not null - * @param prefix the output starts with this if not null - * @param nullRendering the output of a null entry - entry is skipped (no delim) if null - * @param escape any delim in an item will be prefixed by escape if not null - * @param delim two items in the output will be separated by delim if not null - * @param suffix the output ends with this if not null - * @param sink the StringBuffer to use for output - * @return null if sink is not null (results added to sink) or rendering otherwise - * @throws IllegalArgumentException if input is null - * or if any prefix does not start the input - * or if any suffix does not end the input - */ - public static ArrayList unflatten( - String input, - String prefix, - String nullFlattened, - String escape, - String delim, - String suffix, - String emptyUnflattened) { - throwIaxIfNull(input, "input"); - final boolean haveDelim = (!isEmpty(delim)); -// final boolean haveNullFlattened = (null != nullFlattened); -// final boolean escaping = (haveDelim && (null != escape)); - if (!isEmpty(prefix)) { - if (input.startsWith(prefix)) { - input = input.substring(prefix.length()); - } else { - String s = "expecting \"" + prefix + "\" at start of " + input + "\""; - throw new IllegalArgumentException(s); - } - } - if (!isEmpty(suffix)) { - if (input.endsWith(suffix)) { - input = input.substring(0, input.length() - suffix.length()); - } else { - String s = "expecting \"" + suffix + "\" at end of " + input + "\""; - throw new IllegalArgumentException(s); - } - } - - final ArrayList result = new ArrayList(); - if (isEmpty(input)) { - return result; - } - if ((!haveDelim) || (-1 == input.indexOf(delim))) { - result.add(input); - return result; - } - - StringTokenizer st = new StringTokenizer(input, delim, true); -// StringBuffer cur = new StringBuffer(); -// boolean lastEndedWithEscape = false; -// boolean lastWasDelim = false; - while (st.hasMoreTokens()) { - String token = st.nextToken(); - System.out.println("reading " + token); - if (delim.equals(token)) { - } else { - result.add(token); - } - } - return result; - } - - /** combine two string arrays, removing null and duplicates - * @return concatenation of both arrays, less null in either or dups in two - * @see Util#combine(Object[], Object[]) - */ - public static String[] combine(String[] one, String[] two) { - ArrayList twoList = new ArrayList(); - twoList.addAll(org.aspectj.util.LangUtil.arrayAsList(two)); - ArrayList result = new ArrayList(); - if (null != one) { - for (int i = 0; i < one.length; i++) { - if (null != one[i]) { - twoList.remove(one[i]); - result.add(one[i]); - } - } - } - for (Iterator iterator = twoList.iterator(); iterator.hasNext(); ) { - String element = (String) iterator.next(); - if (null != element) { - result.add(element); - } - } - return (String[]) result.toArray(NONE); - } - - public static Properties combine(Properties dest, Properties add, boolean respectExisting) { // XXX - if (null == add) return dest; - if (null == dest) return add; - for (Iterator iterator = add.keySet().iterator(); iterator.hasNext(); ) { - String key = (String) iterator.next(); - if (null == key) { - continue; - } - String value = add.getProperty(key); - if (null == value) { - continue; - } - if (! respectExisting || (null == dest.getProperty(key))) { - dest.setProperty(key, value); - } - } - return dest; - } - - public static List arrayAsList(Object[] ra) { - return org.aspectj.util.LangUtil.arrayAsList(ra); - } - - /** - * return the fully-qualified class names - * inferred from the file names in dir - * assuming dir is the root of the source tree - * and class files end with ".class". - * @throws Error if dir is not properly named as prefix - * of class files found in dir. - */ - public static String[] classesIn(File dir) { - boolean alwaysTrue = true; - FileFilter filter = ValidFileFilter.CLASS_FILE; - CollectorFileFilter collector = new CollectorFileFilter(filter, alwaysTrue); - FileUtil.descendFileTree(dir, collector); - List list = collector.getFiles(); - String[] result = new String[list.size()]; - Iterator it = list.iterator(); - String dirPrefix = dir.getPath(); - for (int i = 0; i < result.length; i++) { - if (!it.hasNext()) { - throw new Error("unexpected end of list at " + i); - } - result[i] = fileToClassname((File) it.next(), dirPrefix); - } - return result; - } - - /** - * Convert String[] to String by using conventions for - * split. Will ignore any entries containing SPLIT_DELIM - * (and write as such to errs if not null). - * @param input the String[] to convert - * @param errs the StringBuffer for error messages (if any) - */ - public static String unsplit(String[] input, StringBuffer errs) { - StringBuffer sb = new StringBuffer(); - sb.append(SPLIT_START); - for (int i = 0; i < input.length; i++) { - if (-1 != input[i].indexOf(SPLIT_DELIM)) { - if (null != errs) { - errs.append("\nLangUtil.unsplit(..) - item " + i + ": \"" + input[i] - + " contains \"" + SPLIT_DELIM + "\""); - } - } else { - sb.append(input[i]); - if (1+i < input.length) { - sb.append(SPLIT_DELIM); - } - } - } - sb.append(SPLIT_END); - return sb.toString(); - - } - - /** - * Split input into substrings on the assumption that it is - * either only one string or it was generated using List.toString(), - * with tokens - * <pre>SPLIT_START {string} { SPLIT_DELIM {string}} SPLIT_END<pre> - * (e.g., <code>"[one, two, three]"</code>). - */ - public static String[] split(String s) { - if (null == s) { - return null; - } - if ((!s.startsWith(SPLIT_START)) || (!s.endsWith(SPLIT_END))) { - return new String[] { s }; - } - s = s.substring(SPLIT_START.length(),s.length()-SPLIT_END.length()); - final int LEN = s.length(); - int start = 0; - final ArrayList result = new ArrayList(); - final String DELIM = ", "; - int loc = s.indexOf(SPLIT_DELIM, start); - while ((start < LEN) && (-1 != loc)) { - result.add(s.substring(start, loc)); - start = DELIM.length() + loc; - loc = s.indexOf(SPLIT_DELIM, start); - } - result.add(s.substring(start)); - return (String[]) result.toArray(new String[0]); - } - - public static String[] strip(String[] src, String[] toStrip) { - if (null == toStrip) { - return strip(src, NONE); - } else if (null == src) { - return strip(NONE, toStrip); - } - List slist = org.aspectj.util.LangUtil.arrayAsList(src); - List tlist = org.aspectj.util.LangUtil.arrayAsList(toStrip); - slist.removeAll(tlist); - return (String[]) slist.toArray(NONE); - } - - /** - * Load all classes specified by args, logging success to out - * and fail to err. - */ - public static void loadClasses(String[] args, StringBuffer out, - StringBuffer err) { - if (null != args) { - for (int i = 0; i < args.length; i++) { - try { - Class c = Class.forName(args[i]); - if (null != out) { - out.append("\n"); - out.append(args[i]); - out.append(": "); - out.append(c.getName()); - } - } catch (Throwable t) { - if (null != err) { - err.append("\n"); - FileUtil.render(t, err); - } - } - } - - } - } - - private static String fileToClassname(File f, String prefix) { - // this can safely assume file exists, starts at base, ends with .class - // this WILL FAIL if full path with drive letter on windows - String path = f.getPath(); - if (!path.startsWith(prefix)) { - String err = "!\"" + path + "\".startsWith(\"" + prefix + "\")"; - throw new IllegalArgumentException(err); - } - int length = path.length() - ".class".length(); - path = path.substring(prefix.length()+1, length); - for (int i = 0; i < SEPS.length; i++) { - path = path.replace(SEPS[i], '.'); - } - return path; - } - - public static void main (String[] args) { // todo remove as testing - StringBuffer err = new StringBuffer(); - StringBuffer out = new StringBuffer(); - for (int i = 0; i < args.length; i++) { - String[] names = classesIn(new File(args[i])); - System.err.println(args[i] + " -> " + render(names)); - loadClasses(names, out, err); - } - if (0 < err.length()) { - System.err.println(err.toString()); - } - if (0 < out.length()) { - System.out.println(out.toString()); - } - } - - public static String render (String[] args) { // todo move as testing - if ((null == args) || (1 > args.length)) { - return "[]"; - } - boolean longFormat = (args.length < 10); - String sep = (longFormat ? ", " : "\n\t"); - StringBuffer sb = new StringBuffer(); - if (!longFormat) sb.append("["); - for (int i = 0; i < args.length; i++) { - if (0 < i) sb.append(sep); - sb.append(args[i]); - } - sb.append(longFormat ? "\n" : "]"); - return sb.toString(); - } - - - /** - * @param thrown the Throwable to render - */ - public static String debugStr(Throwable thrown) { - if (null == thrown) { - return "((Throwable) null)"; - } else if (thrown instanceof InvocationTargetException) { - return debugStr(((InvocationTargetException)thrown).getTargetException()); - } else if (thrown instanceof AbortException) { - IMessage m = ((AbortException) thrown).getIMessage(); - if (null != m) { - return "" + m; - } - } - StringWriter buf = new StringWriter(); - PrintWriter writer = new PrintWriter(buf); - writer.println(thrown.getMessage()); - thrown.printStackTrace(writer); - try { buf.close(); } - catch (IOException ioe) {} - return buf.toString(); - } - - /** - * <code>debugStr(o, false);</code> - * @param source the Object to render - */ - public static String debugStr(Object o) { - return debugStr(o, false); - } - - /** - * Render standard debug string for an object in normal, default form. - * @param source the Object to render - * @param recurse if true, then recurse on all non-primitives unless rendered - */ - public static String debugStr(Object o, boolean recurse) { - if (null == o) { - return "null"; - } else if (recurse) { - ArrayList rendering = new ArrayList(); - rendering.add(o); - return debugStr(o, rendering); - } else { - Class c = o.getClass(); - Field[] fields = c.getDeclaredFields(); - Object[] values = new Object[fields.length]; - String[] names = new String[fields.length]; - for (int i = 0; i < fields.length; i++) { - Field field = fields[i]; - names[i] = field.getName(); - try { - values[i] = field.get(o); - if (field.getType().isArray()) { - List list = org.aspectj.util.LangUtil.arrayAsList((Object[]) values[i]); - values[i] = list.toString(); - } - } catch (IllegalAccessException e) { - values[i] = "<IllegalAccessException>"; - } - } - return debugStr(c, names, values); - } - } - - /** - * recursive variant avoids cycles. - * o added to rendering before call. - */ - private static String debugStr(Object o, ArrayList rendering) { - if (null == o) { - return "null"; - } else if (!rendering.contains(o)) { - throw new Error("o not in rendering"); - } - Class c = o.getClass(); - if (c.isArray()) { - Object[] ra = (Object[]) o; - StringBuffer sb = new StringBuffer(); - sb.append("["); - for (int i = 0; i < ra.length; i++) { - if (i > 0) { - sb.append(", "); - } - rendering.add(ra[i]); - sb.append(debugStr(ra[i], rendering)); - } - sb.append("]"); - return sb.toString(); - } - Field[] fields = nonStaticFields(c.getFields()); - Object[] values = new Object[fields.length]; - String[] names = new String[fields.length]; - for (int i = 0; i < fields.length; i++) { - Field field = fields[i]; - names[i] = field.getName(); - // collapse to String - Object value = privilegedGetField(field,o); - if (null == value) { - values[i] = "null"; - } else if (rendering.contains(value)) { - values[i] = "<recursion>"; - } else { - rendering.add(value); - values[i] = debugStr(value, rendering); - } - } - return debugStr(c, names, values); - } - - /** incomplete - need protection domain */ - private static Object privilegedGetField(final Field field, final Object o) { - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() { - try { - return field.get(o); - } catch(IllegalAccessException e) { - return "<IllegalAccessException>"; - } - } - }); - } catch (PrivilegedActionException e) { - return "<IllegalAccessException>"; - } - } - - private static Field[] nonStaticFields(Field[] fields) { - if (null == fields) { - return new Field[0]; - } - int to = 0; - int from = 0; - while (from < fields.length) { - if (!Modifier.isStatic(fields[from].getModifiers())) { - if (to != from) { - fields[to] = fields[from]; - } - to++; - } - from++; - } - if (to < from) { - Field[] result = new Field[to]; - if (to > 0) { - System.arraycopy(fields, 0, result, 0, to); - } - fields = result; - } - return fields; - } - - /** <code> debugStr(source, names, items, null, null, null, null)<code> */ - public static String debugStr(Class source, String[] names, Object[] items) { - return debugStr(source, null, names, null, items, null, null); - } - - /** - * Render standard debug string for an object. - * This is the normal form and an example with the default values:<pre> - * {className}{prefix}{{name}{infix}{value}{delimiter}}..{suffix} - * Structure[head=root, tail=leaf]</pre> - * Passing null for the formatting entries provokes the default values, - * so to print nothing, you should pass "". Default values:<pre> - * prefix: "[" SPLIT_START - * infix: "=" - * delimiter: ", " SPLIT_DELIM - * suffix: "]" SPLIT_END - * @param source the Class prefix to render unqualified - omitted if null - * @param names the String[] (field) names of the items - omitted if null - * @param items the Object[] (field) values - * @param prefix the String to separate classname and start of name/values - * @param delimiter the String to separate name/value instances - * @param infix the String to separate name and value - * used only if both name and value exist - * @param suffix the String to delimit the end of the name/value instances - * used only if classname exists - */ - public static String debugStr(Class source, String prefix, String[] names, - String infix, Object[] items, String delimiter, String suffix) { - - if (null == delimiter) { - delimiter = SPLIT_DELIM; - } - if (null == prefix) { - prefix = SPLIT_START; - } - if (null == infix) { - infix = "="; - } - if (null == suffix) { - suffix = SPLIT_END; - } - StringBuffer sb = new StringBuffer(); - if (null != source) { - sb.append(org.aspectj.util.LangUtil.unqualifiedClassName(source)); - } - sb.append(prefix); - if (null == names) { - names = NONE; - } - if (null == items) { - items = NONE; - } - final int MAX - = (names.length > items.length ? names.length : items.length); - for (int i = 0; i < MAX; i++) { - if (i > 0) { - sb.append(delimiter); - } - if (i < names.length) { - sb.append(names[i]); - } - if (i < items.length) { - if (i < names.length) { - sb.append(infix); - } - sb.append(items[i] + ""); - } - } - sb.append(suffix); - return sb.toString(); - } - - /** - * @return a String with the unqualified class name of the object (or "null") - */ - public static String unqualifiedClassName(Object o) { - return unqualifiedClassName(null == o ? null : o.getClass()); - } - - /** - * @return a String with the unqualified class name of the class (or "null") - */ - public static String unqualifiedClassName(Class c) { - if (null == c) { - return "null"; - } - String name = c.getName(); - int loc = name.lastIndexOf("."); - if (-1 != loc) - name = name.substring(1 + loc); - return name; - } - - /** - * Calculate exact diffs and report missing and extra items. - * This assumes the input List are not modified concurrently. - * @param expectedListIn the List of expected results - treated as empty if null - * @param actualListIn the List of actual results - treated as empty if null - * @param extraListOut the List for any actual results not expected - ignored if null - * @param missingListOut the List for any expected results not found - ignored if null - * */ - public static void makeDiffs( - List expectedListIn, - List actualListIn, - List missingListOut, - List extraListOut) { - if ((null == missingListOut) && (null == extraListOut)) { - return; - } - if (null == expectedListIn) { - expectedListIn = Collections.EMPTY_LIST; - } - if (null == actualListIn) { - actualListIn = Collections.EMPTY_LIST; - } - if ((0 == actualListIn.size()) && (0 == expectedListIn.size()) ) { - return; - } - BitSet actualExpected = new BitSet(); - for (int i = 0; i < expectedListIn.size(); i++) { - Object expect = expectedListIn.get(i); - int loc = actualListIn.indexOf(expect); - if (-1 == loc) { - if (null != missingListOut) { - missingListOut.add(expect); - } - } else { - actualExpected.set(loc); - } - } - if (null != extraListOut) { - for (int i = 0; i < actualListIn.size(); i++) { - if (!actualExpected.get(i)) { - extraListOut.add(actualListIn.get(i)); - } - } - } - } - // XXX unit test for makeSoftDiffs - /** - * Calculate potentially "soft" diffs using - * Comparator.compare(expected, actual). - * This shallow-copies and sorts the input Lists. - * @param expectedListIn the List of expected results - treated as empty if null - * @param actualListIn the List of actual results - treated as empty if null - * @param extraListOut the List for any actual results not expected - ignored if null - * @param missingListOut the List for any expected results not found - ignored if null - * @param comparator the Comparator for comparisons - not null - * @throws IllegalArgumentException if comp is null - */ - public static void makeSoftDiffs( // XXX no intersect or union on collections??? - List expectedListIn, - List actualListIn, - List missingListOut, - List extraListOut, - Comparator comparator) { - if ((null == missingListOut) && (null == extraListOut)) { - return; - } - if (null == comparator) { - throw new IllegalArgumentException("null comparator"); - } - if (null == expectedListIn) { - expectedListIn = Collections.EMPTY_LIST; - } - if (null == actualListIn) { - actualListIn = Collections.EMPTY_LIST; - } - if ((0 == actualListIn.size()) && (0 == expectedListIn.size()) ) { - return; - } - - ArrayList expected = new ArrayList(); - expected.addAll(expectedListIn); - Collections.sort(expected, comparator); - - ArrayList actual = new ArrayList(); - actual.addAll(actualListIn); - Collections.sort(actual, comparator); - Iterator actualIter = actual.iterator(); - Object act = null; - - if (missingListOut != null) { - missingListOut.addAll(expectedListIn); - } - if (extraListOut != null) { - extraListOut.addAll(actualListIn); - } - - // AMC: less efficient, but simplified implementation. Needed since messages can - // now match on text content too, and the old algorithm did not cope with two expected - // messages on the same line, but with different text content. - while (actualIter.hasNext()) { - act = actualIter.next(); - for (Iterator expectedIter = expected.iterator(); expectedIter.hasNext();) { - Object exp = expectedIter.next(); - // if actual matches expected remove actual from extraListOut, and - // remove expected from missingListOut - int diff = comparator.compare(exp,act); - if (diff == 0) { - extraListOut.remove(act); - missingListOut.remove(exp); - } else if (diff > 0) { - // since list is sorted, there can be no more matches... - break; - } - } - } - -// while (((null != act) || actualIter.hasNext()) -// && ((null != exp) || expectedIter.hasNext())) { -// if (null == act) { -// act = actualIter.next(); -// } -// if (null == exp) { -// exp = expectedIter.next(); -// } -// int diff = comparator.compare(exp, act); -// if (0 > diff) { // exp < act -// if (null != missingListOut) { -// missingListOut.add(exp); -// exp = null; -// } -// } else if (0 < diff) { // exp > act -// if (null != extraListOut) { -// extraListOut.add(act); -// act = null; -// } -// } else { // got match of actual to expected -// // absorb all actual matching expected (duplicates) -// while ((0 == diff) && actualIter.hasNext()) { -// act = actualIter.next(); -// diff = comparator.compare(exp, act); -// } -// if (0 == diff) { -// act = null; -// } -// exp = null; -// } -// } -// if (null != missingListOut) { -// if (null != exp) { -// missingListOut.add(exp); -// } -// while (expectedIter.hasNext()) { -// missingListOut.add(expectedIter.next()); -// } -// } -// if (null != extraListOut) { -// if (null != act) { -// extraListOut.add(act); -// } -// while (actualIter.hasNext()) { -// extraListOut.add(actualIter.next()); -// } -// } - } - public static class FlattenSpec { - /** - * This tells unflatten(..) to throw IllegalArgumentException - * if it finds two contiguous delimiters. - */ - public static final String UNFLATTEN_EMPTY_ERROR - = "empty items not permitted when unflattening"; - /** - * This tells unflatten(..) to skip empty items when unflattening - * (since null means "use null") - */ - public static final String UNFLATTEN_EMPTY_AS_NULL - = "unflatten empty items as null"; - - /** - * This tells unflatten(..) to skip empty items when unflattening - * (since null means "use null") - */ - public static final String SKIP_EMPTY_IN_UNFLATTEN - = "skip empty items when unflattening"; - - /** - * For Ant-style attributes: "item,item" (with escaped commas). - * There is no way when unflattening to distinguish - * values which were empty from those which were null, - * so all are unflattened as empty. - */ - public static final FlattenSpec COMMA - = new FlattenSpec(null, "", "\\", ",", null, "") { - public String toString() { return "FlattenSpec.COMMA"; } - }; - - /** this attempts to mimic ((List)l).toString() */ - public static final FlattenSpec LIST - = new FlattenSpec("[", "", null, ", ", "]", UNFLATTEN_EMPTY_ERROR) { - public String toString() { return "FlattenSpec.LIST"; } - }; - - /** how toString renders null values */ - public static final String NULL = "<null>"; - private static String r(String s) { - return (null == s ? NULL : s); - } - - public final String prefix; - public final String nullFlattened; - public final String escape; - public final String delim; - public final String suffix; - public final String emptyUnflattened; - private transient String toString; - - public FlattenSpec( - String prefix, - String nullRendering, - String escape, - String delim, - String suffix, - String emptyUnflattened) { - this.prefix = prefix; - this.nullFlattened = nullRendering; - this.escape = escape; - this.delim = delim; - this.suffix = suffix; - this.emptyUnflattened = emptyUnflattened; - throwIaxIfNull(emptyUnflattened, "use UNFLATTEN_EMPTY_AS_NULL"); - } - - public String toString() { - if (null == toString) { - toString = "FlattenSpec(" - + "prefix=" + r(prefix) - + ", nullRendering=" + r(nullFlattened) - + ", escape=" + r(escape) - + ", delim=" + r(delim) - + ", suffix=" + r(suffix) - + ", emptyUnflattened=" + r(emptyUnflattened) - + ")"; - } - return toString; - } - } -} // class LangUtil - -// --------- java runs using Ant -// /** -// * Run a Java command separately. -// * @param className the fully-qualified String name of the class -// * with the main method to run -// * @param classpathFiles the File to put on the classpath -// * @param args to the main method of the class -// * @param outSink the PrintStream for the output stream - may be null -// */ -// public static void oldexecuteJava( -// String className, -// File[] classpathFiles, -// String[] args, -// PrintStream outSink) { -// Project project = new Project(); -// project.setName("LangUtil.executeJava(" + className + ")"); -// Path classpath = new Path(project, classpathFiles[0].getAbsolutePath()); -// for (int i = 1; i < classpathFiles.length; i++) { -// classpath.addExisting(new Path(project, classpathFiles[i].getAbsolutePath())); -// } -// -// Commandline cmds = new Commandline(); -// cmds.addArguments(new String[] {className}); -// cmds.addArguments(args); -// -// ExecuteJava runner = new ExecuteJava(); -// runner.setClasspath(classpath); -// runner.setJavaCommand(cmds); -// if (null != outSink) { -// runner.setOutput(outSink); // XXX todo -// } -// runner.execute(project); -// } - -// public static void executeJava( -// String className, -// File dir, -// File[] classpathFiles, -// String[] args, -// PrintStream outSink) { -// StringBuffer sb = new StringBuffer(); -// -// sb.append("c:/apps/jdk1.3.1/bin/java.exe -classpath \""); -// for (int i = 0; i < classpathFiles.length; i++) { -// if (i < 0) { -// sb.append(";"); -// } -// sb.append(classpathFiles[i].getAbsolutePath()); -// } -// sb.append("\" -verbose " + className); -// for (int i = 0; i < args.length; i++) { -// sb.append(" " + args[i]); -// } -// Exec exec = new Exec(); -// Project project = new Project(); -// project.setProperty("ant.home", "c:/home/wes/aj/aspectj/modules/lib/ant"); -// System.setProperty("ant.home", "c:/home/wes/aj/aspectj/modules/lib/ant"); -// exec.setProject(new Project()); -// exec.setCommand(sb.toString()); -// exec.setDir(dir.getAbsolutePath()); -// exec.execute(); -// } -// public static void execJavaProcess( -// String className, -// File dir, -// File[] classpathFiles, -// String[] args, -// PrintStream outSink) throws Throwable { -// StringBuffer sb = new StringBuffer(); -// -// sb.append("c:\\apps\\jdk1.3.1\\bin\\java.exe -classpath \""); -// for (int i = 0; i < classpathFiles.length; i++) { -// if (i > 0) { -// sb.append(";"); -// } -// sb.append(classpathFiles[i].getAbsolutePath()); -// } -// sb.append("\" -verbose " + className); -// for (int i = 0; i < args.length; i++) { -// sb.append(" " + args[i]); -// } -// String command = sb.toString(); -// System.err.println("launching process: " + command); -// Process process = Runtime.getRuntime().exec(command); -// // huh? err/out -// InputStream errStream = null; -// InputStream outStream = null; -// Throwable toThrow = null; -// int result = -1; -// try { -// System.err.println("waiting for process: " + command); -// errStream = null; // process.getErrorStream(); -// outStream = null; // process.getInputStream(); // misnamed - out -// result = process.waitFor(); -// System.err.println("Done waiting for process: " + command); -// process.destroy(); -// } catch (Throwable t) { -// toThrow = t; -// } finally { -// if (null != outStream) { -// FileUtil.copy(outStream, System.out, false); -// try { outStream.close(); } -// catch (IOException e) {} -// } -// if (null != errStream) { -// FileUtil.copy(errStream, System.err, false); -// try { errStream.close(); } -// catch (IOException e) {} -// } -// } -// if (null != toThrow) { -// throw toThrow; -// } -// } -// try { -// // show the command -// log(command, Project.MSG_VERBOSE); -// -// // exec command on system runtime -// Process proc = Runtime.getRuntime().exec(command); -// -// if (out != null) { -// fos = new PrintWriter(new FileWriter(out)); -// log("Output redirected to " + out, Project.MSG_VERBOSE); -// } -// -// // copy input and error to the output stream -// StreamPumper inputPumper = -// new StreamPumper(proc.getInputStream(), Project.MSG_INFO); -// StreamPumper errorPumper = -// new StreamPumper(proc.getErrorStream(), Project.MSG_WARN); -// -// // starts pumping away the generated output/error -// inputPumper.start(); -// errorPumper.start(); -// -// // Wait for everything to finish -// proc.waitFor(); -// inputPumper.join(); -// errorPumper.join(); -// proc.destroy(); -// -// // close the output file if required -// logFlush(); -// -// // check its exit value -// err = proc.exitValue(); -// if (err != 0) { -// if (failOnError) { -// throw new BuildException("Exec returned: " + err, getLocation()); -// } else { -// log("Result: " + err, Project.MSG_ERR); -// } -// } -// } catch (IOException ioe) { -// throw new BuildException("Error exec: " + command, ioe, getLocation()); -// } catch (InterruptedException ex) {} -// - - diff --git a/testing/src/main/java/org/aspectj/testing/util/LineReader.java b/testing/src/main/java/org/aspectj/testing/util/LineReader.java deleted file mode 100644 index a6af8266a..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/LineReader.java +++ /dev/null @@ -1,204 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * LineReader.java created on May 3, 2002 - * - */ -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.ArrayList; - -/** LineNumberReader which absorbs our lines and renders as file:line */ -public class LineReader extends LineNumberReader { - /** delimited multi-line output of readToBlankLine */ - public static final String RETURN= "\n\r"; - - private static final String[] NONE = new String[0]; - private static final String cSCRIPT = "#"; - private static final String cJAVA = "//"; - private static final String[] TESTER_LEAD = new String[] {cSCRIPT, cJAVA}; - - /** - * Convenience factory for tester suite files - * @return null if IOException or IllegalArgumentException thrown - */ - public static final LineReader createTester(File file) { - return create(file, TESTER_LEAD, null); - } - - /** - * convenience factory - * @return null if IOException or IllegalArgumentException thrown - */ - public static final LineReader create(File file, - String[] leadComments, String[] eolComments) { - try { - FileReader reader = new FileReader(file); - return new LineReader(reader, file, leadComments, eolComments); - } catch (IllegalArgumentException e) { - } catch (IOException e) { - } - return null; - } - - final private File file; - final private String[] eolComments; - final private String[] leadComments; - - /** - * @param file the File used to open the FileReader - * @param leadComments the String[] to be taken as the start of - * comments when they are the first non-blank text on a line - - * pass null to signal none. - * @param leadComments the String[] to be taken as the start of - * comment anywhere on a line - pass null to signal none. - *@throws IllegalArgumentException if any String in - * leadComments or eolComments is null. - */ - public LineReader(FileReader reader, File file, - String[] leadComments, String[] eolComments) { - super(reader); - this.file = file; - this.eolComments = normalize(eolComments); - this.leadComments = normalize(leadComments); - } - public LineReader(FileReader reader, File file) { - this(reader, file, null, null); - } - - /** @return file:line */ - public String toString() { - return file.getPath() + ":" + getLineNumber(); - } - - /** @return underlying file */ - public File getFile() { return file; } - - /** - * Reader first..last (inclusive) and return in String[]. - * This will return (1+(last-first)) elements only if this - * reader has not read past the first line and there are last lines - * and there are no IOExceptions during reads. - * @param first the first line to read - if negative, use 0 - * @param last the last line to read (inclusive) - * - if less than first, use first - * @return String[] of first..last (inclusive) lines read or - */ - public String[] readLines(int first, int last) { - if (0 > first) first = 0; - if (first > last) last = first; - ArrayList list = new ArrayList(); - try { - String line = null; - while (getLineNumber() < first) { - line = readLine(); - if (null == line) { - break; - } - } - if (getLineNumber() > first) { - // XXX warn? something else read past line - } - if ((null != line) && (first == getLineNumber())) { - list.add(line); - while (last >= getLineNumber()) { - line = readLine(); - if (null == line) { - break; - } - list.add(line); - } - } - } catch (IOException e) { - return NONE; - } - return (String[]) list.toArray(NONE); - } - - /** Skip to next blank line - * @return the String containing all lines skipped (delimited with RETURN) - */ - public String readToBlankLine() throws IOException { - StringBuffer sb = new StringBuffer(); - String input; - while (null != (input = nextLine(false))) { // get next empty line to restart - sb.append(input); - sb.append(RETURN);// XXX verify/ignore/correct - } - return sb.toString(); - } - - /** - * Get the next line from the input stream, stripping eol and - * leading comments. - * If emptyLinesOk is true, then this reads past lines which are - * empty after omitting comments and trimming until the next non-empty line. - * Otherwise, this returns null on reading an empty line. - * (The input stream is not exhausted until this - * returns null when emptyLines is true.) - * @param emptyLinesOk if false, return null if the line is empty - * @return next non-null, non-empty line in reader, - * ignoring comments - */ - public String nextLine(boolean emptyLinesOk) throws IOException { - int len = 0; - String result = null; - do { - result = readLine(); - if (result == null) - return null; - result = result.trim(); - for (int i = 0; i < eolComments.length; i++) { - int loc = result.indexOf(eolComments[i]); - if (-1 != loc) { - result = result.substring(0, loc); - break; - } - } - len = result.length(); - if (0 < len) { - for (int i = 0; i < leadComments.length; i++) { - if (result.startsWith(leadComments[i])) { - result = ""; - break; - } - } - len = result.length(); - } - len = result.length(); - if (!emptyLinesOk && (0 == len)) - return null; - } while (0 == len); - return result; - } - - private String[] normalize(String[] input) { - if ((null == input) || (0 == input.length)) return NONE; - String[] result = new String[input.length]; - System.arraycopy(input, 0, result, 0, result.length); - for (int i = 0; i < result.length; i++) { - if ((null == result[i]) || (0 == result[i].length())) { - throw new IllegalArgumentException("empty input at [" + i + "]"); - } - } - return result; - } - -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/LinkCheck.java b/testing/src/main/java/org/aspectj/testing/util/LinkCheck.java deleted file mode 100644 index 3f1ef92a1..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/LinkCheck.java +++ /dev/null @@ -1,546 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.*; -import java.net.*; -import java.util.*; - -import javax.swing.text.MutableAttributeSet; -import javax.swing.text.html.*; -import javax.swing.text.html.HTML.Tag; - -import org.aspectj.bridge.*; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.util.LangUtil; -//import org.aspectj.util.FileUtil; - -/** - * Quick and dirty link checker. - * This checks that links into file: and http: targets work, - * and that links out of file: targets work. - */ -public class LinkCheck { - /* - * Known issues: - * - main interface only, though API's easily upgraded - * - https MalformedUrlExceptions on redirect - * - Swing won't quit without System.exit - * - single-threaded - */ - static final URL COMMAND_LINE; - static { - URL commandLine = null; - try { - commandLine = new URL("file://commandLine"); - } catch (Throwable t) { - } - COMMAND_LINE = commandLine; - } - - /** @param args file {-logFile {file} | -printInfo } */ - public static void main(String[] args) { - final String syntax = "java " - + LinkCheck.class.getName() - + " file {-log <file> | -printInfo}.."; - if ((null == args) || (0 >= args.length)) { - System.err.println(syntax); - System.exit(1); - } - final String startingURL = "file:///" + args[0].replace('\\', '/'); - String logFile = null; - boolean printInfo = false; - for (int i = 1; i < args.length; i++) { - if ("-log".equals(args[i]) && ((i+1) < args.length)) { - logFile = args[++i]; - } else if ("-printInfo".equals(args[i])) { - printInfo = true; - } else { - System.err.println(syntax); - System.exit(1); - } - } - final boolean useSystemOut = (null == logFile); - final MessageHandler mh; - final OutputStream out; - if (useSystemOut) { - mh = new MessageHandler(); - out = null; - } else { - - try { - out = new FileOutputStream(logFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return; - } - final PrintStream ps = new PrintStream(out, true); - final boolean printAll = printInfo; - mh = new MessageHandler() { - public boolean handleMessage(IMessage message) { - if (printAll || !message.isInfo()) { - ps.println(message.toString()); - } - return super.handleMessage(message); - } - - }; - } - Link.Check exists - = Link.getProtocolChecker(new String[] {"file", "http"}); - Link.Check contents - = Link.getProtocolChecker(new String[] {"file"}); - LinkCheck me = new LinkCheck(mh, exists, contents); - me.addLinkToCheck(COMMAND_LINE, startingURL); // pwd as base? - try { - String label = "checking URLs from " + startingURL; - if (useSystemOut) { - System.out.println(label); - } - MessageUtil.info("START " + label); - long start = System.currentTimeMillis(); - me.run(); - long duration = (System.currentTimeMillis() - start)/1000; - long numChecked = me.checkedUrls.size(); - if (numChecked > 0) { - float cps = (float) duration / (float) numChecked; - StringBuffer sb = new StringBuffer(); - sb.append("DONE. Checked " + numChecked); - sb.append(" URL's in " + duration); - sb.append(" seconds (" + cps); - sb.append(" seconds per URL)."); - MessageUtil.info("END " + label + ": " + sb); - if (useSystemOut) { - System.out.println(sb.toString()); - } - } - MessageUtil.info(MessageUtil.renderCounts(mh)); - try { - if (null != out) { - out.flush(); - } - } catch (IOException e) { - // ignore - } - if (useSystemOut && (null != logFile)) { - System.out.println("Find log in " + logFile); - } - } finally { - if (null != out) { - try { - out.close(); - } catch (IOException e1) { - } - } - System.exit(mh.numMessages(IMessage.ERROR, true)); // XXX dumb swing - } - } - -// private static boolean isCheckedFileType(URL url) { -// if (null == url) { -// return false; -// } -// String file = url.getFile(); -// return !FileUtil.hasZipSuffix(file) -// && !file.endsWith(".pdf"); -// } - - private final Messages messages; - private final HTMLEditorKit.Parser parser; // XXX untested - stateful - private final ArrayList linksToCheck; // Link - private final ArrayList checkedUrls; // String (URL.toString) - private final ArrayList validRefs; // String (URL.toString) - private final ArrayList refsToCheck; // String (URL.toString) - - private final Link.Check checkExists; - private final Link.Check checkContents; - - public LinkCheck(IMessageHandler handler, - Link.Check checkExists, - Link.Check checkContents) { - LangUtil.throwIaxIfNull(handler, "handler"); - LangUtil.throwIaxIfNull(checkExists, "checkExists"); - LangUtil.throwIaxIfNull(checkContents, "checkContents"); - this.messages = new Messages(handler); - linksToCheck = new ArrayList(); - checkedUrls = new ArrayList(); - refsToCheck = new ArrayList(); - validRefs = new ArrayList(); - parser = new HTMLEditorKit() { - public HTMLEditorKit.Parser getParser() { - return super.getParser(); - } - } - .getParser(); - this.checkExists = checkExists; - this.checkContents = checkContents; - } - - public synchronized void addLinkToCheck(URL doc, String link) { - URL linkURL = makeURL(doc, link); - if (null == linkURL) { -// messages.addingNullLinkFrom(doc); - return; - } - String linkString = linkURL.toString(); - if ((null != link) && !checkedUrls.contains(linkString) ) { - if (!checkExists.check(linkURL)) { - checkedUrls.add(linkString); - messages.acceptingUncheckedLink(doc, linkURL); - } else { - Link toAdd = new Link(doc, linkURL); - if (!linksToCheck.contains(toAdd)) { // equals overridden - linksToCheck.add(toAdd); - } - } - } - } - - public synchronized void run() { - ArrayList list = new ArrayList(); - while (0 < linksToCheck.size()) { - messages.checkingLinks(linksToCheck.size()); - list.clear(); - list.addAll(linksToCheck); - for (Iterator iter = list.iterator(); iter.hasNext();) { - final Link link = (Link) iter.next(); - String urlString = link.url.toString(); - if (!checkedUrls.contains(urlString)) { - checkedUrls.add(urlString); - messages.checkingLink(link); - checkLink(link); - } - } - linksToCheck.removeAll(list); - } - // now check that all named references are accounted for - for (Iterator iter = refsToCheck.iterator(); iter.hasNext();) { - String ref = (String) iter.next(); - if (!validRefs.contains(ref)) { - messages.namedReferenceNotFound(ref); - } - } - } - - /** @return null if link known or if unable to create */ - private URL makeURL(URL doc, String link) { - if (checkedUrls.contains(link)) { - return null; - } - URL result = null; - try { - result = new URL(link); - } catch (MalformedURLException e) { - if (null == doc) { - messages.malformedUrl(null, link, e); - } else { - try { - URL res = new URL(doc, link); - String resultString = res.toString(); - if (checkedUrls.contains(resultString)) { - return null; - } - result = res; - } catch (MalformedURLException me) { - messages.malformedUrl(doc, link, me); - } - } - } - return result; - } - - /** @param link a Link with a url we can handle */ - private void checkLink(final Link link) { - if (handleAsRef(link)) { - return; - } - URL url = link.url; - InputStream input = null; - try { - URLConnection connection = url.openConnection(); - if (null == connection) { - messages.cantOpenConnection(url); - return; - } - // get bad urls to fail on read before skipping by type - input = connection.getInputStream(); - String type = connection.getContentType(); - if (null == type) { - messages.noContentType(link); - } else if (!type.toLowerCase().startsWith("text/")) { - messages.notTextContentType(link); - } else { - boolean addingLinks = checkContents.check(url); - parser.parse( - new InputStreamReader(input), - new LinkListener(url, addingLinks), true); - } - } catch (IOException e) { - messages.exceptionReading(link, e); - } finally { - if (null != input) { - try { - input.close(); - } catch (IOException e1) { - // ignore - } - } - } - } - - /** @return true if link is to an internal ...#name */ - private boolean handleAsRef(Link link) { - String ref = link.url.getRef(); - if (!LangUtil.isEmpty(ref)) { - String refString = link.url.toString(); // XXX canonicalize? - if (!refsToCheck.contains(refString)) { - refsToCheck.add(refString); - // add pseudo-link to force reading of ref'd doc XXX hmm - int refLoc = refString.indexOf("#"); - if (-1 == refLoc) { - messages.uncommentedReference(link); - } else { - refString = refString.substring(0, refLoc); - addLinkToCheck(link.doc, refString); - } - return true; - } - } - return false; - } - - /** LinkListener callback */ - private boolean addKnownNamedAnchor(URL doc, String name) { - String namedRef = "#" + name; - try { - String ref = new URL(doc + namedRef).toString(); - if (!validRefs.contains(ref)) { - validRefs.add(ref); - } - return true; - } catch (MalformedURLException e) { - messages.malformedUrl(doc, namedRef, e); - return false; - } - } - - private class Messages { - private final IMessageHandler handler; - private Messages(IMessageHandler handler) { - LangUtil.throwIaxIfNull(handler, "handler"); - this.handler = handler; - } - - private void info(String label, Object more) { - MessageUtil.info(handler, label + " " + more); - } - - private void fail(String label, Object more, Throwable thrown) { - MessageUtil.fail(handler, label + " " + more, thrown); - } - - private void uncommentedReference(Link link) { - info("uncommentedReference", link); // XXX bug? - } - -// private void addingNullLinkFrom(URL doc) { -// info("addingNullLinkFrom", doc); -// } -// -// private void noContentCheck(Link link) { -// info("noContentCheck", link); -// } - - private void notTextContentType(Link link) { - info("notTextContentType", link); - } - - private void noContentType(Link link) { - info("noContentType", link); - } - - private void checkingLinks(int i) { - info("checkingLinks", new Integer(i)); - } - - private void checkingLink(Link link) { - info("checkingLink", link); - } - - private void acceptingUncheckedLink(URL doc, URL link) { - info("acceptingUncheckedLink", "doc=" + doc + " link=" + link); - } - -// private void cantHandleRefsYet(Link link) { -// info("cantHandleRefsYet", link.url); -// } - - private void namedReferenceNotFound(String ref) { - // XXX find all references to this unfound named reference - fail("namedReferenceNotFound", ref, null); - } - - private void malformedUrl(URL doc, String link, MalformedURLException e) { - fail("malformedUrl", "doc=" + doc + " link=" + link, e); - } - - private void cantOpenConnection(URL url) { - fail("cantOpenConnection", url, null); - } - - private void exceptionReading(Link link, IOException e) { - // only info if redirect from http to https - String m = e.getMessage(); - if ((m != null) - && (-1 != m.indexOf("protocol")) - && (-1 != m.indexOf("https")) - && "http".equals(link.url.getProtocol())) { - info("httpsRedirect", link); - return; - } - fail("exceptionReading", link, e); - } - - private void nullLink(URL doc, Tag tag) { - // ignore - many tags do not have links - } - - private void emptyLink(URL doc, Tag tag) { - fail("emptyLink", "doc=" + doc + " tag=" + tag, null); - } - } - - /** - * Register named anchors and add any hrefs to the links to check. - */ - private class LinkListener extends HTMLEditorKit.ParserCallback { - private final URL doc; - private final boolean addingLinks; - - private LinkListener(URL doc, boolean addingLinks) { - this.doc = doc; - this.addingLinks = addingLinks; - } - - public void handleStartTag( - HTML.Tag tag, - MutableAttributeSet attributes, - int position) { - handleSimpleTag(tag, attributes, position); - } - - public void handleSimpleTag( - HTML.Tag tag, - MutableAttributeSet attributes, - int position) { // XXX use position to emit context? - boolean isNameAnchor = registerIfNamedAnchor(tag, attributes); - if (!addingLinks) { - return; - } - Object key = HTML.Tag.FRAME == tag - ? HTML.Attribute.SRC - : HTML.Attribute.HREF; - String link = (String) attributes.getAttribute(key); - - if (null == link) { - if (!isNameAnchor) { - messages.nullLink(doc, tag); - } - } else if (0 == link.length()) { - if (!isNameAnchor) { - messages.emptyLink(doc, tag); - } - } else { - addLinkToCheck(doc, link); - } - } - - private boolean registerIfNamedAnchor( - HTML.Tag tag, - MutableAttributeSet attributes) { - if (HTML.Tag.A.equals(tag)) { - String name - = (String) attributes.getAttribute(HTML.Attribute.NAME); - if (null != name) { - addKnownNamedAnchor(doc, name); - return true; - } - } - return false; - } - - } - - private static class Link { - private static final Check FALSE_CHECKER = new Check() { - public boolean check(Link link) { return false; } - public boolean check(URL url) { return false; } - }; - private static Check getProtocolChecker(String[] protocols) { - final String[] input - = (String[]) LangUtil.safeCopy(protocols, protocols); - if (0 == input.length) { - return FALSE_CHECKER; - } - return new Check() { - final List list = Arrays.asList(input); - public boolean check(URL url) { - return (null != url) && list.contains(url.getProtocol()); - } - }; - } - private final URL doc; - private final URL url; - private String toString; - private Link(URL doc, URL url) { - LangUtil.throwIaxIfNull(doc, "doc"); - LangUtil.throwIaxIfNull(url, "url"); - this.doc = doc; - this.url = url; - } - public boolean equals(Object o) { - if (null == o) { - return false; - } - if (this == o) { - return true; - } - if (Link.class != o.getClass()) { - return false; // exact class - } - Link other = (Link) o; - return doc.equals(other) && url.equals(other); - //return toString().equals(o.toString()); - } - - public int hashCode() { // XXX - return doc.hashCode() + (url.hashCode() >> 4); -// return toString.hashCode(); - } - - public String toString() { - if (null == toString) { - toString = url + " linked from " + doc; - } - return toString; - } - private static class Check { - public boolean check(Link link) { - return (null != link) && check(link.url); - } - public boolean check(URL url) { - return (null != url); - } - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/Node.java b/testing/src/main/java/org/aspectj/testing/util/Node.java deleted file mode 100644 index 9439e57e4..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/Node.java +++ /dev/null @@ -1,162 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * Node.java created on May 14, 2002 - * - */ -package org.aspectj.testing.util; - - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.List; - -/** - * A node in a tree containing other Node or SpecElements items. - */ -public class Node { // XXX render - public static final Node[] EMPTY_NODES = new Node[0]; - public static final Object[] EMPTY_ITEMS = new Object[0]; - - /** - * Visit all the SpecElements (and Node) reachable from node - * in depth-first order, halting if checker objects. - * @param node the Node to pass to checker - * @param itemChecker the ObjectChecker to pass items to - * @param nodeVisitor if not null, then use instead of recursing - * @return false on first objection, true otherwise - * @throws IllegalArgumentExcpetion if checker is null - */ - public static final boolean visit(Node node, ObjectChecker itemChecker, - ObjectChecker nodeVisitor) { - if (null == node) { - return (null == itemChecker ? true : itemChecker.isValid(null)); - } - boolean result = true; - - Node[] nodes = node.getNodes(); - for (int i = 0; result && (i < nodes.length); i++) { - result = (null == nodeVisitor - ? visit(nodes[i], itemChecker, null) - : nodeVisitor.isValid(nodes[i])); - } - if (result) { - Object[] elements = node.getItems(); - for (int i = 0; result && (i < elements.length); i++) { - result = itemChecker.isValid(elements[i]); - } - } - - return result; - } - - public final String name; - public final Class type; - public final Object key; - protected final Object[] typeArray; - protected final List nodes; - protected final List items; - - public Node() { - this("Node"); - } - - public Node(String name) { - this(name, null); - } - - /** use the name as the key */ - public Node(String name, Class type) { - this(name, type, name); - } - /** */ - public Node(String name, Class type, Object key) { - if (null == name) { - throw new IllegalArgumentException("null name"); - } - if (null == key) { - throw new IllegalArgumentException("null key"); - } - this.name = name; - this.type = type; - this.key = key; - nodes = new ArrayList(); - items = new ArrayList(); - if (type == null) { - type = Object.class; - } - typeArray = (Object[]) Array.newInstance(type, 0); - } - - /** - * clear all items and nodes. - */ - public void clear() { // XXX synchronize - nodes.clear(); - items.clear(); - } - - /** - * Add item to list of items - * unless it is null, of the wrong type, or the collection fails to add - * @return true if added - */ - public boolean add(Object item) { - if (null == item) - throw new IllegalArgumentException("null item"); - if ((null != type) && (!type.isAssignableFrom(item.getClass()))) { - return false; - } - return items.add(item); - } - - /** - * Add node to list of nodes - * unless it is null, of the wrong type, or the collection fails to add - * @return true if added - */ - public boolean addNode(Node node) { - if (null == node) { - throw new IllegalArgumentException("null node"); - } - return nodes.add(node); - } - - /** - * Get the current list of nodes - never null - */ - public Node[] getNodes() { - if ((null == nodes) || (1 > nodes.size())) { - return EMPTY_NODES; - } - return (Node[]) nodes.toArray(EMPTY_NODES); - } - - /** - * Get the current list of items - never null - * @return items in current list, cast to type[] if type was not null - */ - public Object[] getItems() { - if ((null == items) || (1 > items.size())) { - return EMPTY_ITEMS; - } - return items.toArray(typeArray); - } - - /** @return name */ - public String toString() { - return name; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/NullPrintStream.java b/testing/src/main/java/org/aspectj/testing/util/NullPrintStream.java deleted file mode 100644 index 686c9c8e2..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/NullPrintStream.java +++ /dev/null @@ -1,95 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * NullPrintStream.java created on May 29, 2002 - * - */ -package org.aspectj.testing.util; - -import java.io.OutputStream; -import java.io.PrintStream; - -/** - * Ignore any output to a NullPrintStream. - * Clients use singleton NULL_PrintStream or NULL_OutputStream. - * @author isberg - */ -public final class NullPrintStream extends PrintStream { - - public static final OutputStream NULL_OutputStream = NullOutputStream.ME; - public static final PrintStream NULL_PrintStream = new NullPrintStream(); - - private NullPrintStream() { - super(NULL_OutputStream); - } - public void write(int b) { - } - public void write(byte[] b) { - } - public void write(byte[] b, int off, int len) { - } - public void print(boolean arg0) { - } - public void print(char arg0) { - } - public void print(char[] arg0) { - } - public void print(double arg0) { - } - public void print(float arg0) { - } - public void print(int arg0) { - } - public void print(long arg0) { - } - public void print(Object arg0) { - } - public void print(String arg0) { - } - public void println() { - } - public void println(boolean arg0) { - } - public void println(char arg0) { - } - public void println(char[] arg0) { - } - public void println(double arg0) { - } - public void println(float arg0) { - } - public void println(int arg0) { - } - public void println(long arg0) { - } - public void println(Object arg0) { - } - public void println(String arg0) { - } - -} - -final class NullOutputStream extends OutputStream { - static final OutputStream ME = new NullOutputStream(); - - private NullOutputStream() { - } - public void write(int b) { - } - public void write(byte[] b) { - } - public void write(byte[] b, int off, int len) { - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/ObjectChecker.java b/testing/src/main/java/org/aspectj/testing/util/ObjectChecker.java deleted file mode 100644 index 25985ae5e..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/ObjectChecker.java +++ /dev/null @@ -1,51 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -/** - * Check input for validity. - */ -public interface ObjectChecker { - /** this returns true for any input, even if null */ - public static final ObjectChecker ANY = new ObjectChecker() { - public final boolean isValid(Object input) { return true; } - public final String toString() { return "ObjectChecker.ANY"; } - }; - - /** this returns true for any non-null object */ - public static final ObjectChecker NOT_NULL = new ObjectChecker() { - public boolean isValid(Object input) { return (null != input); } - public String toString() { return "ObjectChecker.NOT_NULL"; } - }; - - /** @return true if input is 0 Integer or any other non-Integer reference. */ - public static final ObjectChecker ANY_ZERO = new ObjectChecker() { - public boolean isValid(Object input) { - if (input instanceof Integer) { - return (0 == ((Integer) input).intValue()); - } else { - return true; - } - } - public String toString() { return "ObjectChecker.ANY_ZERO"; } - }; - - /** - * Check input for validity. - * @param input the Object to check - * @return true if input is ok - */ - public boolean isValid(Object input); -} diff --git a/testing/src/main/java/org/aspectj/testing/util/ProxyPrintStream.java b/testing/src/main/java/org/aspectj/testing/util/ProxyPrintStream.java deleted file mode 100644 index 5c5bbe9de..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/ProxyPrintStream.java +++ /dev/null @@ -1,104 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.IOException; -import java.io.PrintStream; - -/** Wrap a delegate PrintStream, permitting output to be suppressed. */ -public class ProxyPrintStream extends PrintStream { - - private final PrintStream delegate; - private boolean hiding; - public ProxyPrintStream(PrintStream delegate ) { - super(NullPrintStream.NULL_OutputStream); - LangUtil.throwIaxIfNull(delegate, "delegate"); - this.delegate = delegate; - } - public void hide() { - hiding = true; - } - public void show() { - hiding = false; - } - public boolean isHiding() { - return hiding; - } - public void write(int b) { - if (!hiding) delegate.write(b); - } - public void write(byte[] b) throws IOException { - if (!hiding) delegate.write(b); - } - public void write(byte[] b, int off, int len) { - if (!hiding) delegate.write(b, off, len); - } - public void print(boolean arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(char arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(char[] arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(double arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(float arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(int arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(long arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(Object arg0) { - if (!hiding) delegate.print(arg0); - } - public void print(String arg0) { - if (!hiding) delegate.print(arg0); - } - public void println() { - if (!hiding) delegate.println(); - } - public void println(boolean arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(char arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(char[] arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(double arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(float arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(int arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(long arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(Object arg0) { - if (!hiding) delegate.println(arg0); - } - public void println(String arg0) { - if (!hiding) delegate.println(arg0); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/RunUtils.java b/testing/src/main/java/org/aspectj/testing/util/RunUtils.java deleted file mode 100644 index 86c29a4a2..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/RunUtils.java +++ /dev/null @@ -1,368 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.PrintStream; -import java.util.Iterator; - -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.IMessageHolder; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.bridge.MessageUtil.IMessageRenderer; -import org.aspectj.testing.harness.bridge.AbstractRunSpec; -import org.aspectj.testing.harness.bridge.IRunSpec; -import org.aspectj.testing.run.IRunStatus; -import org.aspectj.testing.run.RunValidator; -import org.aspectj.util.LangUtil; - -/** - * - */ -public class RunUtils { - - /** enable verbose for this an any related AbstractRunSpec children */ - public static void enableVerbose(AbstractRunSpec spec) { // instanceof hack - LangUtil.throwIaxIfNull(spec, "spec"); - spec.runtime.setVerbose(true); - for (Iterator iter = spec.getChildren().iterator(); iter.hasNext();) { - IRunSpec child = (IRunSpec) iter.next(); - if (child instanceof AbstractRunSpec) { - enableVerbose((AbstractRunSpec) child); - } - } - } - - /** - * Calculate failures for this status. - * If the input status has no children and failed, the result is 1. - * If it has children and recurse is false, then - * the result is the number of children whose status has failed - * (so a failed status with some passing and no failing children - * will return 0). - * If it has children and recurse is true, - * then return the number of leaf failures in the tree, - * ignoring (roll-up) node failures. - * @return number of failures in children of this status - */ - public static int numFailures(IRunStatus status, boolean recurse) { - int numFails = 0; - IRunStatus[] children = status.getChildren(); - int numChildren = (null == children? 0 : children.length); - if (0 == numChildren) { - if (!RunValidator.NORMAL.runPassed(status)) { - return 1; - } - } else { -// int i = 0; - for (int j = 0; j < children.length; j++) { - if (recurse) { - numFails += numFailures(children[j], recurse); - } else { - if (!RunValidator.NORMAL.runPassed(children[j])) { - numFails++; - } - } - } - } - return numFails; - } - - // ------------------------ printing status - public static void printShort(PrintStream out, IRunStatus status) { - if ((null == out) || (null == status)) { - return; - } - printShort(out, "", status); - } - - public static void printShort(PrintStream out, String prefix, IRunStatus status) { - int numFails = numFailures(status, true); - String fails = (0 == numFails ? "" : " - " + numFails + " failures"); - out.println(prefix + toShortString(status) + fails); - IRunStatus[] children = status.getChildren(); - int numChildren = (null == children? 0 : children.length); - if (0 < numChildren) { - int i = 0; - for (int j = 0; j < children.length; j++) { - printShort(out, prefix + "[" + LangUtil.toSizedString(i++, 3) + "]: ", children[j]); - if (!RunValidator.NORMAL.runPassed(children[j])) { - numFails++; - } - } - } - } - - public static void print(PrintStream out, IRunStatus status) { - if ((null == out) || (null == status)) { - return; - } - print(out, "", status); - } - - public static void print(PrintStream out, String prefix, IRunStatus status) { - print(out, prefix, status, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL); - } - - public static void print(PrintStream out, String prefix, IRunStatus status, - IMessageRenderer renderer, IMessageHandler selector) { - String label = status.getIdentifier() - + (status.runResult() ? "PASS" : "FAIL"); - out.println(prefix + label); - out.println(prefix + debugString(status)); - IMessageHolder messageHolder = status; - if ((null != messageHolder) && (0 < messageHolder.numMessages(null, true))) { - MessageUtil.print(out, messageHolder, prefix, renderer, selector); - } - Throwable thrown = status.getThrown(); - if (null != thrown) { - out.println(prefix + "--- printing stack trace for thrown"); - thrown.printStackTrace(out); - } - IRunStatus[] children = status.getChildren(); - int numChildren = (null == children? 0 : children.length); - int numFails = 0; - if (0 < numChildren) { - out.println(prefix + "--- printing children [" + numChildren + "]"); - int i = 0; - for (int j = 0; j < children.length; j++) { - print(out, prefix + "[" + LangUtil.toSizedString(i++, 3) + "]: ", children[j]); - if (!RunValidator.NORMAL.runPassed(children[j])) { - numFails++; - } - } - } - if (0 < numFails) { - label = numFails + " fails " + label; - } - out.println(""); - } - - - public static String debugString(IRunStatus status) { - if (null == status) { - return "null"; - } - final String[] LABELS = - new String[] { - "runResult", - "id", - "result", - "numChildren", - "completed", - //"parent", - "abort", - "started", - "thrown", - "messages" }; - String runResult = status.runResult() ? "PASS" : "FAIL"; - Throwable thrown = status.getThrown(); - String thrownString = LangUtil.unqualifiedClassName(thrown); - IRunStatus[] children = status.getChildren(); - String numChildren = (null == children? "0" : ""+children.length); - String numMessages = ""+status.numMessages(null, IMessageHolder.EQUAL); - Object[] values = - new Object[] { - runResult, - status.getIdentifier(), - status.getResult(), - numChildren, - new Boolean(status.isCompleted()), - //status.getParent(), // costly if parent printing us - status.getAbortRequest(), - new Boolean(status.started()), - thrownString, - numMessages }; - return org.aspectj.testing.util.LangUtil.debugStr(status.getClass(), LABELS, values); - } - - public static String toShortString(IRunStatus status) { - if (null == status) { - return "null"; - } - String runResult = status.runResult() ? " PASS: " : " FAIL: "; - return (runResult + status.getIdentifier()); - } - - /** renderer for IRunStatus */ - public static interface IRunStatusPrinter { - void printRunStatus(PrintStream out, IRunStatus status); - } - - public static final IRunStatusPrinter VERBOSE_PRINTER = new IRunStatusPrinter() { - public String toString() { return "VERBOSE_PRINTER"; } - /** Render IRunStatus produced by running an AjcTest */ - public void printRunStatus(PrintStream out, IRunStatus status) { - printRunStatus(out, status, ""); - } - private void printRunStatus(PrintStream out, IRunStatus status, String prefix) { - LangUtil.throwIaxIfNull(out, "out"); - LangUtil.throwIaxIfNull(status, "status"); - String label = (status.runResult() ? " PASS: " : " FAIL: ") - + status.getIdentifier(); - out.println(prefix + "------------ " + label); - out.println(prefix + "--- result: " + status.getResult()); - if (0 < status.numMessages(null, true)) { - out.println(prefix + "--- messages "); - MessageUtil.print(out, status, prefix, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL); - } - Throwable thrown = status.getThrown(); - if (null != thrown) { - out.println(prefix + "--- thrown"); - thrown.printStackTrace(out); - } - IRunStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) { - String number = "[" + LangUtil.toSizedString(i,3) + "] "; - printRunStatus(out, children[i], prefix + number); - } - } - }; - - /** print only status and fail/abort messages */ - public static final IRunStatusPrinter TERSE_PRINTER = new IRunStatusPrinter() { - public String toString() { return "TERSE_PRINTER"; } - - /** print only status and fail messages */ - public void printRunStatus(PrintStream out, IRunStatus status) { - printRunStatus(out, status, ""); - } - private void printRunStatus(PrintStream out, IRunStatus status, String prefix) { - LangUtil.throwIaxIfNull(out, "out"); - LangUtil.throwIaxIfNull(status, "status"); - String label = (status.runResult() ? "PASS: " : "FAIL: ") - + status.getIdentifier(); - out.println(prefix + label); - Object result = status.getResult(); - if ((null != result) && (IRunStatus.PASS != result) && (IRunStatus.FAIL != result)) { - out.println(prefix + "--- result: " + status.getResult()); - } - if (0 < status.numMessages(IMessage.FAIL, true)) { - MessageUtil.print(out, status, prefix, MessageUtil.MESSAGE_ALL, MessageUtil.PICK_FAIL_PLUS); - } - Throwable thrown = status.getThrown(); - if (null != thrown) { - out.println(prefix + "--- thrown: " + LangUtil.renderException(thrown, true)); - } - IRunStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) { - if (!children[i].runResult()) { - String number = "[" + LangUtil.toSizedString(i,3) + "] "; - printRunStatus(out, children[i], prefix + number); - } - } - out.println(""); - } - }; - - /** Render IRunStatus produced by running an AjcTest.Suite. */ - public static final IRunStatusPrinter AJCSUITE_PRINTER = new IRunStatusPrinter() { - public String toString() { return "AJCSUITE_PRINTER"; } - - /** - * Render IRunStatus produced by running an AjcTest.Suite. - * This renders only test failures and - * a summary at the end. - */ - public void printRunStatus(PrintStream out, IRunStatus status) { - LangUtil.throwIaxIfNull(out, "out"); - LangUtil.throwIaxIfNull(status, "status"); - final String prefix = ""; - final boolean failed = status.runResult(); - String label = (status.runResult() ? "PASS: " : "FAIL: ") - + status.getIdentifier(); - out.println(prefix + label); - // print all messages - these are validator comments - if (0 < status.numMessages(null, true)) { - MessageUtil.print(out, status, "init", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL); - } - // XXX ignore thrown if failed - will be printed as message anyway? - Throwable thrown = status.getThrown(); - if ((null != thrown) && !failed) { - out.println(prefix + "--- printing stack trace for thrown"); - thrown.printStackTrace(out); - } - IRunStatus[] children = status.getChildren(); - int numChildren = (null == children? 0 : children.length); - int numFails = 0; - if (0 < numChildren) { - for (int j = 0; j < children.length; j++) { - if (!RunValidator.NORMAL.runPassed(children[j])) { - numFails++; - } - } - } - if (0 < numFails) { - out.println(prefix + "--- " + numFails + " failures when running " + children.length + " tests"); - for (int j = 0; j < children.length; j++) { - if (!RunValidator.NORMAL.runPassed(children[j])) { - print(out, prefix + "[" + LangUtil.toSizedString(j, 3) + "]: ", children[j]); - out.println(""); - } - } - } - label = "ran " + children.length + " tests" - + (numFails == 0 ? "" : "(" + numFails + " fails)"); - out.println(""); - } - - }; - /** Render IRunStatus produced by running an AjcTest (verbose) */ - public static final IRunStatusPrinter AJCTEST_PRINTER = VERBOSE_PRINTER; - - /** print this with messages, then children using AJCRUN_PRINTER */ - public static final IRunStatusPrinter AJC_PRINTER = new IRunStatusPrinter() { - public String toString() { return "AJC_PRINTER"; } - /** Render IRunStatus produced by running an AjcTest */ - public void printRunStatus(PrintStream out, IRunStatus status) { - LangUtil.throwIaxIfNull(out, "out"); - LangUtil.throwIaxIfNull(status, "status"); - String label = (status.runResult() ? " PASS: " : " FAIL: ") - + status.getIdentifier(); - out.println("------------ " + label); - MessageUtil.print(out, status, "", MessageUtil.MESSAGE_ALL, MessageUtil.PICK_ALL); - IRunStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) { - AJCRUN_PRINTER.printRunStatus(out, children[i]); - } - //out.println("------------ END " + label); - out.println(""); - } - }; - - - /** print only fail messages */ - public static final IRunStatusPrinter AJCRUN_PRINTER = new IRunStatusPrinter() { - public String toString() { return "AJCRUN_PRINTER"; } - /** Render IRunStatus produced by running an AjcTest child */ - public void printRunStatus(PrintStream out, IRunStatus status) { - LangUtil.throwIaxIfNull(out, "out"); - LangUtil.throwIaxIfNull(status, "status"); - final boolean orGreater = false; - int numFails = status.numMessages(IMessage.FAIL, orGreater); - if (0 < numFails) { - out.println("--- " + status.getIdentifier()); - IMessage[] fails = status.getMessages(IMessage.FAIL, orGreater); - for (int i = 0; i < fails.length; i++) { - out.println("[fail " + LangUtil.toSizedString(i, 3) + "]: " - + MessageUtil.MESSAGE_ALL.renderToString(fails[i])); - } - } - } - }; - - private RunUtils() { - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/util/SFileReader.java b/testing/src/main/java/org/aspectj/testing/util/SFileReader.java deleted file mode 100644 index eecf2d304..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/SFileReader.java +++ /dev/null @@ -1,184 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; - -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.util.LangUtil; - - -/** - * This reads a structured (config) file, which may have - * lines with @ signalling a recursive read - * and EOL comments # or //. - * This duplicates ConfigFileUtil in some sense. - */ -public class SFileReader { - // XXX move into LineReader, but that forces util to depend on AbortException? - // Formerly in SuiteReader - - /** - * Read args as config files and echo to stderr. - * @param args String[] of fully-qualified paths to config files - */ - public static void main(String[] args) throws IOException { - ArrayList result = new ArrayList(); - ObjectChecker collector = new StandardObjectChecker(String.class, result); - SFileReader me = new SFileReader(null); - for (int i = 0; i < args.length; i++) { - Node node = me.readNodes(new File(args[i]), null, true, System.err); - if (!Node.visit(node, collector, null)) { - System.err.println("halted during copy of " +args[i]); - } else { - String s = org.aspectj.testing.util.LangUtil.debugStr(null, "\n ", null, - null, result.toArray(), "\n ", ""); - System.err.println(args[i] + ": " + s); - } - } - } - - /* - * readSuite(..) reads .txt file, and for each test case specification - * creates a spec using readTestSpecifications - * and (if the specifications match the constraints) - * creates a test case using creatTestCase. - */ - - /** pass this to protected methods requiring String[] if you have none */ - protected static final String[] NONE = new String[0]; - - final Maker maker; - - /** @param maker the Maker factory to use - if null, use Maker.ECHO */ - public SFileReader(Maker maker) { - this.maker = (null == maker ? Maker.ECHO : maker); - } - - /** - * Creates a (potentially recursive) tree of node - * by reading from the file and constructing using the maker. - * Clients may read results in Node tree form when complete - * or snoop the selector for a list of objects made. - * The selector can prevent collection in the node by - * returning false. - * Results are guaranteed by the Maker to be of the Maker's type. - * @param file an absolute path to a structured file - * @param selector determines whether not to keep an object made. - * (if null, then all are kept) - * @return Node with objects available from getItems() - * and sub-suite Node available from getNodes() - * @throws Error on any read error if abortOnReadError (default) - */ - public Node readNodes( - final File file, - final ObjectChecker selector, - final boolean abortOnReadError, - final PrintStream err) - throws IOException { - final Node result = new Node(file.getPath(), maker.getType()); - if (null == file) { - throw new IllegalArgumentException("null file"); - } else if (!file.isAbsolute()) { - throw new IllegalArgumentException("file not absolute"); - } - UtilLineReader reader = null; - try { - reader = UtilLineReader.createTester(file); - if (null == reader) { - throw new IOException("no reader for " + file); - } - final String baseDir = file.getParent(); - - String line; - boolean skipEmpties = true; - while (null != (line = reader.nextLine(skipEmpties))) { - if (line.charAt(0) == '@') { - if (line.length() > 1) { - String newFilePath = line.substring(1).trim(); - File newFile = new File(newFilePath); - if (!newFile.isAbsolute()) { - newFile = new File(baseDir, newFilePath); - } - Node node = readNodes(newFile, selector, abortOnReadError, err); - if (!result.addNode(node)) { - // XXX signal error? - System.err.println("warning: unable to add node: " + node); - break; - } - } - } else { - try { - Object made = maker.make(reader); - if ((null == selector) || (selector.isValid(made))) { - if (!result.add(made)) { - break; // XXX signal error? - } - } - } catch (AbortException e) { - if (abortOnReadError) { // XXX todo - verify message has context? - throw e; - } - if (null != err) { - String m; - IMessage mssg = e.getIMessage(); - if (null != mssg) { - m = "Message: " + mssg; - } else { - m = LangUtil.unqualifiedClassName(e) + "@" + e.getMessage(); - } - err.println(m); - } - reader.readToBlankLine(); - } - } - } - } finally { - try { - if (null != reader) { - reader.close(); - } - } catch (IOException e) { - } // ignore - } - - return result; - } - - /** factory produces objects by reading LineReader */ - public interface Maker { - /** - * Make the result using the input from the LineReader, - * starting with lastLine(). - */ - Object make(UtilLineReader reader) throws AbortException, IOException; - - /** @return type of the Object made */ - Class getType(); - - /** This echoes each line, prefixed by the reader. - * @return file:line: {line} - */ - static final Maker ECHO = new Maker() { - public Object make(UtilLineReader reader) { - return reader + ": " + reader.lastLine(); - } - public Class getType() { return String.class; } - }; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/StandardObjectChecker.java b/testing/src/main/java/org/aspectj/testing/util/StandardObjectChecker.java deleted file mode 100644 index bc2f520ad..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StandardObjectChecker.java +++ /dev/null @@ -1,127 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * StandardObjectChecker.java created on May 7, 2002 - * - */ -package org.aspectj.testing.util; - -import java.util.List; - -/** - * Superclass for checkers that require non-null input - * of a given type. - * Clients may supply delegator for further checks, - * or a list to collect results. - * Subclasses may instead implement doIsValid(). - * @author isberg - */ -public class StandardObjectChecker implements ObjectChecker { - - public final Class type; - private final ObjectChecker delegate; - private final List collector; - private final boolean collectionResult; - - /** - * Create one with no delegate. - * @param type the Class of the type required of the input - */ - public StandardObjectChecker(Class type) { - this(type, ANY, (List) null, true); - } - - /** - * @param type the Class of the type required of the input - * @param delegate the ObjectChecker to delegate to after - * checking for non-null input of the correct type. - */ - public StandardObjectChecker(Class type, ObjectChecker delegate) { - this(type, delegate, null, true); - } - - /** - * same as StandardObjectChecker(type, collector, true) - * @param type the Class of the type required of the input - * @param collector the list to collect valid entries - */ - public StandardObjectChecker(Class type, List collector) { - this(type, ANY, collector, true); - } - - /** - * @param type the Class of the type required of the input - * @param collector the list to collect valid entries - * @param collectionResult the value to return when entry was added - */ - public StandardObjectChecker(Class type, List collector, boolean collectionResult) { - this(type, ANY, collector, collectionResult); - } - - /** - * @param type the Class of the type required of the input - * @param collector the list to collect valid entries - */ - public StandardObjectChecker(Class type, ObjectChecker delegate, - List collector, boolean collectionResult) { - if (null == type) throw new IllegalArgumentException("null type"); - this.type = type; - this.delegate = delegate; - this.collector = collector; - this.collectionResult = collectionResult; - } - - /** - * Check if object is valid by confirming is is non-null and of the - * right type, then delegating to any delegate or calling doIsValid(), - * then (if true) passing to any collector, and returning - * false if the collector failed or the collection result otherwise. - * @see ObjectChecker#isValid(Object) - * @return true unless input is null or wrong type - * or if one of subclass (doIsValid(..)) or delegates - * (list, collector) returns false. - */ - public final boolean isValid(Object input) { - if ((null == input) || (!(type.isAssignableFrom(input.getClass())))) { - return false; - } else if (null != delegate) { - if (!delegate.isValid(input)) { - return false; - } - } - if (!doIsValid(input)) { - return false; - } - if (null == collector) { - return true; - } else if (!collector.add(input)) { - return false; - } else { - return collectionResult; - } - } - - /** - * Delegate of isValid guarantees that the input - * is not null as is assignable to the specified type. - * Subclasses implement their funtionality here. - * This implementation returns true; - * @return true - */ - public boolean doIsValid(Object input) { - return true; - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/util/StreamSniffer.java b/testing/src/main/java/org/aspectj/testing/util/StreamSniffer.java deleted file mode 100644 index cb143604e..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StreamSniffer.java +++ /dev/null @@ -1,76 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * StreamGrabber.java created on May 16, 2002 - * - */ -package org.aspectj.testing.util; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Listen to a stream using StringBuffer. - * Clients install and remove buffer to enable/disable listening. - * Does not affect data passed to underlying stream - */ -public class StreamSniffer extends FilterOutputStream { - StringBuffer buffer; - /** have to use delegate, not super, because super we will double-count input */ - final OutputStream delegate; - - public StreamSniffer(OutputStream stream) { - super(stream); - delegate = stream; - } - - /** set to null to stop copying */ - public void setBuffer(StringBuffer sb) { - buffer = sb; - } - - //---------------- FilterOutputStream - public void write(int b) throws IOException { - StringBuffer sb = buffer; - if (null != sb) { - if ((b > Character.MAX_VALUE) - || (b < Character.MIN_VALUE)) { - throw new Error("don't know double-byte"); // XXX - } else { - sb.append((char) b); - } - } - delegate.write(b); - } - - public void write(byte[] b) throws IOException { - StringBuffer sb = buffer; - if (null != sb) { - String s = new String(b); - sb.append(s); - } - delegate.write(b); - } - - public void write(byte[] b, int offset, int length) throws IOException { - StringBuffer sb = buffer; - if (null != sb) { - String s = new String(b, offset, length); - sb.append(s); - } - delegate.write(b, offset, length); - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/StreamsHandler.java b/testing/src/main/java/org/aspectj/testing/util/StreamsHandler.java deleted file mode 100644 index fc69d9900..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StreamsHandler.java +++ /dev/null @@ -1,217 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.PrintStream; - -/** - * Manage system err and system out streams. - * Clients can suppress stream output during StreamsHandler lifecycle - * and intermittantly listen to both streams if signalled on construction. - * To print to the underlying streams (without hiding or listening), - * use either the log methods (which manage lineation) - * or the out and err fields. - * <pre> - * boolean hideStreams = true; - * boolean listen = true; - * StreamsHander streams = new StreamsHander(hideStreams, listen); - * streams.startListening(); - * ... - * streams.out.println("this goes out to without listening"); XXX verify - * StreamsHandler.Result result = streams.stopListening(); - * streams.restoreStreams(); - * System.out.println("Suppressed output stream follows"); - * System.out.print(result.out); - * System.out.println("Suppressed error stream follows"); - * System.out.print(result.err); - * </pre> - * Warning: does not distinguish streams from different threads. - */ -public class StreamsHandler { - - /** real output stream and sink for log if logToOut */ - public final PrintStream out; - - /** real error stream and sink for log if !logToOut */ - public final PrintStream err; - - /** if true, then can listen using startListening() */ - protected final boolean listening; - - /** if logToOut, then out, else err */ - private final PrintStream log; - - /** true if the last logged item was a newline */ - private boolean loggedLine; - - /** sniffs stream to gather test output to System.out */ - protected StreamSniffer outSniffer; - - /** sniffs stream to gather test output to System.err */ - protected StreamSniffer errSniffer; - - /** permits us to hide output stream (after sniffing by outSniffer */ - protected ProxyPrintStream outDelegate; - - /** permits us to hide error stream (after sniffing by errSniffer */ - protected ProxyPrintStream errDelegate; - - /** when sniffing, this has sniffed contents of output stream */ - protected StringBuffer outListener; - - /** when sniffing, this has sniffed contents of error stream */ - protected StringBuffer errListener; - - /** @param hide if true, then suppress stream output (can still listen) */ - public StreamsHandler(boolean listen) { - this(listen, false); - } - - /** - * @param listen possible to sniff streams only if true - * @param logToOut if true, then log methods go to System.out -- otherwise, System.err. - */ - public StreamsHandler( - boolean listen, - boolean logToOut) { - this.err = System.err; - this.out = System.out; - outDelegate = new ProxyPrintStream(System.out); - errDelegate = new ProxyPrintStream(System.err); - this.listening = listen; -// final PrintStream HIDE = NullPrintStream.NULL_PrintStream; - outSniffer = new StreamSniffer(outDelegate); - System.setOut(new PrintStream(outSniffer)); - errSniffer = new StreamSniffer(errDelegate); - System.setErr(new PrintStream(errSniffer)); - log = (logToOut ? this.out : this.err); - loggedLine = true; - } - - /** render output and error streams (after sniffing) */ - public void show() { - outDelegate.show(); - errDelegate.show(); - } - - /** suppress output and error streams (after sniffing) */ - public void hide() { - outDelegate.hide(); - errDelegate.hide(); - } - - /** restore streams. Do not use this after restoring. */ - public void restoreStreams() { - if (null != outSniffer) { - outSniffer = null; - errSniffer = null; - System.setOut(out); - System.setErr(err); - } - } - - /** @return PrintStream used for direct logging */ - public PrintStream getLogStream() { - return log; - } - - /** log item without newline. */ - public void log(String s) { - log.print(s); - if (loggedLine) { - loggedLine = false; - } - } - - /** - * Log item with newline. - * If previous log did not have a newline, - * then this prepends a newline. - */ - public void lnlog(String s) { - if (!loggedLine) { - log.println(""); - } - log.println(s); - } - - /** - * Start listening to both streams. - * Tosses any old data captured. - * (Has no effect if not listening.) - * @throws IllegalStateException if called after restoreStreams() - * @see endListening() - */ - public void startListening() { - if (null == outSniffer) { - throw new IllegalStateException("no listening after restore"); - } - if (listening) { - if (null != outListener) { - outListener.setLength(0); - errListener.setLength(0); - } else { - outListener = new StringBuffer(); - outSniffer.setBuffer(outListener); - errListener = new StringBuffer(); - errSniffer.setBuffer(errListener); - } - } - } - - /** - * End listening to both streams and return data captured. - * Must call startListening() first. - * @throws IllegalStateException if called when not listening - * @return Result with sniffed output and error String - * @see startListening() - */ - public Result endListening() { - return endListening(true); - } - - /** - * End listening to both streams and return data captured. - * Must call startListening() first. - * @param getResult if false, return Result.EMPTY - * and avoid converting buffer to String. - * @throws IllegalStateException if called when not listening - * @return Result with sniffed output and error String - * @see startListening() - */ - public Result endListening(boolean getResult) { - if (!listening) { - return Result.EMPTY; - } - if (null == outListener) { - throw new IllegalStateException("listening not started"); - } - Result result = (!getResult ? Result.EMPTY - : new Result(outListener.toString(), errListener.toString())); - errListener = null; - outListener = null; - return result; - } - - /** output and error String */ - public static class Result { - static final Result EMPTY = new Result(null, null); - public final String out; - public final String err; - private Result(String out, String err) { - this.out = out; - this.err = err; - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/StringAccumulator.java b/testing/src/main/java/org/aspectj/testing/util/StringAccumulator.java deleted file mode 100644 index 234592386..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StringAccumulator.java +++ /dev/null @@ -1,99 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -/* - * StringAccumulator.java created on May 14, 2002 - * - */ -package org.aspectj.testing.util; - - - -/** - * Accumulate String with delimiters. - */ -public class StringAccumulator implements ObjectChecker { - - private final String prefix; - private final String infix; - private final String suffix; - private final String nullString; - private final StringBuffer sb; - private int index; - - /** - * Accumulate string with delimiter between elements, - * treaing null elements as "". - */ - public StringAccumulator(String delimiter) { - this(delimiter, null, null, ""); - } - - /** - * Constructor for StringAccumulator which specifies how to - * process each result, optionally postfixing or prefixing - * or infixing (adding index plus infix to prefix). e.g., - * for prefix="[", infix="]\"", postfix="\"\n", then each entry - * becomes a line: <pre>"[{index}]"{entry}"\n</pre> - * - * @param prefix if not null, prepend to each result - * @param infix if not null, the add index and infix before each result, after prefix - * @param postfix if not null, append to each result - * @param nullString if null, ignore null completely (no index); otherwise render null as nullString - * @param type - */ - public StringAccumulator(String prefix, String infix, String suffix, String nullString) { - this.prefix = prefix; - this.infix = infix; - this.suffix = suffix; - this.nullString = nullString; - sb = new StringBuffer(); - } - - /** Clear buffer and index */ - public synchronized void clear() { - sb.setLength(0); - index = 0; - } - - /** - * Accumulate input.toString into - * @return true - * @see StandardObjectChecker#doIsValid(Object) - */ - public synchronized boolean isValid(Object input) { - if (input == null) { - if (nullString == null) return true; // ignore - input = nullString; - } - if (null != prefix) sb.append(prefix); - if (null != infix) { - sb.append(index++ + infix); - } - sb.append(input.toString()); - if (null != suffix) sb.append(suffix); - return true; - } - - /** @return result accumulated so far */ - public String toString() { - return sb.toString(); - } - /** @return result accumulated so far */ - public String debugString() { - return "StringAccumulator prefix=" + prefix + " infix=" + infix + " suffix=" + suffix - + " nullString=" + nullString + " index=" + index + " toString=" + toString(); - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/util/StringVisitor.java b/testing/src/main/java/org/aspectj/testing/util/StringVisitor.java deleted file mode 100644 index 123376df4..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StringVisitor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -// todo: non-distribution license? - -package org.aspectj.testing.util; - -/** - * Visitor interface for String -*/ -public interface StringVisitor { - /** - * @param input the String to evaluate - may be null - * @return true if input is accepted and/or process should continue - */ - public boolean accept(String input); -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/StructureModelUtil.java b/testing/src/main/java/org/aspectj/testing/util/StructureModelUtil.java deleted file mode 100644 index 10e03dd22..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/StructureModelUtil.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; - -import org.aspectj.asm.AsmManager; -import org.aspectj.asm.IHierarchy; -import org.aspectj.asm.IProgramElement; - -/** - * Prototype functionality for package view clients. - */ -public class StructureModelUtil { - - public static class ModelIncorrectException extends Exception { - - private static final long serialVersionUID = 8920868549577870993L; - - public ModelIncorrectException(String s) { - super(s); - } - } - - /** - * Check the properties of the current model. The parameter string lists properties of the model that should be correct. If any - * of the properties are incorrect, a ModelIncorrectException is thrown. - * - * @param toCheck comma separated list of name=value pairs that should be found in the ModelInfo object - * @throws ModelIncorrectException thrown if any of the name=value pairs in toCheck are not found - */ - public static void checkModel(String toCheck) throws ModelIncorrectException { - Properties modelProperties = AsmManager.lastActiveStructureModel.summarizeModel().getProperties(); - - // Break toCheck into pieces and check each exists - StringTokenizer st = new StringTokenizer(toCheck, ",="); - while (st.hasMoreTokens()) { - String key = st.nextToken(); - String expValue = st.nextToken(); - boolean expectingZero = false; - try { - expectingZero = (Integer.parseInt(expValue) == 0); - } catch (NumberFormatException nfe) { - // this is ok as expectingZero will be false - } - String value = modelProperties.getProperty(key); - if (value == null) { - if (!expectingZero) - throw new ModelIncorrectException("Couldn't find '" + key + "' property for the model"); - } else if (!value.equals(expValue)) { - throw new ModelIncorrectException("Model property '" + key + "' incorrect: Expected " + expValue + " but found " - + value); - } - } - } - - /** - * This method returns a map from affected source lines in a class to a List of aspects affecting that line. Based on method of - * same name by mik kirsten. To be replaced when StructureModelUtil corrects its implementation - * - * @param the full path of the source file to get a map for - * - * @return a Map from line numbers to a List of ProgramElementNodes. - */ - public static Map getLinesToAspectMap(String sourceFilePath) { - - // Map annotationsMap = - // AsmManager.getDefault().getInlineAnnotations( - // sourceFilePath, - // true, - // true); - - Map aspectMap = new HashMap(); - // Set keys = annotationsMap.keySet(); - // for (Iterator it = keys.iterator(); it.hasNext();) { - // Object key = it.next(); - // List annotations = (List) annotationsMap.get(key); - // for (Iterator it2 = annotations.iterator(); it2.hasNext();) { - // IProgramElement node = (IProgramElement) it2.next(); - - // List relations = node.getRelations(); - // - // for (Iterator it3 = relations.iterator(); it3.hasNext();) { - // IRelationship relationNode = (IRelationship) it3.next(); - - // if (relationNode.getKind().equals("Advice")) { - // List children = relationNode.getTargets(); - // - // List aspects = new Vector(); - // - // for (Iterator it4 = children.iterator(); - // it4.hasNext(); - // ) { - // Object object = it4.next(); - // - // // if (object instanceof LinkNode) { - // // IProgramElement pNode = - // // ((LinkNode) object).getProgramElementNode(); - // // - // // if (pNode.getProgramElementKind() - // // == IProgramElement.Kind.ADVICE) { - // // - // // IProgramElement theAspect = pNode.getParent(); - // // - // // aspects.add(theAspect); - // // - // // } - // // } - // } - // if (!aspects.isEmpty()) { - // aspectMap.put(key, aspects); - // } - // } - // - // } - // } - // } - return aspectMap; - } - - /** - * This method is copied from StructureModelUtil inoder for it to use the working version of getLineToAspectMap() - * - * @return the set of aspects with advice that affects the specified package - */ - public static Set getAspectsAffectingPackage(IProgramElement packageNode) { - List files = StructureModelUtil.getFilesInPackage(packageNode); - Set aspects = new HashSet(); - for (Iterator it = files.iterator(); it.hasNext();) { - IProgramElement fileNode = (IProgramElement) it.next(); - Map adviceMap = getLinesToAspectMap(fileNode.getSourceLocation().getSourceFile().getAbsolutePath()); - Collection values = adviceMap.values(); - for (Iterator it2 = values.iterator(); it2.hasNext();) { - aspects.add(it2.next()); - } - } - return aspects; - } - - public static List getPackagesInModel(AsmManager modl) { - List packages = new ArrayList(); - IHierarchy model = modl.getHierarchy(); - if (model.getRoot().equals(IHierarchy.NO_STRUCTURE)) { - return null; - } else { - return getPackagesHelper(model.getRoot(), IProgramElement.Kind.PACKAGE, null, packages); - } - } - - private static List getPackagesHelper(IProgramElement node, IProgramElement.Kind kind, String prename, List matches) { - - if (kind == null || node.getKind().equals(kind)) { - if (prename == null) { - prename = new String(node.toString()); - } else { - prename = new String(prename + "." + node); - } - Object[] o = new Object[2]; - o[0] = node; - o[1] = prename; - - matches.add(o); - } - - for (Iterator it = node.getChildren().iterator(); it.hasNext();) { - IProgramElement nextNode = (IProgramElement) it.next(); - getPackagesHelper(nextNode, kind, prename, matches); - } - - return matches; - } - - /** - * Helper function sorts a list of resources into alphabetical order - */ - // private List sortElements(List oldElements) { - // Object[] temp = oldElements.toArray(); - // SortingComparator comparator = new SortingComparator(); - // - // Arrays.sort(temp, comparator); - // - // List newResources = Arrays.asList(temp); - // - // return newResources; - // } - // - // private static List sortArray(List oldElements) { - // Object[] temp = oldElements.toArray(); - // SortArrayComparator comparator = new SortArrayComparator(); - // - // Arrays.sort(temp, comparator); - // - // List newElements = Arrays.asList(temp); - // - // return newElements; - // } - // private class SortingComparator implements Comparator { - // public int compare(Object o1, Object o2) { - // IProgramElement p1 = (IProgramElement) o1; - // IProgramElement p2 = (IProgramElement) o2; - // - // String name1 = p1.getName(); - // String name2 = p2.getName(); - // - // return name1.compareTo(name2); - // } - // } - // - // private static class SortArrayComparator implements Comparator { - // public int compare(Object o1, Object o2) { - // Object[] array1 = (Object[]) o1; - // Object[] array2 = (Object[]) o2; - // - // IProgramElement p1 = (IProgramElement) array1[1]; - // IProgramElement p2 = (IProgramElement) array2[1]; - // - // String name1 = p1.getName(); - // String name2 = p2.getName(); - // - // return name1.compareTo(name2); - // } - // } - /** - * @return all of the AspectJ and Java source files in a package - */ - public static List getFilesInPackage(IProgramElement packageNode) { - List packageContents; - if (packageNode == null) { - return null; - } else { - packageContents = packageNode.getChildren(); - } - List files = new ArrayList(); - for (Iterator it = packageContents.iterator(); it.hasNext();) { - IProgramElement packageItem = (IProgramElement) it.next(); - if (packageItem.getKind() == IProgramElement.Kind.FILE_JAVA - || packageItem.getKind() == IProgramElement.Kind.FILE_ASPECTJ) { - files.add(packageItem); - } - } - return files; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/TestClassLoader.java b/testing/src/main/java/org/aspectj/testing/util/TestClassLoader.java deleted file mode 100644 index dd9c10c8f..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/TestClassLoader.java +++ /dev/null @@ -1,157 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * Load classes as File from File[] dirs or URL[] jars. - */ -public class TestClassLoader extends URLClassLoader { - - /** seek classes in dirs first */ - List /*File*/ dirs; - - /** save URL[] only for toString */ - private URL[] urlsForDebugString; - - public TestClassLoader(URL[] urls, File[] dirs) { - super(urls); - this.urlsForDebugString = urls; - LangUtil.throwIaxIfComponentsBad(dirs, "dirs", null); - ArrayList dcopy = new ArrayList(); - - if (!LangUtil.isEmpty(dirs)) { - dcopy.addAll(Arrays.asList(dirs)); - } - this.dirs = Collections.unmodifiableList(dcopy); - } - - - public URL getResource(String name) { - return ClassLoader.getSystemResource(name); - } - - public InputStream getResourceAsStream(String name) { - return ClassLoader.getSystemResourceAsStream(name); - } - - /** We don't expect test classes to have prefixes java, org, or com */ - protected boolean maybeTestClassName(String name) { - return (null != name) - && !name.startsWith("java") - && !name.startsWith("org.") - && !name.startsWith("com."); - } - - public synchronized Class loadClass(String name, boolean resolve) - throws ClassNotFoundException { - // search the cache, our dirs (if maybe test), - // the system, the superclass (URL[]), - // and our dirs again (if not maybe test) - ClassNotFoundException thrown = null; - final boolean maybeTestClass = maybeTestClassName(name); - Class result = findLoadedClass(name); - if (null != result) { - resolve = false; - } else if (maybeTestClass) { - // subvert the dominant paradigm... - byte[] data = readClass(name); - if (data != null) { - result = defineClass(name, data, 0, data.length); - } // handle ClassFormatError? - } - if (null == result) { - try { - result = findSystemClass(name); - } catch (ClassNotFoundException e) { - thrown = e; - } - } - if (null == result) { - try { - result = super.loadClass(name, resolve); - } catch (ClassNotFoundException e) { - thrown = e; - } - if (null != result) { // resolved by superclass - return result; - } - } - if ((null == result) && !maybeTestClass) { - byte[] data = readClass(name); - if (data != null) { - result = defineClass(name, data, 0, data.length); - } // handle ClassFormatError? - } - - if (null == result) { - throw (null != thrown ? thrown : new ClassNotFoundException(name)); - } - if (resolve) { - resolveClass(result); - } - return result; - } - - /** @return null if class not found or byte[] of class otherwise */ - private byte[] readClass(String className) throws ClassNotFoundException { - final String fileName = className.replace('.', '/')+".class"; - for (Iterator iter = dirs.iterator(); iter.hasNext();) { - File file = new File((File) iter.next(), fileName); - if (file.canRead()) { - return getClassData(file); - } - } - return null; - } - - private byte[] getClassData(File f) { - try { - FileInputStream stream= new FileInputStream(f); - ByteArrayOutputStream out= new ByteArrayOutputStream(1000); - byte[] b= new byte[4096]; - int n; - while ((n= stream.read(b)) != -1) { - out.write(b, 0, n); - } - stream.close(); - out.close(); - return out.toByteArray(); - } catch (IOException e) { - } - return null; - } - - /** @return String with debug info: urls and classes used */ - public String toString() { - return "TestClassLoader(urls=" - + Arrays.asList(urlsForDebugString) - + ", dirs=" - + dirs - + ")"; - } -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/TestDiffs.java b/testing/src/main/java/org/aspectj/testing/util/TestDiffs.java deleted file mode 100644 index 54f72e9b9..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/TestDiffs.java +++ /dev/null @@ -1,360 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; - -import org.aspectj.util.LangUtil; - -/** - * Calculated differences between two test runs - * based on their output files - * assuming that tests are logged with prefix [PASS|FAIL] - * (as they are when using <tt>-traceTestsMin</tt> with the Harness). - * @see org.aspectj.testing.drivers.Harness - */ -public class TestDiffs { // XXX pretty dumb implementation - - /** @param args expected, actual test result files */ - public static void main(String[] args) { - if ((null == args) || (2 > args.length)) { - System.err.println("java " + TestDiffs.class.getName() + " expectedFile actualFile {test}"); - return; - } - File expected = new File(args[0]); - File actual = new File(args[1]); - - TestDiffs result = compareResults(expected, actual); - - System.out.println("## Differences between test runs"); - print(System.out, result.added, "added"); - print(System.out, result.missing, "missing"); - print(System.out, result.fixed, "fixed"); - print(System.out, result.broken, "broken"); - - System.out.println("## Summary"); - System.out.println(" # expected " + result.expected.size() + " tests: " + args[0] ); - System.out.println(" # actual " + result.actual.size() + " tests: " + args[1]); - StringBuffer sb = new StringBuffer(); - append(sb, result.added, " added"); - append(sb, result.missing, " missing"); - append(sb, result.broken, " broken"); - append(sb, result.fixed, " fixed"); - append(sb, result.stillPassing, " still passing"); - append(sb, result.stillFailing, " still failing"); - System.out.println(" # diffs: " + sb); - } - - /** - * @param expected the expected/old File results with Harness -traceTestsMin lines - * @param actual the actual/new File results with Harness -traceTestsMin lines - * @return TestDiffs null if error, valid otherwise - */ - public static TestDiffs compareResults(File expected, File actual) { - ArrayList exp = null; - ArrayList act = null; - File reading = expected; - try { - exp = TestDiffs.readTestResults(expected, expected.getPath()); - reading = actual; - act = TestDiffs.readTestResults(actual, actual.getPath()); - - Diffs tests = Diffs.makeDiffs("tests", exp, act, TestResult.BY_NAME); - // remove missing/unexpected (removed, added) tests from results - // otherwise, unexpected-[pass|fail] look like [fixes|broken] - ArrayList expResults = trimByName(exp, tests.missing); - ArrayList actResults = trimByName(act, tests.unexpected); - - Diffs results = Diffs.makeDiffs("results", expResults, actResults, TestResult.BY_PASSNAME); - - // broken tests show up in results as unexpected-fail or missing-pass - // fixed tests show up in results as unexpected-pass or missing-fail - ArrayList broken = new ArrayList(); - ArrayList fixed = new ArrayList(); - split(results.unexpected, fixed, broken); - - return new TestDiffs( - exp, - act, - tests.missing, - tests.unexpected, - broken, - fixed); - } catch (IOException e) { - System.err.println("error reading " + reading); - e.printStackTrace(System.err); // XXX - return null; - } - } - - private static void append(StringBuffer sb, List list, String label) { - if (!LangUtil.isEmpty(list)) { - if (0 < sb.length()) { - sb.append(" "); - } - sb.append(list.size() + label); - } - } - - private static void print(PrintStream out, List list, String label) { - if ((null == out) || LangUtil.isEmpty(list)) { - return; - } -// int i = 0; - final String suffix = " " + label; - final String LABEL = list.size() + suffix; - out.println("## START " + LABEL); - for (Iterator iter = list.iterator(); iter.hasNext();) { - TestResult result = (TestResult) iter.next(); - out.println(" " + result.test + " ## " + suffix); - } - out.println("## END " + LABEL); - } - - /** - * Create ArrayList with input TestResult list - * but without elements in trim list, - * comparing based on test name only. - * @param input - * @param trim - * @return ArrayList with all input except those in trim (by name) - */ - private static ArrayList trimByName(List input, List trim) { - ArrayList result = new ArrayList(); - result.addAll(input); - if (!LangUtil.isEmpty(input) && !LangUtil.isEmpty(trim)) { - for (ListIterator iter = result.listIterator(); iter.hasNext();) { - TestResult inputItem = (TestResult) iter.next(); - for (Iterator iterator = trim.iterator(); - iterator.hasNext(); - ) { - TestResult trimItem = (TestResult) iterator.next(); - if (inputItem.test.equals(trimItem.test)) { - iter.remove(); - break; - } - } - } - } - return result; - } - - - /** split input List by whether the TestResult element passed or failed */ - private static void split(List input, ArrayList pass, ArrayList fail) { - for (ListIterator iter = input.listIterator(); iter.hasNext();) { - TestResult result = (TestResult) iter.next(); - if (result.pass) { - pass.add(result); - } else { - fail.add(result); - } - } - } - - /** - * Read a file of test results, - * defined as lines starting with [PASS|FAIL] - * (produced by Harness option <tt>-traceTestsmin</tt>). - * @return ArrayList of TestResult, one for every -traceTestsMin line in File - */ - private static ArrayList readTestResults(File file, String config) throws IOException { - LangUtil.throwIaxIfNull(file, "file"); - if (null == config) { - config = file.getPath(); - } - ArrayList result = new ArrayList(); - FileReader in = null; - try { - in = new FileReader(file); - BufferedReader input = new BufferedReader(in); - String line; - // XXX handle stream interleaving more carefully - // XXX clip trailing () - // XXX fix elision in test name rendering by -traceTestsMin? - while (null != (line = input.readLine())) { - boolean pass = line.startsWith("PASS"); - boolean fail = false; - if (!pass) { - fail = line.startsWith("FAIL"); - } - if (pass || fail) { - String test = line.substring(4).trim(); - result.add(new TestResult(test, config, pass)); - } - } - } finally { - if (null != in) { - try { in.close(); } - catch (IOException e) {} // ignore - } - } - return result; - } - - private static List safeList(List list) { - return (null == list - ? Collections.EMPTY_LIST - : Collections.unmodifiableList(list)); - } - - /** List of TestResult results from expected run. */ - public final List expected; - - /** List of TestResult results from actual run. */ - public final List actual; - - /** List of TestResult tests disappeared from test suite between expected and actual runs. */ - public final List missing; - - /** List of TestResult tests added to test suite between expected and actual runs. */ - public final List added; - - /** List of TestResult tests in both runs, expected to pass but actually failed */ - public final List broken; - - /** List of TestResult tests in both runs, expected to fail but actually passed */ - public final List fixed; - - /** List of TestResult passed tests in expected run */ - public final List expectedPassed; - - /** List of TestResult failed tests in expected run */ - public final List expectedFailed; - - /** List of TestResult passed tests in actual run */ - public final List actualPassed; - - /** List of TestResult tests failed in actual run */ - public final List actualFailed; - - /** List of TestResult tests passed in both expected and actual run */ - public final List stillPassing; - - /** List of TestResult tests failed in both expected and actual run */ - public final List stillFailing; - - private TestDiffs( - List expected, - List actual, - List missing, - List added, - List broken, - List fixed) { - this.expected = safeList(expected); - this.actual = safeList(actual); - this.missing = safeList(missing); - this.added = safeList(added); - this.broken = safeList(broken); - this.fixed = safeList(fixed); - // expected[Passed|Failed] - ArrayList passed = new ArrayList(); - ArrayList failed = new ArrayList(); - split(this.expected, passed, failed); - expectedPassed = safeList(passed); - expectedFailed = safeList(failed); - - // actual[Passed|Failed] - passed = new ArrayList(); - failed = new ArrayList(); - split(this.actual, passed, failed); - actualPassed = safeList(passed); - actualFailed = safeList(failed); - - // stillPassing: expected.passed w/o broken, missingPasses - passed = new ArrayList(); - passed.addAll(expectedPassed); - passed = trimByName(passed, this.broken); - ArrayList missingPasses = new ArrayList(); - ArrayList missingFails = new ArrayList(); - split(this.missing, missingPasses, missingFails); - passed = trimByName(passed, missingPasses); - stillPassing = safeList(passed); - - // stillFailing: expected.failed w/o fixed, missingFails - failed = new ArrayList(); - failed.addAll(expectedFailed); - failed = trimByName(failed, this.fixed); - failed = trimByName(failed, missingFails); - stillFailing = safeList(failed); - } - - /** results of a test */ - public static class TestResult { - public static final Comparator BY_PASSNAME = new Comparator() { - public int compare(Object o1, Object o2) { - if (o1 == o2) { - return 0; - } - TestResult lhs = (TestResult) o1; - TestResult rhs = (TestResult) o2; - return (lhs.pass == rhs.pass - ? lhs.test.compareTo(rhs.test) - : (lhs.pass ? 1 : -1 )); - } - - public boolean equals(Object lhs, Object rhs) { - return (0 == compare(lhs, rhs)); - } - }; - - public static final Comparator BY_NAME = new Comparator() { - public int compare(Object o1, Object o2) { - if (o1 == o2) { - return 0; - } - TestResult lhs = (TestResult) o1; - TestResult rhs = (TestResult) o2; - return lhs.test.compareTo(rhs.test); - } - - public boolean equals(Object lhs, Object rhs) { - return (0 == compare(lhs, rhs)); - } - }; - - //private static final ArrayList TESTS = new ArrayList(); - public static final String FIELDSEP = "\t"; - - public final String test; - public final String config; - public final boolean pass; - private final String toString; - - public TestResult(String test, String config, boolean pass) { - LangUtil.throwIaxIfNull(test, "test"); - LangUtil.throwIaxIfNull(test, "config"); - this.test = test; - this.config = config; - this.pass = pass; - toString = (pass ? "PASS" : "FAIL") + FIELDSEP + test + FIELDSEP + config; - - } - - /** @return [PASS|FAIL]{FIELDSEP}test{FIELDSEP}config */ - public String toString() { - return toString; - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/UtilLineReader.java b/testing/src/main/java/org/aspectj/testing/util/UtilLineReader.java deleted file mode 100644 index ebb6c9d98..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/UtilLineReader.java +++ /dev/null @@ -1,212 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.*; -import java.util.ArrayList; - -/** - * LineNumberReader which absorbs comments and blank lines - * and renders as file:line - */ -public class UtilLineReader extends LineNumberReader { - /** delimited multi-line output of readToBlankLine */ - public static final String RETURN= "\n\r"; - - private static final String[] NONE = new String[0]; - private static final String cSCRIPT = "#"; - private static final String cJAVA = "//"; - private static final String[] TESTER_LEAD = new String[] {cSCRIPT, cJAVA}; - - /** - * Convenience factory for tester suite files - * @return null if IOException or IllegalArgumentException thrown - */ - public static final UtilLineReader createTester(File file) { - return create(file, TESTER_LEAD, null); - } - - /** - * convenience factory - * @return null if IOException or IllegalArgumentException thrown - */ - public static final UtilLineReader create(File file, - String[] leadComments, String[] eolComments) { - try { - FileReader reader = new FileReader(file); - return new UtilLineReader(reader, file, leadComments, eolComments); - } catch (IllegalArgumentException e) { - } catch (IOException e) { - } - return null; - } - - final private File file; - final private String[] eolComments; - final private String[] leadComments; - transient String lastLine; - - /** - * @param file the File used to open the FileReader - * @param leadComments the String[] to be taken as the start of - * comments when they are the first non-blank text on a line - - * pass null to signal none. - * @param leadComments the String[] to be taken as the start of - * comment anywhere on a line - pass null to signal none. - *@throws IllegalArgumentException if any String in - * leadComments or eolComments is null. - */ - public UtilLineReader(FileReader reader, File file, - String[] leadComments, String[] eolComments) { - super(reader); - this.file = file; - this.eolComments = normalize(eolComments); - this.leadComments = normalize(leadComments); - } - public UtilLineReader(FileReader reader, File file) { - this(reader, file, null, null); - } - - /** @return file:line */ - public String toString() { - return file.getPath() + ":" + getLineNumber(); - } - - /** @return underlying file */ - public File getFile() { return file; } - - /** - * Reader first..last (inclusive) and return in String[]. - * This will return (1+(last-first)) elements only if this - * reader has not read past the first line and there are last lines - * and there are no IOExceptions during reads. - * @param first the first line to read - if negative, use 0 - * @param last the last line to read (inclusive) - * - if less than first, use first - * @return String[] of first..last (inclusive) lines read or - */ - public String[] readLines(int first, int last) { - if (0 > first) first = 0; - if (first > last) last = first; - ArrayList list = new ArrayList(); - try { - String line = null; - while (getLineNumber() < first) { - line = readLine(); - if (null == line) { - break; - } - } - if (getLineNumber() > first) { - // XXX warn? something else read past line - } - if ((null != line) && (first == getLineNumber())) { - list.add(line); - while (last >= getLineNumber()) { - line = readLine(); - if (null == line) { - break; - } - list.add(line); - } - } - } catch (IOException e) { - return NONE; - } - return (String[]) list.toArray(NONE); - } - - /** Skip to next blank line - * @return the String containing all lines skipped (delimited with RETURN) - */ - public String readToBlankLine() throws IOException { - StringBuffer sb = new StringBuffer(); - String input; - while (null != (input = nextLine(false))) { // get next empty line to restart - sb.append(input); - sb.append(RETURN);// XXX verify/ignore/correct - } - return sb.toString(); - } - - /** - * lastLine is set only by readClippedLine, not readLine. - * @return the last line read, after clipping - */ - public String lastLine() { - return lastLine; - } - - /** - * Get the next line from the input stream, stripping eol and - * leading comments. - * If emptyLinesOk is true, then this reads past lines which are - * empty after omitting comments and trimming until the next non-empty line. - * Otherwise, this returns null on reading an empty line. - * (The input stream is not exhausted until this - * returns null when emptyLines is true.) - * @param skipEmpties if true, run to next non-empty line; if false, return next line - * @return null if no more lines or got an empty line when they are not ok, - * or next non-null, non-empty line in reader, - * ignoring comments - */ - public String nextLine(boolean skipEmpties) throws IOException { - String result; - do { - result = readClippedLine(); - if ((null != result) && skipEmpties && (0 == result.length())) { - continue; - } - return result; - } while (true); - } - - /** @return null if no more lines or a clipped line otherwise */ - protected String readClippedLine() throws IOException { - String result = readLine(); - if (result != null) { - result = result.trim(); - int len = result.length(); - for (int i = 0; ((0 < len) && (i < leadComments.length)); i++) { - if (result.startsWith(leadComments[i])) { - result = ""; - len = 0; - } - } - for (int i = 0; ((0 < len) && (i < eolComments.length)); i++) { - int loc = result.indexOf(eolComments[i]); - if (-1 != loc) { - result = result.substring(0, loc); - len = result.length(); - } - } - } - lastLine = result; - return result; - } - - private String[] normalize(String[] input) { - if ((null == input) || (0 == input.length)) return NONE; - String[] result = new String[input.length]; - System.arraycopy(input, 0, result, 0, result.length); - for (int i = 0; i < result.length; i++) { - if ((null == result[i]) || (0 == result[i].length())) { - throw new IllegalArgumentException("empty input at [" + i + "]"); - } - } - return result; - } -} - diff --git a/testing/src/main/java/org/aspectj/testing/util/ValidFileFilter.java b/testing/src/main/java/org/aspectj/testing/util/ValidFileFilter.java deleted file mode 100644 index 8d069af0f..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/ValidFileFilter.java +++ /dev/null @@ -1,123 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileFilter; - -/** - * FileFilter that accepts existing files - * with static singleton variants - * made from inner subclasses. - */ -public class ValidFileFilter implements FileFilter { - //----------------------------- singleton variants - public static final FileFilter EXIST = new ValidFileFilter(); - public static final FileFilter FILE_EXISTS = new FilesOnlyFilter(); - public static final FileFilter DIR_EXISTS = new DirsOnlyFilter(); - public static final FileFilter CLASS_FILE = new ClassOnlyFilter(); - public static final FileFilter JAVA_FILE = new JavaOnlyFilter(); - public static final FileFilter RESOURCE = new ResourcesOnlyFilter(); - - //----------------------------- members - protected final FileFilter delegate; - protected ValidFileFilter(){ - this(null); - } - protected ValidFileFilter(FileFilter delegate){ - this.delegate = delegate; - } - - /** - * Implement <code>FileFilter.accept(File)</code> by checking - * taht input is not null, exists, and is accepted by any delegate. - */ - public boolean accept(File f) { - return ((null != f) && (f.exists()) - && ((null == delegate) || delegate.accept(f))); - } - - //----------------------------- inner subclasses - static class FilesOnlyFilter extends ValidFileFilter { - public boolean accept(File f) { - return (super.accept(f) && (!f.isDirectory())); - } - } - static class ResourcesOnlyFilter extends FilesOnlyFilter { - public boolean accept(File f) { - return (super.accept(f) && (FileUtil.isResourcePath(f.getPath()))); - } - } - static class DirsOnlyFilter extends ValidFileFilter { - public final boolean accept(File f) { - return (super.accept(f) && (f.isDirectory())); - } - } - // todo: StringsFileFilter, accepts String[] variants for each - static class StringFileFilter extends ValidFileFilter { - public static final boolean IGNORE_CASE = true; - protected final String prefix; - protected final String substring; - protected final String suffix; - protected final boolean ignoreCase; - /** true if one of the String specifiers is not null */ - protected final boolean haveSpecifier; - public StringFileFilter(String prefix, String substring, - String suffix, boolean ignoreCase) { - this.ignoreCase = ignoreCase; - this.prefix = preprocess(prefix); - this.substring = preprocess(substring); - this.suffix = preprocess(suffix); - haveSpecifier = ((null != prefix) || (null != substring) - || (null != suffix)); - } - private final String preprocess(String input) { - if ((null != input) && ignoreCase) { - input = input.toLowerCase(); - } - return input; - } - public boolean accept(File f) { - if (!(super.accept(f))) { - return false; - } else if (haveSpecifier) { - String path = preprocess(f.getPath()); - if ((null == path) || (0 == path.length())) { - return false; - } - if ((null != prefix) && (!(path.startsWith(prefix)))) { - return false; - } - if ((null != substring) && (-1 == path.indexOf(substring))) { - return false; - } - if ((null != suffix) && (!(path.endsWith(suffix)))) { - return false; - } - } - return true; - } - } // class StringFileFilter - - static class ClassOnlyFilter extends StringFileFilter { - ClassOnlyFilter() { - super(null, null, ".class", IGNORE_CASE); - } - } - static class JavaOnlyFilter extends StringFileFilter { - JavaOnlyFilter() { - super(null, null, ".java", IGNORE_CASE); - } - } -} // class ValidFileFilter - diff --git a/testing/src/main/java/org/aspectj/testing/util/WebInstall.java b/testing/src/main/java/org/aspectj/testing/util/WebInstall.java deleted file mode 100644 index 3433d55b6..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/WebInstall.java +++ /dev/null @@ -1,208 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2000 Xerox Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - - -package org.aspectj.testing.util; - -import java.io.File; -import java.io.FileWriter; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; - -/** - * Install programmatically using http URL. - * (Very strange that java tool classpath does not accept http URL's.) - * - * Example: - * <p><code>java -classpath aj-testing.jar org.aspectj.testing.util.WebInstall - * http://aspectj.org/download/distribution/aspectj10-tools.jar -text - * install.properties</code> - * - * <p>You can omit the <code>-text install.properties</code> if there is - * a file called "install.properties" in the current directory. - * - * <p>The properties file must define the properties - * <code>output.dir</code> and <code>context.javaPath</code> - * in properties- and platform specifie ways. - * For property values, a backslash must be escaped with another backslash, - * and directory separators should be valid. E.g., on Windows: - * <pre>output.dir=c:\\output\\dir - * context.javaPath=c:\\apps\\jdk1.3.1</pre> - * - * For an installer to complete programmatically, - * the output directory must be empty of colliding files. - * This will fail with a stack trace if anything goes wrong, except for - * simple input errors. - * - * <p>You may also use this as a driver for the known installers - * by specifying the following options (-baseurl must be first):<pre> - * -baseurl {baseurl} - * -version {version} - * -context.javaPath {path to JDK} (properties form) - * -output.dir {path to outDir} (properties form, including trailing /) - * -outdir {path to outDir} (actual form) </pre> - * such that URL= - * <code>{baseurl}<packagePrefix>{version}<packageSuffix>.jar</code> - * and paths to context.javaPath and output.dir are specified in - * properties-compliant format - * - * @see ant script test-product.xml for example of installing from files - * which can be driven from the command-line. - */ -public class WebInstall { - private static final String EOL = "\n"; // todo where is this defined? - public static final String SYNTAX - = "java WebInstall url {args}" + EOL - + " url - to installer" + EOL - + " args - normally -text install.properties" + EOL - + " (if n/a, use install.properties)" + EOL; - - /** default arguments assume file <code>install.properties</code> - * is in current directory */ - private static final String[] ARGS = new String[] - { "-text", "install.properties" }; - - /** @param args the String[] <code>{ "<url>" {, "-text", "<propsPath>" }</code> */ - public static void main(String[] args) throws Exception { - if ((null != args) && (args.length > 0) - && ("-baseurl".equals(args[0]))) { - driver(args); - } else { - try { - new WebInstall().install(args); - } catch (Throwable t) { - System.err.println("Error installing args "); - for (int i = 0; i < args.length; i++) { - System.err.println(" " + i + ": " + args[i]); - } - t.printStackTrace(System.err); - } - } - } - - /** known .jar packages {(prefix, suffix}...} */ - protected static String[] packages = new String[] - { "aspectj-tools-", "" - , "aspectj-docs-", "" - , "ajde-forteModule-", "" - , "ajde-jbuilderOpenTool-", "" - }; - - /** - * Drive install of all jar-based installers. - * @param args the String[] containing<pre> - * -baseurl {baseurl} - * -version {version} - * -context.javaPath {path to JDK} (properties form) - * -output.dir {path to outDir} (properties form, including trailing /) - * -outdir {path to outDir} (actual form) </pre> - * such that URL= - * <code>{baseurl}<packagePrefix>{version}<packageSuffix>.jar</code> - * and paths to context.javaPath and output.dir are specified in - * properties-compliant format - */ - protected static void driver(String[] args) throws Exception { - String baseurl = null; - String version = null; - String outputDir = null; - File outdir = null; - String jdk = null; - for (int i = 0; i < args.length; i++) { - if ("-baseurl".equals(args[i])) { - baseurl = args[++i]; - } else if ("-version".equals(args[i])) { - version = args[++i]; - } else if ("-context.javaPath".equals(args[i])) { - jdk = args[++i]; - } else if ("-output.dir".equals(args[i])) { - outputDir=args[++i]; - } else if ("-outdir".equals(args[i])) { - outdir = new File(args[++i]).getCanonicalFile(); - if (!outdir.isDirectory()) { - outdir.mkdir(); - } - } - } - final File props = File.createTempFile("WebInstall", null); - final String[] ARGS = new String [] {null, "-text", props.getCanonicalPath()}; - for (int i = 0; i < packages.length; i++) { - String name = packages[i++] + version + packages[i]; - File outDir = new File(outdir, name); - FileWriter fw = null; - try { - if (!outDir.isDirectory()) { - outDir.mkdir(); - } - fw = new FileWriter(props); - fw.write("output.dir=" + outputDir + name + "\n"); - fw.write("context.javaPath=" + jdk + "\n"); - fw.close(); - fw = null; - ARGS[0] = baseurl + name + ".jar"; - main(ARGS); - } finally { - try { if (null != fw) fw.close(); } - catch (java.io.IOException e) {} // ignore - } - } - if (props.exists()) props.delete(); - } // driver - - private static boolean printError(String err) { - if (null != err) System.err.println(err); - System.err.println(SYNTAX); - return (null != err); - } - - /** - * Create a classloader using the first argument (presumed to be URL for classloader), - * construct the installer, and invoke it using remaining arguments (or default args). - */ - protected void install(String[] args) throws Exception { - if ((null == args) || (args.length < 1) - || (null == args[0]) || (1 > args[0].length())) { - if (printError("expecting installer URL")) return; - } - URL[] urls = new URL[] { new URL(args[0]) }; - //System.err.println("before: " + render(args)); - args = getArgs(args); - //System.err.println("after: " + render(args)); - URLClassLoader cl = new URLClassLoader(urls); - Class c = cl.loadClass("$installer$.org.aspectj.Main"); // todo: dependency on class name - Method ms = c.getMethod("main", new Class[]{String[].class}); - ms.invoke(null, new Object[] { args }); - } - public static final String render(String[] args) { - StringBuffer sb = new StringBuffer(); - sb.append("["); - for (int i = 0; i < args.length; i++) { - if (0 < i) sb.append(", "); - sb.append("" + args[i]); - } - sb.append("]"); - return sb.toString(); - } - - /** @return args less args[0] or default args if less than 3 arguments */ - - protected String[] getArgs(String[] args) { - if ((null == args) || (args.length < 3)) { - return ARGS; - } else { - String[] result = new String[args.length-1]; - System.arraycopy(args, 1, result, 0, result.length); - return result; - } - } - -} diff --git a/testing/src/main/java/org/aspectj/testing/util/options/Option.java b/testing/src/main/java/org/aspectj/testing/util/options/Option.java deleted file mode 100644 index e845a89bf..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/options/Option.java +++ /dev/null @@ -1,707 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util.options; - -import java.util.*; - -import org.aspectj.util.LangUtil; - -/** - * Immutable schema for an input (command-line) option. - * The schema contains the expected name/label, - * the family (for comparison purposes), - * and permitted prefixes. - * This has operations to accept input values and compare options. - * Options cannot be created directly; for that, use an - * <code>Option.Factory</code>, since it enforces uniqueness - * within the families and options created by the factory. - * <p> - * Option is used with related nested classes to implement relations: - * <ul> - * <li>Option.Factory produces Option</li> - * <li>An Option has a set of Option.Prefixes, - * which are variants of Option.Prefix - * valid for the option (e.g., on/set, force-off, and force-on)</li> - * <li>Option evaluates input, produces Option.Value</li> - * <li>Related instances of Option share an Option.Family, - * which enforce option exclusion, etc.</li> - * </ul> - * The classes are nested as "friends" in order to hide private - * members (esp. constructors) that can be used within relations. - * Most of these classes are immutable. - */ -public class Option implements Comparable { - public static final Prefix ON = new Prefix("-", "on", true, false); - public static final Prefix NONE = new Prefix("", "none", true, false); - public static final Prefix FORCE_ON = - new Prefix("!", "force-on", true, true); - - public static final Prefix FORCE_OFF = - new Prefix("^", "force-off", false, true); - public static final Prefixes LITERAL_PREFIXES = - new Prefixes(new Prefix[] { NONE }); - public static final Prefixes STANDARD_PREFIXES = - new Prefixes(new Prefix[] { ON }); - public static final Prefixes FORCE_PREFIXES = - new Prefixes(new Prefix[] { ON, FORCE_ON, FORCE_OFF }); - - /** family is the key for comparing two options */ - private final Family family; - - /** label expected for the option */ - private final String name; - - /** unique identifier for option */ - private final String optionIdentifier; - - /** prefixes permitted for the option in input */ - private final Prefixes permittedPrefixes; - - /** if true, then match on input that has extra suffix beyond prefix and name */ - private final boolean acceptSuffixedInput; - - /** - * If true, no collision if there are multiple values - * that share the same family but not the same literal value - */ - private final boolean permitMultipleValues; - - /** int number of arguments expected after the option itself */ - private final int numArguments; - - /** - * If numArguments > 0, each element has a list of arguments - * permitted at that index from the initial matching value. - * Elements are not null. - */ - private final String[][] permittedArguments; - - private final int nameLength; - - /* - * Create a standard named boolean option, - * permitting force-on and force-off. - * @param name the String name of the option, e.g., "1.3" for "-1.3" - * @param family - * @param permittedPrefixes - * @param acceptSuffixedInput - * @param permittedArguments - */ - public Option( - String name, - Family family, - Prefixes permittedPrefixes, - boolean acceptSuffixedInput, - String[][] permittedArguments) { - LangUtil.throwIaxIfNull(name, "name"); - LangUtil.throwIaxIfNull(family, "family"); - LangUtil.throwIaxIfNull(permittedPrefixes, "permittedPrefixes"); - this.name = name; - this.nameLength = name.length(); - this.family = family; - this.permittedPrefixes = permittedPrefixes; - this.acceptSuffixedInput = acceptSuffixedInput; - this.permitMultipleValues = false; - if (LangUtil.isEmpty(permittedArguments)) { - permittedArguments = new String[][] { }; - // nominal, unused - } else { - String[][] temp = new String[permittedArguments.length][]; - for (int i = 0; i < temp.length; i++) { - String[] toCopy = permittedArguments[i]; - LangUtil.throwIaxIfNull(toCopy, "no permitted args"); - final int len = toCopy.length; - String[] variants = new String[len]; - System.arraycopy(toCopy, 0, variants, 0, len); - temp[i] = variants; - } - permittedArguments = temp; - } - this.permittedArguments = permittedArguments; - numArguments = permittedArguments.length; - optionIdentifier = family.familyName + "." + name; - } - - public int compareTo(Object other) { - Option option = (Option) other; - int diff = family.compareTo(option.family); - if (0 == diff) { - diff = name.compareTo(option.name); - } - return diff; - } - - public Family getFamily() { - return family; - } - - public boolean permitMultipleValues() { - return permitMultipleValues; - } - - /** - * @return int number of elements in this option, - * e.g., 0 for -g or 1 for -source 1.4 - */ - public int numArguments() { - return numArguments; - } - - /** - * If this value String represents a valid input for this option, - * then create and return the associated Value. - * - * @param value the Value created, or null if invalid - * @return Value if this value is permitted by this option - */ - public Value acceptValue(String value) { - Prefix prefix = hasPrefix(value); - if (null != prefix) { - if (value.startsWith(name, prefix.length())) { - value = value.substring(prefix.length()); - if (value.length() == nameLength) { - return new Value(value, prefix, this); - } else if (acceptSuffixedInput) { - return new Value(value, prefix, this); - } else { - return rejectingSuffixedInput(value); - } - } - } - return null; - } - - /** @return true if we have same option family */ - public boolean sameOptionFamily(Option other) { - return ((null != other) && other.family.equals(family)); - } - - /** @return true if we have same option family and name */ - public boolean sameOptionIdentifier(Option other) { - return (sameOptionFamily(other) && name.equals(other.name)); - } - - public String toString() { - return name; - } - - /** - * Called when ignoreSuffix is off but we got value with suffix. - */ - protected Value rejectingSuffixedInput(String value) { - return null; - } - - /** - * Verify that the input is permitted at this position. - * @param input the String input to check for validity - * @param position the int proposed position (0-based) - * for the input (position 0 is for first argument) - * @return null if this input is valid at this position, - * or a String error message otherwise. - */ - String validArgument(String input, int position) { - if (null == input) { - return "null input"; - } - // assert numArguments == permittedInput.length - if ((position < 0) || (position >= numArguments)) { - return "no input permitted at " + position; - } - String[] permitted = permittedArguments[position]; - for (int i = 0; i < permitted.length; i++) { - if (input.equals(permitted[i])) { - return null; - } - } - return input + " not permitted, expecting one of " - + Arrays.asList(permitted); - } - - String getName() { - return name; - } - Object getKey() { - return family; - } - - private String optionIdentifier() { - return optionIdentifier; - } - - private Prefix hasPrefix(String value) { - for (Iterator iter = permittedPrefixes.iterator(); - iter.hasNext(); - ) { - Prefix prefix = (Prefix) iter.next(); - if (-1 != prefix.prefixLength(value)) { - return prefix; - } - } - return null; - } - - /** - * An option family identifies a set of related options that - * might share no literal specification. - * E.g., the compiler family of options might include - * -ajc and -eclipse, and the debugInfo family of options - * might include -g and -g:vars. - * Option families may permit or avoid option collisions. - * <p> - * For subclasses to permit some collisions and not others, - * they should set permitMultipleFamilyValues to false - * and implement <code>doCollision(Option, Option)</code>. - * <p> - * This relies on Factory to ensure that familyName is - * a unique identifier for the factory. - */ - public static class Family implements Comparable { - - /** unique String identifier for this family */ - private final String familyName; - - /** if true, then report no collisions */ - private final boolean permitMultipleFamilyValues; - - protected Family( - String familyName, - boolean permitMultipleFamilyValues) { - this.familyName = familyName; - this.permitMultipleFamilyValues = permitMultipleFamilyValues; - } - - public int compareTo(Object arg0) { - Family family = (Family) arg0; - return familyName.compareTo(family.familyName); - } - - public boolean sameFamily(Family family) { - return ( - (null != family) && familyName.equals(family.familyName)); - } - - boolean permitMultipleFamilyValues() { - return permitMultipleFamilyValues; - } - - /** - * Options collide if they share the same family - * but are not the same, - * and multiple values are not permitted by the family. - * @param lhs the Option to compare with rhs - * @param rhs the Option to compare with lhs - * @return true if the two options collide, false otherwise - * @throws IllegalArgumentException if the input differ - * and share the same family, but this isn't it. - */ - public final boolean collision(Option lhs, Option rhs) { - if ((lhs == rhs) || (null == lhs) || (null == rhs)) { - return false; - } - Family lhsFamily = lhs.getFamily(); - Family rhsFamily = rhs.getFamily(); - if (!(lhsFamily.sameFamily(rhsFamily))) { - return false; - } - if (lhs.sameOptionIdentifier(rhs)) { - return false; - } - if (this != lhsFamily) { - String s = - "expected family " + this +" got family " + lhsFamily; - throw new IllegalArgumentException(s); - } - return doCollision(lhs, rhs); - } - - /** - * Subclasses implement this to resolve collisions on - * a case-by-case basis. Input are guaranteed to be - * non-null, different, and to share this family. - * This implementation returns - * <code>!permitMultipleFamilyValues</code>. - * - * @param lhs the Option to compare - * @param rhs the other Option to compare - * @return true if there is a collision. - */ - protected boolean doCollision(Option lhs, Option rhs) { - return !permitMultipleFamilyValues; - } - } - - /** - * A factory enforces a namespace on options. - * All options produced from a given factory are unique, - * as are all families. - * Once an option or family is created, it cannot be changed. - * To have a family permit multiple values - * (i.e., ignore collisions), set up the family before any - * associated options are created using - * <code>setupFamily(String, boolean)</code>. - */ - public static class Factory { - private final String factoryName; - - /** enforce uniqueness of family */ - private final Map familyNameToFamily = new TreeMap(); - - /** enforce uniqueness of options */ - private final ArrayList names = new ArrayList(); - - public Factory(String factoryName) { - this.factoryName = factoryName; - } - - /** - * Ensure that the family with this name has the - * specified permission. If the family does not exist, - * it is created. If it does, the permission is checked. - * If this returns false, there is no way to change the - * family permission. - * @param name the String identifier for the family - * @param permitMultipleValues the boolean permission whether to - * allow multiple values in this family - * @return true if family exists with this name and permission - */ - public boolean setupFamily( - String name, - boolean permitMultipleValues) { - LangUtil.throwIaxIfNull(name, "name"); - Family family; - synchronized (familyNameToFamily) { - family = (Family) familyNameToFamily.get(name); - if (null == family) { - family = new Family(name, permitMultipleValues); - familyNameToFamily.put(name, family); - } else if ( - permitMultipleValues - != family.permitMultipleFamilyValues) { - return false; - } - } - return true; - } - - /** - * Register a family with this factory. - * @return null if the family was successfully registered, - * or a String error otherwise - */ - public String registerFamily(Family family) { - if (null == family) { - return "null family"; - } - synchronized (familyNameToFamily) { - Family knownFamily = - (Family) familyNameToFamily.get(family.familyName); - if (null == knownFamily) { - familyNameToFamily.put(family.familyName, family); - } else if (!knownFamily.equals(family)) { - return "different family registered, have " - + knownFamily - + " registering " - + family; - } - } - - return null; - } - - public Option create(String name) { - return create(name, name, FORCE_PREFIXES, false); - } - - public Option create( - String name, - String family, - Prefixes permittedPrefixes, - boolean acceptSuffixedInput) { - return create( - name, - family, - permittedPrefixes, - acceptSuffixedInput, - (String[][]) null); - } - - public Option create( - String name, - String family, - Prefixes permittedPrefixes, - boolean acceptSuffixedInput, - String[][] permittedArguments) { - LangUtil.throwIaxIfNull(name, "name"); - LangUtil.throwIaxIfNull(family, "family"); - LangUtil.throwIaxIfNull( - permittedPrefixes, - "permittedPrefixes"); - Family resolvedFamily; - synchronized (familyNameToFamily) { - resolvedFamily = (Family) familyNameToFamily.get(family); - if (null == resolvedFamily) { - resolvedFamily = new Family(family, false); - familyNameToFamily.put(family, resolvedFamily); - } - } - Option result = - new Option( - name, - resolvedFamily, - permittedPrefixes, - acceptSuffixedInput, - permittedArguments); - synchronized (names) { - String optionIdentifier = result.optionIdentifier(); - if (names.contains(optionIdentifier)) { - String s = "not unique: " + result; - throw new IllegalArgumentException(s); - } else { - names.add(optionIdentifier); - } - } - return result; - } - - public String toString() { - return Factory.class.getName() + ": " + factoryName; - } - -// private void checkUnique(Option result) { -// String name = result.family + "." + result.name; -// } - } - - /** - * The actual input value for an option. - * When an option takes arguments, all the arguments - * are absorbed/flattened into its value. - */ - public static class Value { - private static final String FLATTEN_DELIM = "_"; - - private static final int NOTARGUMENT = -1; - - private static String flatten(String prefix, String suffix) { - return prefix + FLATTEN_DELIM + suffix; - } - - private static String[] unflatten(Value value) { - if (value.argIndex == Value.NOTARGUMENT) { - return new String[] { value.value }; - } - StringTokenizer st = - new StringTokenizer(value.value, FLATTEN_DELIM); - String[] result = new String[st.countTokens()]; - // assert result.length == 1+inputIndex - for (int i = 0; i < result.length; i++) { - result[i] = st.nextToken(); - } - return result; - - } - - public final String value; - public final Prefix prefix; - public final Option option; - private final int argIndex; - - private Value( - String value, - Prefix prefix, - Option option) { - this(value, prefix, option, NOTARGUMENT); - } - private Value( - String value, - Prefix prefix, - Option option, - int argIndex) { - this.value = value; - this.prefix = prefix; - this.option = option; - this.argIndex = argIndex; - // asserts deferred - local clients only - // assert null != value - // assert null != prefix - // assert null != option - // assert 0 <= inputIndex - // assert inputIndex <= option.numArguments() - // assert {number of DELIM} == argIndex - } - - public String[] unflatten() { - return unflatten(this); - } - - /** - * Create new value same as this, but with new prefix. - * If the prefix is the same, return this. - * @param prefix the Prefix to convert to - * @return Value with new prefix - never null - */ - public Value convert(Prefix prefix) { - LangUtil.throwIaxIfNull(prefix, "prefix"); - if (this.prefix.equals(prefix)) { - return this; - } - return new Value( - this.value, - prefix, - this.option, - this.argIndex); - } - - /** - * - * @param other - * @return true if other == this for purposes of collisions - */ - public boolean sameValueIdentifier(Value other) { - return ( - (null != other) - && sameValueIdentifier(option, other.value)); - } - - public boolean sameValueIdentifier(Option option, String value) { - return ( - (null != option) - && this.option.sameOptionIdentifier(option) - && this.value.equals(value)); - } - - public boolean conflictsWith(Value other) { - return ( - (null != other) - && option.equals(other.option) - && (prefix.force == other.prefix.force) - && ((prefix.set != other.prefix.set) - || !value.equals(other.value))); - } - - public String toString() { - return option + "=" + prefix + value; - } - - final Value nextInput(String input) throws InvalidInputException { - final int index = argIndex + 1; - String err = option.validArgument(input, index); - if (null != err) { - throw new InvalidInputException(err, input, option); - } - return new Value(flatten(value, input), prefix, option, index); - } - } - - /** - * A bunch of prefixes. - */ - public static class Prefixes { - final List list; - private Prefixes(Prefix[] prefixes) { - if (LangUtil.isEmpty(prefixes)) { - list = Collections.EMPTY_LIST; - } else { - list = - Collections.unmodifiableList( - Arrays.asList( - LangUtil.safeCopy(prefixes, new Prefix[0]))); - } - } - public Iterator iterator() { - return list.iterator(); - } - } - - /** - * A permitted prefix for an option, mainly so that options - * "-verbose", "^verbose", and "!verbose" can be treated - * as variants (set, force-off, and force-on) of the - * same "verbose" option. - */ - public static class Prefix { - private final String prefix; - private final int prefixLength; - private final String name; - private final boolean set; - private final boolean force; - private Prefix( - String prefix, - String name, - boolean set, - boolean force) { - this.prefix = prefix; - this.name = name; - this.set = set; - this.force = force; - this.prefixLength = prefix.length(); - } - - /** - * Render a value for input if this is set. - * @param value the String to render as an input value - * @return null if value is null or option is not set, - * "-" + value otherwise - */ - public String render(String value) { - return ((!set || (null == value)) ? null : "-" + value); - } - - boolean forceOff() { - return force && !set; - } - boolean forceOn() { - return force && set; - } - public boolean isSet() { - return set; - } - private int length() { - return prefixLength; - } - private int prefixLength(String input) { - if ((null != input) && input.startsWith(prefix)) { - return length(); - } - return -1; - } - public String toString() { - return prefix; - } - } - - /** - * Thrown when an Option specifies required arguments, - * but the arguments are not available. - */ - public static class InvalidInputException extends Exception { - public final String err; - public final String input; - public final Option option; - InvalidInputException(String err, String input, Option option) { - super(err); - this.err = err; - this.input = input; - this.option = option; - } - public String getFullMessage() { - return "illegal input \"" - + input - + "\" for option " - + option - + ": " - + err; - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/options/Options.java b/testing/src/main/java/org/aspectj/testing/util/options/Options.java deleted file mode 100644 index 04a968d88..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/options/Options.java +++ /dev/null @@ -1,152 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util.options; - -import java.util.*; - -import org.aspectj.util.LangUtil; - -/** - * A bunch of options that handle search boilerplate. - * This enforces an initialization phase by permitting - * options to be added only until frozen, and - * permitting matching only after frozen. - */ -public class Options { - - /** if true, then perform extra checks to debug problems */ -// private static final boolean verifying = false; - private static final boolean FROZEN = true; - - /** - * List input unmatched by options, if any. - * @param input the String[] used to generate the values - * @param values the Option.Value[] found from the input - * @return null if no values are null, String list of missed otherwise - */ - public static String missedMatchError( - String[] input, - Values values) { - int[] missed = values.indexMissedMatches(); - LangUtil.throwIaxIfNull(input, "input"); - LangUtil.throwIaxIfNull(values, "values"); - LangUtil.throwIaxIfFalse( - input.length == values.length(), - "input is not matched by values"); - if (0 == missed.length) { - return null; - } - StringBuffer sb = new StringBuffer(); - sb.append("missed values: ["); - for (int i = 0; i < missed.length; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(missed[i] + ": " + input[missed[i]]); - } - sb.append("]"); - return sb.toString(); - } - - private final ArrayList options = new ArrayList(); - private final boolean stopAtFirstMatch; - private boolean frozen = !FROZEN; - - public Options(boolean stopAtFirstMatch) { - this.stopAtFirstMatch = stopAtFirstMatch; - } - - public void freeze() { - if (frozen != FROZEN) { - frozen = FROZEN; - } - } - - public boolean isFrozen() { - return (frozen == FROZEN); - } - - public void addOption(Option option) { - checkFrozen("adding option", !FROZEN); - LangUtil.throwIaxIfNull(option, "option"); - options.add(option); - } - - /** - * Associate options matched, if any, with input by index. - * If an input element is not matched, the corresponding - * result element will be null. - * If there are multi-argument options matched, then - * only the initial element will be non-null, but it - * will contain the accumulated value of the arguments. - * @param input the String[] of input - * @return Option.Value[] corresponding to input - * @throws Option.InvalidInputException when encountering - * invalid arguments to a matched multi-argument option. - */ - public Values acceptInput(String[] input) - throws Option.InvalidInputException { - checkFrozen("matching options", FROZEN); - if ((null == input) || (0 == input.length)) { - return Values.EMPTY; - } - Option.Value[] results = new Option.Value[input.length]; - for (int i = 0; i < input.length; i++) { - Option.Value result = firstMatch(input[i]); - final int index = i; - if (null != result) { - for (int len = result.option.numArguments(); - len > 0; - len--) { - i++; - if (i >= input.length) { - throw new Option.InvalidInputException( - "not enough arguments", - null, - result.option); - } - result = result.nextInput(input[i]); - } - } - results[index] = result; - } - return Values.wrapValues(results); - } - - private void checkFrozen(String actionLabel, boolean expectFrozen) { - if (expectFrozen != isFrozen()) { - if (null == actionLabel) { - actionLabel = "use"; - } - if (expectFrozen) { - actionLabel = "must freeze before " + actionLabel; - } else { - actionLabel = "frozen before " + actionLabel; - } - throw new IllegalStateException(actionLabel); - } - } - - private Option.Value firstMatch(String value) { - LangUtil.throwIaxIfNull(value, "value"); -// ArrayList list = new ArrayList(); - for (Iterator iter = options.iterator(); iter.hasNext();) { - Option option = (Option) iter.next(); - Option.Value result = option.acceptValue(value); - if (null != result) { - return result; - } - } - return null; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/util/options/Values.java b/testing/src/main/java/org/aspectj/testing/util/options/Values.java deleted file mode 100644 index 574969080..000000000 --- a/testing/src/main/java/org/aspectj/testing/util/options/Values.java +++ /dev/null @@ -1,714 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.util.options; - -import java.util.*; - -import org.aspectj.testing.util.options.Option.Value; -import org.aspectj.util.LangUtil; - -/** - * Wrapper for Value[] that handles search boilerplate. - */ -public class Values { - public static final Values EMPTY; - /** used by methods taking Selector to halt processing early */ - private static final boolean VERIFYING = true; - private static final boolean FIND_ALL = true; - - private static final String NO_ERROR = "no error"; - - static { - EMPTY = new Values(new Value[0]); - } - - public static Values wrapValues(Value[] values) { - if ((null == values) || (0 == values.length)) { - return EMPTY; - } - return new Values(values); - } - - public static Values wrapValues(Values[] values) { - if ((null == values) || (0 == values.length)) { - return EMPTY; - } - Value[] input = null; - if (values.length == 1) { - input = values[0].asArray(); - LangUtil.throwIaxIfNull(input, "values"); - } else { - int length = 0; - for (int i = 0; i < values.length; i++) { - if (values[i] == null) { - LangUtil.throwIaxIfNull(null, "null value[" + i + "]"); - } - length += values[i].length(); - } - input = new Value[length]; - length = 0; - Value[] temp; - for (int i = 0; i < values.length; i++) { - temp = values[i].asArray(); - System.arraycopy(temp, 0, input, length, temp.length); - length += temp.length; - } - } - return new Values(input); - } - - static int[] invert(int[] missed, int length) { - final int MAX = length; - final int len = MAX - missed.length; - final int[] result = new int[len]; - int missedIndex = 0; - int resultIndex = 0; - for (int counter = 0; counter < MAX; counter++) { - // catch result up to missed - while (((missedIndex >= missed.length) - || (missed[missedIndex] > counter)) - && (counter < MAX)) { - result[resultIndex++] = counter++; - } - // absorb missed up to counter - while ((missedIndex < missed.length) - && (missed[missedIndex] <= counter) - && (counter < MAX)) { - missedIndex++; - } - } - return result; - } - - private static Option.Value[] toArray(ArrayList list) { - return (Option.Value[]) list.toArray(new Option.Value[0]); - } - - /** - * Resolve input to remove any values matching the same options, - * where option conflicts are handled by option forcing. - * First, for any force-off value, all matching set-on and - * the force-off itself are removed. At this time, if there - * is a matching force-on, then this will return an error. - * Next, for any force-on value, it is converted to set-on, - * and any other matching set-on value is removed. - * Finally, this signals a collision if two values share - * the same option family and the family reports that this is - * a collision. - * In all cases, only the first error detected is reported. - * @param input the Option.Value[] matched from the input, - * (forced/duplicate options will be set to null) - * @return String error during resolution, or null if no error - */ - private static String resolve(Option.Value[] input) { - String err = null; - if (LangUtil.isEmpty(input)) { - return null; - } - - Map familyToMatches = new TreeMap(); - for (int i = 0;(null == err) && (i < input.length); i++) { - if (null != input[i]) { - Option.Family family = input[i].option.getFamily(); - int[] matches = (int[]) familyToMatches.get(family); - if (null == matches) { - matches = match(input, i); - familyToMatches.put(family, matches); - } - } - } - - familyToMatches = Collections.unmodifiableMap(familyToMatches); - for (Iterator iter = familyToMatches.entrySet().iterator(); - (null == err) && iter.hasNext(); - ) { - Map.Entry entry = (Map.Entry) iter.next(); - int[] matches = (int[]) entry.getValue(); - err = resolve(input, matches); - } - return err; - } - - /** - * Resolve all related options into one - * by nullifying or modifying the values. - * - * First, for any force-off value, - * remove all identical set-on - * and the force-off itself, - * and alert on any identical force-on. - * - * Next, for any force-on value, - * convert to set-on, - * throw Error on any same-family force-off value, - * remove any identical force-on or set-on value, - * alert on any other non-identical same-family force-on value, - * remove any same-family set-on value, - * and alert on any same-family set-off value. - * - * Finally, alert if any two remaining values share - * the same option family, unless the option is marked - * as permitting multiple values. - * - * @param input the Option.Value[] matching the input - * @param matches the int[] list of indexes into input for - * values for related by option - * (all such values must have option matched by family) - * @return String error, if any, or null if no error - * @see #match(Option.Value[], int) - */ - private static String resolve(Option.Value[] input, int[] matches) { - String err = null; - // seek force-off -// Option.Value forceOff = null; - Option option = null; - // find and remove any force-off - for (int i = 0;(null == err) && (i < matches.length); i++) { - Option.Value value = input[matches[i]]; - if (null != value) { - // verify that matches are in the same family - if (VERIFYING) { - if (null == option) { - option = value.option; - } else if (!(option.sameOptionFamily(value.option))) { - String s = - value.option - + " has different family from " - + option; - throw new IllegalArgumentException(s); - } - } - if (value.prefix.forceOff()) { - err = removeForceOff(input, value, matches); - } - } - } - // find and set any force-on, removing others - for (int i = 0;(null == err) && (i < matches.length); i++) { - Option.Value value = input[matches[i]]; - if (null != value) { - if (value.prefix.forceOn()) { - err = convertForceOn(input, i, matches); - } - } - } - // remove any exact duplicates - for (int i = 0;(null == err) && (i < matches.length); i++) { - Option.Value value = input[matches[i]]; - if (null != value) { - for (int j = i + 1; j < matches.length; j++) { - if (value.sameValueIdentifier(input[matches[j]])) { - input[matches[j]] = null; - } - } - } - } - // signal error if two left unless permitMultipleFamilyValues - Option.Value first = null; - for (int i = 0;(null == err) && (i < matches.length); i++) { - Option.Value value = input[matches[i]]; - if (null != value) { - if (null == first) { - first = value; - if (first - .option - .getFamily() - .permitMultipleFamilyValues()) { - break; - } - } else { - err = "collision between " + first + " and " + value; - } - } - } - - return err; - } - - /** - * For any force-off value, - * remove all set-on or force-off with same value - * (including the force-off itself), - * and alert on any identical force-on. - * @param input the Option.Value[] matching the input - * @param value the force-off Option.Value to remove - * @param matches the int[] list of indexes into input for - * values for related by option - * (all such values must have matching option) - * @return String error if any - */ - private static String removeForceOff( - Option.Value[] input, - Option.Value value, - int[] matches) { - if (!value.prefix.forceOff()) { - throw new IllegalArgumentException( - "expecting force-off: " + value); - } - for (int i = 0; i < matches.length; i++) { - Option.Value match = input[matches[i]]; - if ((null != match) && value.sameValueIdentifier(match)) { - if (match.prefix.forceOn()) { - return "force conflict between " - + value - + " and " - + match; - } else { - input[matches[i]] = null; // unset matches[i]? - } - } - } - return null; - } - - /** - * For this force-on value, convert to set-on, - * throw Error on any same-family force-off value, - * remove any identical force-on or set-on value, - * alert on any other non-identical same-family force-on value, - * remove any same-family set-on value, - * and alert on any same-family set-off value. - * This must be called after <code>removeForceOff(..)</code>. - * @param input the Option.Value[] to modify - * @param valueIndex the int index in matches to find the force-on - * and to start after - * @param matches the int[] map into input entries with matching options - * @return - * @throw Error if any matching force-off found - */ - private static String convertForceOn( - Option.Value[] input, - int valueIndex, - int[] matches) { - Option.Value value = input[matches[valueIndex]]; - if (!value.prefix.forceOn()) { - throw new IllegalArgumentException( - "expecting force-on: " + value); - } - input[matches[valueIndex]] = value.convert(Option.ON); - for (int i = 0; i < matches.length; i++) { - if (i == valueIndex) { - continue; - } - Option.Value match = input[matches[i]]; - if (null != match) { - // assert match.sameOptionFamily(value); - if (match.prefix.forceOff()) { - throw new Error( - "unexpected force-off:" - + match - + " when processing " - + value); - } - if (value.option.sameOptionIdentifier(match.option)) { - input[matches[i]] = null; - // remove any identical force-on or set - } else if (match.prefix.forceOn()) { - return "conflict between " + match + " and " + value; - } else if (match.prefix.isSet()) { - input[matches[i]] = null; - // remove any same-value set-on value - } else { // same family, force-off - return "collision between " + match + " and " + value; - } - } - } - return null; - } - - /** - * Get a list of input matching the option in the initial value, - * rendered as indexes into the input array. - * @param input the Option.Value[] to seek in - * @param start the int index of the starting position - * @return int[] of indexes into input with the same option - * as index[start] - never null, but can be empty - */ - private static int[] match(Option.Value[] input, int start) { - IntList result = new IntList(); - Option.Family key = null; - Option.Family nextKey = null; - for (int i = start; i < input.length; i++) { - if (null != input[i]) { - nextKey = input[i].option.getFamily(); - if (null == key) { - key = nextKey; - result.add(i); - } else if (key.equals(nextKey)) { - result.add(i); - } - } - } - return result.getList(); - } - - static int nullify(Option.Value[] values, Selector selector) { - LangUtil.throwIaxIfNull(selector, "selector"); - int changed = 0; - for (int i = 0; i < values.length; i++) { - final boolean accepted; - try { - accepted = selector.accept(values[i]); - } catch (Error e) { - if (e != Selector.STOP) { - throw e; - } - break; - } - if (accepted) { - if (null != values[i]) { - values[i] = null; - changed++; - } - } - } - return changed; - } - - /** - * Render set values as String using associated prefix. - * @param values the Value[] to render - * @return String[] of values rendered for output - * (never null or longer than values, but might be shorter) - */ - private static String[] render(Value[] values) { - ArrayList list = new ArrayList(); - for (int i = 0; i < values.length; i++) { - if (null != values[i]) { - String[] output = values[i].unflatten(); - if (LangUtil.isEmpty(output)) { - throw new Error("no output for " + values[i]); - } - - String s = values[i].prefix.render(output[0]); - if (null != s) { // this means the prefix is set - list.add(s); - for (int j = 1; j < output.length; j++) { - list.add(output[j]); - } - } - } - } - return (String[]) list.toArray(new String[list.size()]); - } - - private final Option.Value[] values; - private Option.Value[] valuesNotNull; - private String resolveError; - - private Values(Value[] values) { - this.values = new Value[values.length]; - System.arraycopy(values, 0, this.values, 0, values.length); - } - - public int length() { - return values.length; - } - - public Option.Value[] asArray() { - Option.Value[] result = new Option.Value[values.length]; - System.arraycopy(values, 0, result, 0, result.length); - return result; - } - - /** - * Emit as String[] the non-null values. - * @return String[] of matched entries (never null, elements not null) - */ - public String[] render() { - return Values.render(valuesNotNull()); - } - - public String toString() { - return Arrays.asList(values).toString(); - } - - /** - * Create index into values of those that were matched, - * including the options and their arguments. - * @return int[] of elements in values that are not null (options) - * or that represent option arguments - */ - public int[] indexMatches() { - // must be in order, low to high - final int[] missed = indexMissedMatches(); - return invert(missed, length()); - } - - /** - * Create index into values of missed input, - * taking into account that matched arguments are - * represented as null. - * @return int[] of elements in values that are null - * or optionally represent option arguments - */ - public int[] indexMissedMatches() { - MissedSelector selector = new MissedSelector(); - find(selector, FIND_ALL); - String errors = selector.getErrors(); - if (null != errors) { - throw new Error(errors); - } - return selector.getResult(); - } - - public Value firstInFamily(Option.Family family) { - return findFirst(new ValueSelector(family)); - } - - public Value[] allInFamily(Option.Family family) { - return find(new ValueSelector(family), FIND_ALL); - } - - public Value firstOption(Option option) { - return findFirst(new ValueSelector(option)); - } - - public Value[] allOption(Option option) { - return find(new ValueSelector(option), FIND_ALL); - } - - public Value firstValue(Option option, String value) { - LangUtil.throwIaxIfNull(value, "value"); - return findFirst(new ValueSelector(option, value)); - } - - public Value[] allValues(Option option, String value) { - LangUtil.throwIaxIfNull(value, "value"); - return find(new ValueSelector(option, value), FIND_ALL); - } - - public boolean isResolved() { - return ((this != EMPTY) && (null != resolveError)); - } - - /** - * - * @param selector the Selector to pick out entries to nullify - * (should throw STOP to halt processing) - * @return Values resulting from nullifying entries, - * or this if none were changed - */ - public Values nullify(Selector selector) { - if (null == selector) { - return this; - } - Value[] temp = asArray(); - int changed = nullify(temp, selector); - if (0 == changed) { - return this; - } - return new Values(temp); - } - - /** - * Resolve options, removing duplicates by force if necessary. - * If any error is returned, then the values are left unchanged. - * @return String error, if any - * @throws IllegalStateException if <code>isResolved()</code> - */ - public String resolve() { - if (isResolved()) { - throw new IllegalStateException("already resolved"); - } - Option.Value[] temp = asArray(); - resolveError = resolve(temp); - if (null == resolveError) { - System.arraycopy(temp, 0, values, 0, temp.length); - valuesNotNull = null; - resolveError = NO_ERROR; - return null; - } - return resolveError; - } - - protected Option.Value findFirst(Selector filter) { - Option.Value[] result = find(filter, !FIND_ALL); - return (0 == result.length ? null : result[0]); - } - - protected Option.Value[] find(Selector filter, boolean findAll) { - LangUtil.throwIaxIfNull(filter, "filter"); - ArrayList result = new ArrayList(); - for (int i = 0; i < values.length; i++) { - final boolean accepted; - try { - accepted = filter.accept(values[i]); - } catch (Error e) { - if (Selector.STOP != e) { - throw e; - } - break; - } - if (accepted) { - result.add(values[i]); - if (findAll != FIND_ALL) { - break; - } - } - } - return toArray(result); - } - - private Option.Value[] valuesNotNull() { - if (null == valuesNotNull) { - ArrayList list = new ArrayList(); - for (int i = 0; i < this.values.length; i++) { - if (null != this.values[i]) { - list.add(this.values[i]); - } - } - valuesNotNull = toArray(list); - } - return valuesNotNull; - } - - public static class Selector { - public static final Error STOP = new Error("stop invoking Selector"); - protected Selector() { - } - protected boolean accept(Value value) { - return false; - } - } - protected static class ValueSelector extends Selector { - - private final Option option; - private final Option.Family family; - private final String value; - ValueSelector(Option.Family family) { - LangUtil.throwIaxIfNull(family, "family"); - this.family = family; - option = null; - value = null; - } - ValueSelector(Option option) { - this(option, (String) null); - } - ValueSelector(Option option, String value) { - LangUtil.throwIaxIfNull(option, "option"); - this.option = option; - family = null; - this.value = value; - } - protected boolean accept(Value value) { - if (null == value) { - return false; - } - if (null != family) { - return family.sameFamily(value.option.getFamily()); - } else if (!option.sameOptionIdentifier(value.option)) { - return false; - } else { - return ((null == this.value) - || (this.value.equals(value.value))); - } - } - } - - /** pick all null entries (except for args), return as int[] */ - protected static class MissedSelector extends Selector { - public static final String DELIM = "; "; - final IntList result = new IntList(); - int index; - final StringBuffer errors = new StringBuffer(); - int argsExpected; - Option argsExpectedFor; - MissedSelector() { - } - - int[] getResult() { - return result.getList(); - } - - /** - * add index if value is null - * unless skipArguments - */ - protected boolean accept(Value value) { - index++; - if (null != value) { - if (0 < argsExpected) { // expected more (null) args - missedArgsFor(argsExpectedFor, argsExpected); - } - argsExpected = value.option.numArguments(); - argsExpectedFor = value.option; - } else if (0 < argsExpected) { // ignore null in arg position - argsExpected--; - if (0 == argsExpected) { - argsExpectedFor = null; - } - } else { // null, not expecting arg, so missing - result.add(index - 1); - return true; - } - return false; - } - - private void missedArgsFor(Option option, int numArgs) { - errors.append("missed "); - errors.append(numArgs + " args for "); - errors.append(option + DELIM); - } - - String getErrors() { - if (0 < argsExpected) { - } - if (0 == errors.length()) { - return null; - } - return errors.toString(); - } - } - - static class IntList { - // not synchronized - used only in one thread - static String render(int[] input) { - if (null == input) { - return "null"; - } - StringBuffer sb = new StringBuffer(); - sb.append("["); - for (int i = 0; i < input.length; i++) { - if (i > 0) { - sb.append(", " + input[i]); - } else { - sb.append("" + input[i]); - } - } - sb.append("]"); - return sb.toString(); - } - - private int[] input = new int[256]; - private int insert; - private void add(int i) { - if (insert >= input.length) { - int[] temp = new int[insert + 256]; - for (int j = 0; j < input.length; j++) { - temp[j] = input[j]; - } - input = temp; - } - input[insert++] = i; - } - - private int[] getList() { - int[] result = new int[insert]; - for (int i = 0; i < result.length; i++) { - result[i] = input[i]; - } - return result; - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/xml/AjcSpecXmlReader.java b/testing/src/main/java/org/aspectj/testing/xml/AjcSpecXmlReader.java deleted file mode 100644 index 370a9ac91..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/AjcSpecXmlReader.java +++ /dev/null @@ -1,526 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC), - * 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * Wes Isberg resolver - * ******************************************************************/ - -package org.aspectj.testing.xml; - -import java.io.*; -//import java.util.Vector; - -import org.apache.commons.digester.Digester; -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.bridge.SourceLocation; -import org.aspectj.testing.harness.bridge.*; -import org.aspectj.testing.util.RunUtils; -import org.aspectj.util.LangUtil; -import org.xml.sax.*; -import org.xml.sax.SAXException; - -/** - * Read an ajc test specification in xml form. - * Input files should comply with DOCTYPE - */ -public class AjcSpecXmlReader { - /* - * To add new elements or attributes: - * - update the DOCTYPE - * - update setupDigester(..) - * - new sub-elements should be created - * - new attributes should have values set as bean properties - * (possibly by mapping names) - * - new sub-elements should be added to parents - * => the parents need the add method - e.g., add{foo}({foo} toadd) - * - add tests - * - add compile-time checks for mapping APIs in - * setupDigesterComipileTimeCheck - * - when adding an attribute set by bean introspection, - * add to the list returned by expectedProperties() - * - update any client writers referring to the DOCTYPE, as necessary. - * - the parent IXmlWriter should delegate to the child component - * as IXmlWriter (or write the subelement itself) - * - * Debugging - * - use logLevel = 2 for tracing - * - common mistakes - * - dtd has to match input - * - no rule defined (or misdefined) so element ignored - * - property read-only (?) - */ - -// private static final String EOL = "\n"; - - /** presumed relative-path to dtd file for any XML files written by writeSuiteToXmlFile */ - public static final String DTD_PATH = "../tests/ajcTestSuite.dtd"; - - /** expected doc type of AjcSpec XML files */ - public static final String DOCTYPE = "<!DOCTYPE " - + AjcTest.Suite.Spec.XMLNAME + " SYSTEM \"" + DTD_PATH + "\">"; - - private static final AjcSpecXmlReader ME - = new AjcSpecXmlReader(); - - /** @return shared instance */ - public static final AjcSpecXmlReader getReader() { - return ME; - } - - public static void main(String[] a) throws IOException { - writeDTD(new File("../tests/ajcTestSuite2.dtd")); - } - - /** - * Write a DTD to dtdFile. - * @deprecated - * @param dtdFile the File to write to - */ - public static void writeDTD(File dtdFile) throws IOException { - LangUtil.throwIaxIfNull(dtdFile, "dtdFile"); - PrintWriter out = new PrintWriter(new FileWriter(dtdFile)); - try { - out.println("<!-- document type for ajc test suite - see " - + AjcSpecXmlReader.class.getName() + " -->"); - //out.println(getDocType()); - } finally { - out.close(); - } - } - - private static final String[] LOG = new String[] {"info", "debug", "trace" }; - - // XXX logLevel n>0 causes JUnit tests to fail! - private int logLevel = 0; // use 2 for tracing - - private AjcSpecXmlReader() {} - - /** @param level 0..2, info..trace */ - public void setLogLevel(int level) { - if (level < 0) { - level = 0; - } - if (level > 2) { - level = 2; - } - logLevel = level; - } - - /** - * Print an IXmlWritable to the output file - * with our leader and DOCTYPE. - * @param output the File to write to - overwritten - * @param tests the List of IXmlWritable to write - * @return null if no warnings detected, warnings otherwise - */ - public String writeSuiteToXmlFile(File output, IXmlWritable topNode) throws IOException { - PrintWriter writer = new PrintWriter(new FileOutputStream(output)); - XMLWriter printSink = new XMLWriter(writer); - writer.println(""); - writer.println(AjcSpecXmlReader.DOCTYPE); - writer.println(""); - topNode.writeXml(printSink); - writer.close(); - String parent = output.getParent(); - if (null == parent) { - parent = "."; - } - String dtdPath = parent + "/" + DTD_PATH; - File dtdFile = new File(dtdPath); - if (!dtdFile.canRead()) { - return "expecting dtd file: " + dtdFile.getPath(); - } - return null; - } - - /** - * Read the specifications for a suite of AjcTest from an XML file. - * This also sets the suite dir in the specification. - * @param file the File must be readable, comply with DOCTYPE. - * @return AjcTest.Suite.Spec read from file - * @see setLogLevel(int) - */ - public AjcTest.Suite.Spec readAjcSuite(File file) throws IOException, AbortException { - // setup loggers for digester and beanutils... - System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); // XXX - System.setProperty("org.apache.commons.logging.simplelog.defaultlog", LOG[logLevel]); // trace debug XXX - - final Digester digester = makeDigester(file); - SuiteHolder holder = new SuiteHolder(); - digester.push(holder); - FileInputStream input = new FileInputStream(file); - try { - digester.parse(input); - } catch (SAXException e) { - MessageUtil.fail("parsing " + file, e); - } finally { - if (null != input) { - input.close(); - input = null; - } - } - AjcTest.Suite.Spec result = holder.spec; - if (null != result) { - file = file.getAbsoluteFile(); - result.setSourceLocation(new SourceLocation(file, 1)); - File suiteDir = file.getParentFile(); - if (null == suiteDir) { - // should not be the case if absolute - suiteDir = new File("."); // user.dir? - } - result.setSuiteDirFile(suiteDir); - if (result.runtime.isVerbose()) { // XXX hack fixup - RunUtils.enableVerbose(result); - } - } - return result; - } - - private Digester makeDigester(final File suiteFile) { - // implement EntityResolver directly; set is failing - Digester result = new Digester() { - final SuiteResolver resolver = new SuiteResolver(suiteFile); - public InputSource resolveEntity( - String publicId, - String systemId) - throws SAXException { - return resolver.resolveEntity(publicId, systemId); - } - }; - setupDigester(result); - return result; - } - - /** set up the mapping between the xml and Java. */ - private void setupDigester(Digester digester) { - // XXX supply sax parser to ignore white space? - digester.setValidating(true); -// try { -// // this is the correct approach, but the commons parser -// // fails to accept a second, overriding registration - see -// // http://lists.xml.org/archives/xml-dev/200111/msg00959.html -// digester.getXMLReader().setEntityResolver(new SuiteResolver(suiteFile)); -// } catch (SAXException e) { -// System.err.println("unable to set entity resolver"); -// e.printStackTrace(System.err); -// } - - // element names come from the element components - final String suiteX = AjcTest.Suite.Spec.XMLNAME; - final String ajctestX = suiteX + "/" + AjcTest.Spec.XMLNAME; - final String compileX = ajctestX + "/" + CompilerRun.Spec.XMLNAME; - final String inccompileX = ajctestX + "/" + IncCompilerRun.Spec.XMLNAME; - final String runX = ajctestX + "/" + JavaRun.Spec.XMLNAME; - final String dirchangesX = "*/" + DirChanges.Spec.XMLNAME; - final String messageX = "*/" + SoftMessage.XMLNAME; - final String messageSrcLocX = messageX + "/" +SoftSourceLocation.XMLNAME; - - // ---- each sub-element needs to be created - // handle messages the same at any level - digester.addObjectCreate(suiteX, AjcTest.Suite.Spec.class.getName()); - digester.addObjectCreate(ajctestX, AjcTest.Spec.class.getName()); - digester.addObjectCreate(compileX, CompilerRun.Spec.class.getName()); - //digester.addObjectCreate(compileX + "/file", AbstractRunSpec.WrapFile.class.getName()); - digester.addObjectCreate(inccompileX, IncCompilerRun.Spec.class.getName()); - digester.addObjectCreate(runX, JavaRun.Spec.class.getName()); - digester.addObjectCreate(messageX, SoftMessage.class.getName()); - digester.addObjectCreate(messageSrcLocX, SoftSourceLocation.class.getName()); - digester.addObjectCreate(dirchangesX, DirChanges.Spec.class.getName()); - - // ---- set bean properties for sub-elements created automatically - // -- some remapped - warnings - // - if property exists, map will not be used - digester.addSetProperties(suiteX); // ok to have suite messages and global suite options, etc. - digester.addSetProperties(ajctestX, - new String[] { "title", "dir", "pr"}, - new String[] { "description", "testDirOffset", "bugId"}); - digester.addSetProperties(compileX, - new String[] { "files", "argfiles"}, - new String[] { "paths", "argfiles"}); - digester.addSetProperties(compileX + "/file"); - digester.addSetProperties(inccompileX, "classes", "paths"); - digester.addSetProperties(runX, - new String[] { "class", "vm", "skipTester", "fork", "vmargs", "aspectpath", "module"}, - new String[] { "className", "javaVersion", "skipTester", "fork", "vmArgs", "aspectpath", "module"}); - digester.addSetProperties(dirchangesX); - digester.addSetProperties(messageX); - digester.addSetProperties(messageSrcLocX, "line", "lineAsString"); - digester.addSetProperties(messageX, "kind", "kindAsString"); - digester.addSetProperties(messageX, "line", "lineAsString"); - //digester.addSetProperties(messageX, "details", "details"); - // only file subelement of compile uses text as path... XXX vestigial - digester.addCallMethod(compileX + "/file", "setFile", 0); - - // ---- when subelements are created, add to parent - // add ajctest to suite, runs to ajctest, files to compile, messages to any parent... - // the method name (e.g., "addSuite") is in the parent (SuiteHolder) - // the class (e.g., AjcTest.Suite.Spec) refers to the type of the object created - digester.addSetNext(suiteX, "addSuite", AjcTest.Suite.Spec.class.getName()); - digester.addSetNext(ajctestX, "addChild", AjcTest.Spec.class.getName()); - digester.addSetNext(compileX, "addChild", CompilerRun.Spec.class.getName()); - digester.addSetNext(inccompileX, "addChild", IncCompilerRun.Spec.class.getName()); - digester.addSetNext(runX, "addChild", JavaRun.Spec.class.getName()); - //digester.addSetNext(compileX + "/file", "addWrapFile", AbstractRunSpec.WrapFile.class.getName()); - digester.addSetNext(messageX, "addMessage", IMessage.class.getName()); - // setSourceLocation is for the inline variant - // addSourceLocation is for the extra - digester.addSetNext(messageSrcLocX, "addSourceLocation", ISourceLocation.class.getName()); - digester.addSetNext(dirchangesX, "addDirChanges", DirChanges.Spec.class.getName()); - - // can set parent, but prefer to have "knows-about" flow down only... - } - - // ------------------------------------------------------------ testing code - /** - * Get expected bean properties for introspection tests. - * This should return an expected property for every attribute in DOCTYPE, - * using any mapped-to names from setupDigester. - */ - static BProps[] expectedProperties() { - return new BProps[] - { - new BProps(AjcTest.Suite.Spec.class, - new String[] { "suiteDir"}), // verbose removed - new BProps(AjcTest.Spec.class, - new String[] { "description", "testDirOffset", "bugId"}), - // mapped from { "title", "dir", "pr"} - new BProps(CompilerRun.Spec.class, - new String[] { "files", "options", - "staging", "badInput", "reuseCompiler", "includeClassesDir", - "argfiles", "aspectpath", "classpath", "extdirs", - "sourceroots", "xlintfile", "outjar"}), - new BProps(IncCompilerRun.Spec.class, - new String[] { "tag" }), - new BProps(JavaRun.Spec.class, - new String[] { "className", "skipTester", "options", - "javaVersion", "errStreamIsError", "outStreamIsError", - "fork", "vmArgs", "aspectpath"}), - // mapped from { "class", ...} - new BProps(DirChanges.Spec.class, - new String[] { "added", "removed", "updated", "unchanged", "dirToken", "defaultSuffix"}), -// new BProps(AbstractRunSpec.WrapFile.class, -// new String[] { "path"}), - new BProps(SoftMessage.class, - new String[] { "kindAsString", "lineAsString", "text", "details", "file"}) - // mapped from { "kind", "line", ...} - }; - } - - /** - * This is only to do compile-time checking for the APIs impliedly - * used in setupDigester(..). - * The property setter checks are redundant with tests based on - * expectedProperties(). - */ - private static void setupDigesterCompileTimeCheck() { - if (true) { throw new Error("never invoked"); } - AjcTest.Suite.Spec suite = new AjcTest.Suite.Spec(); - AjcTest.Spec test = new AjcTest.Spec(); - Sandbox sandbox = null; - Validator validator = null; -// AjcTest ajctest = new AjcTest(test, sandbox, validator); -// ajctest.addRunSpec((AbstractRunSpec) null); -//// test.makeIncCompilerRun((IncCompilerRun.Spec) null); -//// test.makeJavaRun((JavaRun.Spec) null); -// ajctest.setDescription((String) null); -// ajctest.setTestBaseDirOffset((String) null); -// ajctest.setBugId((String) null); -// ajctest.setTestSourceLocation((ISourceLocation) null); - - CompilerRun.Spec crunSpec = new CompilerRun.Spec(); - crunSpec.addMessage((IMessage) null); - // XXX crunSpec.addSourceLocation((ISourceLocation) null); -// crunSpec.addWrapFile((AbstractRunSpec.WrapFile) null); - crunSpec.setOptions((String) null); - crunSpec.setPaths((String) null); - crunSpec.setIncludeClassesDir(false); - crunSpec.setReuseCompiler(false); - crunSpec.setXlintfile((String) null); - crunSpec.setOutjar((String)null); - - IncCompilerRun.Spec icrunSpec = new IncCompilerRun.Spec(); - icrunSpec.addMessage((IMessage) null); - icrunSpec.setTag((String) null); - icrunSpec.setFresh(false); - - JavaRun.Spec jrunspec = new JavaRun.Spec(); - jrunspec.addMessage((IMessage) null); - jrunspec.setClassName((String) null); - jrunspec.addMessage((IMessage) null); - // input s.b. interpretable by Boolean.valueOf(String) - jrunspec.setSkipTester(true); - jrunspec.setErrStreamIsError("false"); - jrunspec.setOutStreamIsError("false"); - jrunspec.setAspectpath(""); - jrunspec.setClasspath(""); - jrunspec.setFork(false); - jrunspec.setLTW("false"); - jrunspec.setException("Error"); - - - DirChanges.Spec dcspec = new DirChanges.Spec(); - dcspec.setAdded((String) null); - dcspec.setRemoved((String) null); - dcspec.setUpdated((String) null); - dcspec.setDefaultSuffix((String) null); - dcspec.setDirToken((String) null); - - SoftMessage m = new SoftMessage(); - m.setSourceLocation((ISourceLocation) null); - m.setText((String) null); - m.setKindAsString((String) null); - m.setDetails((String) null); - - SoftSourceLocation sl = new SoftSourceLocation(); - sl.setFile((String) null); - sl.setLine((String) null); - sl.setColumn((String) null); - sl.setEndLine((String) null); - - // add attribute setters to validate? - } - - /** top element on Digester stack holds the test suite */ - public static class SuiteHolder { - AjcTest.Suite.Spec spec; - public void addSuite(AjcTest.Suite.Spec spec) { - this.spec = spec; - } - } - - /** hold class/properties association for testing */ - static class BProps { - final Class cl; - final String[] props; - BProps(Class cl, String[] props) { - this.cl = cl; - this.props = props; - } - } - - /** - * Find file NAME=="ajcTestSuite.dtd" from some reasonably-local - * relative directories. - * XXX bug: commons parser doesn't accept second registration, - * so we override Digester's implementation instead. - * XXX cannot JUnit test SuiteResolver since they run from - * local directory with valid reference - * XXX does not fix JDK 1.4 parser message "unable to resolve without base URI" - * XXX should be able to just set BaseURI instead... - */ - static class SuiteResolver implements EntityResolver { - public static final String NAME = "ajcTestSuite.dtd"; - private static boolean isDir(File dir) { - return ((null != dir) && dir.canRead() && dir.isDirectory()); - } - private final File suiteFile; - public SuiteResolver(File suiteFile) { - this.suiteFile = suiteFile; - } - - - private String getPath(String id) { - // first, try id relative to suite file - final File suiteFileDir = suiteFile.getParentFile(); - if (isDir(suiteFileDir)) { - String path = suiteFileDir.getPath() - + "/" + id; - File result = new File(path); - if (result.canRead() && result.isFile()) { - return result.getPath(); - } - } - // then try misc paths relative to suite file or current dir - final File[] baseDirs = new File[] - { suiteFileDir, new File(".") - }; - final String[] locations = new String[] - { ".", "..", "../tests", "../../tests", - "../../../tests", "tests", "modules/tests" - }; - File baseDir; - for (int j = 0; j < baseDirs.length; j++) { - baseDir = baseDirs[j]; - if (!isDir(baseDir)) { - continue; - } - for (int i = 0; i < locations.length; i++) { - File dir = new File(baseDir, locations[i]); - if (isDir(dir)) { - File temp = new File(dir, NAME); - if (temp.isFile() && temp.canRead()) { - return temp.getPath(); - } - } - } - } - return null; - } - public InputSource resolveEntity( - String publicId, - String systemId) - throws SAXException { - InputSource result = null; - if ((null != systemId) && - systemId.endsWith(NAME)) { - String path = getPath(systemId); - if (null != path) { - result = new InputSource(path); - result.setSystemId(path); - result.setPublicId(path); - } - } - return result; - } - } -} - -//private String getDocTypePath() { -// String result = null; -// if (null != suiteFile) { -// FileReader fr = null; -// try { -// fr = new FileReader(suiteFile); -// BufferedReader reader = new BufferedReader(fr); -// String line; -// while (null != (line = reader.readLine())) { -// String upper = line.trim(); -// line = upper.toLowerCase(); -// if (line.startsWith("<")) { -// if (line.startsWith("<!doctype ")) { -// int start = line.indexOf("\""); -// int end = line.lastIndexOf(NAME + "\""); -// if ((0 < start) && (start < end)) { -// return upper.substring(start+1, -// end + NAME.length()); -// } -// } else if (!line.startsWith("<?xml")) { -// break; // something else... -// } -// } -// } -// } catch (IOException e) { -// // ignore -// } finally { -// if (null != fr) { -// try { -// fr.close(); -// } catch (IOException e1) { // ignore -// } -// } -// } -// } -// return null; -//} - diff --git a/testing/src/main/java/org/aspectj/testing/xml/IXmlWritable.java b/testing/src/main/java/org/aspectj/testing/xml/IXmlWritable.java deleted file mode 100644 index a11b32be3..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/IXmlWritable.java +++ /dev/null @@ -1,25 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.xml; - -/** - * - */ -public interface IXmlWritable { - /** - * Write self out to XML. - * @param out the XMLWriter to write to - */ - void writeXml(XMLWriter out); -} diff --git a/testing/src/main/java/org/aspectj/testing/xml/MessageListXmlReader.java b/testing/src/main/java/org/aspectj/testing/xml/MessageListXmlReader.java deleted file mode 100644 index cde5e99dd..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/MessageListXmlReader.java +++ /dev/null @@ -1,215 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2003 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Wes Isberg initial implementation - * ******************************************************************/ - -package org.aspectj.testing.xml; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.digester.Digester; -import org.aspectj.bridge.AbortException; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.util.LangUtil; -import org.xml.sax.SAXException; - -/** - * Read a list of messages in xml form. - * Input files should comply with DOCTYPE - */ -public class MessageListXmlReader { - private static final String INLINE_DOCTYPE; - static { - final String EOL = LangUtil.EOL; - final StringBuffer r = new StringBuffer(); - - r.append("<!DOCTYPE "); - r.append(MessageList.XMLNAME); - r.append(" ["); - r.append(EOL + " <!ELEMENT " + MessageList.XMLNAME - + " (" + SoftMessage.XMLNAME + "+) >"); - String name = SoftMessage.XMLNAME; - r.append(EOL + " <!ELEMENT " + name + " (" + SoftSourceLocation.XMLNAME + ")*>"); - r.append(EOL + " <!ATTLIST " + name + " kind CDATA #REQUIRED >"); - r.append(EOL + " <!ATTLIST " + name + " message CDATA #IMPLIED >"); - name = SoftSourceLocation.XMLNAME; - r.append(EOL + " <!ELEMENT " + name + " (#PCDATA) >"); - r.append(EOL + " <!ATTLIST " + name + " line CDATA #REQUIRED >"); - r.append(EOL + " <!ATTLIST " + name + " endLine CDATA #IMPLIED >"); - r.append(EOL + " <!ATTLIST " + name + " column CDATA #IMPLIED >"); - r.append(EOL + " <!ATTLIST " + name + " sourceFile CDATA #IMPLIED >"); - - r.append(EOL + "] >"); - INLINE_DOCTYPE = r.toString(); - } - - private static final String[] LOG = new String[] {"info", "debug", "trace" }; - - private int logLevel; - - /** - * Print IMessage[] to the output file as XML. - * @param output the File to write to - overwritten - * @param messages the IMessage[] to write - * @return null if no warnings detected, warnings otherwise - */ - public String writeMessages(File output, IMessage[] messages) throws IOException { - LangUtil.throwIaxIfNull(output, "output"); - LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(messages), "no messages"); - PrintWriter writer = new PrintWriter(new FileOutputStream(output)); - XMLWriter printSink = new XMLWriter(writer); - writer.println(""); - writer.println(INLINE_DOCTYPE); - writer.println(""); - writer.println("<" + MessageList.XMLNAME + ">"); - SoftMessage.writeXml(printSink, messages); - writer.println("</" + MessageList.XMLNAME + ">"); - writer.close(); - return null; - } - - /** @param level 0..2, info..trace */ - public void setLogLevel(int level) { - if (level < 0) { - level = 0; - } - if (level > 2) { - level = 2; - } - logLevel = level; - } - - /** - * Read the specifications for a list of IMessage from an XML file. - * @param file the File must be readable, comply with DOCTYPE. - * @return IMessage[] read from file - * @see setLogLevel(int) - */ - public IMessage[] readMessages(File file) throws IOException, AbortException { - // setup loggers for digester and beanutils... - System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); // XXX - System.setProperty("org.apache.commons.logging.simplelog.defaultlog", LOG[logLevel]); // trace debug XXX - - final Digester digester = new Digester(); - setupDigester(digester); - - MessageListHolder holder = new MessageListHolder(); - digester.push(holder); - FileInputStream input = new FileInputStream(file); - try { - digester.parse(input); - } catch (SAXException e) { - MessageUtil.fail("parsing " + file, e); - } finally { - if (null != input) { - input.close(); - input = null; - } - } - return (null == holder.list - ? new IMessage[0] - : holder.list.getMessages()); - } - - /** set up the mapping between the xml and Java. */ - private void setupDigester(Digester digester) { - // XXX supply sax parser to ignore white space? - digester.setValidating(true); - - // element names come from the element components - final String messageListX = MessageList.XMLNAME; - final String messageX = messageListX + "/" + SoftMessage.XMLNAME; - final String messageSrcLocX = messageX + "/" + SoftSourceLocation.XMLNAME; - - // ---- each sub-element needs to be created - // handle messages the same at any level - digester.addObjectCreate(messageListX, MessageList.class.getName()); - digester.addObjectCreate(messageX, SoftMessage.class.getName()); - digester.addObjectCreate(messageSrcLocX, SoftSourceLocation.class.getName()); - - // ---- set bean properties for sub-elements created automatically - // -- some remapped - warnings - // - if property exists, map will not be used - digester.addSetProperties(messageListX); - digester.addSetProperties(messageX); - digester.addSetProperties(messageSrcLocX); - digester.addSetProperties(messageX, "kind", "kindAsString"); - digester.addSetProperties(messageX, "line", "lineAsString"); - - // ---- when subelements are created, add to parent - digester.addSetNext(messageListX, "addMessage", IMessage.class.getName()); - digester.addSetNext(messageX, "setSourceLocation", ISourceLocation.class.getName()); - - // can set parent, but prefer to have "knows-about" flow down only... - } - - // ------------------------------------------------------------ testing code - - /** - * This is only to do compile-time checking for the APIs impliedly - * used in setupDigester(..). - * The property setter checks are redundant with tests based on - * expectedProperties(). - */ -// private static void setupDigesterCompileTimeCheck() { -// if (true) { throw new Error("never invoked"); } -// -// MessageListHolder holder = new MessageListHolder(); -// MessageList ml = new MessageList(); -// SoftMessage m = new SoftMessage(); -// SoftSourceLocation sl = new SoftSourceLocation(); -// -// holder.setMessageList(ml); -// ml.addMessage((IMessage) null); -// m.setSourceLocation(sl); -// m.setText((String) null); -// m.setKindAsString((String) null); -// -// sl.setFile((String) null); -// sl.setLine((String) null); -// sl.setColumn((String) null); -// sl.setEndLine((String) null); -// -// // add attribute setters to validate? -// } - - // inner classes, to make public for bean utilities - /** a list of messages */ - public static class MessageList { - public static final String XMLNAME = "message-list"; - private List messages = new ArrayList(); - public void addMessage(IMessage message) { - messages.add(message); - } - IMessage[] getMessages() { - return (IMessage[]) messages.toArray(new IMessage[0]); - } - } - - /** push on digester stack to hold message list */ - public static class MessageListHolder { - public MessageList list; - public void setMessageList(MessageList list) { - this.list = list; - } - } - -} - - - diff --git a/testing/src/main/java/org/aspectj/testing/xml/SoftMessage.java b/testing/src/main/java/org/aspectj/testing/xml/SoftMessage.java deleted file mode 100644 index f59bf397e..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/SoftMessage.java +++ /dev/null @@ -1,368 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.xml; - -import java.io.File; -import java.util.ArrayList; -//import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.aspectj.bridge.*; -import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.MessageUtil; -import org.aspectj.bridge.SourceLocation; -import org.aspectj.util.LangUtil; - -/** - * Implement messages. - * This implementation is immutable if ISourceLocation is immutable, - * except for adding source locations. - */ -public class SoftMessage implements IMessage { - public static String XMLNAME = "message"; - public static final File NO_FILE = ISourceLocation.NO_FILE; - private String message; - private IMessage.Kind kind; - private Throwable thrown; - private ISourceLocation sourceLocation; - private String details; - private int id; - private int sourceStart,sourceEnd; - private final ArrayList extraSourceLocations = new ArrayList(); - - //private ISourceLocation pseudoSourceLocation; // set directly - // collapse enclosed source location for shorter, property-based xml - private String file; - private int line = Integer.MAX_VALUE; - - /** convenience for constructing failure messages */ - public static SoftMessage fail(String message, Throwable thrown) { - return new SoftMessage(message, IMessage.FAIL, thrown, null); - } - - /** - * Print messages. - * @param messages List of IMessage - */ - public static void writeXml(XMLWriter out, IMessageHolder messages) { - if ((null == out) - || (null == messages) - || (0 == messages.numMessages(null, true))) { - return; - } - List list = messages.getUnmodifiableListView(); - for (Iterator iter = list.iterator(); iter.hasNext();) { - writeXml(out, (IMessage) iter.next()); - } - } - - /** - * Print messages. - * @param messages IMessage[] - */ - public static void writeXml(XMLWriter out, IMessage[] messages) { - if ((null == out) || (null == messages)) { - return; - } - for (int i = 0; i < messages.length; i++) { - writeXml(out, messages[i]); - } - } - - /** print message as an element - * XXX has to sync with ajcTests.dtd - * @throws IllegalArgumentException if message.getThrown() is not null - */ - public static void writeXml( - XMLWriter out, - IMessage message) { // XXX short form only, no files - if ((null == out) || (null == message)) { - return; - } - Throwable thrown = message.getThrown(); - if (null != thrown) { - String m = "unable to write " + message + " thrown not permitted"; - throw new IllegalArgumentException(m); - } - final String elementName = XMLNAME; - out.startElement(elementName, false); - out.printAttribute("kind", message.getKind().toString()); - String value = message.getMessage(); - if (null != value) { - value = XMLWriter.attributeValue(value); - out.printAttribute("text", value); - } - value = message.getDetails(); - if (null != value) { - value = XMLWriter.attributeValue(value); - out.printAttribute("details", value); - } - ISourceLocation sl = message.getSourceLocation(); - if (null != sl) { - int line = sl.getLine(); - if (-1 < line) { - out.printAttribute("line", "" + line); - } - File file = sl.getSourceFile(); - if ((null != file) && !ISourceLocation.NO_FILE.equals(file)) { - value = XMLWriter.attributeValue(file.getPath()); - out.printAttribute("file", value); - } - } - List extras = message.getExtraSourceLocations(); - if (!LangUtil.isEmpty(extras)) { - out.endAttributes(); - for (Iterator iter = extras.iterator(); iter.hasNext();) { - /*ISourceLocation element = (ISourceLocation)*/ iter.next(); - SoftSourceLocation.writeXml(out, sl); - } - } - out.endElement(elementName); - } - - public SoftMessage() { - } // XXX programmatic only - - /** - * Create a (compiler) error or warning message - * @param message the String used as the underlying message - * @param sourceLocation the ISourceLocation, if any, associated with this message - * @param isError if true, use IMessage.ERROR; else use IMessage.WARNING - */ - public SoftMessage( - String message, - ISourceLocation location, - boolean isError) { - this( - message, - (isError ? IMessage.ERROR : IMessage.WARNING), - null, - location); - } - - /** - * Create a message, handling null values for message and kind - * if thrown is not null. - * @param message the String used as the underlying message - * @param kind the IMessage.Kind of message - not null - * @param thrown the Throwable, if any, associated with this message - * @param sourceLocation the ISourceLocation, if any, associated with this message - * @throws IllegalArgumentException if message is null and - * thrown is null or has a null message, or if kind is null - * and thrown is null. - */ - public SoftMessage( - String message, - IMessage.Kind kind, - Throwable thrown, - ISourceLocation sourceLocation) { - this.message = message; - this.kind = kind; - this.thrown = thrown; - this.sourceLocation = sourceLocation; - if (null == message) { - if (null != thrown) { - message = thrown.getMessage(); - } - if (null == message) { - throw new IllegalArgumentException("null message"); - } - } - if (null == kind) { - throw new IllegalArgumentException("null kind"); - } - } - - /** @return the kind of this message */ - public IMessage.Kind getKind() { - return kind; - } - - /** @return true if kind == IMessage.ERROR */ - public boolean isError() { - return kind == IMessage.ERROR; - } - - /** @return true if kind == IMessage.WARNING */ - public boolean isWarning() { - return kind == IMessage.WARNING; - } - - /** @return true if kind == IMessage.DEBUG */ - public boolean isDebug() { - return kind == IMessage.DEBUG; - } - - /** - * @return true if kind == IMessage.INFO - */ - public boolean isInfo() { - return kind == IMessage.INFO; - } - - public boolean isTaskTag() { - return kind == IMessage.TASKTAG; - } - - /** @return true if kind == IMessage.ABORT */ - public boolean isAbort() { - return kind == IMessage.ABORT; - } - - /** - * @return true if kind == IMessage.FAIL - */ - public boolean isFailed() { - return kind == IMessage.FAIL; - } - - public boolean getDeclared() { return false; } - - /** @return non-null String with simple message */ - final public String getMessage() { - return message; - } - - /** @return Throwable associated with this message, or null if none */ - final public Throwable getThrown() { - return thrown; - } - - /** - * This returns any ISourceLocation set or a mock-up - * if file and/or line were set. - * @return ISourceLocation associated with this message, - * a mock-up if file or line is available, or null if none - */ - final public ISourceLocation getSourceLocation() { - if ((null == sourceLocation) - && ((null != file) || (line != Integer.MAX_VALUE))) { - File f = (null == file ? NO_FILE : new File(file)); - int line = (this.line == Integer.MAX_VALUE ? 0 : this.line); - sourceLocation = new SourceLocation(f, line); - } - return sourceLocation; - } - - /** set the kind of this message */ - public void setMessageKind(IMessage.Kind kind) { - this.kind = (null == kind ? IMessage.ERROR : kind); - } - - /** set the file for the underlying source location of this message - * @throws IllegalStateException if source location was set directly - * or indirectly by calling getSourceLocation after setting - * file or line. - */ - public void setFile(String path) { - LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(path), "empty path"); - if (null != sourceLocation) { - throw new IllegalStateException("cannot set line after creating source location"); - } - this.file = path; - } - - /** set the kind of this message */ - public void setKindAsString(String kind) { - setMessageKind(MessageUtil.getKind(kind)); - } - - public void setSourceLocation(ISourceLocation sourceLocation) { - this.sourceLocation = sourceLocation; - } - - /** - * Set the line for the underlying source location. - * @throws IllegalStateException if source location was set directly - * or indirectly by calling getSourceLocation after setting - * file or line. - */ - public void setLineAsString(String line) { - if (null != sourceLocation) { - throw new IllegalStateException("cannot set line after creating source location"); - } - this.line = Integer.valueOf(line).intValue(); - SourceLocation.validLine(this.line); - } - - public void setText(String text) { - this.message = (null == text ? "" : text); - } - - public String toString() { - StringBuffer result = new StringBuffer(); - - result.append(null == getKind() ? "<null kind>" : getKind().toString()); - - String messageString = getMessage(); - if (!LangUtil.isEmpty(messageString)) { - result.append(messageString); - } - - ISourceLocation loc = getSourceLocation(); - if ((null != loc) && (loc != ISourceLocation.NO_FILE)) { - result.append(" at " + loc); - } - if (null != thrown) { - result.append(" -- " + LangUtil.renderExceptionShort(thrown)); - } - return result.toString(); - } - - public String getDetails() { - return details; - } - - public void setDetails(String string) { - details = string; - } - - public int getID() { - return id; - } - - public void setID(int id) { - this.id = id; - } - - public int getSourceStart() { - return sourceStart; - } - - public void setSourceStart(int s) { - sourceStart = s; - } - - public int getSourceEnd() { - return sourceStart; - } - - public void setSourceEnd(int s) { - sourceEnd = s; - } - - /* (non-Javadoc) - * @see org.aspectj.bridge.IMessage#getExtraSourceLocations() - */ - public List getExtraSourceLocations() { - return extraSourceLocations; - } - public void addSourceLocation(ISourceLocation location) { - if (null != location) { - extraSourceLocations.add(location); - } - } -} diff --git a/testing/src/main/java/org/aspectj/testing/xml/SoftSourceLocation.java b/testing/src/main/java/org/aspectj/testing/xml/SoftSourceLocation.java deleted file mode 100644 index 17f5ae673..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/SoftSourceLocation.java +++ /dev/null @@ -1,133 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC), - * 2004 Contributors. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * Wes Isberg 2004 updates - * ******************************************************************/ - -package org.aspectj.testing.xml; - - -import java.io.File; - -import org.aspectj.bridge.ISourceLocation; -import org.aspectj.util.LangUtil; - -/** - * A mutable ISourceLocation for XML initialization of tests. - * This does not support reading/writing of the attributes - * column, context, or endline. - */ -public class SoftSourceLocation implements ISourceLocation { - public static final File NONE = ISourceLocation.NO_FILE; - public static final String XMLNAME = "source"; - - /** - * Write an ISourceLocation as XML element to an XMLWriter sink. - * @param out the XMLWriter sink - * @param sl the ISourceLocation to write. - */ - public static void writeXml(XMLWriter out, ISourceLocation sl) { - if ((null == out) || (null == sl)) { - return; - } - final String elementName = XMLNAME; - out.startElement(elementName, false); - out.printAttribute("line", "" + sl.getLine()); - // other attributes not supported - File file = sl.getSourceFile(); - if ((null != file) && !ISourceLocation.NO_FILE.equals(file)) { - String value = XMLWriter.attributeValue(file.getPath()); - out.printAttribute("file", value); - } - out.endElement(elementName); - } - - private File sourceFile; - private int line = -1; // required for no-line comparisons to work - private int column; - private int endLine; - private String context; - - public SoftSourceLocation() { - } - - public File getSourceFile() { - return (null != sourceFile ? sourceFile : NONE); - } - public int getLine() { - return line; - } - - public int getColumn() { - return column; - } - - public int getEndLine() { - return line; - } - public String getContext() { - return context; - } - - public void setFile(String sourceFile) { - this.sourceFile = new File(sourceFile); - } - - public void setLine(String line) { - setLineAsString(line); - } - - public void setLineAsString(String line) { - this.line = convert(line); - if (0 == endLine) { - endLine = this.line; - } - } - public String getLineAsString() { - return ""+line; - } - - public void setColumn(String column) { - this.column = convert(column); - } - - public void setEndLine(String line) { - this.endLine = convert(line); - } - - public void setContext(String context) { - this.context = context; - } - - private int convert(String in) { - return Integer.valueOf(in).intValue(); - } - - public String getLocationContext() { - return null; - } - - public int getOffset() { - return -1; - } - - /** @return String : {context\n}file:line:column */ - public String toString() { - return (null == context ? "" : context + LangUtil.EOL) - + getSourceFile().getPath() - + ":" + getLine() ; - } - - public String getSourceFileName() { - return null; - } -} diff --git a/testing/src/main/java/org/aspectj/testing/xml/XMLWriter.java b/testing/src/main/java/org/aspectj/testing/xml/XMLWriter.java deleted file mode 100644 index 422576c56..000000000 --- a/testing/src/main/java/org/aspectj/testing/xml/XMLWriter.java +++ /dev/null @@ -1,365 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 1999-2001 Xerox Corporation, - * 2002 Palo Alto Research Center, Incorporated (PARC). - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Xerox/PARC initial implementation - * ******************************************************************/ - -package org.aspectj.testing.xml; - -import java.io.PrintWriter; -import java.util.List; -import java.util.Stack; - -import org.aspectj.util.LangUtil; - -/** - * Manage print stream to an XML document. - * This tracks start/end elements and signals on error, - * and optionally lineates buffer by accumulating - * up to a maximum width (including indent). - * This also has utilities for un/flattening lists and - * rendering buffer. - */ -public class XMLWriter { - static final String SP = " "; - static final String TAB = SP + SP; - - /** maximum value for maxWidth, when flowing buffer */ - public static final int MAX_WIDTH = 8000; - - /** default value for maxWidth, when flowing buffer */ - public static final int DEFAULT_WIDTH = 80; - - /** extremely inefficient! */ - public static String attributeValue(String input) { -// if (-1 != input.indexOf("&")) { -// String saved = input; -// input = LangUtil.replace(input, "&", "ampamp;"); -// if (-1 == input.indexOf("&")) { -// input = saved; -// } else { -// input = LangUtil.replace(input, "&", "&"); -// input = LangUtil.replace(input, "ampamp;", "&"); -// } -// } else if (-1 != input.indexOf("&")) { -// input = LangUtil.replace(input, "&", "&"); -// } - input = input.replace('"', '~'); - input = input.replace('&', '='); - return input; - } - - /** @return name="{attributeValue({value})" */ - public static String makeAttribute(String name, String value) { - return (name + "=\"" + attributeValue(value) + "\""); - } - - /** same as flattenList, except also normalize \ -> / */ - public static String flattenFiles(String[] strings) { - return flattenList(strings).replace('\\', '/'); - } - - /** same as flattenList, except also normalize \ -> / */ - public static String flattenFiles(List paths) { - return flattenList(paths).replace('\\', '/'); - } - - /** - * Expand comma-delimited String into list of values, without trimming - * @param list List of items to print - null is silently ignored, - * so for empty items use "" - * @return String[]{} for null input, String[] {input} for input without comma, - * or new String[] {items..} otherwise - * @throws IllegalArgumentException if {any item}.toString() contains a comma - */ - public static String[] unflattenList(String input) { - return (String[]) LangUtil.commaSplit(input).toArray(new String[0]); - } - - /** flatten input and add to list */ - public static void addFlattenedItems(List list, String input) { - LangUtil.throwIaxIfNull(list, "list"); - if (null != input) { - String[] items = XMLWriter.unflattenList(input); - if (!LangUtil.isEmpty(items)) { - for (int i = 0; i < items.length; i++) { - if (!LangUtil.isEmpty(items[i])) { - list.add(items[i]); - } - } - } - } - } - - /** - * Collapse list into a single comma-delimited value (e.g., for list buffer) - * @param list List of items to print - null is silently ignored, - * so for empty items use "" - * @return item{,item}... - * @throws IllegalArgumentException if {any item}.toString() contains a comma - */ - public static String flattenList(List list) { - if ((null == list) || (0 == list.size())) { - return ""; - } - return flattenList(list.toArray()); - } - - - /** - * Collapse list into a single comma-delimited value (e.g., for list buffer) - * @param list the String[] items to print - null is silently ignored, - * so for empty items use "" - * @return item{,item}... - * @throws IllegalArgumentException if list[i].toString() contains a comma - */ - public static String flattenList(Object[] list) { - StringBuffer sb = new StringBuffer(); - if (null != list) { - boolean printed = false; - for (int i = 0; i < list.length; i++) { - Object o = list[i]; - if (null != o) { - if (printed) { - sb.append(","); - } else { - printed = true; - } - String s = o.toString(); - if (-1 != s.indexOf(",")) { - throw new IllegalArgumentException("comma in " + s); - } - sb.append(s); - } - } - } - return sb.toString(); - } - - /** output sink */ - PrintWriter out; - - /** stack of String element names */ - Stack stack = new Stack(); - - /** false if doing attributes */ - boolean attributesDone = true; - - /** current element prefix */ - String indent = ""; - - /** maximum width (in char) of indent and buffer when flowing */ - int maxWidth; - - /** - * Current text being flowed. - * length() is always less than maxWidth. - */ - StringBuffer buffer; - - /** @param out PrintWriter to print to - not null */ - public XMLWriter(PrintWriter out) { - LangUtil.throwIaxIfNull(out, "out"); - this.out = out; - buffer = new StringBuffer(); - maxWidth = DEFAULT_WIDTH; - } - - /** - * Set maximum width (in chars) of buffer to accumulate. - * @param maxWidth int 0..MAX_WIDTH for maximum number of char to accumulate - */ - public void setMaxWidth(int maxWidth) { - if (0 > maxWidth) { - this.maxWidth = 0; - } else if (MAX_WIDTH < maxWidth) { - this.maxWidth = MAX_WIDTH; - } else { - this.maxWidth = maxWidth; - } - } - - /** shortcut for entire element */ - public void printElement(String name, String attributes) { - if (!attributesDone) throw new IllegalStateException("finish attributes"); - if (0 != buffer.length()) { // output on subelement - outPrintln(buffer + ">"); - buffer.setLength(0); - } - String oldIndent = indent; - if (0 < stack.size()) { - indent += TAB; - ((StackElement) stack.peek()).numChildren++; - } - outPrintln(indent + "<" + name + " " + attributes + "/>"); - indent = oldIndent; - } - - /** - * Start element only - * @param name the String label of the element - * @param closeTag if true, delimit the end of the starting tag - */ - public void startElement(String name, boolean closeTag) { - startElement(name, "", closeTag); - } - - /** - * Start element with buffer on the same line. - * This does not flow buffer. - * @param name String tag for the element - * @param attr {name="value"}.. where value - * is a product of attributeValue(String) - */ - public void startElement(String name, String attr, boolean closeTag) { - if (!attributesDone) throw new IllegalStateException("finish attributes"); - LangUtil.throwIaxIfFalse(!LangUtil.isEmpty(name), "empty name"); - - if (0 != buffer.length()) { // output on subelement - outPrintln(buffer + ">"); - buffer.setLength(0); - } - if (0 < stack.size()) { - indent += TAB; - } - StringBuffer sb = new StringBuffer(); - sb.append(indent); - sb.append("<"); - sb.append(name); - - if (!LangUtil.isEmpty(attr)) { - sb.append(" "); - sb.append(attr.trim()); - } - attributesDone = closeTag; - if (closeTag) { - sb.append(">"); - outPrintln(sb.toString()); - } else if (maxWidth <= sb.length()) { - outPrintln(sb.toString()); - } else { - if (0 != this.buffer.length()) { - throw new IllegalStateException("expected empty attributes starting " + name); - } - this.buffer.append(sb.toString()); - } - if (0 < stack.size()) { - ((StackElement) stack.peek()).numChildren++; - } - stack.push(new StackElement(name)); - } - - /** - * @param name should be the same as that given to start the element - * @throws IllegalStateException if start element does not match - */ - public void endElement(String name) { -// int level = stack.size(); - String err = null; - StackElement element = null; - if (0 == stack.size()) { - err = "empty stack"; - } else { - element = (StackElement) stack.pop(); - if (!element.name.equals(name)) { - err = "expecting element " + element.name; - } - } - if (null != err) { - err = "endElement(" + name + ") " + stack + ": " + err; - throw new IllegalStateException(err); - } - if (0 < element.numChildren) { - outPrintln(indent + "</" + name + ">"); - } else if (0 < buffer.length()) { - outPrintln(buffer + "/>"); - buffer.setLength(0); - } else { - outPrintln(indent + "/>"); - } - if (!attributesDone) { - attributesDone = true; - } - if (0 < stack.size()) { - indent = indent.substring(0, indent.length() - TAB.length()); - } - } - - - /** - * Print name=value if neither is null and name is not empty after trimming, - * accumulating these until they are greater than maxWidth or buffer are - * terminated with endAttributes(..) or endElement(..). - * @param value the String to convert as attribute value - ignored if null - * @param name the String to use as the attribute name - * @throws IllegalArgumentException if name is null or empty after trimming - */ - public void printAttribute(String name, String value) { - if (attributesDone) throw new IllegalStateException("not in attributes"); - if (null == value) { - return; - } - if ((null == name) || (0 == name.trim().length())) { - throw new IllegalArgumentException("no name=" + name + "=" + value); - } - - String newAttr = name + "=\"" + attributeValue(value) + "\""; - int indentLen = indent.length(); - int bufferLen = buffer.length(); - int newAttrLen = (0 == bufferLen ? indentLen : 0) + newAttr.length(); - - if (maxWidth > (bufferLen + newAttrLen)) { - buffer.append(" "); - buffer.append(newAttr); - } else { // at least print old attributes; maybe also new - if (0 < bufferLen) { - outPrintln(buffer.toString()); - buffer.setLength(0); - } - buffer.append(indent + SP + newAttr); - } - } - - public void endAttributes() { - if (attributesDone) throw new IllegalStateException("not in attributes"); - attributesDone = true; - } - - public void printComment(String comment) { - if (!attributesDone) throw new IllegalStateException("in attributes"); - outPrintln(indent + "<!-- " + comment + "-->"); - } - - public void close() { - if (null != out) { - out.close(); - } - - } - - public void println(String string) { - outPrintln(string); - } - - private void outPrintln(String s) { - if (null == out) { - throw new IllegalStateException("used after close"); - } - out.println(s); - } - static class StackElement { - String name; - int numChildren; - public StackElement(String name) { - this.name = name; - } - } - -} |