KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2002-2006 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
21 import org.springframework.aop.Advisor;
22 import org.springframework.aop.aspectj.AspectJAopUtils;
23 import org.springframework.aop.aspectj.AspectJPrecedenceInformation;
24 import org.springframework.core.OrderComparator;
25 import org.springframework.util.Assert;
26
27 /**
28  * Orders AspectJ advice/advisors by precedence (<i>not</i> invocation order).
29  *
30  * <p>Given two pieces of advice, <code>a</code> and <code>b</code>:
31  * <ul>
32  * <li>if <code>a</code> and <code>b</code> are defined in different
33  * aspects, then the advice in the aspect with the lowest order
34  * value has the highest precedence</li>
35  * <li>if <code>a</code> and <code>b</code> are defined in the same
36  * aspect, then if one of <code>a</code> or <code>b</code> is a form of
37  * after advice, then the advice declared last in the aspect has the
38  * highest precedence. If neither <code>a</code> nor <code>b</code> is a
39  * form of after advice, then the advice declared first in the aspect has
40  * the highest precedence.</li>
41  * </ul>
42  *
43  * <p>Important: Note that unlike a normal comparator a return of 0 means
44  * we don't care about the ordering, not that the two elements must be sorted
45  * identically. Used with AspectJ PartialOrder class.
46  *
47  * @author Adrian Colyer
48  * @author Juergen Hoeller
49  * @since 2.0
50  */

51 class AspectJPrecedenceComparator implements Comparator JavaDoc {
52
53     private static final int HIGHER_PRECEDENCE = -1;
54     private static final int SAME_PRECEDENCE = 0;
55     private static final int LOWER_PRECEDENCE = 1;
56     private static final int NOT_COMPARABLE = 0;
57
58     private final Comparator JavaDoc advisorComparator;
59
60
61     /**
62      * Create a default AspectJPrecedenceComparator.
63      */

64     public AspectJPrecedenceComparator() {
65         this.advisorComparator = new OrderComparator();
66     }
67
68     /**
69      * Create a AspectJPrecedenceComparator, using the given Comparator
70      * for comparing {@link org.springframework.aop.Advisor} instances.
71      * @param advisorComparator the Comparator to use for Advisors
72      */

73     public AspectJPrecedenceComparator(Comparator JavaDoc advisorComparator) {
74         Assert.notNull(advisorComparator, "Advisor comparator must not be null");
75         this.advisorComparator = advisorComparator;
76     }
77
78
79     public int compare(Object JavaDoc o1, Object JavaDoc o2) {
80         if (!(o1 instanceof Advisor && o2 instanceof Advisor)) {
81             throw new IllegalArgumentException JavaDoc(
82                     "AspectJPrecedenceComparator can only compare the order of Advisors, " +
83                     "but was passed [" + o1 + "] and [" + o2 + "]");
84         }
85
86         Advisor advisor1 = (Advisor) o1;
87         Advisor advisor2 = (Advisor) o2;
88
89         boolean oneOrOtherIsAfterAdvice =
90                 (AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
91         boolean oneOrOtherIsBeforeAdvice =
92                 (AspectJAopUtils.isBeforeAdvice(advisor1) || AspectJAopUtils.isBeforeAdvice(advisor2));
93         if (oneOrOtherIsAfterAdvice && oneOrOtherIsBeforeAdvice) {
94             return NOT_COMPARABLE;
95         }
96         else {
97             int advisorPrecedence = this.advisorComparator.compare(advisor1, advisor2);
98             if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(advisor1, advisor2)) {
99                 advisorPrecedence = comparePrecedenceWithinAspect(advisor1, advisor2);
100             }
101             return advisorPrecedence;
102         }
103     }
104
105     private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
106         boolean oneOrOtherIsAfterAdvice =
107                 (AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
108         int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);
109         
110         if (oneOrOtherIsAfterAdvice) {
111             // the advice declared last has higher precedence
112
if (adviceDeclarationOrderDelta < 0) {
113                 // advice1 was declared before advice2
114
// so advice1 has lower precedence
115
return LOWER_PRECEDENCE;
116             }
117             else if (adviceDeclarationOrderDelta == 0) {
118                 return SAME_PRECEDENCE;
119             }
120             else {
121                 return HIGHER_PRECEDENCE;
122             }
123         }
124         else {
125             // the advice declared first has higher precedence
126
if (adviceDeclarationOrderDelta < 0) {
127                 // advice1 was declared before advice2
128
// so advice1 has higher precedence
129
return HIGHER_PRECEDENCE;
130             }
131             else if (adviceDeclarationOrderDelta == 0) {
132                 return SAME_PRECEDENCE;
133             }
134             else {
135                 return LOWER_PRECEDENCE;
136             }
137         }
138     }
139
140     private boolean declaredInSameAspect(Advisor advisor1, Advisor advisor2) {
141         if (!(hasAspectName(advisor1) && hasAspectName(advisor2))) {
142             return false;
143         }
144         else {
145             return getAspectName(advisor1).equals(getAspectName(advisor2));
146         }
147     }
148
149     private boolean hasAspectName(Advisor anAdvisor) {
150         return (anAdvisor instanceof AspectJPrecedenceInformation ||
151                 anAdvisor.getAdvice() instanceof AspectJPrecedenceInformation);
152     }
153
154     // pre-condition is that hasAspectName returned true
155
private String JavaDoc getAspectName(Advisor anAdvisor) {
156         return AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor).getAspectName();
157     }
158
159     private int getAspectDeclarationOrder(Advisor anAdvisor) {
160         AspectJPrecedenceInformation precedenceInfo =
161             AspectJAopUtils.getAspectJPrecedenceInformationFor(anAdvisor);
162         if (precedenceInfo != null) {
163             return precedenceInfo.getDeclarationOrder();
164         }
165         else {
166             return 0;
167         }
168     }
169
170 }
171
Popular Tags