fix some build issues - some more left in deps handling refactored IMessageHandler to support dontIgnore()AspectJ5_Development
<target name="compile" if="jdk15" depends="init, | <target name="compile" if="jdk15" depends="init, | ||||
runtime.compile"> | runtime.compile"> | ||||
<!-- FIXME: we override compile due to use of java5-src instead of src.. and source/target attrs --> | <!-- FIXME: we override compile due to use of java5-src instead of src.. and source/target attrs --> | ||||
<mkdir dir="${basedir}/bin"/> | |||||
<javac debug="on" destdir="${basedir}/bin" source="1.5" target="1.5"> | |||||
<src path="${basedir}/java5-src"/> | |||||
<mkdir dir="../aspectj5rt/bin"/> | |||||
<javac debug="on" destdir="../aspectj5rt/bin" source="1.5" target="1.5"> | |||||
<src path="../aspectj5rt/java5-src"/> | |||||
<classpath refid="aspectj5rt.src.path"/> | <classpath refid="aspectj5rt.src.path"/> | ||||
</javac> | </javac> | ||||
</target> | </target> |
if (proxy != null) proxy.reset(); | if (proxy != null) proxy.reset(); | ||||
counters.clear(); | counters.clear(); | ||||
} | } | ||||
/** | |||||
* Not supported | |||||
* @param kind | |||||
*/ | |||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
} | } |
public boolean isIgnoring(IMessage.Kind kind) { | public boolean isIgnoring(IMessage.Kind kind) { | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
}; | }; | ||||
/** | /** | ||||
* @return true if this handler is ignoring all messages of this type | * @return true if this handler is ignoring all messages of this type | ||||
*/ | */ | ||||
boolean isIgnoring(IMessage.Kind kind); | boolean isIgnoring(IMessage.Kind kind); | ||||
/** | |||||
* Allow fine grained configuration. This implementation does not ignore anything. | |||||
* @param kind | |||||
*/ | |||||
void dontIgnore(IMessage.Kind kind); | |||||
} | } |
public boolean isIgnoring(Kind kind) { | public boolean isIgnoring(Kind kind) { | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
}; | }; | ||||
return visitMessages(holder, selector, true, false); | return visitMessages(holder, selector, true, false); | ||||
} | } | ||||
String text = message.getMessage(); | String text = message.getMessage(); | ||||
return ((null != message) && (-1 != text.indexOf(infix))); | return ((null != message) && (-1 != text.indexOf(infix))); | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
} | } | ||||
// ------------------ components to render messages | // ------------------ components to render messages |
} | } | ||||
/** | /** | ||||
* @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind) | |||||
* @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind) | |||||
*/ | */ | ||||
public boolean isIgnoring(IMessage.Kind kind) { | public boolean isIgnoring(IMessage.Kind kind) { | ||||
// XXX share MessageHandler implementation in superclass | // XXX share MessageHandler implementation in superclass | ||||
return message.toString(); | return message.toString(); | ||||
} | } | ||||
/** | |||||
* Override to allow fine grained configuration. This implementation does not ignore anything. | |||||
* @param kind | |||||
*/ | |||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
} | } |
<sequential> | <sequential> | ||||
<echo message="compile ... @{project}"/> | <echo message="compile ... @{project}"/> | ||||
<mkdir dir="../@{project}/${build.dir}"/> | <mkdir dir="../@{project}/${build.dir}"/> | ||||
<javac debug="on" destdir="../@{project}/${build.dir}" source="1.2" target="1.1"> | |||||
<javac debug="on" destdir="../@{project}/${build.dir}" source="1.3" target="1.3"> | |||||
<src path="../@{project}/${src.dir}"/> | <src path="../@{project}/${src.dir}"/> | ||||
<classpath refid="@{path}"/> | <classpath refid="@{path}"/> | ||||
</javac> | </javac> | ||||
<sequential> | <sequential> | ||||
<echo message="test:compile ... @{project}"/> | <echo message="test:compile ... @{project}"/> | ||||
<mkdir dir="../@{project}/${test.build.dir}"/> | <mkdir dir="../@{project}/${test.build.dir}"/> | ||||
<javac debug="on" destdir="../@{project}/${test.build.dir}" source="1.2" target="1.1"> | |||||
<javac debug="on" destdir="../@{project}/${test.build.dir}" source="1.3" target="1.3"> | |||||
<src path="../@{project}/${test.src.dir}"/> | <src path="../@{project}/${test.src.dir}"/> | ||||
<classpath refid="@{path}"/> | <classpath refid="@{path}"/> | ||||
<classpath path="../@{project}/${build.dir}"/> | <classpath path="../@{project}/${build.dir}"/> | ||||
<attribute name="suite"/> | <attribute name="suite"/> | ||||
<sequential> | <sequential> | ||||
<!-- showoutput="on" --> | <!-- showoutput="on" --> | ||||
<junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on"> | |||||
<junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on" dir="../@{project}"> | |||||
<classpath> | <classpath> | ||||
<pathelement path="../@{project}/${build.dir}"/> | <pathelement path="../@{project}/${build.dir}"/> | ||||
<pathelement path="../@{project}/${test.build.dir}"/> | <pathelement path="../@{project}/${test.build.dir}"/> |
testing-drivers/build.xml, | testing-drivers/build.xml, | ||||
ajdoc/build.xml, | ajdoc/build.xml, | ||||
ajbrowser/build.xml, | ajbrowser/build.xml, | ||||
tests/build.xml"/> | |||||
tests/build.xml, | |||||
loadtime/build.xml, | |||||
loadtime5/build.xml"/> | |||||
</subant> | </subant> | ||||
</sequential> | </sequential> | ||||
</macrodef> | </macrodef> | ||||
ajde/build.xml, | ajde/build.xml, | ||||
taskdefs/build.xml, | taskdefs/build.xml, | ||||
ajdoc/build.xml, | ajdoc/build.xml, | ||||
ajbrowser/build.xml"/> | |||||
ajbrowser/build.xml, | |||||
loadtime/build.xml, | |||||
loadtime5/build.xml"/> | |||||
<!-- TODO av org.aspectj.lib --> | <!-- TODO av org.aspectj.lib --> | ||||
</subant> | </subant> | ||||
<!-- FIXME av bcel-builder --> | <!-- FIXME av bcel-builder --> |
<?xml version="1.0"?> | |||||
<project name="loadtime" default="all" basedir="."> | |||||
<import file="../build-common.xml"/> | |||||
<import file="../asm/build.xml"/> | |||||
<import file="../bridge/build.xml"/> | |||||
<import file="../util/build.xml"/> | |||||
<import file="../weaver/build.xml"/> | |||||
<path id="loadtime.test.src.path"> | |||||
<fileset dir="${basedir}/../lib"> | |||||
<include name="junit/*.jar"/> | |||||
</fileset> | |||||
<path refid="loadtime.src.path"/> | |||||
</path> | |||||
<path id="loadtime.src.path"> | |||||
<pathelement path="../asm/bin"/> | |||||
<pathelement path="../bridge/bin"/> | |||||
<pathelement path="../util/bin"/> | |||||
<pathelement path="../weaver/bin"/> | |||||
<fileset dir="${basedir}/../lib"> | |||||
<include name="bcel/*.jar"/> | |||||
</fileset> | |||||
</path> | |||||
<target name="compile" depends="init, | |||||
asm.compile, | |||||
bridge.compile, | |||||
util.compile, | |||||
weaver.compile"> | |||||
<srccompile project="loadtime" path="loadtime.src.path"/> | |||||
</target> | |||||
<target name="test:compile" depends="compile"> | |||||
</target> | |||||
<target name="test" depends="test:compile"> | |||||
</target> | |||||
<target name="jar" depends="compile"> | |||||
<delete file="${build.ajdir}/jars/loadtime.jar"/> | |||||
<jar destfile="${build.ajdir}/jars/loadtime.jar"> | |||||
<fileset dir="bin"> | |||||
<include name="**/*"/> | |||||
</fileset> | |||||
</jar> | |||||
</target> | |||||
</project> | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!--***************************************************************************************************************************** | |||||
AspectJ 5 DTD | |||||
To use this DTD, start your defintion file with | |||||
<!DOCTYPE aspectj PUBLIC | |||||
"-//AspectJ//DTD 1.5.0//EN" | |||||
"http://.../dtd/aspectj_1_5_0.dtd"> | |||||
You can also use the "aliasing DTD" that matchs always the latest release of AspectJ | |||||
<!DOCTYPE aspectj PUBLIC | |||||
"-//AspectJ//DTD//EN" | |||||
"http://.../dtd/aspectj.dtd"> | |||||
To not use this DTD, start your definition file with | |||||
<?xml version="1.0"?> | |||||
******************************************************************************************************************************--> | |||||
<!--***************************************************************************************************************************** | |||||
aspectj | |||||
********************************************************************************************************************************* | |||||
[aspectj] defines the root element | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT aspectj ( | |||||
weaver?, | |||||
aspects? | |||||
)> | |||||
<!--***************************************************************************************************************************** | |||||
weaver | |||||
********************************************************************************************************************************* | |||||
[weaver] defines the weaver configuration | |||||
@options defines a command like line of option | |||||
When multiple aspectj DD are found, the options are simply toggled | |||||
TODO: Note: the scope of the options can be ClassLoader aware but should be assumed JVM wide | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT weaver ( | |||||
(include | exclude)* | |||||
)> | |||||
<!ATTLIST weaver | |||||
options CDATA #IMPLIED | |||||
> | |||||
<!--***************************************************************************************************************************** | |||||
include | |||||
********************************************************************************************************************************* | |||||
[include] narrows the scope of the weaver | |||||
A class must be matched by ALL the include elements to be exposed to the weaver | |||||
@within defines a type pattern | |||||
(it is not a startWith) | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT include EMPTY> | |||||
<!ATTLIST include | |||||
within CDATA #REQUIRED | |||||
> | |||||
<!--***************************************************************************************************************************** | |||||
exclude | |||||
********************************************************************************************************************************* | |||||
[exclude] narrows the scope of the weaver | |||||
A class must be matched by NONE of the exclude elements to be exposed to the weaver | |||||
@within defines a type pattern | |||||
(it is not a startWith) | |||||
TODO should it be called @from: "<exclude from=..> instead of <exclude within=..> | |||||
TODO: AND must be written that way and not with the "&&" symbol. Thus NOT and OR exists as well. | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT exclude EMPTY> | |||||
<!ATTLIST exclude | |||||
within CDATA #REQUIRED | |||||
> | |||||
<!--***************************************************************************************************************************** | |||||
aspects | |||||
********************************************************************************************************************************* | |||||
[aspects] defines a set of aspects | |||||
TODO we were about to use include but it is already used for weaver scope with "within" which is not relevant | |||||
for aspects. I (AV) decided to use only aspect and provide include= thru name, and exclude= as exclude. | |||||
see sample. | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT aspects ( | |||||
(aspect | exclude | concrete-aspect)* | |||||
)> | |||||
<!--***************************************************************************************************************************** | |||||
aspect | |||||
TODO: did not used include since already used in weaver/include@within and @within does not makes sense | |||||
********************************************************************************************************************************* | |||||
[aspect] defines an aspect to include | |||||
@name FQN of the aspect, nested class must use $ | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT aspect EMPTY> | |||||
<!ATTLIST aspect | |||||
name CDATA #REQUIRED | |||||
> | |||||
<!--***************************************************************************************************************************** | |||||
exclude | |||||
********************************************************************************************************************************* | |||||
[exclude] defines a set of aspect to exclude | |||||
@within within pattern (even from other systems / parent classloader) | |||||
SAME AS FOR weaver/exclude | |||||
******************************************************************************************************************************--> | |||||
<!--***************************************************************************************************************************** | |||||
concrete-aspect | |||||
********************************************************************************************************************************* | |||||
[concrete-aspect] defines a concrete aspect from an abstract one | |||||
@name FQN of the concrete aspect (use $ for nested class) [will be jit generated] | |||||
@extends FQN of the abstract aspect (use $ for nested class) | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT concrete-aspect ( | |||||
pointcut+ | |||||
)> | |||||
<!ATTLIST concrete-aspect | |||||
name CDATA #REQUIRED | |||||
extends CDATA #REQUIRED | |||||
> | |||||
<!--***************************************************************************************************************************** | |||||
pointcut | |||||
********************************************************************************************************************************* | |||||
[pointcut] defines a concrete pointcut within a concrete aspect from an abstract one | |||||
@name name of the abstract pointcut (method name, unique in aspect class hierarchy) | |||||
@expression pointcut expression | |||||
Note: for argument binding, the bounded arguments must be present and bounded: | |||||
<pointcut name="myAdvice(int i)" expression="... AND args(i)"/> | |||||
TODO: AND must be written that way and not with the "&&" symbol. Thus NOT and OR exists as well. | |||||
******************************************************************************************************************************--> | |||||
<!ELEMENT pointcut EMPTY> | |||||
<!ATTLIST pointcut | |||||
name CDATA #REQUIRED | |||||
expression CDATA #REQUIRED | |||||
> |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime; | |||||
import org.aspectj.asm.IRelationship; | |||||
import org.aspectj.bridge.IMessage; | |||||
import org.aspectj.bridge.ISourceLocation; | |||||
import org.aspectj.bridge.Message; | |||||
import org.aspectj.weaver.ICrossReferenceHandler; | |||||
import org.aspectj.weaver.World; | |||||
import org.aspectj.weaver.bcel.BcelWeaver; | |||||
import org.aspectj.weaver.bcel.BcelWorld; | |||||
import org.aspectj.weaver.loadtime.definition.Definition; | |||||
import org.aspectj.weaver.loadtime.definition.DocumentParser; | |||||
import org.aspectj.weaver.tools.GeneratedClassHandler; | |||||
import org.aspectj.weaver.tools.WeavingAdaptor; | |||||
import java.io.File; | |||||
import java.io.FileOutputStream; | |||||
import java.lang.reflect.Method; | |||||
import java.net.URL; | |||||
import java.util.ArrayList; | |||||
import java.util.Enumeration; | |||||
import java.util.Iterator; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.WeakHashMap; | |||||
/** | |||||
* Adapter between the generic class pre processor interface and the AspectJ weaver | |||||
* Load time weaving consistency relies on Bcel.setRepository | |||||
* | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class Aj implements ClassPreProcessor { | |||||
/** | |||||
* Initialization | |||||
*/ | |||||
public void initialize() { | |||||
; | |||||
} | |||||
/** | |||||
* Weave | |||||
* | |||||
* @param className | |||||
* @param bytes | |||||
* @param loader | |||||
* @return | |||||
*/ | |||||
public byte[] preProcess(String className, byte[] bytes, ClassLoader loader) { | |||||
//System.out.println("Aj.preProcess " + className + " @ " + loader + " " + Thread.currentThread()); | |||||
//TODO av needs to spec and doc that | |||||
//TODO av should skip org.aspectj as well unless done somewhere else | |||||
if (loader == null | |||||
|| className == null) { | |||||
// skip boot loader or null classes (hibernate) | |||||
return bytes; | |||||
} | |||||
try { | |||||
byte[] weaved = WeaverContainer.getWeaver(loader).weaveClass(className, bytes); | |||||
//TODO av make dump optionnal and configurable | |||||
__dump(className, weaved); | |||||
return weaved; | |||||
} catch (Throwable t) { | |||||
t.printStackTrace(); | |||||
return bytes; | |||||
} | |||||
} | |||||
/** | |||||
* Cache of weaver | |||||
* There is one weaver per classloader | |||||
*/ | |||||
static class WeaverContainer { | |||||
private static Map weavingAdaptors = new WeakHashMap(); | |||||
static WeavingAdaptor getWeaver(ClassLoader loader) { | |||||
synchronized (weavingAdaptors) { | |||||
WeavingAdaptor weavingAdaptor = (WeavingAdaptor) weavingAdaptors.get(loader); | |||||
if (weavingAdaptor == null) { | |||||
weavingAdaptor = new ClassLoaderWeavingAdaptor(loader); | |||||
weavingAdaptors.put(loader, weavingAdaptor); | |||||
} | |||||
return weavingAdaptor; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Adaptor with the AspectJ WeavingAdaptor | |||||
*/ | |||||
static class ClassLoaderWeavingAdaptor extends WeavingAdaptor { | |||||
public ClassLoaderWeavingAdaptor(final ClassLoader loader) { | |||||
super(null);// at this stage we don't have yet a generatedClassHandler to define to the VM the closures | |||||
this.generatedClassHandler = new GeneratedClassHandler() { | |||||
/** | |||||
* Callback when we need to define a Closure in the JVM | |||||
* | |||||
* @param name | |||||
* @param bytes | |||||
*/ | |||||
public void acceptClass(String name, byte[] bytes) { | |||||
//TODO av make dump configurable | |||||
try { | |||||
__dump(name, bytes); | |||||
} catch (Throwable throwable) { | |||||
throwable.printStackTrace(); | |||||
} | |||||
defineClass(loader, name, bytes);// could be done lazily using the hook | |||||
} | |||||
}; | |||||
bcelWorld = new BcelWorld( | |||||
loader, messageHandler, new ICrossReferenceHandler() { | |||||
public void addCrossReference(ISourceLocation from, ISourceLocation to, IRelationship.Kind kind, boolean runtimeTest) { | |||||
;// for tools only | |||||
} | |||||
} | |||||
); | |||||
// //TODO this AJ code will call | |||||
// //org.aspectj.apache.bcel.Repository.setRepository(this); | |||||
// //ie set some static things | |||||
// //==> bogus as Bcel is expected to be | |||||
// org.aspectj.apache.bcel.Repository.setRepository(new ClassLoaderRepository(loader)); | |||||
weaver = new BcelWeaver(bcelWorld); | |||||
// register the definitions | |||||
registerDefinitions(weaver, loader); | |||||
// after adding aspects | |||||
weaver.prepareForWeave(); | |||||
} | |||||
} | |||||
private static void defineClass(ClassLoader loader, String name, byte[] bytes) { | |||||
try { | |||||
//TODO av protection domain, and optimize | |||||
Method defineClass = ClassLoader.class.getDeclaredMethod( | |||||
"defineClass", new Class[]{ | |||||
String.class, bytes.getClass(), int.class, int.class | |||||
} | |||||
); | |||||
defineClass.setAccessible(true); | |||||
defineClass.invoke( | |||||
loader, new Object[]{ | |||||
name, | |||||
bytes, | |||||
new Integer(0), | |||||
new Integer(bytes.length) | |||||
} | |||||
); | |||||
} catch (Throwable t) { | |||||
t.printStackTrace(); | |||||
} | |||||
} | |||||
/** | |||||
* Dump the given bytcode in _dump/... | |||||
* | |||||
* @param name | |||||
* @param b | |||||
* @throws Throwable | |||||
*/ | |||||
private static void __dump(String name, byte[] b) throws Throwable { | |||||
String className = name.replace('.', '/'); | |||||
final File dir; | |||||
if (className.indexOf('/') > 0) { | |||||
dir = new File("_dump" + File.separator + className.substring(0, className.lastIndexOf('/'))); | |||||
} else { | |||||
dir = new File("_dump"); | |||||
} | |||||
dir.mkdirs(); | |||||
String fileName = "_dump" + File.separator + className + ".class"; | |||||
FileOutputStream os = new FileOutputStream(fileName); | |||||
os.write(b); | |||||
os.close(); | |||||
} | |||||
/** | |||||
* Load and cache the aop.xml/properties according to the classloader visibility rules | |||||
* | |||||
* @param weaver | |||||
* @param loader | |||||
*/ | |||||
private static void registerDefinitions(final BcelWeaver weaver, final ClassLoader loader) { | |||||
try { | |||||
//TODO av underoptimized: we will parse each XML once per CL that see it | |||||
Enumeration xmls = loader.getResources("/META-INF/aop.xml"); | |||||
List definitions = new ArrayList(); | |||||
//TODO av dev mode needed ? TBD -Daj5.def=... | |||||
if (loader != null && loader != ClassLoader.getSystemClassLoader().getParent()) { | |||||
String file = System.getProperty("aj5.def", null); | |||||
if (file != null) { | |||||
definitions.add(DocumentParser.parse((new File(file)).toURL())); | |||||
} | |||||
} | |||||
while (xmls.hasMoreElements()) { | |||||
URL xml = (URL) xmls.nextElement(); | |||||
definitions.add(DocumentParser.parse(xml)); | |||||
} | |||||
registerOptions(weaver, loader, definitions); | |||||
registerAspects(weaver, loader, definitions); | |||||
registerFilters(weaver, loader, definitions); | |||||
} catch (Exception e) { | |||||
weaver.getWorld().getMessageHandler().handleMessage( | |||||
new Message("Register definition failed", IMessage.FAIL, e, null) | |||||
); | |||||
} | |||||
} | |||||
/** | |||||
* Configure the weaver according to the option directives | |||||
* TODO av - don't know if it is that good to reuse, since we only allow a small subset of options in LTW | |||||
* | |||||
* @param weaver | |||||
* @param loader | |||||
* @param definitions | |||||
*/ | |||||
private static void registerOptions(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { | |||||
StringBuffer allOptions = new StringBuffer(); | |||||
for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { | |||||
Definition definition = (Definition) iterator.next(); | |||||
allOptions.append(definition.getWeaverOptions()).append(' '); | |||||
} | |||||
Options.WeaverOption weaverOption = Options.parse(allOptions.toString(), loader); | |||||
// configure the weaver and world | |||||
// AV - code duplicates AspectJBuilder.initWorldAndWeaver() | |||||
World world = weaver.getWorld(); | |||||
world.setMessageHandler(weaverOption.messageHandler); | |||||
world.setXlazyTjp(weaverOption.lazyTjp); | |||||
weaver.setReweavableMode(weaverOption.reWeavable, false); | |||||
world.setXnoInline(weaverOption.noInline); | |||||
world.setBehaveInJava5Way(weaverOption.java5); | |||||
//TODO proceedOnError option | |||||
} | |||||
/** | |||||
* Register the aspect, following include / exclude rules | |||||
* | |||||
* @param weaver | |||||
* @param loader | |||||
* @param definitions | |||||
*/ | |||||
private static void registerAspects(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { | |||||
//TODO: the exclude aspect allow to exclude aspect defined upper in the CL hierarchy - is it what we want ?? | |||||
// if not, review the getResource so that we track which resource is defined by which CL | |||||
//it aspectClassNames | |||||
//exclude if in any of the exclude list | |||||
for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { | |||||
Definition definition = (Definition) iterator.next(); | |||||
for (Iterator aspects = definition.getAspectClassNames().iterator(); aspects.hasNext();) { | |||||
String aspectClassName = (String) aspects.next(); | |||||
if (!Definition.isAspectExcluded(aspectClassName, definitions)) { | |||||
weaver.addLibraryAspect(aspectClassName); | |||||
} | |||||
} | |||||
} | |||||
//it concreteAspects | |||||
//exclude if in any of the exclude list | |||||
//TODO | |||||
} | |||||
/** | |||||
* Register the include / exclude filters | |||||
* | |||||
* @param weaver | |||||
* @param loader | |||||
* @param definitions | |||||
*/ | |||||
private static void registerFilters(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { | |||||
//TODO | |||||
; | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime; | |||||
/** | |||||
* Generic class pre processor interface that allows to separate the AspectJ 5 load time weaving | |||||
* from Java 5 JVMTI interfaces for further use on Java 1.3 / 1.4 | |||||
* | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public interface ClassPreProcessor { | |||||
/** | |||||
* Post constructor initialization, usually empty | |||||
*/ | |||||
void initialize(); | |||||
/** | |||||
* Weave | |||||
* | |||||
* @param className | |||||
* @param bytes | |||||
* @param classLoader | |||||
* @return | |||||
*/ | |||||
byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader); | |||||
} |
/************************************************************************************** | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. * | |||||
* http://aspectwerkz.codehaus.org * | |||||
* ---------------------------------------------------------------------------------- * | |||||
* The software in this package is published under the terms of the LGPL license * | |||||
* a copy of which has been included with this distribution in the license.txt file. * | |||||
**************************************************************************************/ | |||||
package org.aspectj.weaver.loadtime; | |||||
import org.aspectj.bridge.AbortException; | |||||
import org.aspectj.bridge.IMessage; | |||||
import org.aspectj.bridge.IMessageHandler; | |||||
import org.aspectj.bridge.Message; | |||||
import org.aspectj.util.LangUtil; | |||||
import java.util.Collections; | |||||
import java.util.Iterator; | |||||
import java.util.List; | |||||
/** | |||||
* A class that hanldes LTW options. | |||||
* Note: AV - I choosed to not reuse AjCompilerOptions and alike since those implies too many dependancies on | |||||
* jdt and ajdt modules. | |||||
* | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class Options { | |||||
private static class DefaultMessageHandler implements IMessageHandler { | |||||
boolean isVerbose = false; | |||||
boolean showWeaveInfo = false; | |||||
boolean showWarn = true; | |||||
public boolean handleMessage(IMessage message) throws AbortException { | |||||
return SYSTEM_OUT.handleMessage(message); | |||||
} | |||||
public boolean isIgnoring(IMessage.Kind kind) { | |||||
if (kind.equals(IMessage.WEAVEINFO)) { | |||||
return !showWeaveInfo; | |||||
} | |||||
if (kind.isSameOrLessThan(IMessage.INFO)) { | |||||
return !isVerbose; | |||||
} | |||||
return !showWarn; | |||||
} | |||||
public void dontIgnore(IMessage.Kind kind) { | |||||
if (kind.equals(IMessage.WEAVEINFO)) { | |||||
showWeaveInfo = true; | |||||
} else if (kind.equals(IMessage.DEBUG)) { | |||||
isVerbose = true; | |||||
} else if (kind.equals(IMessage.WARNING)) { | |||||
showWarn = false; | |||||
} | |||||
} | |||||
} | |||||
private final static String OPTION_15 = "-1.5"; | |||||
private final static String OPTION_lazyTjp = "-XlazyTjp"; | |||||
private final static String OPTION_noWarn = "-nowarn"; | |||||
private final static String OPTION_noWarnNone = "-warn:none"; | |||||
private final static String OPTION_proceedOnError = "-proceedOnError"; | |||||
private final static String OPTION_verbose = "-verbose"; | |||||
private final static String OPTION_reweavable = "-Xreweavable"; | |||||
private final static String OPTION_noinline = "-Xnoinline"; | |||||
private final static String OPTION_showWeaveInfo = "-showWeaveInfo"; | |||||
private final static String OPTIONVALUED_messageHolder = "-XmessageHolderClass:";//TODO rename to Handler | |||||
//FIXME dump option - dump what - dump before/after ? | |||||
public static WeaverOption parse(String options, ClassLoader laoder) { | |||||
// the first option wins | |||||
List flags = LangUtil.anySplit(options, " "); | |||||
Collections.reverse(flags); | |||||
WeaverOption weaverOption = new WeaverOption(); | |||||
weaverOption.messageHandler = new DefaultMessageHandler();//default | |||||
// do a first round on the message handler since it will report the options themselves | |||||
for (Iterator iterator = flags.iterator(); iterator.hasNext();) { | |||||
String arg = (String) iterator.next(); | |||||
if (arg.startsWith(OPTIONVALUED_messageHolder)) { | |||||
if (arg.length() > OPTIONVALUED_messageHolder.length()) { | |||||
String handlerClass = arg.substring(OPTIONVALUED_messageHolder.length()).trim(); | |||||
try { | |||||
Class handler = Class.forName(handlerClass, false, laoder); | |||||
weaverOption.messageHandler = ((IMessageHandler) handler.newInstance()); | |||||
} catch (Throwable t) { | |||||
weaverOption.messageHandler.handleMessage( | |||||
new Message( | |||||
"Cannot instantiate message handler " + handlerClass, | |||||
IMessage.ERROR, | |||||
t, | |||||
null | |||||
) | |||||
); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// configure the other options | |||||
for (Iterator iterator = flags.iterator(); iterator.hasNext();) { | |||||
String arg = (String) iterator.next(); | |||||
if (arg.equals(OPTION_15)) { | |||||
weaverOption.java5 = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_lazyTjp)) { | |||||
weaverOption.lazyTjp = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_noinline)) { | |||||
weaverOption.noInline = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_noWarn) || arg.equalsIgnoreCase(OPTION_noWarnNone)) { | |||||
weaverOption.noWarn = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_proceedOnError)) { | |||||
weaverOption.proceedOnError = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_reweavable)) { | |||||
weaverOption.reWeavable = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_showWeaveInfo)) { | |||||
weaverOption.showWeaveInfo = true; | |||||
} else if (arg.equalsIgnoreCase(OPTION_verbose)) { | |||||
weaverOption.verbose = true; | |||||
} else { | |||||
weaverOption.messageHandler.handleMessage( | |||||
new Message( | |||||
"Cannot configure weaver with option " + arg + ": unknown option", | |||||
IMessage.WARNING, | |||||
null, | |||||
null | |||||
) | |||||
); | |||||
} | |||||
} | |||||
// refine message handler configuration | |||||
if (weaverOption.noWarn) { | |||||
weaverOption.messageHandler.dontIgnore(IMessage.WARNING); | |||||
} | |||||
if (weaverOption.verbose) { | |||||
weaverOption.messageHandler.dontIgnore(IMessage.DEBUG); | |||||
} | |||||
if (weaverOption.showWeaveInfo) { | |||||
weaverOption.messageHandler.dontIgnore(IMessage.WEAVEINFO); | |||||
} | |||||
return weaverOption; | |||||
} | |||||
public static class WeaverOption { | |||||
boolean java5; | |||||
boolean lazyTjp; | |||||
boolean noWarn; | |||||
boolean proceedOnError; | |||||
boolean verbose; | |||||
boolean reWeavable; | |||||
boolean noInline; | |||||
boolean showWeaveInfo; | |||||
IMessageHandler messageHandler; | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime.definition; | |||||
import java.util.List; | |||||
import java.util.ArrayList; | |||||
/** | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class Definition { | |||||
private StringBuffer m_weaverOptions; | |||||
private List m_includePatterns; | |||||
private List m_excludePatterns; | |||||
private List m_aspectClassNames; | |||||
private List m_aspectExcludePatterns; | |||||
private List m_concreteAspects; | |||||
public Definition() { | |||||
m_weaverOptions = new StringBuffer(); | |||||
m_includePatterns = new ArrayList(0); | |||||
m_excludePatterns = new ArrayList(0); | |||||
m_aspectClassNames = new ArrayList(); | |||||
m_aspectExcludePatterns = new ArrayList(0); | |||||
m_concreteAspects = new ArrayList(0); | |||||
} | |||||
public String getWeaverOptions() { | |||||
return m_weaverOptions.toString(); | |||||
} | |||||
public List getIncludePatterns() { | |||||
return m_includePatterns; | |||||
} | |||||
public List getExcludePatterns() { | |||||
return m_excludePatterns; | |||||
} | |||||
public List getAspectClassNames() { | |||||
return m_aspectClassNames; | |||||
} | |||||
public List getAspectExcludePatterns() { | |||||
return m_aspectExcludePatterns; | |||||
} | |||||
public List getConcreteAspects() { | |||||
return m_concreteAspects; | |||||
} | |||||
public static class ConcreteAspect { | |||||
String name; | |||||
String extend; | |||||
List pointcuts; | |||||
public ConcreteAspect(String name, String extend) { | |||||
this.name = name; | |||||
this.extend = extend; | |||||
this.pointcuts = new ArrayList(); | |||||
} | |||||
} | |||||
public static class Pointcut { | |||||
String name; | |||||
String expression; | |||||
public Pointcut(String name, String expression) { | |||||
this.name = name; | |||||
this.expression = expression; | |||||
} | |||||
} | |||||
public static boolean isAspectExcluded(String aspectClassName, List definitions) { | |||||
//TODO | |||||
return false; | |||||
} | |||||
public void appendWeaverOptions(String option) { | |||||
m_weaverOptions.append(option.trim()).append(' '); | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime.definition; | |||||
import org.xml.sax.ContentHandler; | |||||
import org.xml.sax.SAXException; | |||||
import org.xml.sax.InputSource; | |||||
import org.xml.sax.Attributes; | |||||
import org.xml.sax.SAXParseException; | |||||
import org.xml.sax.XMLReader; | |||||
import org.xml.sax.SAXNotRecognizedException; | |||||
import org.xml.sax.helpers.DefaultHandler; | |||||
import org.xml.sax.helpers.XMLReaderFactory; | |||||
import org.aspectj.weaver.loadtime.definition.Definition; | |||||
import java.util.Iterator; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import java.net.URL; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.io.File; | |||||
/** | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class DocumentParser extends DefaultHandler { | |||||
/** | |||||
* The current DTD public id. The matching dtd will be searched as a resource. | |||||
*/ | |||||
private final static String DTD_PUBLIC_ID = "-//AspectJ//DTD 1.5.0//EN"; | |||||
/** | |||||
* The DTD alias, for better user experience. | |||||
*/ | |||||
private final static String DTD_PUBLIC_ID_ALIAS = "-//AspectJ//DTD//EN"; | |||||
/** | |||||
* A handler to the DTD stream so that we are only using one file descriptor | |||||
*/ | |||||
private final static InputStream DTD_STREAM = DocumentParser.class.getResourceAsStream("/aspectj_1_5_0.dtd"); | |||||
private final static String ASPECTJ_ELEMENT = "aspectj"; | |||||
private final static String WEAVER_ELEMENT = "weaver"; | |||||
private final static String OPTIONS_ATTRIBUTE = "options"; | |||||
private final static String ASPECTS_ELEMENT = "aspects"; | |||||
private final static String ASPECT_ELEMENT = "aspect"; | |||||
private final static String CONCRETE_ASPECT_ELEMENT = "concrete-aspect"; | |||||
private final static String NAME_ATTRIBUTE = "name"; | |||||
private final static String EXTEND_ATTRIBUTE = "extends"; | |||||
private final static String POINTCUT_ELEMENT = "pointcut"; | |||||
private final static String EXPRESSION_ATTRIBUTE = "expression"; | |||||
private final Definition m_definition; | |||||
private boolean m_inAspectJ; | |||||
private Definition.ConcreteAspect m_lastConcreteAspect; | |||||
private DocumentParser() { | |||||
m_definition = new Definition(); | |||||
} | |||||
public static Definition parse(final URL url) throws Exception { | |||||
InputStream in = null; | |||||
try { | |||||
DocumentParser parser = new DocumentParser(); | |||||
XMLReader xmlReader = XMLReaderFactory.createXMLReader(); | |||||
xmlReader.setEntityResolver(parser); | |||||
xmlReader.setContentHandler(parser); | |||||
//TODO use a locator for error location reporting ? | |||||
try { | |||||
if (xmlReader.getFeature("http://xml.org/sax/features/validation")) { | |||||
xmlReader.setFeature("http://xml.org/sax/features/validation", false); | |||||
} | |||||
// xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); | |||||
// xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); | |||||
} | |||||
catch (SAXNotRecognizedException e) { | |||||
;//fine, the parser don't do validation | |||||
} | |||||
in = url.openStream(); | |||||
xmlReader.parse(new InputSource(in)); | |||||
return parser.m_definition; | |||||
} finally { | |||||
try {in.close();} catch (Throwable t) {;} | |||||
} | |||||
} | |||||
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException { | |||||
if (publicId.equals(DTD_PUBLIC_ID) || publicId.equals(DTD_PUBLIC_ID_ALIAS)) { | |||||
InputStream in = DTD_STREAM; | |||||
if (in == null) { | |||||
// System.err.println("AspectJ - WARN - could not open DTD"); | |||||
return null; | |||||
} else { | |||||
return new InputSource(in); | |||||
} | |||||
} else { | |||||
// System.err.println( | |||||
// "AspectJ - WARN - deprecated DTD " | |||||
// + publicId | |||||
// + " - consider upgrading to " | |||||
// + DTD_PUBLIC_ID | |||||
// ); | |||||
return null;//new InputSource(); | |||||
} | |||||
} | |||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { | |||||
if (ASPECT_ELEMENT.equals(qName)) { | |||||
String name = attributes.getValue(NAME_ATTRIBUTE); | |||||
if (!isNull(name)) { | |||||
m_definition.getAspectClassNames().add(name); | |||||
} | |||||
} else if (WEAVER_ELEMENT.equals(qName)) { | |||||
String options = attributes.getValue(OPTIONS_ATTRIBUTE); | |||||
if (!isNull(options)) { | |||||
m_definition.appendWeaverOptions(options); | |||||
} | |||||
} else if (CONCRETE_ASPECT_ELEMENT.equals(qName)) { | |||||
String name = attributes.getValue(NAME_ATTRIBUTE); | |||||
String extend = attributes.getValue(EXTEND_ATTRIBUTE); | |||||
if (!isNull(name) && !isNull(extend)) { | |||||
m_lastConcreteAspect = new Definition.ConcreteAspect(name, extend); | |||||
m_definition.getConcreteAspects().add(m_lastConcreteAspect); | |||||
} | |||||
} else if (POINTCUT_ELEMENT.equals(qName) && m_lastConcreteAspect != null) { | |||||
String name = attributes.getValue(NAME_ATTRIBUTE); | |||||
String expression = attributes.getValue(EXPRESSION_ATTRIBUTE); | |||||
if (!isNull(name) && !isNull(expression)) { | |||||
m_lastConcreteAspect.pointcuts.add(new Definition.Pointcut(name, replaceXmlAnd(expression))); | |||||
} | |||||
} else if (ASPECTJ_ELEMENT.equals(qName)) { | |||||
if (m_inAspectJ) { | |||||
throw new SAXException("Found nested <aspectj> element"); | |||||
} | |||||
m_inAspectJ = true; | |||||
} else if (ASPECTS_ELEMENT.equals(qName)) { | |||||
;//nothing to do | |||||
} else { | |||||
throw new SAXException("Unknown element while parsing <aspectj> element: " + qName); | |||||
} | |||||
//TODO include / exclude | |||||
super.startElement(uri, localName, qName, attributes); | |||||
} | |||||
public void endElement(String uri, String localName, String qName) throws SAXException { | |||||
if (CONCRETE_ASPECT_ELEMENT.equals(qName)) { | |||||
m_lastConcreteAspect = null; | |||||
} else if (ASPECTJ_ELEMENT.equals(qName)) { | |||||
m_inAspectJ = false; | |||||
} | |||||
super.endElement(uri, localName, qName); | |||||
} | |||||
public void warning(SAXParseException e) throws SAXException { | |||||
super.warning(e); | |||||
} | |||||
public void error(SAXParseException e) throws SAXException { | |||||
super.error(e); | |||||
} | |||||
public void fatalError(SAXParseException e) throws SAXException { | |||||
super.fatalError(e); | |||||
} | |||||
private static String replaceXmlAnd(String expression) { | |||||
//TODO av do we need to handle "..)AND" or "AND(.." ? | |||||
//FIXME av Java 1.4 code - if KO, use some Strings util | |||||
return expression.replaceAll(" AND ", " && "); | |||||
} | |||||
public static void main(String args[]) throws Throwable { | |||||
Definition def = parse(new File(args[0]).toURL()); | |||||
System.out.println(def); | |||||
} | |||||
private boolean isNull(String s) { | |||||
return (s == null || s.length() <= 0); | |||||
} | |||||
} |
<?xml version="1.0"?> | |||||
<project name="loadtime5" default="all" basedir="."> | |||||
<import file="../build-common.xml"/> | |||||
<import file="../asm/build.xml"/> | |||||
<import file="../bridge/build.xml"/> | |||||
<import file="../loadtime/build.xml"/> | |||||
<import file="../weaver/build.xml"/> | |||||
<import file="../util/build.xml"/> | |||||
<import file="../runtime/build.xml/"/> | |||||
<import file="../aspectj5rt/build.xml"/> | |||||
<path id="loadtime5.test.src.path"> | |||||
<fileset dir="${basedir}/../lib"> | |||||
<include name="junit/*.jar"/> | |||||
</fileset> | |||||
<path refid="loadtime5.src.path"/> | |||||
<pathelement path="../runtime/bin"/> | |||||
<pathelement path="../aspectj5rt/bin"/> | |||||
<pathelement path="../util/bin"/> | |||||
</path> | |||||
<path id="loadtime5.src.path"> | |||||
<pathelement path="../asm/bin"/> | |||||
<pathelement path="../bridge/bin"/> | |||||
<pathelement path="../loadtime/bin"/> | |||||
<pathelement path="../weaver/bin"/> | |||||
<fileset dir="${basedir}/../lib"> | |||||
<include name="bcel/*.jar"/> | |||||
</fileset> | |||||
</path> | |||||
<target name="compile" depends="init, | |||||
asm.compile, | |||||
bridge.compile, | |||||
loadtime.compile, | |||||
weaver.compile" if="jdk15"> | |||||
<!-- FIXME: we override compile due to use of 1.5 --> | |||||
<mkdir dir="${basedir}/bin"/> | |||||
<javac debug="on" destdir="${basedir}/bin" source="1.5" target="1.5"> | |||||
<src path="${basedir}/src"/> | |||||
<classpath refid="loadtime5.src.path"/> | |||||
</javac> | |||||
</target> | |||||
<target name="test:compile" depends="compile" if="jdk15"> | |||||
<!-- FIXME sucky deps --> | |||||
<antcall target="runtime.compile"/> | |||||
<antcall target="aspectj5rt.compile"/> | |||||
<!-- FIXME: we override compile due to use of 1.5 --> | |||||
<mkdir dir="${basedir}/bintest"/> | |||||
<javac debug="on" destdir="${basedir}/bintest" source="1.5" target="1.5"> | |||||
<src path="${basedir}/testsrc"/> | |||||
<classpath refid="loadtime5.test.src.path"/> | |||||
</javac> | |||||
</target> | |||||
<target name="test" depends="test:compile, jar" if="jdk15"> | |||||
<!-- FIXME sucky deps --> | |||||
<antcall target="util.compile"/> | |||||
<java fork="true" classname="org.aspectj.weaver.loadtime5.test.AllTests"> | |||||
<jvmarg line="-javaagent:${build.ajdir}/jars/loadtime5.jar -Daj5.def=../loadtime5/testsrc/aop.xml"/> | |||||
<classpath refid="loadtime5.test.src.path"/> | |||||
<classpath> | |||||
<pathelement path="${basedir}/bintest"/> | |||||
</classpath> | |||||
</java> | |||||
</target> | |||||
<target name="jar" depends="compile"> | |||||
<delete file="${build.ajdir}/jars/loadtime5.jar"/> | |||||
<copy file="loadtime5.mf.txt" todir="${build.ajdir}/temp" filtering="yes"/> | |||||
<jar destfile="${build.ajdir}/jars/loadtime5.jar" manifest="${build.ajdir}/temp/loadtime5.mf.txt"> | |||||
<fileset dir="bin"> | |||||
<include name="**/*"/> | |||||
</fileset> | |||||
</jar> | |||||
</target> | |||||
</project> | |||||
Premain-Class: org.aspectj.weaver.loadtime.Agent | |||||
Can-Redefine-Classes: true |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime; | |||||
import java.lang.instrument.Instrumentation; | |||||
import java.lang.instrument.ClassFileTransformer; | |||||
/** | |||||
* Java 1.5 preMain agent to hook in the class pre processor | |||||
* Can be used with -javaagent:aspectjweaver.jar | |||||
* | |||||
* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class Agent { | |||||
/** | |||||
* The instrumentation instance | |||||
*/ | |||||
private static Instrumentation s_instrumentation; | |||||
/** | |||||
* The ClassFileTransformer wrapping the weaver | |||||
*/ | |||||
private static ClassFileTransformer s_transformer = new ClassPreProcessorAgentAdapter(); | |||||
/** | |||||
* JSR-163 preMain Agent entry method | |||||
* | |||||
* @param options | |||||
* @param instrumentation | |||||
*/ | |||||
public static void premain(String options, Instrumentation instrumentation) { | |||||
s_instrumentation = instrumentation; | |||||
s_instrumentation.addTransformer(s_transformer); | |||||
} | |||||
/** | |||||
* Returns the Instrumentation system level instance | |||||
*/ | |||||
public static Instrumentation getInstrumentation() { | |||||
if (s_instrumentation == null) { | |||||
throw new UnsupportedOperationException("Java 5 was not started with preMain -javaagent for AspectJ"); | |||||
} | |||||
return s_instrumentation; | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime; | |||||
import org.aspectj.weaver.loadtime.Aj; | |||||
import org.aspectj.weaver.loadtime.ClassPreProcessor; | |||||
import java.lang.instrument.ClassFileTransformer; | |||||
import java.lang.instrument.IllegalClassFormatException; | |||||
import java.security.ProtectionDomain; | |||||
/** | |||||
* Java 1.5 adapter for class pre processor | |||||
* | |||||
* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class ClassPreProcessorAgentAdapter implements ClassFileTransformer { | |||||
/** | |||||
* Concrete preprocessor. | |||||
*/ | |||||
private static ClassPreProcessor s_preProcessor; | |||||
static { | |||||
try { | |||||
s_preProcessor = new Aj(); | |||||
s_preProcessor.initialize(); | |||||
} catch (Exception e) { | |||||
throw new ExceptionInInitializerError("could not initialize JSR163 preprocessor due to: " + e.toString()); | |||||
} | |||||
} | |||||
/** | |||||
* Weaving delegation | |||||
* | |||||
* @param loader the defining class loader | |||||
* @param className the name of class beeing loaded | |||||
* @param classBeingRedefined when hotswap is called | |||||
* @param protectionDomain | |||||
* @param bytes the bytecode before weaving | |||||
* @return the weaved bytecode | |||||
*/ | |||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, | |||||
ProtectionDomain protectionDomain, byte[] bytes) throws IllegalClassFormatException { | |||||
if (classBeingRedefined == null) { | |||||
return s_preProcessor.preProcess(className, bytes, loader); | |||||
} else { | |||||
//FIXME av for now we skip hotswap. We should think more about that | |||||
new Exception("AspectJ5 does not weave hotswapped class (" + className + ")").printStackTrace(); | |||||
return bytes; | |||||
} | |||||
} | |||||
} |
<!-- FIXME fails when DTD here and call from Ant--> | |||||
<!--<!DOCTYPE aspectj PUBLIC--> | |||||
<!-- "-//AspectJ//DTD//EN"--> | |||||
<!-- "http://www.aspectj.org/dtd/aspectj_1_5_0.dtd">--> | |||||
<aspectj> | |||||
<weaver options="-showWeaveInfo"/> | |||||
<aspects> | |||||
<!-- see here nested class with ".", "$" is accepted as well --> | |||||
<aspect name="test.loadtime5.AtAspectJTest.TestAspect"/> | |||||
</aspects> | |||||
</aspectj> |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package org.aspectj.weaver.loadtime5.test; | |||||
import junit.framework.Test; | |||||
import junit.framework.TestCase; | |||||
import junit.framework.TestSuite; | |||||
import test.loadtime5.AtAspectJTest; | |||||
/** | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class AllTests extends TestCase { | |||||
public static Test suite() { | |||||
TestSuite suite = new TestSuite("All tests"); | |||||
suite.addTestSuite(AtAspectJTest.class); | |||||
// suite.addTestSuite(SingletonAspectBindingsTest.class); | |||||
// suite.addTestSuite(CflowTest.class); | |||||
// suite.addTestSuite(PointcutReferenceTest.class); | |||||
// suite.addTestSuite(AfterXTest.class); | |||||
// | |||||
// //FIXME AV - fix the pc grammar to support if for @AJ aspects | |||||
// System.err.println("(AllTests: IfPointcutTest fails)"); | |||||
// //suite.addTestSuite(IfPointcutTest.class); | |||||
// | |||||
// suite.addTestSuite(XXJoinPointTest.class); | |||||
// suite.addTestSuite(PrecedenceTest.class); | |||||
// suite.addTestSuite(BindingTest.class); | |||||
// | |||||
// suite.addTestSuite(PerClauseTest.class); | |||||
return suite; | |||||
} | |||||
public static void main(String[] args) { | |||||
junit.textui.TestRunner.run(suite()); | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) Jonas Bonér, Alexandre Vasseur | |||||
* 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 | |||||
*******************************************************************************/ | |||||
package test.loadtime5; | |||||
import org.aspectj.lang.annotation.Before; | |||||
import org.aspectj.lang.annotation.Aspect; | |||||
import org.aspectj.lang.annotation.After; | |||||
import org.aspectj.lang.annotation.Around; | |||||
import org.aspectj.lang.JoinPoint; | |||||
import org.aspectj.lang.ProceedingJoinPoint; | |||||
import junit.framework.TestCase; | |||||
import junit.textui.TestRunner; | |||||
/** | |||||
* Test various advice and JoinPoint + binding, without pc ref | |||||
* | |||||
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> | |||||
*/ | |||||
public class AtAspectJTest extends TestCase { | |||||
static StringBuffer s_log = new StringBuffer(); | |||||
static void log(String s) { | |||||
s_log.append(s).append(" "); | |||||
} | |||||
public static void main(String[] args) { | |||||
TestRunner.run(AtAspectJTest.class); | |||||
} | |||||
public static junit.framework.Test suite() { | |||||
return new junit.framework.TestSuite(AtAspectJTest.class); | |||||
} | |||||
public void hello() { | |||||
log("hello"); | |||||
} | |||||
public void hello(String s) { | |||||
log("hello-"); | |||||
log(s); | |||||
} | |||||
public void testExecutionWithThisBinding() { | |||||
s_log = new StringBuffer(); | |||||
AtAspectJTest me = new AtAspectJTest(); | |||||
me.hello(); | |||||
// see here advice precedence as in source code order | |||||
//TODO check around relative order | |||||
// see fix in BcelWeaver sorting shadowMungerList | |||||
//assertEquals("around2_ around_ before hello after _around _around2 ", s_log.toString()); | |||||
assertEquals("around_ around2_ before hello _around2 _around after ", s_log.toString()); | |||||
} | |||||
public void testExecutionWithArgBinding() { | |||||
s_log = new StringBuffer(); | |||||
AtAspectJTest me = new AtAspectJTest(); | |||||
me.hello("x"); | |||||
assertEquals("before- x hello- x ", s_log.toString()); | |||||
} | |||||
@Aspect | |||||
public static class TestAspect { | |||||
static int s = 0; | |||||
static { | |||||
s++; | |||||
} | |||||
public TestAspect() { | |||||
// assert clinit has run when singleton aspectOf reaches that | |||||
assertTrue(s>0); | |||||
} | |||||
//public static TestAspect aspectOf() {return null;} | |||||
@Around("execution(* test.loadtime5.AtAspectJTest.hello())") | |||||
public void aaround(ProceedingJoinPoint jp) { | |||||
log("around_"); | |||||
try { | |||||
jp.proceed(); | |||||
} catch (Throwable throwable) { | |||||
throwable.printStackTrace(); | |||||
} | |||||
log("_around"); | |||||
} | |||||
@Around("execution(* test.loadtime5.AtAspectJTest.hello()) && this(t)") | |||||
public void around2(ProceedingJoinPoint jp, Object t) { | |||||
log("around2_"); | |||||
assertEquals(AtAspectJTest.class.getName(), t.getClass().getName()); | |||||
try { | |||||
jp.proceed(); | |||||
} catch (Throwable throwable) { | |||||
throwable.printStackTrace(); | |||||
} | |||||
log("_around2"); | |||||
} | |||||
@Before("execution(* test.loadtime5.AtAspectJTest.hello())") | |||||
public void before(JoinPoint.StaticPart sjp) { | |||||
log("before"); | |||||
assertEquals("hello", sjp.getSignature().getName()); | |||||
} | |||||
@After("execution(* test.loadtime5.AtAspectJTest.hello())") | |||||
public void after(JoinPoint.StaticPart sjp) { | |||||
log("after"); | |||||
assertEquals("execution(public void test.loadtime5.AtAspectJTest.hello())", sjp.toLongString()); | |||||
} | |||||
//TODO see String alias, see before advice name clash - all that works | |||||
// 1/ String is in java.lang.* - see SimpleScope.javalangPrefix array | |||||
// 2/ the advice is register thru its Bcel Method mirror | |||||
@Before("execution(* test.loadtime5.AtAspectJTest.hello(String)) && args(s)") | |||||
public void before(String s, JoinPoint.StaticPart sjp) { | |||||
log("before-"); | |||||
log(s); | |||||
assertEquals("hello", sjp.getSignature().getName()); | |||||
} | |||||
} | |||||
} |
public boolean isIgnoring(Kind kind) { | public boolean isIgnoring(Kind kind) { | ||||
return sink.isIgnoring(kind); | return sink.isIgnoring(kind); | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
private int getStartPos(ISourceLocation sLoc,CompilationResult result) { | private int getStartPos(ISourceLocation sLoc,CompilationResult result) { | ||||
int pos = 0; | int pos = 0; | ||||
if (sLoc == null) return 0; | if (sLoc == null) return 0; |
public void setLintMode(String lintMode) { | public void setLintMode(String lintMode) { | ||||
this.lintMode = lintMode; | this.lintMode = lintMode; | ||||
String lintValue = null; | |||||
if (AJLINT_IGNORE.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.IGNORE; | |||||
} else if (AJLINT_WARN.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.WARNING; | |||||
} else if (AJLINT_ERROR.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.ERROR; | |||||
} | |||||
if (lintValue != null) { | |||||
Map lintOptions = new HashMap(); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion,lintValue); | |||||
options.set(lintOptions); | |||||
} | |||||
options.setLintMode(lintMode); | |||||
} | } | ||||
public boolean isNoWeave() { | public boolean isNoWeave() { |
package org.aspectj.ajdt.internal.core.builder; | package org.aspectj.ajdt.internal.core.builder; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.HashMap; | |||||
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; | import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions; | ||||
return map; | return map; | ||||
} | } | ||||
public void setLintMode(String lintMode) { | |||||
String lintValue = null; | |||||
if (AjBuildConfig.AJLINT_IGNORE.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.IGNORE; | |||||
} else if (AjBuildConfig.AJLINT_WARN.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.WARNING; | |||||
} else if (AjBuildConfig.AJLINT_ERROR.equals(lintMode)) { | |||||
lintValue = AjCompilerOptions.ERROR; | |||||
} | |||||
if (lintValue != null) { | |||||
Map lintOptions = new HashMap(); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidAbsoluteTypeName,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportInvalidWildcardTypeName,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportUnresolvableMember,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportTypeNotExposedToWeaver,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportShadowNotInStructure,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportUnmatchedSuperTypeInCall,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportCannotImplementLazyTJP,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportNeedSerialVersionUIDField,lintValue); | |||||
lintOptions.put(AjCompilerOptions.OPTION_ReportIncompatibleSerialVersion,lintValue); | |||||
set(lintOptions); | |||||
} | |||||
} | |||||
/* (non-Javadoc) | /* (non-Javadoc) | ||||
* @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions#set(java.util.Map) | * @see org.eclipse.jdt.internal.compiler.impl.CompilerOptions#set(java.util.Map) | ||||
*/ | */ |
if (kind == IMessage.DEBUG || kind == IMessage.INFO) return true; | if (kind == IMessage.DEBUG || kind == IMessage.INFO) return true; | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
/** | /** | ||||
* Render message differently. | * Render message differently. | ||||
* If abort, then prefix stack trace with feedback request. | * If abort, then prefix stack trace with feedback request. |
public boolean isIgnoring(IMessage.Kind kind) { | public boolean isIgnoring(IMessage.Kind kind) { | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
public boolean handleMessage(IMessage message) { | public boolean handleMessage(IMessage message) { | ||||
(message.isFailed() ? failures : passes).add(message); | (message.isFailed() ? failures : passes).add(message); | ||||
return true; | return true; |
<import file="../build-common.xml"/> | <import file="../build-common.xml"/> | ||||
<import file="../bridge/build.xml"/> | <import file="../bridge/build.xml"/> | ||||
<import file="../util/build.xml"/> | <import file="../util/build.xml"/> | ||||
<import file="../runtime/build.xml"/> | |||||
<path id="testing-util.test.src.path"> | <path id="testing-util.test.src.path"> | ||||
<fileset dir="${basedir}/../lib"> | <fileset dir="${basedir}/../lib"> | ||||
<include name="junit/*.jar"/> | <include name="junit/*.jar"/> | ||||
<include name="bcel/*.jar"/> | |||||
</fileset> | </fileset> | ||||
<!-- depends on weaver to use Dissasemble feature on LazyClassGen to test comparison of .class file --> | |||||
<pathelement path="../weaver/bin"/> | |||||
<pathelement path="../runtime/bin"/> | |||||
<path refid="testing-util.src.path"/> | <path refid="testing-util.src.path"/> | ||||
</path> | </path> | ||||
<testcompile project="testing-util" path="testing-util.test.src.path"/> | <testcompile project="testing-util" path="testing-util.test.src.path"/> | ||||
</target> | </target> | ||||
<!-- FIXME: seems to depend on weaver, seems to emit warnings --> | |||||
<target name="test" depends="test:compile"> | |||||
<target name="test" depends="test:compile, | |||||
runtime.compile"> | |||||
<!-- depends on weaver to access .class dissassemble utility hence circular --> | |||||
<subant antfile="build.xml" target="test:compile" buildpath="../weaver" /> | |||||
<testrun project="testing-util" path="testing-util.test.src.path" suite="TestingUtilModuleTests"/> | <testrun project="testing-util" path="testing-util.test.src.path" suite="TestingUtilModuleTests"/> | ||||
</target> | </target> | ||||
AV - should be added to CVS since I have renamed old files |
public void testFileCompareNonClass() throws IOException { | public void testFileCompareNonClass() throws IOException { | ||||
MessageHandler holder = new MessageHandler(); | MessageHandler holder = new MessageHandler(); | ||||
File thisFile = new File(UtilTests.TESTING_UTIL_PATH + "/testsrc/org/aspectj/testing/util/TestUtilTest.java"); | |||||
File thisFile = new File(UtilTests.TESTING_UTIL_PATH + "/testsrc/org/aspectj/testingutil/TestUtilTest.java"); | |||||
//File thisFile = new File("src/testing-util.lst"); | //File thisFile = new File("src/testing-util.lst"); | ||||
assertTrue(TestUtil.sameFiles(holder, thisFile, thisFile)); | assertTrue(TestUtil.sameFiles(holder, thisFile, thisFile)); | ||||
} | } | ||||
MessageHandler holder = new MessageHandler(); | MessageHandler holder = new MessageHandler(); | ||||
File classBase = new File(UtilTests.TESTING_UTIL_PATH + "/testdata/testCompareClassFiles"); | File classBase = new File(UtilTests.TESTING_UTIL_PATH + "/testdata/testCompareClassFiles"); | ||||
String path = "org/aspectj/testing/util/TestCompareClassFile.class"; | |||||
String path = "org/aspectj/testingutil/TestCompareClassFile.class"; | |||||
File classFile = new File(classBase, path); | File classFile = new File(classBase, path); | ||||
try { | try { |
public boolean isIgnoring(IMessage.Kind kind) { | public boolean isIgnoring(IMessage.Kind kind) { | ||||
return messageHolder.isIgnoring(kind); | return messageHolder.isIgnoring(kind); | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
/** | /** | ||||
* @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) | * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean) | ||||
*/ | */ |
public boolean isIgnoring(IMessage.Kind kind) { | public boolean isIgnoring(IMessage.Kind kind) { | ||||
return false; | return false; | ||||
} | } | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
}); | }); | ||||
String[] parms = (String[]) args.toArray(new String[0]); | String[] parms = (String[]) args.toArray(new String[0]); | ||||
boolean result = command.runCommand(parms, handler); | boolean result = command.runCommand(parms, handler); |
<testrun project="tests" path="tests.test.src.path" suite="org.aspectj.systemtest.AllTests"/> | <testrun project="tests" path="tests.test.src.path" suite="org.aspectj.systemtest.AllTests"/> | ||||
</target> | </target> | ||||
<!-- run a single test with "ant -Dtest=org.aspectj.systemtest.AllTests15 atest" --> | |||||
<target name="atest" depends="test:compile, | <target name="atest" depends="test:compile, | ||||
runtime.compile, | runtime.compile, | ||||
weaver.compile"> | weaver.compile"> |
return (i>=0); | return (i>=0); | ||||
} | } | ||||
@Pointcut("args(i) && if(i>0)") | |||||
//FIXME av if pcd support | |||||
//@Pointcut("args(i) && if(i>0)") | |||||
void ifPc(int i) {} | void ifPc(int i) {} | ||||
@Before("execution(* ataspectj.IfPointcutTest.hello(int)) && ifPc(i)") | |||||
//FIXME av if pcd support | |||||
//@Before("execution(* ataspectj.IfPointcutTest.hello(int)) && ifPc(i)") | |||||
void before(int i) { | void before(int i) { | ||||
System.out.println("IfPointcutTest$TestAspect.before"); | System.out.println("IfPointcutTest$TestAspect.before"); | ||||
} | } |
public void testPrecedence() { | public void testPrecedence() { | ||||
s_log = new StringBuffer(); | s_log = new StringBuffer(); | ||||
hello(); | hello(); | ||||
assertEquals("TestAspect_3 TestAspect_2 TestAspect_1 hello", s_log.toString()); | |||||
assertEquals("TestAspect_3 TestAspect_2 TestAspect_1 hello ", s_log.toString()); | |||||
} | } | ||||
TestSuite suite = new TestSuite("AspectJ System Test Suite - JDK 1.5"); | TestSuite suite = new TestSuite("AspectJ System Test Suite - JDK 1.5"); | ||||
//$JUnit-BEGIN$ | //$JUnit-BEGIN$ | ||||
suite.addTest(AllTests14.suite()); | suite.addTest(AllTests14.suite()); | ||||
suite.addTestSuite(AllTestsAspectJ150_NeedJava15.class); | |||||
suite.addTest(AllTestsAspectJ150_NeedJava15.suite()); | |||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; | ||||
} | } |
import junit.framework.Test; | import junit.framework.Test; | ||||
import junit.framework.TestSuite; | import junit.framework.TestSuite; | ||||
import junit.framework.TestCase; | |||||
import org.aspectj.systemtest.ajc150.ataspectj.AtAjc150Tests; | import org.aspectj.systemtest.ajc150.ataspectj.AtAjc150Tests; | ||||
/** | /** | ||||
suite.addTestSuite(Annotations.class); | suite.addTestSuite(Annotations.class); | ||||
suite.addTestSuite(AnnotationBinding.class); | suite.addTestSuite(AnnotationBinding.class); | ||||
//ATAJ tests | |||||
//ATAeJ tests | |||||
suite.addTest(AtAjc150Tests.suite()); | suite.addTest(AtAjc150Tests.suite()); | ||||
//$JUnit-END$ | //$JUnit-END$ |
ISourceContext context; | ISourceContext context; | ||||
IMessageHandler handler; | IMessageHandler handler; | ||||
public AjAttributeStruct(ResolvedTypeX type) { | |||||
public AjAttributeStruct(ResolvedTypeX type, ISourceContext sourceContext) { | |||||
enclosingType = type; | enclosingType = type; | ||||
context = sourceContext; | |||||
} | } | ||||
} | } | ||||
Method method; | Method method; | ||||
public AjAttributeMethodStruct(Method method, ResolvedTypeX type) { | |||||
super(type); | |||||
public AjAttributeMethodStruct(Method method, ResolvedTypeX type, ISourceContext sourceContext) { | |||||
super(type, sourceContext); | |||||
this.method = method; | this.method = method; | ||||
} | } | ||||
* @return list of AjAttributes | * @return list of AjAttributes | ||||
*/ | */ | ||||
public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { | public static List readAj5ClassAttributes(JavaClass javaClass, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { | ||||
AjAttributeStruct struct = new AjAttributeStruct(type); | |||||
AjAttributeStruct struct = new AjAttributeStruct(type, context); | |||||
Attribute[] attributes = javaClass.getAttributes(); | Attribute[] attributes = javaClass.getAttributes(); | ||||
for (int i = 0; i < attributes.length; i++) { | for (int i = 0; i < attributes.length; i++) { | ||||
Attribute attribute = attributes[i]; | Attribute attribute = attributes[i]; | ||||
//TODO can that be too slow ? | //TODO can that be too slow ? | ||||
for (int m = 0; m < javaClass.getMethods().length; m++) { | for (int m = 0; m < javaClass.getMethods().length; m++) { | ||||
Method method = javaClass.getMethods()[m]; | Method method = javaClass.getMethods()[m]; | ||||
AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type); | |||||
//TODO optimize, this method struct will gets recreated for advice extraction | |||||
AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, type, context); | |||||
Attribute[] mattributes = method.getAttributes(); | Attribute[] mattributes = method.getAttributes(); | ||||
for (int i = 0; i < mattributes.length; i++) { | for (int i = 0; i < mattributes.length; i++) { | ||||
* @return list of AjAttributes | * @return list of AjAttributes | ||||
*/ | */ | ||||
public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { | public static List readAj5MethodAttributes(Method method, ResolvedTypeX type, ISourceContext context,IMessageHandler msgHandler) { | ||||
AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type); | |||||
AjAttributeMethodStruct struct = new AjAttributeMethodStruct(method, type, context); | |||||
Attribute[] attributes = method.getAttributes(); | Attribute[] attributes = method.getAttributes(); | ||||
for (int i = 0; i < attributes.length; i++) { | for (int i = 0; i < attributes.length; i++) { |
final class BcelMethod extends ResolvedMember { | final class BcelMethod extends ResolvedMember { | ||||
private Method method; | |||||
Method method; | |||||
public int foo() { | |||||
return method.getLineNumberTable().getLineNumberTable()[0].getLineNumber();//getSourceLine(0); | |||||
} | |||||
private boolean isAjSynthetic; | private boolean isAjSynthetic; | ||||
private ShadowMunger associatedShadowMunger; | private ShadowMunger associatedShadowMunger; | ||||
private AjAttribute.EffectiveSignatureAttribute effectiveSignature; | private AjAttribute.EffectiveSignatureAttribute effectiveSignature; |
import org.aspectj.weaver.WeaverMetrics; | import org.aspectj.weaver.WeaverMetrics; | ||||
import org.aspectj.weaver.WeaverStateInfo; | import org.aspectj.weaver.WeaverStateInfo; | ||||
import org.aspectj.weaver.AjcMemberMaker; | import org.aspectj.weaver.AjcMemberMaker; | ||||
import org.aspectj.weaver.World; | |||||
import org.aspectj.weaver.patterns.AndPointcut; | import org.aspectj.weaver.patterns.AndPointcut; | ||||
import org.aspectj.weaver.patterns.BindingAnnotationTypePattern; | import org.aspectj.weaver.patterns.BindingAnnotationTypePattern; | ||||
import org.aspectj.weaver.patterns.BindingTypePattern; | import org.aspectj.weaver.patterns.BindingTypePattern; | ||||
public boolean isReweavable() { | public boolean isReweavable() { | ||||
return inReweavableMode; | return inReweavableMode; | ||||
} | } | ||||
public World getWorld() { | |||||
return world; | |||||
} | |||||
} | } |
return false; | return false; | ||||
} | } | ||||
public boolean isIgnoring(Kind kind) {return false;} | public boolean isIgnoring(Kind kind) {return false;} | ||||
public void dontIgnore(IMessage.Kind kind) { | |||||
; | |||||
} | |||||
} | } | ||||
public void testReferenceToNonAnnotationType() { | public void testReferenceToNonAnnotationType() { |