</sect1>
+
+ <sect1>
+ <title>Tools</title>
+
+ <sect2>
+ <title>Aspectpath</title>
+
+ <para>AspectJ 5 allows the specification of directories (containing .class files) on the aspectpath in
+ addition to jar/zip files.</para>
+ </sect2>
+
+ </sect1>
</chapter>
while (st.hasMoreTokens()) {
String filename = st.nextToken();
File jarFile = makeFile(filename);
- if (jarFile.exists() && FileUtil.hasZipSuffix(filename)) {
+ if (jarFile.exists() && (FileUtil.hasZipSuffix(filename) || jarFile.isDirectory())) {
buildConfig.getAspectpath().add(jarFile);
} else {
showError("bad aspectpath: " + filename);
\t-injars <jarList> use classes in <jarList> zip files as source\n\
\t (<jarList> uses classpath delimiter)\n\
\t deprecated - use inpath instead.\n\
-\t-aspectpath <list> weave aspects from <list> zip files into sources\n\
+\t-aspectpath <list> weave aspects in .class files from <list> dirs and jars/zip into sources\n\
\t (<list> uses classpath delimiter)\n\
\t-outjar <file> put output classes in zip file <file>\n\
\t-argfile <file> specify line-delimited list of source files\n\
return ret;
}
+ private boolean classFileChangedInDirSinceLastBuild(File dir) {
+ File[] classFiles = FileUtil.listFiles(dir, new FileFilter(){
+
+ public boolean accept(File pathname) {
+ return pathname.getName().endsWith(".class");
+ }
+
+ });
+ for (int i = 0; i < classFiles.length; i++) {
+ long modTime = classFiles[i].lastModified();
+ if (modTime + 1000 >= lastSuccessfulBuildTime) return true;
+ }
+ return false;
+ }
+
private boolean pathChange(AjBuildConfig oldConfig, AjBuildConfig newConfig) {
boolean changed = false;
List oldClasspath = oldConfig.getClasspath();
List newClasspath = newConfig.getClasspath();
- if (changed(oldClasspath,newClasspath)) return true;
+ if (changed(oldClasspath,newClasspath,true)) return true;
List oldAspectpath = oldConfig.getAspectpath();
List newAspectpath = newConfig.getAspectpath();
- if (changed(oldAspectpath,newAspectpath)) return true;
+ if (changed(oldAspectpath,newAspectpath,true)) return true;
List oldInJars = oldConfig.getInJars();
List newInJars = newConfig.getInJars();
- if (changed(oldInJars,newInJars)) return true;
+ if (changed(oldInJars,newInJars,false)) return true;
List oldInPath = oldConfig.getInpath();
List newInPath = newConfig.getInpath();
- if (changed(oldInPath, newInPath)) return true;
+ if (changed(oldInPath, newInPath,false)) return true;
return changed;
}
- private boolean changed(List oldPath, List newPath) {
+ private boolean changed(List oldPath, List newPath, boolean checkClassFiles) {
if (oldPath == null) oldPath = new ArrayList();
if (newPath == null) newPath = new ArrayList();
if (oldPath.size() != newPath.size()) {
if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) {
return true;
}
+ if (f.exists() && f.isDirectory() && checkClassFiles) {
+ return classFileChangedInDirSinceLastBuild(f);
+ }
}
return false;
}
--- /dev/null
+public aspect MyAspect {
+
+ declare warning : execution(* *(..)) : "a method";
+
+}
\ No newline at end of file
--- /dev/null
+public class MyClass {
+
+ void foo() {}
+
+}
\ No newline at end of file
runTest("varargs in constructor sig");
}
+ public void testAspectpathdirs() {
+ runTest("dirs on aspectpath");
+ }
+
// helper methods.....
public SyntheticRepository createRepos(File cpentry) {
<compile files="HandlerBinding.aj" options="-1.5"/>
<run class="HandlerBinding"/>
</ajc-test>
-
+
<ajc-test dir="java5/annotations/binding" vm="1.5" title="@withincode() and call(* println(..))">
<compile files="WithinCodeBinding1.aj" options="-1.5"/>
<run class="WithinCodeBinding1"/>
<run class="p.q.DeathByAnnotations"/>
</ajc-test>
+
+ <!-- ============================================================== -->
+
+ <ajc-test dir="options/aspectpath" title="dirs on aspectpath">
+ <compile files="MyAspect.aj" options="-d out"/>
+ <compile files="MyClass.java" options="-aspectpath out">
+ <message kind="warning" line="3" text="a method"/>
+ </compile>
+ </ajc-test>
+
</suite>
\ No newline at end of file
public void addLibraryJarFile(File inFile) throws IOException {
- ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); //??? buffered
+ List addedAspects = null;
+ if (inFile.isDirectory()) {
+ addedAspects = addAspectsFromDirectory(inFile);
+ } else {
+ addedAspects = addAspectsFromJarFile(inFile);
+ }
+ for (Iterator i = addedAspects.iterator(); i.hasNext();) {
+ ResolvedTypeX aspectX = (ResolvedTypeX) i.next();
+ xcutSet.addOrReplaceAspect(aspectX);
+ }
+ }
+
+ private List addAspectsFromJarFile(File inFile) throws FileNotFoundException, IOException {
+ ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); //??? buffered
List addedAspects = new ArrayList();
-
while (true) {
ZipEntry entry = inStream.getNextEntry();
if (entry == null) break;
continue;
}
- ClassParser parser = new ClassParser(new ByteArrayInputStream(FileUtil.readAsByteArray(inStream)), entry.getName());
- JavaClass jc = parser.parse();
- inStream.closeEntry();
-
- ResolvedTypeX type = world.addSourceObjectType(jc).getResolvedTypeX();
- if (type.isAspect()) {
- addedAspects.add(type);
- }
-
+ addIfAspect(FileUtil.readAsByteArray(inStream), entry.getName(), addedAspects);
+ inStream.closeEntry();
}
-
inStream.close();
+ return addedAspects;
+ }
+
+ private List addAspectsFromDirectory(File dir) throws FileNotFoundException, IOException{
+ List addedAspects = new ArrayList();
+ File[] classFiles = FileUtil.listFiles(dir,new FileFilter(){
- for (Iterator i = addedAspects.iterator(); i.hasNext();) {
- ResolvedTypeX aspectX = (ResolvedTypeX) i.next();
- xcutSet.addOrReplaceAspect(aspectX);
+ public boolean accept(File pathname) {
+ return pathname.getName().endsWith(".class");
+ }
+
+ });
+ for (int i = 0; i < classFiles.length; i++) {
+ FileInputStream fis = new FileInputStream(classFiles[i]);
+ byte[] bytes = FileUtil.readAsByteArray(fis);
+ addIfAspect(bytes,classFiles[i].getAbsolutePath(),addedAspects);
}
+ return addedAspects;
+ }
+
+ private void addIfAspect(byte[] bytes, String name, List toList) throws IOException {
+ ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes),name);
+ JavaClass jc = parser.parse();
+ ResolvedTypeX type = world.addSourceObjectType(jc).getResolvedTypeX();
+ if (type.isAspect()) {
+ toList.add(type);
+ }
}
-
// // The ANT copy task should be used to copy resources across.
// private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false;