@@ -91,5 +91,17 @@ | |||
</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> | |||
@@ -441,7 +441,7 @@ public class BuildArgParser extends Main { | |||
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); |
@@ -22,7 +22,7 @@ AspectJ-specific options:\n\ | |||
\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\ |
@@ -170,24 +170,39 @@ public class AjState { | |||
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()) { | |||
@@ -207,6 +222,9 @@ public class AjState { | |||
if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) { | |||
return true; | |||
} | |||
if (f.exists() && f.isDirectory() && checkClassFiles) { | |||
return classFileChangedInDirSinceLastBuild(f); | |||
} | |||
} | |||
return false; | |||
} |
@@ -0,0 +1,5 @@ | |||
public aspect MyAspect { | |||
declare warning : execution(* *(..)) : "a method"; | |||
} |
@@ -0,0 +1,5 @@ | |||
public class MyClass { | |||
void foo() {} | |||
} |
@@ -145,6 +145,10 @@ public class Ajc150Tests extends org.aspectj.testing.XMLBasedAjcTestCase { | |||
runTest("varargs in constructor sig"); | |||
} | |||
public void testAspectpathdirs() { | |||
runTest("dirs on aspectpath"); | |||
} | |||
// helper methods..... | |||
public SyntheticRepository createRepos(File cpentry) { |
@@ -312,7 +312,7 @@ | |||
<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"/> | |||
@@ -2019,4 +2019,14 @@ | |||
<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> |
@@ -142,10 +142,22 @@ public class BcelWeaver implements IWeaver { | |||
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; | |||
@@ -154,25 +166,38 @@ public class BcelWeaver implements IWeaver { | |||
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; |