@@ -0,0 +1,62 @@ | |||
import java.lang.annotation.*; | |||
public aspect DeclareAnnotation { | |||
declare @type : org.xyz.model..* : @BusinessDomain; | |||
declare @method : public * BankAccount+.*(..) : @Secured(role="supervisor"); | |||
declare @field : * DAO+.* : @Persisted; | |||
declare warning : staticinitialization(@BusinessDomain *) | |||
: "@BusinessDomain"; | |||
declare warning : execution(@Secured * *(..)) : "@Secured"; | |||
declare warning : set(@Persisted * *) : "@Persisted"; | |||
public static void main(String[] args) throws Exception { | |||
Class bAcc = BankAccount.class; | |||
java.lang.reflect.Method credit = bAcc.getDeclaredMethod("credit"); | |||
Secured secured = credit.getAnnotation(Secured.class); | |||
if (!secured.role().equals("supervisor")) { | |||
throw new RuntimeException("BankAccount.credit should have @Secured(role=supervisor) annotation"); | |||
} | |||
} | |||
} | |||
@interface BusinessDomain {} | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@interface Secured { | |||
String role() default ""; | |||
} | |||
@interface Persisted {} | |||
class BankAccount { | |||
public void credit() {} | |||
public void debit() {} | |||
protected void transfer() {} | |||
} | |||
class ExecutiveBankAccount extends BankAccount { | |||
public void interest() {} | |||
protected void commission() {} | |||
} | |||
class DAO { | |||
int x = 5; | |||
} | |||
class SubDAO extends DAO { | |||
int y = 6; | |||
} |
@@ -0,0 +1,48 @@ | |||
import org.xyz.model.Model; | |||
public aspect DeclaresWithAnnotations { | |||
declare warning : withincode(@PerformanceCritical * *(..)) && | |||
call(@ExpensiveOperation * *(..)) | |||
: "Expensive operation called from within performance critical section"; | |||
declare error : call(* org.xyz.model.*.*(..)) && | |||
!@within(Trusted) | |||
: "Untrusted code should not call the model classes directly"; | |||
} | |||
@interface PerformanceCritical {} | |||
@interface ExpensiveOperation {} | |||
@interface Trusted {} | |||
class Foo { | |||
@PerformanceCritical Foo getFoo() { | |||
Model m = new Model(); | |||
m.foo(); // DE | |||
Foo foo = makeFoo(); // DW | |||
return foo; | |||
} | |||
Foo getFoo2() { | |||
Foo foo = makeFoo(); | |||
return foo; | |||
} | |||
@ExpensiveOperation Foo makeFoo() { | |||
return new Foo(); | |||
} | |||
} | |||
@Trusted class Goo { | |||
public void goo() { | |||
Model m = new Model(); | |||
m.foo(); | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
public aspect DecpAnnotations { | |||
public String SecuredObject.getSecurityCredentials() { | |||
return "none"; | |||
} | |||
declare parents : (@Secured *) implements SecuredObject; | |||
declare parents : (@Secured BankAccount+) implements SecuredObject; | |||
public static void main(String[] args) { | |||
Foo foo = new Foo(); | |||
Goo goo = new Goo(); | |||
BankAccount acc = new BankAccount(); | |||
PrivateBankAccount pacc = new PrivateBankAccount(); | |||
BusinessBankAccount bacc = new BusinessBankAccount(); | |||
System.out.println("Test Foo is not secured: " + | |||
((foo instanceof SecuredObject) ? "FAIL" : "PASS") | |||
); | |||
System.out.println("Test Goo is secured: " + | |||
((goo instanceof SecuredObject) ? "PASS" : "FAIL") | |||
); | |||
System.out.println("goo credentials: " + goo.getSecurityCredentials()); | |||
System.out.println("Test BankAccount is not secured: " + | |||
((acc instanceof SecuredObject) ? "FAIL" : "PASS") | |||
); | |||
System.out.println("Test PrivateBankAccount is not secured: " + | |||
((pacc instanceof SecuredObject) ? "FAIL" : "PASS") | |||
); | |||
System.out.println("Test BusinessBankAccount is secured: " + | |||
((bacc instanceof SecuredObject) ? "PASS" : "FAIL") | |||
); | |||
} | |||
} | |||
interface SecuredObject {} | |||
@interface Secured {} | |||
class Foo {} | |||
@Secured class Goo{} | |||
class BankAccount {} | |||
class PrivateBankAccount extends BankAccount {} | |||
@Secured class BusinessBankAccount extends BankAccount {} |
@@ -0,0 +1,45 @@ | |||
public aspect PrecedenceAnnotations { | |||
declare precedence : (@Security *), *; | |||
declare precedence : *, (@Performance *); | |||
public static void main(String[] args) { | |||
A a = new A(); | |||
a.foo(); | |||
} | |||
} | |||
@interface Security {} | |||
@interface Performance{} | |||
class A { | |||
pointcut foo() : execution(* foo()); | |||
void foo() {} | |||
} | |||
aspect S1 { | |||
before() : A.foo() { | |||
System.out.println("S1"); | |||
} | |||
} | |||
@Security aspect S2 { | |||
before() : A.foo() { | |||
System.out.println("@Security S2"); | |||
} | |||
} | |||
aspect P1 { | |||
after() returning : A.foo() { | |||
System.out.println("P1"); | |||
} | |||
} | |||
@Performance aspect P2 { | |||
after() returning : A.foo() { | |||
System.out.println("@Performance P2"); | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
package org.xyz.model; | |||
public class Model { | |||
public void foo() {} | |||
} |
@@ -0,0 +1,47 @@ | |||
public aspect AJDKExamples { | |||
declare warning : call(* whoAreYou()) | |||
: "call(* whoAreYou())"; | |||
declare warning : call(* A.whoAreYou()) | |||
: "call(* A.whoAreYou())"; | |||
declare warning : call(A whoAreYou()) | |||
: "call(A whoAreYou())"; | |||
declare warning : call(A B.whoAreYou()) | |||
: "call(A B.whoAreYou())"; | |||
declare warning : call(A+ B.whoAreYou()) | |||
: "call(A+ B.whoAreYou())"; | |||
declare warning : call(B A.whoAreYou()) | |||
: "call(B A.whoAreYou())"; | |||
declare warning : call(B whoAreYou()) | |||
: "call(B whoAreYou())"; | |||
declare warning : call(B B.whoAreYou()) | |||
: "call(B B.whoAreYou())"; | |||
} | |||
class A { | |||
public A whoAreYou() { return this; } | |||
} | |||
class B extends A { | |||
// override A.whoAreYou *and* narrow the return type. | |||
public B whoAreYou() { return this; } | |||
} | |||
class C { | |||
public C() { | |||
A a = new A(); | |||
B b = new B(); | |||
a.whoAreYou(); | |||
b.whoAreYou(); | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
import java.util.*; | |||
public aspect AJDKExamples pertypewithin(org.xyz..*) { | |||
// use WeakHashMap for auto-garbage collection of keys | |||
private Map<Object,Boolean> instances = new WeakHashMap<Object,Boolean>(); | |||
after(Object o) returning() : execution(new(..)) && this(o) { | |||
instances.put(o,true); | |||
} | |||
public Set<?> getInstances() { | |||
return instances.keySet(); | |||
} | |||
public static void main(String[] args) { | |||
A a = new A(); | |||
A a2 = new A(); | |||
B b = new B(); | |||
B b2 = new B(); | |||
B b3 = new B(); | |||
System.out.println(AJDKExamples.hasAspect(A.class)); | |||
System.out.println(AJDKExamples.hasAspect(B.class)); | |||
Set<?> as = AJDKExamples.aspectOf(A.class).getInstances(); | |||
Set<?> bs = AJDKExamples.aspectOf(B.class).getInstances(); | |||
System.out.println("There are " + as.size() + " As"); | |||
System.out.println("There are " + bs.size() + " Bs"); | |||
} | |||
} | |||
class A {} | |||
class B {} |
@@ -0,0 +1,31 @@ | |||
public aspect AJDKExamples { | |||
declare warning : call(* org.xyz.*.*(int, String...)) : "call vararg match"; | |||
declare warning : execution(* org.xyz.*.*(Integer...)) : "execution vararg match"; | |||
declare warning : initialization(org.xyz.*.new((Foo || Goo)...)) : "init vararg match"; | |||
declare warning : execution(* *.*(String...)) : "single vararg"; | |||
declare warning : execution(* *.*(String[])) : "single String[]"; | |||
before(int i, String[] ss) : call(* foo(int,String...)) && args(i,ss) { | |||
System.out.println("Matched at " + thisJoinPoint); | |||
} | |||
public static void main(String[] args) { | |||
X foo = new X(); | |||
foo.foo(5,"hello"); | |||
foo.bar(5,new String[]{"hello"}); | |||
} | |||
} | |||
class X { | |||
public void foo(String... ss) {} | |||
public void bar(String[] ss) {} | |||
public void foo(int i,String... ss) {} | |||
public void bar(int i,String[] ss) {} | |||
} | |||
@@ -0,0 +1,5 @@ | |||
package org.xyz; | |||
public class Foo { | |||
} |
@@ -0,0 +1,5 @@ | |||
package org.xyz; | |||
public class Goo { | |||
} |
@@ -0,0 +1,16 @@ | |||
package org.xyz; | |||
public class Hoo { | |||
public Hoo(Foo... foos) {} | |||
public Hoo(Goo... goos) {} | |||
public Hoo(String... ss) { | |||
intStringVar(5,ss); | |||
intString(5,ss[0]); | |||
} | |||
void intStringVar(int i, String... ss) {} | |||
void intString(int i, String s) {} | |||
void integerVar(Integer... is) {} | |||
} |
@@ -153,6 +153,22 @@ public class Annotations extends XMLBasedAjcTestCase { | |||
runTest("ajdk: @inherited"); | |||
} | |||
public void testAnnotationDEOW() { | |||
runTest("ajdk: deow-ann"); | |||
} | |||
public void testAnnotationDecp() { | |||
runTest("ajdk: decp-ann"); | |||
} | |||
public void testAnnotationDecPrecedence() { | |||
runTest("ajdk: dec precedence"); | |||
} | |||
public void testAnnotationDecAnnotation() { | |||
runTest("ajdk: dec annotation"); | |||
} | |||
// helper methods..... | |||
public SyntheticRepository createRepos(File cpentry) { |
@@ -160,4 +160,7 @@ public class CovarianceTests extends XMLBasedAjcTestCase { | |||
runTest("covariance 10"); | |||
} | |||
public void testAJDKExamples() { | |||
runTest("ajdk: covariance"); | |||
} | |||
} |
@@ -85,6 +85,10 @@ public class PerTypeWithinTests extends XMLBasedAjcTestCase { | |||
public void testBinaryWeaving_AspectsAreBinary() { | |||
runTest("ptw binary aspect"); | |||
} | |||
public void testAJDKExamples() { | |||
runTest("ajdk: ptw"); | |||
} | |||
// // Compile the aspect H.java into classes3 | |||
// CompilationResult cR = ajc(new File("../tests/java5/pertypewithin"),new String[]{"H.java","-outjar","aspects.jar"}); | |||
// setShouldEmptySandbox(false); |
@@ -64,5 +64,9 @@ public class VarargsTests extends XMLBasedAjcTestCase { | |||
public void test_usingVarargsInPointcuts2() { | |||
runTest("call with varargs multi-signature"); | |||
} | |||
public void testAJDKExamples() { | |||
runTest("ajdk: varargs"); | |||
} | |||
} |
@@ -1151,5 +1151,95 @@ | |||
<message kind="warning" line="17" text="c1MethodCall()"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: deow-ann"> | |||
<compile files="DeclaresWithAnnotations.aj,org/xyz/model/Model.java" options="-1.5"> | |||
<message kind="warning" line="27" text="Expensive operation called from within performance critical section"/> | |||
<message kind="error" line="26" text="Untrusted code should not call the model classes directly"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: decp-ann"> | |||
<compile files="DecpAnnotations.aj" options="-1.5"> | |||
</compile> | |||
<run class="DecpAnnotations"> | |||
<stdout> | |||
<line text="Test Foo is not secured: PASS"/> | |||
<line text="Test Goo is secured: PASS"/> | |||
<line text="goo credentials: none"/> | |||
<line text="Test BankAccount is not secured: PASS"/> | |||
<line text="Test PrivateBankAccount is not secured: PASS"/> | |||
<line text="Test BusinessBankAccount is secured: PASS"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: dec precedence"> | |||
<compile files="PrecedenceAnnotations.aj" options="-1.5"> | |||
</compile> | |||
<run class="PrecedenceAnnotations"> | |||
<stdout> | |||
<line text="@Security S2"/> | |||
<line text="S1"/> | |||
<line text="@Performance P2"/> | |||
<line text="P1"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="java5/annotations/ajdkExamples" title="ajdk: dec annotation"> | |||
<compile files="DeclareAnnotation.aj,org/xyz/model/Model.java" options="-1.5"> | |||
<message kind="warning" line="3" text="@BusinessDomain"/> | |||
<message kind="warning" line="39" text="@Secured"/> | |||
<message kind="warning" line="40" text="@Secured"/> | |||
<message kind="warning" line="47" text="@Secured"/> | |||
<message kind="warning" line="54" text="@Persisted"/> | |||
<message kind="warning" line="60" text="@Persisted"/> | |||
</compile> | |||
<run class="PrecedenceAnnotations"/> | |||
</ajc-test> | |||
<ajc-test dir="java5/covariance/ajdk" title="ajdk: covariance"> | |||
<compile files="AJDKExamples.aj" options="-1.5"> | |||
<message kind="warning" line="43" text="call(* whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(* whoAreYou())"/> | |||
<message kind="warning" line="43" text="call(* A.whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(* A.whoAreYou())"/> | |||
<message kind="warning" line="43" text="call(A whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(A whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(A+ B.whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(B whoAreYou())"/> | |||
<message kind="warning" line="44" text="call(B B.whoAreYou())"/> | |||
</compile> | |||
</ajc-test> | |||
<ajc-test dir="java5/varargs/ajdk" title="ajdk: varargs"> | |||
<compile files="AJDKExamples.aj,org/xyz/Foo.java,org/xyz/Goo.java,org/xyz/Hoo.java" options="-1.5"> | |||
<message kind="warning" line="8" text="call vararg match"/> | |||
<message kind="warning" line="14" text="execution vararg match"/> | |||
<message kind="warning" line="5" text="init vararg match"/> | |||
<message kind="warning" line="6" text="init vararg match"/> | |||
<message kind="warning" line="26" text="single vararg"/> | |||
<message kind="warning" line="27" text="single String[]"/> | |||
<message kind="warning" line="17" text="single String[]"/> | |||
</compile> | |||
<run class="AJDKExamples"> | |||
<stdout> | |||
<line text="Matched at xxx"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
<ajc-test dir="java5/pertypewithin/ajdk" title="ajdk: ptw"> | |||
<compile files="AJDKExamples.aj" options="-1.5"/> | |||
<run class="AJDKExamples"> | |||
<stdout> | |||
<line text="true"/> | |||
<line text="true"/> | |||
<line text="There are 3 As"/> | |||
<line text="There are 2 Bs"/> | |||
</stdout> | |||
</run> | |||
</ajc-test> | |||
</suite> | |||