diff options
31 files changed, 722 insertions, 39 deletions
diff --git a/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java b/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java index 8d0d2cf8e..821c259e1 100644 --- a/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java +++ b/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserProperties.java @@ -150,6 +150,10 @@ public class BrowserProperties implements ProjectPropertiesAdapter { return null; } + public Set getInpath() { + return null; + } + public String getOutJar( ) { // XXX unimplemented return null; } diff --git a/ajde/src/org/aspectj/ajde/ProjectPropertiesAdapter.java b/ajde/src/org/aspectj/ajde/ProjectPropertiesAdapter.java index 2934932ee..6ba8134bb 100644 --- a/ajde/src/org/aspectj/ajde/ProjectPropertiesAdapter.java +++ b/ajde/src/org/aspectj/ajde/ProjectPropertiesAdapter.java @@ -69,6 +69,14 @@ public interface ProjectPropertiesAdapter { public Set getInJars(); /** + * Get the set of input path elements for this compilation. + * Set members should be of the type java.io.File. + * An empty set or null is acceptable for this option. + * From -injars + */ + public Set getInpath(); + + /** * Get the set of non-Java resources for this compilation. * Set members should be of type java.io.File. * An empty set or null is acceptable for this option. diff --git a/ajde/src/org/aspectj/ajde/internal/AspectJBuildManager.java b/ajde/src/org/aspectj/ajde/internal/AspectJBuildManager.java index 84e0bb8ec..8006af593 100644 --- a/ajde/src/org/aspectj/ajde/internal/AspectJBuildManager.java +++ b/ajde/src/org/aspectj/ajde/internal/AspectJBuildManager.java @@ -188,6 +188,7 @@ public class AspectJBuildManager implements BuildManager { + "\n-> classpath: " + properties.getClasspath() + "\n-> bootclasspath: " + properties.getBootClasspath() + "\n-> -injars " + formatSet(properties.getInJars()) + + "\n-> -inpath " + formatSet(properties.getInpath()) + "\n-> -outjar " + formatOptionalString(properties.getOutJar()) + "\n-> -sourceroots " + formatSet(properties.getSourceRoots()) + "\n-> -aspectpath " + formatSet(properties.getAspectPath()) diff --git a/ajde/src/org/aspectj/ajde/internal/CompilerAdapter.java b/ajde/src/org/aspectj/ajde/internal/CompilerAdapter.java index 9ee5f111e..d7db8e849 100644 --- a/ajde/src/org/aspectj/ajde/internal/CompilerAdapter.java +++ b/ajde/src/org/aspectj/ajde/internal/CompilerAdapter.java @@ -451,8 +451,8 @@ public class CompilerAdapter { /** * Add new options from the ProjectPropertiesAdapter to the configuration. * <ul> - * <li>New list entries are added if not duplicates, - * for classpath, aspectpath, injars, and sourceroots</li> + * <li>New list entries are added if not duplicates in, + * for classpath, aspectpath, injars, inpath and sourceroots</li> * <li>New bootclasspath entries are ignored XXX</li> * <li>Set only one new entry for output dir or output jar * only if there is no output dir/jar entry in the config</li> @@ -497,6 +497,7 @@ public class CompilerAdapter { join(config.getSourceRoots(), properties.getSourceRoots()); join(config.getInJars(), properties.getInJars()); + join(config.getInpath(),properties.getInpath()); config.setSourcePathResources(properties.getSourcePathResources()); join(config.getAspectpath(), properties.getAspectPath()); } diff --git a/ajde/testdata/InpathTest/.cvsignore b/ajde/testdata/InpathTest/.cvsignore new file mode 100644 index 000000000..39b6b088c --- /dev/null +++ b/ajde/testdata/InpathTest/.cvsignore @@ -0,0 +1,3 @@ +bin +build.ajsym +build2.ajsym diff --git a/ajde/testdata/InpathTest/build.lst b/ajde/testdata/InpathTest/build.lst new file mode 100644 index 000000000..ec1f031f5 --- /dev/null +++ b/ajde/testdata/InpathTest/build.lst @@ -0,0 +1 @@ +src1/Main.java
diff --git a/ajde/testdata/InpathTest/build2.lst b/ajde/testdata/InpathTest/build2.lst new file mode 100644 index 000000000..263b509b2 --- /dev/null +++ b/ajde/testdata/InpathTest/build2.lst @@ -0,0 +1 @@ +src2/Aspect.java
diff --git a/ajde/testdata/InpathTest/indir1/META-INF/MANIFEST.MF b/ajde/testdata/InpathTest/indir1/META-INF/MANIFEST.MF new file mode 100644 index 000000000..fb5efeb68 --- /dev/null +++ b/ajde/testdata/InpathTest/indir1/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0
+Created-By: 1.3.1_04 (Sun Microsystems Inc.)
+
diff --git a/ajde/testdata/InpathTest/indir1/META-INF/test.xml b/ajde/testdata/InpathTest/indir1/META-INF/test.xml new file mode 100644 index 000000000..f9efa1f1f --- /dev/null +++ b/ajde/testdata/InpathTest/indir1/META-INF/test.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" ?> +<jar name="input1.jar"> +</jar> + diff --git a/ajde/testdata/InpathTest/indir1/test/TestProperties.class b/ajde/testdata/InpathTest/indir1/test/TestProperties.class Binary files differnew file mode 100644 index 000000000..a58740c20 --- /dev/null +++ b/ajde/testdata/InpathTest/indir1/test/TestProperties.class diff --git a/ajde/testdata/InpathTest/indir1/test/test.props b/ajde/testdata/InpathTest/indir1/test/test.props new file mode 100644 index 000000000..8462a7ab6 --- /dev/null +++ b/ajde/testdata/InpathTest/indir1/test/test.props @@ -0,0 +1 @@ +test=test2
\ No newline at end of file diff --git a/ajde/testdata/InpathTest/indir2/example/HelloWorld.class b/ajde/testdata/InpathTest/indir2/example/HelloWorld.class Binary files differnew file mode 100644 index 000000000..e333988e6 --- /dev/null +++ b/ajde/testdata/InpathTest/indir2/example/HelloWorld.class diff --git a/ajde/testdata/InpathTest/indir2/example/HelloWorld.java b/ajde/testdata/InpathTest/indir2/example/HelloWorld.java new file mode 100644 index 000000000..476abc7ee --- /dev/null +++ b/ajde/testdata/InpathTest/indir2/example/HelloWorld.java @@ -0,0 +1,12 @@ +package example; + +public class HelloWorld { + + public static void say(String msg) { + System.err.println(msg); + } + + public static void main(String []argv) { + say("hello world"); + } +} diff --git a/ajde/testdata/InpathTest/injar.jar b/ajde/testdata/InpathTest/injar.jar Binary files differnew file mode 100644 index 000000000..7dcd06f97 --- /dev/null +++ b/ajde/testdata/InpathTest/injar.jar diff --git a/ajde/testdata/InpathTest/src1/Main.java b/ajde/testdata/InpathTest/src1/Main.java new file mode 100644 index 000000000..417fc6809 --- /dev/null +++ b/ajde/testdata/InpathTest/src1/Main.java @@ -0,0 +1,22 @@ +import java.io.IOException; + +/* + * Created on 30-Jul-03 + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + +/** + * @author websterm + * + * To change this generated comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class Main { + + public static void main(String[] args) throws IOException { + String propsName = (args.length > 0)? args[0] : "test.props"; + new test.TestProperties().load(propsName); + } +} diff --git a/ajde/testdata/InpathTest/src2/Aspect.java b/ajde/testdata/InpathTest/src2/Aspect.java new file mode 100644 index 000000000..c70994870 --- /dev/null +++ b/ajde/testdata/InpathTest/src2/Aspect.java @@ -0,0 +1,7 @@ +public aspect Aspect { + pointcut sayCalls(): call(* say(..)); + + before(): sayCalls() { + System.err.println("Before say()"); + } +} diff --git a/ajde/testsrc/org/aspectj/ajde/AjdeTests.java b/ajde/testsrc/org/aspectj/ajde/AjdeTests.java index cf9c57ca5..a6c7b740d 100644 --- a/ajde/testsrc/org/aspectj/ajde/AjdeTests.java +++ b/ajde/testsrc/org/aspectj/ajde/AjdeTests.java @@ -30,6 +30,7 @@ public class AjdeTests extends TestCase { suite.addTestSuite(CompilerMessagesTest.class); suite.addTestSuite(AsmDeclarationsTest.class); suite.addTestSuite(AsmRelationshipsTest.class); + suite.addTestSuite(InpathTestcase.class); suite.addTestSuite(ResourceCopyTestCase.class); suite.addTestSuite(ModelPerformanceTest.class); diff --git a/ajde/testsrc/org/aspectj/ajde/InpathTestcase.java b/ajde/testsrc/org/aspectj/ajde/InpathTestcase.java new file mode 100644 index 000000000..b05c56707 --- /dev/null +++ b/ajde/testsrc/org/aspectj/ajde/InpathTestcase.java @@ -0,0 +1,461 @@ +/* ******************************************************************* + * Copyright (c) 2003 Contributors. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Mik Kersten initial implementation + * Andy Clement Copied/changed for -inpath testing + * ******************************************************************/ + +package org.aspectj.ajde; + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import org.aspectj.util.FileUtil; + +/** + * @author websterm + */ +public class InpathTestcase extends AjdeTestCase { + + public static final String PROJECT_DIR = "InpathTest"; + public static final String binDir = "bin"; + + public static final String indir1Name = "indir1"; + public static final String indir2Name = "indir2"; + public static final String injarName = "injar.jar"; + public static final String outjarName = "/bin/output.jar"; + + /** + * Constructor for JarResourceCopyTestCase. + * @param arg0 + */ + public InpathTestcase(String arg0) { + super(arg0); + } + + + + /* + * Ensure the output directpry in clean + */ + protected void setUp() throws Exception { + super.setUp(PROJECT_DIR); + FileUtil.deleteContents(openFile(binDir)); + } + + + + /** + * Inputs to the compiler: + * inpath = 'indir1/' + * source = 'src' + * output = a jar file + * + * Expected result = output jar file contains contents of indir1 and + * class file for source that was in src + */ + public void testInpathToOutjar() { + Set inpath = new HashSet(); + File indir1 = openFile(indir1Name); + inpath.add(indir1); + ideManager.getProjectProperties().setInpath(inpath); + File outjar = openFile(outjarName); + ideManager.getProjectProperties().setOutJar(outjar.getAbsolutePath()); + assertTrue("Build failed", doSynchronousBuild("build.lst")); + assertTrue("Build warnings", ideManager.getCompilationSourceLineTasks().isEmpty()); + + Set expectedOutputJarContents = new HashSet(); + // From indir1 + expectedOutputJarContents.add("META-INF/MANIFEST.MF"); + expectedOutputJarContents.add("META-INF/test.xml"); + expectedOutputJarContents.add("test/test.props"); + expectedOutputJarContents.add("test/TestProperties.class"); + // From src + expectedOutputJarContents.add("Main.class"); + + compareJars(indir1, "src", outjar, expectedOutputJarContents); + + // Tidy up + FileUtil.deleteContents(openFile(binDir)); + openFile(binDir).delete(); + assertFalse(openFile(binDir).exists()); + } + + + + /** + * Similar to the first test but outputs to a directory rather than + * a jar. + * + */ + public void testInpathToBin() { + Set inpath = new HashSet(); + File indir1 = openFile(indir1Name); + inpath.add(indir1); + ideManager.getProjectProperties().setInpath(inpath); + assertTrue("Build failed", doSynchronousBuild("build.lst")); + assertTrue( + "Build warnings", + ideManager.getCompilationSourceLineTasks().isEmpty()); + + Set expectedBindirContents = new HashSet(); + // From indir1 + expectedBindirContents.add("META-INF/MANIFEST.MF"); + expectedBindirContents.add("META-INF/test.xml"); + expectedBindirContents.add("test/test.props"); + expectedBindirContents.add("test/TestProperties.class"); + // From src + expectedBindirContents.add("Main.class"); + + compareIndirToBin(indir1, "src", "bin", expectedBindirContents); + + // Tidy up + FileUtil.deleteContents(openFile(binDir)); + openFile(binDir).delete(); + assertFalse(openFile(binDir).exists()); + } + + + + /** + * Inputs to the compiler: + * inpath is 'indir2' that contains a helloworld source file and class file. + * source is 'src2' which contains Aspect.java which weaves before advice into the HelloWorld code from 'indir2' + * + * Expected result: HelloWorld copied through to output jar and 'weaved'. Compiled version of Aspect.java put into + * the output jar. The HelloWorld.java source file is also copied through to the output jar. + * + * An extra check is done at the end of this test to verify that HelloWorld has changed size (due to the weaving). + */ + public void testInpathToOutjar2() { + Set inpath = new HashSet(); + File indir2 = openFile(indir2Name); + inpath.add(indir2); + ideManager.getProjectProperties().setInpath(inpath); + File outjar = openFile(outjarName); + ideManager.getProjectProperties().setOutJar(outjar.getAbsolutePath()); + assertTrue("Build failed", doSynchronousBuild("build2.lst")); + assertTrue( + "Build warnings", + ideManager.getCompilationSourceLineTasks().isEmpty()); + + Set expectedOutputJarContents = new HashSet(); + // From indir1 + expectedOutputJarContents.add("example/HelloWorld.class"); + expectedOutputJarContents.add("example/HelloWorld.java"); + // From src + expectedOutputJarContents.add("Aspect.class"); + + compareJars(indir2, "src", outjar, expectedOutputJarContents); + + // Extra test. The HelloWorld class from the input directory should have been woven + // by the aspect - verify that the size of the HelloWorld class in the output directory + // is a different size to the input version. + int outputsize = fetchFromJar(outjar, "example/HelloWorld.class"); + try { + FileInputStream fis = new FileInputStream(openFile(indir2Name+"/example/HelloWorld.class")); + byte[] filedata = FileUtil.readAsByteArray(fis); + int inputsize = filedata.length; + assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same", + (inputsize!=outputsize)); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + + FileUtil.deleteContents(openFile(binDir)); + openFile(binDir).delete(); + assertFalse(openFile(binDir).exists()); + } + + + + /** + * More complex inpath - a jar and a directory + * + * Inputs: + * -inpath injar.jar;indir2 + * source is 'src2' which contains Aspect.java + * + * Expected result: Result should be a directory containing the contents of injar.jar and indir2 and the + * Aspect.class file. + * + */ + public void testInpathAndInjarToBin() { + Set inpath = new HashSet(); + File indir2 = openFile(indir2Name); + inpath.add(indir2); + inpath.add(openFile(injarName)); + ideManager.getProjectProperties().setInpath(inpath); + assertTrue("Build failed", doSynchronousBuild("build2.lst")); + assertTrue("Build warnings",ideManager.getCompilationSourceLineTasks().isEmpty()); + + Set expectedBindirContents = new HashSet(); + + // From indir1 + expectedBindirContents.add("example/HelloWorld.class"); + expectedBindirContents.add("example/HelloWorld.java"); + // From injar.jar + expectedBindirContents.add("props/resources.properties"); + // From src + expectedBindirContents.add("Aspect.class"); + + compareIndirToBin(indir2, "src", "bin", expectedBindirContents); + + // Check the input and output versions of HelloWorld.class are different sizes + try { + FileInputStream fis1 = new FileInputStream(openFile("indir2/example/HelloWorld.class")); + byte[] filedata1 = FileUtil.readAsByteArray(fis1); + int inputsize = filedata1.length; + FileInputStream fis2 = new FileInputStream(openFile("bin/example/HelloWorld.class")); + byte[] filedata2 = FileUtil.readAsByteArray(fis2); + int outputsize = filedata2.length; + assertTrue("Weaving of Aspect should have occurred but the input and output size for HelloWorld.class are the same", + (outputsize!=inputsize)); + + fis1.close(); + fis2.close(); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + + FileUtil.deleteContents(openFile(binDir)); + openFile(binDir).delete(); + assertFalse(openFile(binDir).exists()); + } + + + + // Return the size of specified entry from the output jar file + public int fetchFromJar(File outjarFile, String filename) { + int ret = -1; + try { + ZipInputStream outjar; + + outjar = + new ZipInputStream(new java.io.FileInputStream(outjarFile)); + + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String zipentryname = entry.getName(); + if (zipentryname.equals(filename)) { + byte[] filedata = FileUtil.readAsByteArray(outjar); + ret = filedata.length; + outjar.closeEntry(); + break; + } + outjar.closeEntry(); + } + outjar.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return ret; + } + /* + * Ensure -outjar contains all non-Java resouces from injars + */ + public void compareJars( + File dirFile, + String sourceDir, + File outjarFile, + Set expectedOutputJarContents) { + + try { + assertTrue( + "outjar older than injar", + (outjarFile.lastModified() > dirFile.lastModified())); + + // Go through the output jar file, for each element, remove it from + // the expectedOutputJarContents - when we finish, the expectedOutputJarContents + // set should be empty! + ZipInputStream outjar = + new ZipInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + fileName = fileName.replace('\\', '/'); + boolean b = expectedOutputJarContents.remove(fileName); + assertTrue( + "Unexpectedly found : " + fileName + " in outjar", + b); + outjar.closeEntry(); + } + outjar.close(); + + assertTrue( + "Didnt make it into the output jar: " + + expectedOutputJarContents.toString(), + expectedOutputJarContents.isEmpty()); + } catch (IOException ex) { + fail(ex.toString()); + } + } + + /* + * Ensure -outjar contains all non-Java resouces from source and injars + */ + public void compareSourceToOutjar(String indirName, File outjarFile) { + HashSet resources = new HashSet(); + listSourceResources(indirName, resources); + + try { + + ZipInputStream outjar = + new ZipInputStream(new java.io.FileInputStream(outjarFile)); + ZipEntry entry; + while (null != (entry = outjar.getNextEntry())) { + String fileName = entry.getName(); + + if (!fileName.endsWith(".class")) { + boolean b = resources.remove(fileName); + assertTrue(fileName, b); + } + outjar.closeEntry(); + } + outjar.close(); + + assertTrue( + "Missing resources: " + resources.toString(), + resources.isEmpty()); + } catch (IOException ex) { + fail(ex.toString()); + } + } + + /* + * Ensure bin contains all non-Java resouces from source and injars + */ + public void compareIndirToBin( + File indirFile, + String sourceDir, + String outdirName, + Set expectedOutdirContents) { + + byte[] inManifest = null; + + File binBase = openFile(outdirName); + String[] toResources = FileUtil.listFiles(binBase); + for (int i = 0; i < toResources.length; i++) { + String fileName = toResources[i]; + boolean b = expectedOutdirContents.remove(fileName); + assertTrue("Extraneous resources: " + fileName, b); + } + + assertTrue( + "Missing resources: " + expectedOutdirContents.toString(), + expectedOutdirContents.isEmpty()); + } + + /** + * @param resources + */ + private void dumpResources(HashSet resources) { + System.err.println("Dump: " + resources.size() + " resources"); + for (Iterator iter = resources.iterator(); iter.hasNext();) { + Object element = (Object) iter.next(); + System.err.println(" Resource: " + element); + } + } + + private void listSourceResources(String indirName, Set resources) { + File srcBase = openFile(indirName); + File[] fromResources = + FileUtil.listFiles(srcBase, aspectjResourceFileFilter); + for (int i = 0; i < fromResources.length; i++) { + String name = FileUtil.normalizedPath(fromResources[i], srcBase); + //System.err.println("Checking "+name); + if (!name.startsWith("CVS/") + && (-1 == name.indexOf("/CVS/")) + && !name.endsWith("/CVS")) { + resources.add(name); + } + } + } + + private byte[] listDirResources(File directory, Set resources) { + return listDirResources( + directory.getAbsolutePath(), + directory, + resources); + } + + private byte[] listDirResources( + String prefix, + File directory, + Set resources) { + byte[] manifest = null; + + File[] resourceFiles = directory.listFiles(new FileFilter() { + public boolean accept(File arg0) { + boolean accept = + !arg0.getName().endsWith(".class") && !arg0.isDirectory(); + return accept; + } + }); + for (int i = 0; i < resourceFiles.length; i++) { + File f = resourceFiles[i]; + String name = f.getAbsolutePath(); + if (f.getAbsolutePath().startsWith(prefix)) + name = name.substring(prefix.length()); + name = name.replace('\\', '/'); + + resources.add(resourceFiles[i]); + } + File[] subdirs = directory.listFiles(new FileFilter() { + public boolean accept(File arg0) { + return arg0.isDirectory(); + } + }); + for (int i = 0; i < subdirs.length; i++) { + listDirResources(prefix, subdirs[i], resources); + } + + return manifest; + } + + public static final FileFilter aspectjResourceFileFilter = + new FileFilter() { + public boolean accept(File pathname) { + String name = pathname.getName().toLowerCase(); + return ( + !name.endsWith(".class") + && !name.endsWith(".java") + && !name.endsWith(".aj")); + + } + }; + + /* + * Ensure bin contains all non-Java resouces from source and injars + */ + public void compareDirs(String indirName, String outdirName) { + File binBase = openFile(outdirName); + File[] toResources = + FileUtil.listFiles(binBase, aspectjResourceFileFilter); + + HashSet resources = new HashSet(); + listSourceResources(indirName, resources); + + for (int i = 0; i < toResources.length; i++) { + String fileName = FileUtil.normalizedPath(toResources[i], binBase); + boolean b = resources.remove(fileName); + assertTrue("Extraneous resources: " + fileName, b); + } + + assertTrue( + "Missing resources: " + resources.toString(), + resources.isEmpty()); + } + +} diff --git a/ajde/testsrc/org/aspectj/ajde/NullIdeProperties.java b/ajde/testsrc/org/aspectj/ajde/NullIdeProperties.java index 90203e61f..0ea8c7cca 100644 --- a/ajde/testsrc/org/aspectj/ajde/NullIdeProperties.java +++ b/ajde/testsrc/org/aspectj/ajde/NullIdeProperties.java @@ -28,6 +28,7 @@ public class NullIdeProperties implements ProjectPropertiesAdapter { private List buildConfigFiles = new ArrayList(); private Set inJars; + private Set inpath; private Set sourceRoots; private Set aspectPath; private String outJar; @@ -101,10 +102,16 @@ public class NullIdeProperties implements ProjectPropertiesAdapter { public void setInJars( Set jars ) { this.inJars = jars; } + public void setInpath( Set path) { this.inpath = path; } + public Set getInJars( ) { return inJars; } + public Set getInpath( ) { + return inpath; + } + public Map getSourcePathResources() { File srcBase = new File(getProjectSourcePath()); File[] fromResources = FileUtil.listFiles(srcBase, new FileFilter() { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java index 0fae2686a..7f08a1f9d 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/BuildArgParser.java @@ -297,6 +297,29 @@ public class BuildArgParser extends Main { // trim arg? if (LangUtil.isEmpty(arg)) { showWarning("empty arg found"); + } else if (arg.equals("-inpath")) {; + if (args.size() > nextArgIndex) { + buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_Inpath, CompilerOptions.PRESERVE); + + StringTokenizer st = new StringTokenizer( + ((ConfigParser.Arg)args.get(nextArgIndex)).getValue(), + File.pathSeparator); + while (st.hasMoreTokens()) { + String filename = st.nextToken(); + File file = makeFile(filename); + if (file.exists() && FileUtil.hasZipSuffix(filename)) { + buildConfig.getInpath().add(file); + } else { + if (file.isDirectory()) { + buildConfig.getInpath().add(file); + } else + + showError("bad inpath component: " + filename); + } + } + + args.remove(args.get(nextArgIndex)); + } } else if (arg.equals("-injars")) {; if (args.size() > nextArgIndex) { buildConfig.getAjOptions().put(AjCompilerOptions.OPTION_InJARs, CompilerOptions.PRESERVE); @@ -310,6 +333,11 @@ public class BuildArgParser extends Main { if (jarFile.exists() && FileUtil.hasZipSuffix(filename)) { buildConfig.getInJars().add(jarFile); } else { + File dirFile = makeFile(filename); + if (dirFile.isDirectory()) { + buildConfig.getInJars().add(dirFile); + } else + showError("bad injar: " + filename); } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties index dcaad7781..cb6f71434 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/ajc/messages.properties @@ -15,6 +15,8 @@ misc.usage = AspectJ Compiler 1.1\n\ AspectJ-specific options:\n\ \t-injars <jarList> use classes in <jarList> zip files as source\n\ \t (<jarList> uses classpath delimiter)\n\ +\t-inpath <list> use classes in <list> as source\n\ +\t (<list> uses platform-specific path delimiter)\n\ \t-aspectpath <list> weave aspects from <list> zip files into sources\n\ \t (<list> uses classpath delimiter)\n\ \t-outjar <file> put output classes in zip file <file>\n\ diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index 7eedd3e1c..029e7fd43 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -41,6 +41,7 @@ public class AjBuildConfig { // XXX needs bootclasspath? private List/*File*/ sourceRoots = new ArrayList(); private List/*File*/ files = new ArrayList(); private List/*File*/ inJars = new ArrayList(); + private List/*File*/ inPath = new ArrayList(); private Map/*String->File*/ sourcePathResources = new HashMap(); private List/*File*/ aspectpath = new ArrayList(); private List/*String*/ classpath = new ArrayList(); @@ -189,6 +190,11 @@ public class AjBuildConfig { // XXX needs bootclasspath? public File getOutputJar() { return outputJar; } + + public List/*File*/ getInpath() { + // Elements of the list are either archives (jars/zips) or directories + return inPath; + } public List/*File*/ getInJars() { return inJars; @@ -255,15 +261,18 @@ public class AjBuildConfig { // XXX needs bootclasspath? } /** - * @return List (String) classpath of injars, aspectpath entries, - * specified classpath (bootclasspath, extdirs, and classpath), - * and output dir or jar + * @return List (String) classpath of injars, inpath, aspectpath + * entries, specified classpath (bootclasspath, extdirs, and + * classpath), and output dir or jar */ public List getFullClasspath() { List full = new ArrayList(); for (Iterator i = inJars.iterator(); i.hasNext(); ) { full.add(((File)i.next()).getAbsolutePath()); } + for (Iterator i = inPath.iterator();i.hasNext();) { + full.add(((File)i.next()).getAbsolutePath()); + } for (Iterator i = aspectpath.iterator(); i.hasNext(); ) { full.add(((File)i.next()).getAbsolutePath()); } @@ -324,12 +333,13 @@ public class AjBuildConfig { // XXX needs bootclasspath? XnoInline = xnoInline; } - /** @return true if any config file, sourceroots, sourcefiles, or injars */ + /** @return true if any config file, sourceroots, sourcefiles, injars or inpath */ public boolean hasSources() { return ((null != configFile) || (0 < sourceRoots.size()) || (0 < files.size()) || (0 < inJars.size()) + || (0 < inPath.size()) ); } @@ -377,6 +387,7 @@ public class AjBuildConfig { // XXX needs bootclasspath? incrementalMode = true; } join(inJars, global.inJars); + join(inPath, global.inPath); join(javaOptions, global.javaOptions); if ((null == lintMode) || (AJLINT_DEFAULT.equals(lintMode))) { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index bada76650..fb763ff6b 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -209,7 +209,12 @@ public class AjBuildManager { //??? incremental issues for (Iterator i = buildConfig.getInJars().iterator(); i.hasNext(); ) { File inJar = (File)i.next(); - bcelWeaver.addJarFile(inJar, buildConfig.getOutputDir()); + bcelWeaver.addJarFile(inJar, buildConfig.getOutputDir(),false); + } + + for (Iterator i = buildConfig.getInpath().iterator(); i.hasNext(); ) { + File inPathElement = (File)i.next(); + bcelWeaver.addJarFile(inPathElement,buildConfig.getOutputDir(),true); } if (buildConfig.getSourcePathResources() != null) { diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java index 65769fe10..dcc1b7e8c 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjCompilerOptions.java @@ -22,6 +22,7 @@ public class AjCompilerOptions { public static final String OPTION_Xlint = "org.aspectj.ajdt.core.compiler.Xlint"; public static final String OPTION_InJARs = "org.aspectj.ajdt.core.compiler.injars"; public static final String OPTION_OutJAR = "org.aspectj.ajdt.core.compiler.outjar"; + public static final String OPTION_Inpath = "org.aspectj.ajdt.core.compiler.inpath"; } diff --git a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java index c8eb47cbe..5b203c70b 100644 --- a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java +++ b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java @@ -292,6 +292,7 @@ public class AjcTask extends MatchingTask { // ------- lists resolved in addListArgs() at execute() time private Path srcdir; private Path injars; + private Path inpath; private Path classpath; private Path bootclasspath; private Path forkclasspath; @@ -311,6 +312,7 @@ public class AjcTask extends MatchingTask { // -------- resource-copying /** true if copying injar non-.class files to the output jar */ private boolean copyInjars; + private boolean copyInpath; /** non-null if copying all source root files but the filtered ones */ private String sourceRootCopyFilter; @@ -328,7 +330,7 @@ public class AjcTask extends MatchingTask { * When possibly copying resources to the output jar, * pass ajc a fake output jar to copy from, * so we don't change the modification time of the output jar - * when copying injars into the actual outjar. + * when copying injars/inpath into the actual outjar. */ private File tmpOutjar; @@ -364,6 +366,7 @@ public class AjcTask extends MatchingTask { classpath = null; cmd = new GuardedCommand(); copyInjars = false; + copyInpath = false; destDir = DEFAULT_DESTDIR; executing = false; executingInOtherVM = false; @@ -374,6 +377,7 @@ public class AjcTask extends MatchingTask { inIncrementalFileMode = false; ignored = new ArrayList(); injars = null; + inpath = null; listFileArgs = false; maxMem = null; messageHolder = null; @@ -647,6 +651,8 @@ public class AjcTask extends MatchingTask { log("copyInjars not required since 1.1.1.\n", Project.MSG_WARN); //this.copyInjars = doCopy; } + + /** * Option to copy all files from * all source root directories @@ -771,9 +777,17 @@ public class AjcTask extends MatchingTask { createInjars().setRefid(ref); } + public void setInpathref(Reference ref) { + createInpath().setRefid(ref); + } + public void setInjars(Path path) { injars = incPath(injars, path); } + + public void setInpath(Path path) { + inpath = incPath(inpath,path); + } public Path createInjars() { if (injars == null) { @@ -782,6 +796,13 @@ public class AjcTask extends MatchingTask { return injars.createPath(); } + public Path createInpath() { + if (inpath == null) { + inpath = new Path(project); + } + return inpath.createPath(); + } + public void setClasspath(Path path) { classpath = incPath(classpath, path); } @@ -967,7 +988,7 @@ public class AjcTask extends MatchingTask { // when copying resources, use temp jar for class output // then copy temp jar contents and resources to output jar if ((null != outjar) && !outjarFixedup) { - if (copyInjars || (null != sourceRootCopyFilter)) { + if (copyInjars || copyInpath || (null != sourceRootCopyFilter)) { String path = outjar.getAbsolutePath(); int len = FileUtil.zipSuffixLength(path); if (len < 1) { @@ -1013,6 +1034,7 @@ public class AjcTask extends MatchingTask { if (null != injars) { throw new BuildException("weaveDir incompatible with injars now"); } + File injar = zipDirectory(xweaveDir); setInjars(new Path(getProject(), injar.getAbsolutePath())); setDestdir(xweaveDir); @@ -1315,6 +1337,7 @@ public class AjcTask extends MatchingTask { addFlaggedPath("-extdirs", extdirs, list); addFlaggedPath("-aspectpath", aspectpath, list); addFlaggedPath("-injars", injars, list); + addFlaggedPath("-inpath", inpath, list); addFlaggedPath("-sourceroots", sourceRoots, list); if (argfiles != null) { @@ -1608,6 +1631,8 @@ public class AjcTask extends MatchingTask { setIncremental(true); } else if ("-injars".equals(flag)) { setInjars(new Path(project, in.next())); + } else if ("-inpath".equals(flag)) { + setInpath(new Path(project,in.next())); } else if ("-Xlistfileargs".equals(flag)) { setListFileArgs(true); } else if ("-Xmaxmem".equals(flag)) { diff --git a/testing/src/org/aspectj/testing/ajde/CompileCommand.java b/testing/src/org/aspectj/testing/ajde/CompileCommand.java index 024756804..b670ae485 100644 --- a/testing/src/org/aspectj/testing/ajde/CompileCommand.java +++ b/testing/src/org/aspectj/testing/ajde/CompileCommand.java @@ -352,6 +352,7 @@ class ProjectProperties implements ProjectPropertiesAdapter { = ProjectProperties.class.getName() + ": "; final private String outputDir; private Set inJars; + private Set inpath; private Set sourceRoots; private Set aspectPath; private String outJar; @@ -363,7 +364,9 @@ class ProjectProperties implements ProjectPropertiesAdapter { // known used, per logging proxy public String getDefaultBuildConfigFile() { return null; } public void setInJars(Set input) { inJars = input; } + public void setInpath(Set input) { inpath = input; } public Set getInJars( ) { return inJars; } + public Set getInpath() { return inpath; } public void setSourceRoots(Set input) { sourceRoots = input; } public Set getSourceRoots() { return sourceRoots; } public void setAspectPath(Set path) { aspectPath = path; } diff --git a/testing/src/org/aspectj/testing/harness/bridge/AjcMessageHandler.java b/testing/src/org/aspectj/testing/harness/bridge/AjcMessageHandler.java index 071193a83..d01f26ddc 100644 --- a/testing/src/org/aspectj/testing/harness/bridge/AjcMessageHandler.java +++ b/testing/src/org/aspectj/testing/harness/bridge/AjcMessageHandler.java @@ -225,19 +225,22 @@ public class AjcMessageHandler extends MessageHandler { * @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())) { - return true; + match = true; } } } - if (null != diffs) { + if (!match) { diffs = null; } - return false; + return match; } private IMessage[] getMessagesWithoutExpectedFails() { diff --git a/util/src/org/aspectj/util/FileUtil.java b/util/src/org/aspectj/util/FileUtil.java index a15600054..b8b16c07c 100644 --- a/util/src/org/aspectj/util/FileUtil.java +++ b/util/src/org/aspectj/util/FileUtil.java @@ -411,7 +411,7 @@ public class FileUtil { file.delete(); } } else { - file.delete(); + boolean ret = file.delete(); result++; } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 51b5333ed..78ee0d576 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -13,18 +13,40 @@ package org.aspectj.weaver.bcel; -import java.io.*; -import java.util.*; -import java.util.zip.*; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IProgressListener; import org.aspectj.util.FileUtil; -import org.aspectj.weaver.*; +import org.aspectj.weaver.ConcreteTypeMunger; +import org.aspectj.weaver.CrosscuttingMembersSet; +import org.aspectj.weaver.IWeaver; +import org.aspectj.weaver.NewParentTypeMunger; +import org.aspectj.weaver.ResolvedTypeMunger; +import org.aspectj.weaver.ResolvedTypeX; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.TypeX; import org.aspectj.weaver.patterns.DeclareParents; -import org.aspectj.weaver.patterns.Pointcut; public class BcelWeaver implements IWeaver { private BcelWorld world; @@ -109,34 +131,80 @@ public class BcelWeaver implements IWeaver { } + /** + * Add any .class files in the directory to the outdir. Anything other than .class files in + * the directory (or its subdirectories) are considered resources and are also copied. + * + */ + public void addDirectoryContents(File inFile,File outDir) throws IOException { + + // Get a list of all files (i.e. everything that isnt a directory) + File[] files = FileUtil.listFiles(inFile,new FileFilter() { + public boolean accept(File f) { + boolean accept = !f.isDirectory(); + return accept; + } + }); + + // For each file, add it either as a real .class file or as a resource + for (int i = 0; i < files.length; i++) { + + FileInputStream fis = new FileInputStream(files[i]); + byte[] bytes = FileUtil.readAsByteArray(fis); + String relativePath = files[i].getPath(); + + // ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath() + // or we are in trouble... + String filename = files[i].getAbsolutePath().substring( + inFile.getAbsolutePath().length()+1); + UnwovenClassFile classFile = new UnwovenClassFile(new File(outDir,filename).getAbsolutePath(),bytes); + if (filename.endsWith(".class")) { + // System.err.println("BCELWeaver: processing class from input directory "+classFile); + this.addClassFile(classFile); + } else { + // System.err.println("BCELWeaver: processing resource from input directory "+filename); + addResource(filename,classFile); + } + fis.close(); + } + + } + + /** Adds all class files in the jar */ - public void addJarFile(File inFile, File outDir) throws IOException { + public void addJarFile(File inFile, File outDir, boolean canBeDirectory) throws IOException { // System.err.println("? addJarFile(" + inFile + ", " + outDir + ")"); needToReweaveWorld = true; - ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); //??? buffered - while (true) { - ZipEntry entry = inStream.getNextEntry(); - if (entry == null) break; + // Is this a directory we are looking at? + if (inFile.isDirectory() && canBeDirectory) { + addDirectoryContents(inFile,outDir); + } else { + + ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); //??? buffered + + while (true) { + ZipEntry entry = inStream.getNextEntry(); + if (entry == null) break; - byte[] bytes = FileUtil.readAsByteArray(inStream); - String filename = entry.getName(); - UnwovenClassFile classFile = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes); + byte[] bytes = FileUtil.readAsByteArray(inStream); + String filename = entry.getName(); + UnwovenClassFile classFile = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes); - if (filename.endsWith(".class")) { - this.addClassFile(classFile); - } - else if (!entry.isDirectory()) { + if (filename.endsWith(".class")) { + this.addClassFile(classFile); + } + else if (!entry.isDirectory()) { - /* bug-44190 Copy meta-data */ - addResource(filename,classFile); - } + /* bug-44190 Copy meta-data */ + addResource(filename,classFile); + } - inStream.closeEntry(); + inStream.closeEntry(); + } + inStream.close(); } - - inStream.close(); } public void addResource(String name, File inPath, File outDir) throws IOException { diff --git a/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java b/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java index 249f36325..7f0eb92db 100644 --- a/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java @@ -28,7 +28,7 @@ public class ZipFileWeaver { public void weave(BcelWeaver weaver, File outFile) throws IOException { int count = 0; long startTime = System.currentTimeMillis(); - weaver.addJarFile(inFile, new File(".")); + weaver.addJarFile(inFile, new File("."),false); weaver.weave(outFile); long stopTime = System.currentTimeMillis(); diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java index 1aa65bcfb..5df1e2cfb 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java @@ -56,10 +56,10 @@ public class ZipTestCase extends TestCase { BcelWeaver weaver = new BcelWeaver(world); long startTime = System.currentTimeMillis(); - weaver.addJarFile(inFile, new File(".")); + weaver.addJarFile(inFile, new File("."),false); if (aspectjar != null) { if (isInJar) { - weaver.addJarFile(new File(aspectjar), new File(".")); + weaver.addJarFile(new File(aspectjar), new File("."),false); } else { weaver.addLibraryJarFile(new File(aspectjar)); } |