KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > aspectj > autoproxy > AspectJAwareAdvisorAutoProxyCreator


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.aop.aspectj.autoproxy;
18
19 import java.util.Comparator JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.List JavaDoc;
23
24 import org.aopalliance.aop.Advice;
25 import org.aspectj.util.PartialOrder;
26 import org.aspectj.util.PartialOrder.PartialComparable;
27
28 import org.springframework.aop.Advisor;
29 import org.springframework.aop.aspectj.AbstractAspectJAdvice;
30 import org.springframework.aop.aspectj.AspectJProxyUtils;
31 import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
32 import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
33 import org.springframework.core.Ordered;
34 import org.springframework.util.ClassUtils;
35
36 /**
37  * {@link org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator}
38  * subclass that exposes AspectJ's invocation context and understands AspectJ's rules
39  * for advice precedence when multiple pieces of advice come from the same aspect.
40  *
41  * @author Adrian Colyer
42  * @author Juergen Hoeller
43  * @since 2.0
44  */

45 public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
46
47     private static final Comparator JavaDoc DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();
48
49
50     /**
51      * Sort the rest by AspectJ precedence. If two pieces of advice have
52      * come from the same aspect they will have the same order.
53      * Advice from the same aspect is then further ordered according to the
54      * following rules:
55      * <ul>
56      * <li>if either of the pair is after advice, then the advice declared
57      * last gets highest precedence (runs last)</li>
58      * <li>otherwise the advice declared first gets highest precedence (runs first)</li>
59      * </ul>
60      * <p><b>Important:</b> Advisors are sorted in precedence order, from highest
61      * precedence to lowest. "On the way in" to a join point, the highest precedence
62      * advisor should run first. "On the way out" of a join point, the highest precedence
63      * advisor should run last.
64      */

65     protected List JavaDoc sortAdvisors(List JavaDoc advisors) {
66         // build list for sorting
67
List JavaDoc partiallyComparableAdvisors = new LinkedList JavaDoc();
68         for (Iterator JavaDoc it = advisors.iterator(); it.hasNext();) {
69             Advisor element = (Advisor) it.next();
70             PartiallyComparableAdvisorHolder advisor =
71                     new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR);
72             partiallyComparableAdvisors.add(advisor);
73         }
74         
75         // sort it
76
List JavaDoc sorted = PartialOrder.sort(partiallyComparableAdvisors);
77         if (sorted == null) {
78             // TODO: work much harder to give a better error message here.
79
throw new IllegalArgumentException JavaDoc("Advice precedence circularity error");
80         }
81         
82         // extract results again
83
List JavaDoc result = new LinkedList JavaDoc();
84         for (Iterator JavaDoc it = sorted.iterator(); it.hasNext();) {
85             PartiallyComparableAdvisorHolder pcAdvisor = (PartiallyComparableAdvisorHolder) it.next();
86             result.add(pcAdvisor.getAdvisor());
87         }
88         
89         return result;
90     }
91
92     /**
93      * Adds an {@link ExposeInvocationInterceptor} to the beginning of the advice chain.
94      * These additional advices are needed when using AspectJ expression pointcuts
95      * and when using AspectJ-style advice.
96      */

97     protected void extendAdvisors(List JavaDoc candidateAdvisors) {
98         AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
99     }
100
101
102     /**
103      * Implements AspectJ PartialComparable interface for defining partial orderings.
104      */

105     private static class PartiallyComparableAdvisorHolder implements PartialComparable {
106
107         private final Advisor advisor;
108
109         private final Comparator JavaDoc comparator;
110
111         public PartiallyComparableAdvisorHolder(Advisor advisor, Comparator JavaDoc comparator) {
112             this.advisor = advisor;
113             this.comparator = comparator;
114         }
115
116         public int compareTo(Object JavaDoc obj) {
117             Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
118             return this.comparator.compare(this.advisor, otherAdvisor);
119         }
120
121         public int fallbackCompareTo(Object JavaDoc obj) {
122             return 0;
123         }
124
125         public Advisor getAdvisor() {
126             return this.advisor;
127         }
128
129         public String JavaDoc toString() {
130             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
131             Advice advice = this.advisor.getAdvice();
132             sb.append(ClassUtils.getShortName(advice.getClass()));
133             sb.append(": ");
134             if (this.advisor instanceof Ordered) {
135                 sb.append("order " + ((Ordered) this.advisor).getOrder() + ", ");
136             }
137             if (advice instanceof AbstractAspectJAdvice) {
138                 AbstractAspectJAdvice ajAdvice = (AbstractAspectJAdvice) advice;
139                 sb.append(ajAdvice.getAspectName());
140                 sb.append(", declaration order ");
141                 sb.append(ajAdvice.getDeclarationOrder());
142             }
143             return sb.toString();
144         }
145     }
146
147 }
148
Popular Tags