[jboss-cvs] JBossAS SVN: r59532 - in branches/Branch_AOP_1_5/aop: src/main/org/jboss/aop and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Jan 11 11:29:47 EST 2007
Author: flavia.rainone at jboss.com
Date: 2007-01-11 11:29:27 -0500 (Thu, 11 Jan 2007)
New Revision: 59532
Added:
branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/ComparableMixin.java
Modified:
branches/Branch_AOP_1_5/aop/docs/reference/reference/en/modules/annotated.xml
branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/AspectAnnotationLoader.java
branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java
branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/Instrumentor.java
branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/introduction/InterfaceIntroduction.java
branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/AnnotatedTestCase.java
branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/IntroductionAspect.java
Log:
[JBAOP-317] Task done
Modified: branches/Branch_AOP_1_5/aop/docs/reference/reference/en/modules/annotated.xml
===================================================================
--- branches/Branch_AOP_1_5/aop/docs/reference/reference/en/modules/annotated.xml 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/docs/reference/reference/en/modules/annotated.xml 2007-01-11 16:29:27 UTC (rev 59532)
@@ -595,6 +595,7 @@
<itemizedlist>
<listitem>be public</listitem>
<listitem>be static</listitem>
+ <listitem>have an empty parameter list, or receive the target of introduction as parameter</listitem>
<listitem>contain the logic to create the mixin class</listitem>
<listitem>return an instance of the mixin class</listitem>
</itemizedlist>
Modified: branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/AspectAnnotationLoader.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/AspectAnnotationLoader.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/AspectAnnotationLoader.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -21,8 +21,12 @@
*/
package org.jboss.aop;
+import javassist.CtClass;
+import javassist.CtPrimitiveType;
+import javassist.Modifier;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
+import javassist.bytecode.Descriptor;
import javassist.bytecode.FieldInfo;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.annotation.ArrayMemberValue;
@@ -598,11 +602,78 @@
String name = cf.getName() + "." + minfo.getName(); //Name of the method defined on
- InterfaceIntroduction intro = createIntroduction(name, target, typeExpression, null);
+ InterfaceIntroduction intro = null;
+ String construction = name;
+ switch(Descriptor.numOfParameters(minfo.getDescriptor()))
+ {
+ case 0:
+ construction += "()";
+ intro = createIntroduction(name, target, typeExpression, null, null, null);//cf.getName(), minfo.getName());
+ break;
+ case 1:
+ construction += "(this)";
+ intro = createIntroduction(name, target, typeExpression, null, cf.getName(), minfo.getName());
+
+ String parameter = Descriptor.getParamDescriptor(minfo.getDescriptor());
+
+ if (parameter.charAt(1) != 'L')
+ {
+ String errorMessage = "Mixin creator method '" + name +
+ "' parameter is primitive type ";
+ char desc = parameter.charAt(1);
+ if (desc == ((CtPrimitiveType) CtClass.booleanType).getDescriptor())
+ {
+ errorMessage += "boolean";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.byteType).getDescriptor())
+ {
+ errorMessage += "byte";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.charType).getDescriptor())
+ {
+ errorMessage += "char";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.doubleType).getDescriptor())
+ {
+ errorMessage += "double";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.floatType).getDescriptor())
+ {
+ errorMessage += "float";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.intType).getDescriptor())
+ {
+ errorMessage += "int";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.longType).getDescriptor())
+ {
+ errorMessage += "long";
+ }
+ else if (desc == ((CtPrimitiveType) CtClass.shortType).getDescriptor())
+ {
+ errorMessage += "short";
+ }
+ else
+ {
+ break;
+ }
+ errorMessage += ".\n It should have the introduction target type as parameter, or have no parameter at all.";
+ throw new RuntimeException(errorMessage);
-
- String construction = name + "(this)";
+ }
+ break;
+ default:
+ throw new RuntimeException("Mixin creator method '" + name +
+ "' should not have more than one parameter.");
+ }
+ if (!Modifier.isStatic(minfo.getAccessFlags()) ||
+ !Modifier.isPublic(minfo.getAccessFlags()))
+ {
+ throw new RuntimeException("Mixin creator method '" + name +
+ "' must be public and static.");
+ }
+
//Parse the descriptor to get the returntype of the method.
String classname = getReturnType(minfo);
intro.getMixins().add(new InterfaceIntroduction.Mixin(classname, interfaces, construction, isTransient));
@@ -663,7 +734,7 @@
String name = cf.getName() + "." + finfo.getName(); //Name of the field defined on
- InterfaceIntroduction interfaceIntro = createIntroduction(name, target, typeExpression, interfaces);
+ InterfaceIntroduction interfaceIntro = createIntroduction(name, target, typeExpression, interfaces, null, null);
manager.addInterfaceIntroduction(interfaceIntro);
}
}
@@ -905,7 +976,8 @@
return cf.getName() + "." + finfo.getName();
}
- private InterfaceIntroduction createIntroduction(String name, String target, String typeExpression, String[] interfaces)
+ private InterfaceIntroduction createIntroduction(String name, String target, String typeExpression, String[] interfaces,
+ String constructorClass, String constructorMethod)
throws Exception
{
if (typeExpression != null && typeExpression.trim().equals(""))
@@ -933,12 +1005,12 @@
if (target != null)
{
- intro = new InterfaceIntroduction(name, target, interfaces);
+ intro = new InterfaceIntroduction(name, target, interfaces, constructorClass, constructorMethod);
}
else
{
ASTStart start = new TypeExpressionParser(new StringReader(typeExpression)).Start();
- intro = new InterfaceIntroduction(name, start, interfaces);
+ intro = new InterfaceIntroduction(name, start, interfaces, constructorClass, constructorMethod);
}
return intro;
@@ -946,11 +1018,11 @@
private String getReturnType(MethodInfo minfo)
{
- String descriptor = minfo.getDescriptor();
- int paramsEnd = descriptor.indexOf(";)");
- String classname = descriptor.substring(paramsEnd + 3, descriptor.length() - 1);
- classname = classname.replace('/', '.');
- return classname;
+ String descriptor = minfo.getDescriptor();
+ int paramsEnd = descriptor.indexOf(")");
+ String classname = descriptor.substring(paramsEnd + 2, descriptor.length() - 1);
+ classname = classname.replace('/', '.');
+ return classname;
}
private String getFieldType(FieldInfo finfo)
Modified: branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/ClassicInstrumentor.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -144,14 +144,7 @@
CtMethod wmethod = CtNewMethod.make(method.getReturnType(), method.getName(), method.getParameterTypes(),
method.getExceptionTypes(), null, clazz);
wmethod.setModifiers(method.getModifiers());
- try
- {
- wmethod.setBody(code);
- }
- catch (CannotCompileException e)
- {
- throw new RuntimeException("<mixin> construction may have syntax error: '" + initializer + "'", e);
- }
+ wmethod.setBody(code);
clazz.addMethod(wmethod);
return wmethod;
Modified: branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/Instrumentor.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/Instrumentor.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/instrument/Instrumentor.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -249,6 +249,34 @@
// mixin is adding any interfaces already
// defined in base class or another mixin.
CtClass mixinClass = classPool.get(mixin.getClassName());
+
+ // check mixin constructor method if this is the case
+ if (pointcut.getConstructorClass() != null)
+ {
+ CtClass type = forName(pointcut.getConstructorClass());
+ CtMethod[] methods = type.getDeclaredMethods();
+ boolean correct = false;
+ for (int i = 0; i < methods.length; i++)
+ {
+ if (methods[i].getName().equals(pointcut.getConstructorMethod())
+ && methods[i].getParameterTypes().length == 1)
+ {
+ if (clazz.subclassOf(methods[i].getParameterTypes()[0]))
+ {
+ correct = true;
+ }
+
+ }
+ }
+ if (!correct)
+ {
+ throw new RuntimeException("Could not find a method named '" +
+ pointcut.getConstructorMethod() + "' on class " +
+ pointcut.getConstructorClass() + " that receives " +
+ clazz.getName() + " or one of its superclasses as parameter.");
+ }
+ }
+
String initializer = (mixin.getConstruction() == null) ? ("new " + mixinClass.getName() + "()") : mixin.getConstruction();
CtClass type = forName(mixinClass.getName());
CtField field = new CtField(type, mixinFieldName(mixinClass), clazz);
@@ -289,7 +317,18 @@
}
// If another interface of this mixin has a duplicate method, then its ok, but don't re-add
if (addedMethods.contains(hash)) continue;
- createMixinInvokeMethod(clazz, mixinClass, initializer, method, hash.longValue());
+ try
+ {
+ createMixinInvokeMethod(clazz, mixinClass, initializer, method, hash.longValue());
+ }
+ catch (CannotCompileException e)
+ {
+ String generatedCode = "class " + clazz.getName() + "\n{\n ...\n" +
+ " private " + type.getName() + " = " + initializer + ";\n"
+ + " ...\n}";
+ throw new RuntimeException("Mixin construction expression '"
+ + initializer + "' may have sintax error:\n" + generatedCode, e);
+ }
baseMethods.put(hash, method);
addedMethods.add(hash);
}
Modified: branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/introduction/InterfaceIntroduction.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/introduction/InterfaceIntroduction.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/main/org/jboss/aop/introduction/InterfaceIntroduction.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -106,6 +106,9 @@
protected ClassExpression classExpr;
protected ASTStart ast;
+ protected String constructorClass; // name of the class containing the mixin constructor method
+ protected String constructorMethod; // name of the mixin constructor method
+
public InterfaceIntroduction()
{
@@ -117,12 +120,32 @@
this.classExpr = new ClassExpression(exp);
}
+ // call this constructor only when constructor method receives the mixin target
+ // as parameter, for posterior validation of constructor method signature
+ public InterfaceIntroduction(String name, String exp, String[] interfaces,
+ String constructorClass, String constructorMethod)
+ {
+ this(name, exp, interfaces);
+ this.constructorClass = constructorClass;
+ this.constructorMethod = constructorMethod;
+ }
+
public InterfaceIntroduction(String name, ASTStart ast, String[] interfaces)
{
this.name = name;
this.ast = ast;
this.interfaces = interfaces;
}
+
+ // call this constructor only when constructor method receives the mixin target
+ // as parameter, for posterior validation of constructor method signature
+ public InterfaceIntroduction(String name, ASTStart ast, String[] interfaces,
+ String constructorClass, String constructorMethod)
+ {
+ this(name, ast, interfaces);
+ this.constructorClass = constructorClass;
+ this.constructorMethod = constructorMethod;
+ }
public void setClassExpression(String exp)
{
@@ -171,7 +194,20 @@
return mixins;
}
+ // this value is set only when there is a mixin constructor method and this
+ // method receives the target as parameter
+ public String getConstructorClass()
+ {
+ return this.constructorClass;
+ }
+ // this value is set only when there is a mixin constructor method and this
+ // method receives the target as parameter
+ public String getConstructorMethod()
+ {
+ return this.constructorMethod;
+ }
+
public void addAdvisor(Advisor advisor)
{
advisors.add(new WeakReference(advisor));
Modified: branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/AnnotatedTestCase.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/AnnotatedTestCase.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/AnnotatedTestCase.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -182,7 +182,10 @@
System.out.println("deserialized pojo2.stuff2: " + pojo2.stuff);
assertTrue("writeExternal was not called for pojo2", ExternalizableMixin.write);
assertTrue("readExternal was not called for pojo2", ExternalizableMixin.read);
-
+
+ ComparableMixin.COMPARED = false;
+ ((Comparable) pojo2).compareTo(null);
+ assertTrue("mixin method was not called", ComparableMixin.COMPARED);
}
public void testIntroduction() throws Exception
Added: branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/ComparableMixin.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/ComparableMixin.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/ComparableMixin.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.aop.jdk15.annotated;
+
+/**
+ * Mixin that implements the <code>Comparable</code> interface.
+ *
+ * @author <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+public class ComparableMixin implements Comparable
+{
+ static boolean COMPARED = false;
+
+ public int compareTo(Object o)
+ {
+ COMPARED = true;
+ return 0;
+ }
+}
\ No newline at end of file
Modified: branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/IntroductionAspect.java
===================================================================
--- branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/IntroductionAspect.java 2007-01-11 16:25:34 UTC (rev 59531)
+++ branches/Branch_AOP_1_5/aop/src/test/org/jboss/test/aop/jdk15/annotated/IntroductionAspect.java 2007-01-11 16:29:27 UTC (rev 59532)
@@ -24,6 +24,7 @@
import org.jboss.aop.Mixin;
import org.jboss.aop.Introduction;
import org.jboss.aop.Aspect;
+
/**
*
* @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
@@ -37,6 +38,11 @@
return new ExternalizableMixin(pojo);
}
+ @Mixin (target=org.jboss.test.aop.jdk15.annotated.NoInterfacesPOJO2.class, interfaces={Comparable.class})
+ public static ComparableMixin createComparableMixin() {
+ return new ComparableMixin();
+ }
+
@Introduction (target=org.jboss.test.aop.jdk15.annotated.NoInterfacesPOJO.class, interfaces={org.jboss.test.aop.jdk15.annotated.EmptyInterface.class})
public static Object noInterfacesPOJOIntro;
More information about the jboss-cvs-commits
mailing list