diff options
-rw-r--r-- | build-common.xml | 24 | ||||
-rw-r--r-- | loadtime/build.xml | 10 | ||||
-rw-r--r-- | loadtime/src/aspectj_1_5_0.dtd | 1 | ||||
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/Aj.java | 156 | ||||
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java | 265 | ||||
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java | 10 | ||||
-rw-r--r-- | loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java | 96 | ||||
-rw-r--r-- | loadtime/testsrc/LoadtimeModuleTests.java | 32 | ||||
-rw-r--r-- | loadtime/testsrc/org/aspectj/weaver/loadtime/test/DocumentParserTest.java | 39 | ||||
-rw-r--r-- | loadtime/testsrc/org/aspectj/weaver/loadtime/test/simple.xml | 7 | ||||
-rw-r--r-- | loadtime/testsrc/org/aspectj/weaver/loadtime/test/simpleWithDtd.xml | 11 | ||||
-rw-r--r-- | loadtime5/testsrc/aop.xml | 4 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java | 3 | ||||
-rw-r--r-- | weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java | 9 |
14 files changed, 455 insertions, 212 deletions
diff --git a/build-common.xml b/build-common.xml index 90d81d159..870ef9fff 100644 --- a/build-common.xml +++ b/build-common.xml @@ -99,23 +99,23 @@ <attribute name="suite"/> <sequential> <!-- showoutput="on" --> - <junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on" dir="../@{project}"> - <classpath> - <pathelement path="../@{project}/${build.dir}"/> - <pathelement path="../@{project}/${test.build.dir}"/> - <path refid="@{path}"/> - </classpath> - <test name="@{suite}"/> - </junit> - <!-- TODO AV - using java to invoke JUnit since the junit task is hidding errors - don't know why --> -<!-- <java classname="@{suite}" fork="on" dir="../@{project}">--> -<!-- <jvmarg line=""/>--> +<!-- <junit showoutput="on" fork="on" haltonfailure="on" haltonerror="on" printsummary="on" dir="../@{project}">--> <!-- <classpath>--> <!-- <pathelement path="../@{project}/${build.dir}"/>--> <!-- <pathelement path="../@{project}/${test.build.dir}"/>--> <!-- <path refid="@{path}"/>--> <!-- </classpath>--> -<!-- </java>--> +<!-- <test name="@{suite}"/>--> +<!-- </junit>--> + <!-- TODO AV - using java to invoke JUnit since the junit task is hidding errors - don't know why --> + <java classname="@{suite}" fork="on" dir="../@{project}"> + <jvmarg line=""/> + <classpath> + <pathelement path="../@{project}/${build.dir}"/> + <pathelement path="../@{project}/${test.build.dir}"/> + <path refid="@{path}"/> + </classpath> + </java> </sequential> </macrodef> diff --git a/loadtime/build.xml b/loadtime/build.xml index 0ca5895ee..fb08d53f7 100644 --- a/loadtime/build.xml +++ b/loadtime/build.xml @@ -31,12 +31,22 @@ util.compile, weaver.compile"> <srccompile project="loadtime" path="loadtime.src.path"/> + <!-- copy resources --> + <copy todir="../loadtime/bin"> + <fileset dir="../loadtime/src" includes="**/*.dtd"/> + </copy> </target> <target name="test:compile" depends="compile"> + <testcompile project="loadtime" path="loadtime.src.path"/> + <!-- copy resources --> + <copy todir="../loadtime/bin"> + <fileset dir="../loadtime/testsrc" includes="**/*.xml"/> + </copy> </target> <target name="test" depends="test:compile"> + <testrun project="loadtime" path="loadtime.test.src.path" suite="LoadtimeModuleTests"/> </target> <target name="jar" depends="compile"> diff --git a/loadtime/src/aspectj_1_5_0.dtd b/loadtime/src/aspectj_1_5_0.dtd index 2802dc879..36804485f 100644 --- a/loadtime/src/aspectj_1_5_0.dtd +++ b/loadtime/src/aspectj_1_5_0.dtd @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="UTF-8"?> <!--***************************************************************************************************************************** AspectJ 5 DTD diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java index 20b03d28b..fbbdcc925 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java @@ -13,6 +13,8 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.weaver.ICrossReferenceHandler; import org.aspectj.weaver.World; +import org.aspectj.weaver.patterns.PatternParser; +import org.aspectj.weaver.patterns.TypePattern; import org.aspectj.weaver.bcel.BcelWeaver; import org.aspectj.weaver.bcel.BcelWorld; import org.aspectj.weaver.loadtime.definition.Definition; @@ -95,56 +97,7 @@ public class Aj implements ClassPreProcessor { } } - /** - * 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) { + static void defineClass(ClassLoader loader, String name, byte[] bytes) { try { //TODO av protection domain, and optimize Method defineClass = ClassLoader.class.getDeclaredMethod( @@ -173,7 +126,7 @@ public class Aj implements ClassPreProcessor { * @param b * @throws Throwable */ - private static void __dump(String name, byte[] b) throws Throwable { + static void __dump(String name, byte[] b) throws Throwable { String className = name.replace('.', '/'); final File dir; if (className.indexOf('/') > 0) { @@ -188,105 +141,4 @@ public class Aj implements ClassPreProcessor { 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 - ; - } } diff --git a/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java new file mode 100644 index 000000000..1687bf370 --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/ClassLoaderWeavingAdaptor.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * 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.tools.WeavingAdaptor; +import org.aspectj.weaver.tools.GeneratedClassHandler; +import org.aspectj.weaver.patterns.TypePattern; +import org.aspectj.weaver.patterns.PatternParser; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.bcel.BcelWeaver; +import org.aspectj.weaver.ICrossReferenceHandler; +import org.aspectj.weaver.World; +import org.aspectj.weaver.ResolvedTypeX; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.loadtime.definition.DocumentParser; +import org.aspectj.weaver.loadtime.definition.Definition; +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.Message; +import org.aspectj.bridge.IMessage; +import org.aspectj.asm.IRelationship; + +import java.util.List; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.io.File; +import java.io.IOException; +import java.net.URL; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class ClassLoaderWeavingAdaptor extends WeavingAdaptor { + + //ATAJ LTW include/exclude + private List m_includeTypePattern = new ArrayList(); + private List m_excludeTypePattern = new ArrayList(); + private List m_aspectExcludeTypePattern = new ArrayList(); + public void addIncludeTypePattern(TypePattern typePattern) { + m_includeTypePattern.add(typePattern); + } + public void addExcludeTypePattern(TypePattern typePattern) { + m_excludeTypePattern.add(typePattern); + } + public void addAspectExcludeTypePattern(TypePattern typePattern) { + m_aspectExcludeTypePattern.add(typePattern); + } + + 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 { + Aj.__dump(name, bytes); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + Aj.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(); + } + + /** + * Load and cache the aop.xml/properties according to the classloader visibility rules + * + * @param weaver + * @param loader + */ + private 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); + registerAspectExclude(weaver, loader, definitions); + registerAspects(weaver, loader, definitions); + registerIncludeExclude(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 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 + } + + private void registerAspectExclude(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { + for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { + Definition definition = (Definition) iterator.next(); + for (Iterator iterator1 = definition.getAspectExcludePatterns().iterator(); iterator1.hasNext();) { + String exclude = (String) iterator1.next(); + TypePattern excludePattern = new PatternParser(exclude).parseTypePattern(); + m_aspectExcludeTypePattern.add(excludePattern); + } + } + } + + /** + * Register the aspect, following include / exclude rules + * + * @param weaver + * @param loader + * @param definitions + */ + private 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 (acceptAspect(aspectClassName)) { + 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 void registerIncludeExclude(final BcelWeaver weaver, final ClassLoader loader, final List definitions) { + for (Iterator iterator = definitions.iterator(); iterator.hasNext();) { + Definition definition = (Definition) iterator.next(); + for (Iterator iterator1 = definition.getIncludePatterns().iterator(); iterator1.hasNext();) { + String include = (String) iterator1.next(); + TypePattern includePattern = new PatternParser(include).parseTypePattern(); + m_includeTypePattern.add(includePattern); + } + for (Iterator iterator1 = definition.getExcludePatterns().iterator(); iterator1.hasNext();) { + String exclude = (String) iterator1.next(); + TypePattern excludePattern = new PatternParser(exclude).parseTypePattern(); + m_excludeTypePattern.add(excludePattern); + } + } + } + + protected boolean accept(String className) { + // avoid ResolvedType if not needed + if (m_excludeTypePattern.isEmpty() && m_includeTypePattern.isEmpty()) { + return true; + } + //TODO AV - optimize for className.startWith only + ResolvedTypeX classInfo = weaver.getWorld().getCoreType(TypeX.forName(className)); + //exclude + for (Iterator iterator = m_excludeTypePattern.iterator(); iterator.hasNext();) { + TypePattern typePattern = (TypePattern) iterator.next(); + if (typePattern.matchesStatically(classInfo)) { + // exclude match - skip + return false; + } + } + for (Iterator iterator = m_includeTypePattern.iterator(); iterator.hasNext();) { + TypePattern typePattern = (TypePattern) iterator.next(); + if (! typePattern.matchesStatically(classInfo)) { + // include does not match - skip + return false; + } + } + return true; + } + + private boolean acceptAspect(String aspectClassName) { + // avoid ResolvedType if not needed + if (m_aspectExcludeTypePattern.isEmpty()) { + return true; + } + //TODO AV - optimize for className.startWith only + ResolvedTypeX classInfo = weaver.getWorld().getCoreType(TypeX.forName(aspectClassName)); + //exclude + for (Iterator iterator = m_aspectExcludeTypePattern.iterator(); iterator.hasNext();) { + TypePattern typePattern = (TypePattern) iterator.next(); + if (typePattern.matchesStatically(classInfo)) { + // exclude match - skip + return false; + } + } + return true; + } + +} diff --git a/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java b/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java index b4b6cee47..684d61736 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/definition/Definition.java @@ -7,10 +7,15 @@ *******************************************************************************/ package org.aspectj.weaver.loadtime.definition; +import org.aspectj.weaver.patterns.PatternParser; + import java.util.List; import java.util.ArrayList; +import java.util.Iterator; /** + * A POJO that contains raw strings from the XML (sort of XMLBean for our simple LTW DTD) + * * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public class Definition { @@ -81,11 +86,6 @@ public class Definition { } } - public static boolean isAspectExcluded(String aspectClassName, List definitions) { - //TODO - return false; - } - public void appendWeaverOptions(String option) { m_weaverOptions.append(option.trim()).append(' '); } diff --git a/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java b/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java index 9d83b54b0..0b5664125 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/definition/DocumentParser.java @@ -7,26 +7,26 @@ *******************************************************************************/ 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.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; -import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.DTDHandler; 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; +import java.net.URL; + +import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; /** + * FIXME AV - doc, concrete aspect + * * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ public class DocumentParser extends DefaultHandler { @@ -48,6 +48,8 @@ public class DocumentParser extends DefaultHandler { private final static String ASPECTJ_ELEMENT = "aspectj"; private final static String WEAVER_ELEMENT = "weaver"; + private final static String INCLUDE_ELEMENT = "include"; + private final static String EXCLUDE_ELEMENT = "exclude"; private final static String OPTIONS_ATTRIBUTE = "options"; private final static String ASPECTS_ELEMENT = "aspects"; private final static String ASPECT_ELEMENT = "aspect"; @@ -55,12 +57,15 @@ public class DocumentParser extends DefaultHandler { 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 WITHIN_ATTRIBUTE = "within"; private final static String EXPRESSION_ATTRIBUTE = "expression"; private final Definition m_definition; private boolean m_inAspectJ; + private boolean m_inWeaver; + private boolean m_inAspects; private Definition.ConcreteAspect m_lastConcreteAspect; @@ -74,26 +79,27 @@ public class DocumentParser extends DefaultHandler { DocumentParser parser = new DocumentParser(); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); - xmlReader.setEntityResolver(parser); xmlReader.setContentHandler(parser); - //TODO use a locator for error location reporting ? + xmlReader.setErrorHandler(parser); 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 + 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 } + xmlReader.setEntityResolver(parser); in = url.openStream(); xmlReader.parse(new InputSource(in)); return parser.m_definition; } finally { - try {in.close();} catch (Throwable t) {;} + try { + in.close(); + } catch (Throwable t) { + ; + } } } @@ -101,19 +107,18 @@ public class DocumentParser extends DefaultHandler { 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(); + System.err.println( + "AspectJ - WARN - unknown DTD " + + publicId + + " - consider using " + + DTD_PUBLIC_ID + ); + return null; } } @@ -128,6 +133,7 @@ public class DocumentParser extends DefaultHandler { if (!isNull(options)) { m_definition.appendWeaverOptions(options); } + m_inWeaver = true; } else if (CONCRETE_ASPECT_ELEMENT.equals(qName)) { String name = attributes.getValue(NAME_ATTRIBUTE); String extend = attributes.getValue(EXTEND_ATTRIBUTE); @@ -147,11 +153,25 @@ public class DocumentParser extends DefaultHandler { } m_inAspectJ = true; } else if (ASPECTS_ELEMENT.equals(qName)) { - ;//nothing to do + m_inAspects = true; + } else if (INCLUDE_ELEMENT.equals(qName) && m_inWeaver) { + String typePattern = attributes.getValue(WITHIN_ATTRIBUTE); + if (!isNull(typePattern)) { + m_definition.getIncludePatterns().add(typePattern); + } + } else if (EXCLUDE_ELEMENT.equals(qName) && m_inWeaver) { + String typePattern = attributes.getValue(WITHIN_ATTRIBUTE); + if (!isNull(typePattern)) { + m_definition.getExcludePatterns().add(typePattern); + } + } else if (EXCLUDE_ELEMENT.equals(qName) && m_inAspects) { + String typePattern = attributes.getValue(WITHIN_ATTRIBUTE); + if (!isNull(typePattern)) { + m_definition.getAspectExcludePatterns().add(typePattern); + } } else { throw new SAXException("Unknown element while parsing <aspectj> element: " + qName); } - //TODO include / exclude super.startElement(uri, localName, qName, attributes); } @@ -160,10 +180,15 @@ public class DocumentParser extends DefaultHandler { m_lastConcreteAspect = null; } else if (ASPECTJ_ELEMENT.equals(qName)) { m_inAspectJ = false; + } else if (WEAVER_ELEMENT.equals(qName)) { + m_inWeaver = false; + } else if (ASPECTS_ELEMENT.equals(qName)) { + m_inAspects = false; } super.endElement(uri, localName, qName); } + //TODO AV - define what we want for XML parser error - for now stderr public void warning(SAXParseException e) throws SAXException { super.warning(e); } @@ -177,20 +202,15 @@ public class DocumentParser extends DefaultHandler { } - 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 + //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); } + } diff --git a/loadtime/testsrc/LoadtimeModuleTests.java b/loadtime/testsrc/LoadtimeModuleTests.java new file mode 100644 index 000000000..10c1759a7 --- /dev/null +++ b/loadtime/testsrc/LoadtimeModuleTests.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ + +import junit.framework.TestCase; +import junit.framework.Test; +import junit.framework.TestSuite; +import junit.textui.TestRunner; +import org.aspectj.weaver.loadtime.test.DocumentParserTest; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class LoadtimeModuleTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(LoadtimeModuleTests.class.getName()); + + suite.addTestSuite(DocumentParserTest.class); + + return suite; + } + + public static void main(String args[]) throws Throwable { + TestRunner.run(suite()); + } + +} diff --git a/loadtime/testsrc/org/aspectj/weaver/loadtime/test/DocumentParserTest.java b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/DocumentParserTest.java new file mode 100644 index 000000000..eb6fe1cbd --- /dev/null +++ b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/DocumentParserTest.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.test; + +import junit.framework.TestCase; + +import java.net.URL; + +import org.aspectj.weaver.loadtime.definition.Definition; +import org.aspectj.weaver.loadtime.definition.DocumentParser; + +/** + * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> + */ +public class DocumentParserTest extends TestCase { + + public void testSimple() throws Throwable { + URL url = DocumentParserTest.class.getResource("simple.xml"); + Definition def = DocumentParser.parse(url); + assertEquals("-showWeaveInfo", def.getWeaverOptions().trim()); + } + + public void testSimpleWithDtd() throws Throwable { + URL url = DocumentParserTest.class.getResource("simpleWithDtd.xml"); + Definition def = DocumentParser.parse(url); + assertEquals("-showWeaveInfo", def.getWeaverOptions().trim()); + assertTrue(def.getAspectClassNames().contains("test.Aspect")); + + assertEquals("foo..bar.Goo+", def.getIncludePatterns().get(0)); + assertEquals("@Baz", def.getAspectExcludePatterns().get(0)); + + } + +} diff --git a/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simple.xml b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simple.xml new file mode 100644 index 000000000..54d3dd7af --- /dev/null +++ b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simple.xml @@ -0,0 +1,7 @@ +<aspectj> + <weaver options="-showWeaveInfo"> + </weaver> + <aspects> + <aspect name="test.Aspect"/> + </aspects> +</aspectj> diff --git a/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simpleWithDtd.xml b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simpleWithDtd.xml new file mode 100644 index 000000000..03b77ff3c --- /dev/null +++ b/loadtime/testsrc/org/aspectj/weaver/loadtime/test/simpleWithDtd.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://sswww.aspectj.org/dtd/aspectj_1_5_0.dtd"> +<aspectj> + <weaver options="-showWeaveInfo"> + <include within="foo..bar.Goo+"/> + </weaver> + <aspects> + <exclude within="@Baz"/> + <aspect name="test.Aspect"/> + </aspects> +</aspectj> diff --git a/loadtime5/testsrc/aop.xml b/loadtime5/testsrc/aop.xml index 75266141d..beb77c702 100644 --- a/loadtime5/testsrc/aop.xml +++ b/loadtime5/testsrc/aop.xml @@ -3,7 +3,9 @@ <!-- "-//AspectJ//DTD//EN"--> <!-- "http://www.aspectj.org/dtd/aspectj_1_5_0.dtd">--> <aspectj> - <weaver options="-showWeaveInfo"/> + <weaver options="-showWeaveInfo"> + <include within="test..*"/> + </weaver> <aspects> <!-- see here nested class with ".", "$" is accepted as well --> <aspect name="test.loadtime5.AtAspectJTest.TestAspect"/> diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index d4468ac15..f62f7981a 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -82,6 +82,7 @@ import org.aspectj.weaver.patterns.OrPointcut; import org.aspectj.weaver.patterns.Pointcut; import org.aspectj.weaver.patterns.PointcutRewriter; import org.aspectj.weaver.patterns.WithinPointcut; +import org.aspectj.weaver.patterns.TypePattern; import org.aspectj.weaver.ataspectj.Aj5Attributes; @@ -91,7 +92,7 @@ public class BcelWeaver implements IWeaver { private IProgressListener progressListener = null; private double progressMade; private double progressPerClassFile; - + private boolean inReweavableMode = false; public BcelWeaver(BcelWorld world) { diff --git a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java index 6c3d8af7f..11d023018 100644 --- a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java +++ b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java @@ -184,9 +184,14 @@ public class WeavingAdaptor { private boolean shouldWeave (String name) { name = name.replace('/','.'); boolean b = (enabled && !generatedClasses.containsKey(name) && shouldWeaveName(name) && shouldWeaveAspect(name)); - return b; + return b && accept(name); } - + + //ATAJ + protected boolean accept(String name) { + return true; + } + private boolean shouldWeaveName (String name) { return !((name.startsWith("org.apache.bcel.") || name.startsWith("org.aspectj.") || name.startsWith("java.") || name.startsWith("javax."))); } |