</sect1> | </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> | </chapter> | ||||
while (st.hasMoreTokens()) { | while (st.hasMoreTokens()) { | ||||
String filename = st.nextToken(); | String filename = st.nextToken(); | ||||
File jarFile = makeFile(filename); | File jarFile = makeFile(filename); | ||||
if (jarFile.exists() && FileUtil.hasZipSuffix(filename)) { | |||||
if (jarFile.exists() && (FileUtil.hasZipSuffix(filename) || jarFile.isDirectory())) { | |||||
buildConfig.getAspectpath().add(jarFile); | buildConfig.getAspectpath().add(jarFile); | ||||
} else { | } else { | ||||
showError("bad aspectpath: " + filename); | showError("bad aspectpath: " + filename); |
\t-injars <jarList> use classes in <jarList> zip files as source\n\ | \t-injars <jarList> use classes in <jarList> zip files as source\n\ | ||||
\t (<jarList> uses classpath delimiter)\n\ | \t (<jarList> uses classpath delimiter)\n\ | ||||
\t deprecated - use inpath instead.\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 (<list> uses classpath delimiter)\n\ | ||||
\t-outjar <file> put output classes in zip file <file>\n\ | \t-outjar <file> put output classes in zip file <file>\n\ | ||||
\t-argfile <file> specify line-delimited list of source files\n\ | \t-argfile <file> specify line-delimited list of source files\n\ |
return ret; | 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) { | private boolean pathChange(AjBuildConfig oldConfig, AjBuildConfig newConfig) { | ||||
boolean changed = false; | boolean changed = false; | ||||
List oldClasspath = oldConfig.getClasspath(); | List oldClasspath = oldConfig.getClasspath(); | ||||
List newClasspath = newConfig.getClasspath(); | List newClasspath = newConfig.getClasspath(); | ||||
if (changed(oldClasspath,newClasspath)) return true; | |||||
if (changed(oldClasspath,newClasspath,true)) return true; | |||||
List oldAspectpath = oldConfig.getAspectpath(); | List oldAspectpath = oldConfig.getAspectpath(); | ||||
List newAspectpath = newConfig.getAspectpath(); | List newAspectpath = newConfig.getAspectpath(); | ||||
if (changed(oldAspectpath,newAspectpath)) return true; | |||||
if (changed(oldAspectpath,newAspectpath,true)) return true; | |||||
List oldInJars = oldConfig.getInJars(); | List oldInJars = oldConfig.getInJars(); | ||||
List newInJars = newConfig.getInJars(); | List newInJars = newConfig.getInJars(); | ||||
if (changed(oldInJars,newInJars)) return true; | |||||
if (changed(oldInJars,newInJars,false)) return true; | |||||
List oldInPath = oldConfig.getInpath(); | List oldInPath = oldConfig.getInpath(); | ||||
List newInPath = newConfig.getInpath(); | List newInPath = newConfig.getInpath(); | ||||
if (changed(oldInPath, newInPath)) return true; | |||||
if (changed(oldInPath, newInPath,false)) return true; | |||||
return changed; | 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 (oldPath == null) oldPath = new ArrayList(); | ||||
if (newPath == null) newPath = new ArrayList(); | if (newPath == null) newPath = new ArrayList(); | ||||
if (oldPath.size() != newPath.size()) { | if (oldPath.size() != newPath.size()) { | ||||
if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) { | if (f.exists() && !f.isDirectory() && (f.lastModified() >= lastSuccessfulBuildTime)) { | ||||
return true; | return true; | ||||
} | } | ||||
if (f.exists() && f.isDirectory() && checkClassFiles) { | |||||
return classFileChangedInDirSinceLastBuild(f); | |||||
} | |||||
} | } | ||||
return false; | return false; | ||||
} | } |
public aspect MyAspect { | |||||
declare warning : execution(* *(..)) : "a method"; | |||||
} |
public class MyClass { | |||||
void foo() {} | |||||
} |
runTest("varargs in constructor sig"); | runTest("varargs in constructor sig"); | ||||
} | } | ||||
public void testAspectpathdirs() { | |||||
runTest("dirs on aspectpath"); | |||||
} | |||||
// helper methods..... | // helper methods..... | ||||
public SyntheticRepository createRepos(File cpentry) { | public SyntheticRepository createRepos(File cpentry) { |
<compile files="HandlerBinding.aj" options="-1.5"/> | <compile files="HandlerBinding.aj" options="-1.5"/> | ||||
<run class="HandlerBinding"/> | <run class="HandlerBinding"/> | ||||
</ajc-test> | </ajc-test> | ||||
<ajc-test dir="java5/annotations/binding" vm="1.5" title="@withincode() and call(* println(..))"> | <ajc-test dir="java5/annotations/binding" vm="1.5" title="@withincode() and call(* println(..))"> | ||||
<compile files="WithinCodeBinding1.aj" options="-1.5"/> | <compile files="WithinCodeBinding1.aj" options="-1.5"/> | ||||
<run class="WithinCodeBinding1"/> | <run class="WithinCodeBinding1"/> | ||||
<run class="p.q.DeathByAnnotations"/> | <run class="p.q.DeathByAnnotations"/> | ||||
</ajc-test> | </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> | </suite> |
public void addLibraryJarFile(File inFile) throws IOException { | 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(); | List addedAspects = new ArrayList(); | ||||
while (true) { | while (true) { | ||||
ZipEntry entry = inStream.getNextEntry(); | ZipEntry entry = inStream.getNextEntry(); | ||||
if (entry == null) break; | if (entry == null) break; | ||||
continue; | 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(); | 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. | // // The ANT copy task should be used to copy resources across. | ||||
// private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false; | // private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false; |