KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > advice > PrecedenceSorter


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aop.advice;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Comparator JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedHashMap JavaDoc;
29
30 import org.jboss.aop.AspectManager;
31
32 /**
33  *
34  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
35  * @version $Revision: 46116 $
36  */

37 public class PrecedenceSorter
38 {
39    static Comparator JavaDoc interceptorComparator = new Comparator JavaDoc()
40    {
41       public int compare(Object JavaDoc objA, Object JavaDoc objB)
42       {
43          InterceptorEntry entryA = (InterceptorEntry)objA;
44          InterceptorEntry entryB = (InterceptorEntry)objB;
45          
46          return entryA.precedenceOrder - entryB.precedenceOrder;
47       }
48    };
49    
50    static class InterceptorEntry
51    {
52       Interceptor interceptor;
53       GeneratedAdvisorInterceptor factoryWrapper;
54       int originalOrder;
55       int precedenceOrder = -1;
56       String JavaDoc classname;
57       String JavaDoc method;
58       
59       InterceptorEntry(GeneratedAdvisorInterceptor factoryWrapper)
60       {
61          this.factoryWrapper = factoryWrapper;
62          classname = factoryWrapper.getName();
63          
64          InterceptorFactory ifac = factoryWrapper.getDelegate();
65          
66          if (ifac instanceof GenericInterceptorFactory)
67          {
68             //Dynamically added interceptors
69
classname = ((GenericInterceptorFactory)ifac).getClassName();
70          }
71          else
72          {
73             AspectFactory af = factoryWrapper.getAspect().getFactory();
74             classname = af.getName();
75          }
76          
77          if (ifac instanceof AdviceFactory)
78          {
79             method = ((AdviceFactory)ifac).getAdvice();
80          }
81       }
82       
83       
84       InterceptorEntry(Interceptor interceptor)
85       {
86          this.interceptor = interceptor;
87
88          String JavaDoc interceptorName = null;
89          if (interceptor instanceof PerInstanceInterceptor)
90          {
91             PerInstanceInterceptor icptr = (PerInstanceInterceptor)interceptor;
92             interceptorName = icptr.getName();
93          }
94          else if (interceptor instanceof PerJoinpointInterceptor)
95          {
96             PerJoinpointInterceptor icptr = (PerJoinpointInterceptor)interceptor;
97             interceptorName = icptr.getName();
98          }
99          else if (interceptor instanceof CFlowInterceptor)
100          {
101             CFlowInterceptor icptr = (CFlowInterceptor)interceptor;
102             interceptorName = icptr.getName();
103          }
104          else
105          {
106             interceptorName = interceptor.getClass().getName();
107          }
108          
109          try
110          {
111             boolean isAdvice = interceptorName.startsWith("org.jboss.aop.advice.");
112             if (isAdvice)
113             {
114                String JavaDoc name = interceptor.getName();
115                int index = name.lastIndexOf(".");
116                classname = name.substring(0, index);
117                method = name.substring(index + 1);
118             }
119             else
120             {
121                classname = interceptorName;
122             }
123          }
124          catch (RuntimeException JavaDoc e)
125          {
126             System.err.print(interceptor.getName());
127             throw e;
128          }
129       }
130       
131       public String JavaDoc toString()
132       {
133          return "Entry: " + precedenceOrder + " (" + originalOrder + ")interceptorClass=" + classname + "; adviceMethod=" + method;
134       }
135       
136    }
137    
138    private static boolean matches(InterceptorEntry ientry, PrecedenceDefEntry pentry)
139    {
140       if (ientry.classname.equals(pentry.interceptorClass))
141       {
142          if (ientry.method == null)
143          {
144             if (pentry.adviceMethod == null)
145             {
146                return true;
147             }
148          }
149          else if (pentry.adviceMethod != null)
150          {
151             //This was:
152
//return ientry.classname.equals(pentry.interceptorClass);
153
return ientry.method.equals(pentry.adviceMethod);
154          }
155       }
156       return false;
157    }
158    
159    
160    public static PrecedenceDefEntry[] createOverallPrecedence(AspectManager manager)
161    {
162       ArrayList JavaDoc overall = new ArrayList JavaDoc();
163       
164       LinkedHashMap JavaDoc precedenceDefs = manager.getPrecedenceDefs();
165       boolean first = true;
166       for (Iterator JavaDoc it = precedenceDefs.values().iterator() ; it.hasNext(); )
167       {
168          PrecedenceDef precedenceDef = (PrecedenceDef)it.next();
169          PrecedenceDefEntry[] entries = precedenceDef.getEntries();
170
171          if (first)
172          {
173             //Populate overall with the initial precedence
174
for (int i = 0 ; i < entries.length ; i++)
175             {
176                overall.add(entries[i]);
177             }
178             first = false;
179             continue;
180          }
181          
182          overall = mergePrecedenceDef(overall, precedenceDef);
183       }
184       //System.out.println("OVERALL PRECEDENCE: " + overall);
185
return (PrecedenceDefEntry[])overall.toArray(new PrecedenceDefEntry[overall.size()]);
186    }
187    
188    public static ArrayList JavaDoc mergePrecedenceDef(ArrayList JavaDoc overall, PrecedenceDef precedenceDef)
189    {
190       //TODO This can be improved. If you have the precedences
191
// 1) A, D
192
// 2) C, E
193
// 3) C, D
194
//After adding 2) to 1) since there is no relationship defined you get:
195
// i) A, D, C, E
196
//After adding 3) to i) you end up with an overall precedence of
197
// ii) A, C, D, C, E,
198
//In practice this should be fine, since the applyPrecedence() looks for the
199
//first matching entry, so the second (duplicate) occurrence of C is ignored.
200
PrecedenceDefEntry[] entries = precedenceDef.getEntries();
201       int start = 0, end = 0;
202       int size = overall.size();
203       for (int i = 0 ; i < size ; i++)
204       {
205          PrecedenceDefEntry global = (PrecedenceDefEntry)overall.get(i);
206          boolean found = false;
207
208          //find current overall precedence entry in the new set of defs
209
for (int j = start ; j < entries.length ; j++)
210          {
211             PrecedenceDefEntry cur = entries[j];
212             
213             if (cur.equals(global))
214             {
215                found = true;
216                end = j;
217                break;
218             }
219          }
220          
221          //We found it. Now insert everything until this into global and
222
//reset the counters
223
if (found)
224          {
225             int insert = i;
226             for (int j = start ; j < end ; j++)
227             {
228                overall.add(insert++, entries[j]);
229             }
230             end++;
231             start = end;
232          }
233       }
234
235       for (int j = start ; j < entries.length ; j++)
236       {
237          overall.add(entries[j]);
238       }
239       
240       return overall;
241    }
242    
243    public static Interceptor[] applyPrecedence(Interceptor[] interceptors, AspectManager manager)
244    {
245       if (interceptors.length == 0)
246          return interceptors;
247       
248       ArrayList JavaDoc all = new ArrayList JavaDoc(interceptors.length);
249       ArrayList JavaDoc precedence = new ArrayList JavaDoc(interceptors.length);
250       PrecedenceDefEntry[] precedenceEntries = manager.getSortedPrecedenceDefEntries();
251       
252       //Figure out what interceptors have precedence
253
for (int i = 0 ; i < interceptors.length ; i++)
254       {
255          InterceptorEntry interceptorEntry = new InterceptorEntry(interceptors[i]);
256          all.add(interceptorEntry);
257          for (int j = 0 ; j < precedenceEntries.length ; j++)
258          {
259             if (matches(interceptorEntry, precedenceEntries[j]))
260             {
261                //This interceptor is defined in the precedence
262
interceptorEntry.originalOrder = i;
263                interceptorEntry.precedenceOrder = j;
264                precedence.add(interceptorEntry);
265                break;
266             }
267          }
268       }
269       
270       //Sort the interceptors having precedence
271
Collections.sort(precedence, interceptorComparator);
272       Interceptor[] sortedInterceptors = new Interceptor[interceptors.length];
273       
274       //Build up new array of interceptors depending on their precedence
275
int prec = 0;
276       int allSize = all.size();
277       int precedenceSize = precedence.size();
278       
279       for (int i = 0 ; i < allSize ; i++)
280       {
281          InterceptorEntry entry = (InterceptorEntry)all.get(i);
282          
283          if (entry.precedenceOrder >= 0 && prec < precedenceSize)
284          {
285             entry = (InterceptorEntry)precedence.get(prec++);
286          }
287          sortedInterceptors[i] = entry.interceptor;
288       }
289       
290       return sortedInterceptors;
291    }
292    
293    public static GeneratedAdvisorInterceptor[] applyPrecedence(GeneratedAdvisorInterceptor[] interceptors, AspectManager manager)
294    {
295       ArrayList JavaDoc all = new ArrayList JavaDoc(interceptors.length);
296       ArrayList JavaDoc precedence = new ArrayList JavaDoc(interceptors.length);
297       PrecedenceDefEntry[] precedenceEntries = manager.getSortedPrecedenceDefEntries();
298       
299       //Figure out what interceptors have precedence
300
for (int i = 0 ; i < interceptors.length ; i++)
301       {
302          InterceptorEntry interceptorEntry = new InterceptorEntry(interceptors[i]);
303          all.add(interceptorEntry);
304          for (int j = 0 ; j < precedenceEntries.length ; j++)
305          {
306             if (matches(interceptorEntry, precedenceEntries[j]))
307             {
308                //This interceptor is defined in the precedence
309
interceptorEntry.originalOrder = i;
310                interceptorEntry.precedenceOrder = j;
311                precedence.add(interceptorEntry);
312                break;
313             }
314          }
315       }
316       
317       //Sort the interceptors having precedence
318
Collections.sort(precedence, interceptorComparator);
319       GeneratedAdvisorInterceptor[] sortedInterceptors = new GeneratedAdvisorInterceptor[interceptors.length];
320       
321       //Build up new array of interceptors depending on their precedence
322
int prec = 0;
323       int allSize = all.size();
324       int precedenceSize = precedence.size();
325       
326       for (int i = 0 ; i < allSize ; i++)
327       {
328          InterceptorEntry entry = (InterceptorEntry)all.get(i);
329          
330          if (entry.precedenceOrder >= 0 && prec < precedenceSize)
331          {
332             entry = (InterceptorEntry)precedence.get(prec++);
333          }
334          sortedInterceptors[i] = entry.factoryWrapper;
335       }
336       
337       return sortedInterceptors;
338    }
339    
340 /* public static void main(String[] args)
341    {
342       System.out.println("Hello");
343       AspectManager manager = new AspectManager();
344       PrecedenceDef def = new PrecedenceDef("3",new PrecedenceDefEntry[]{
345             new PrecedenceDefEntry("A", null),
346             new PrecedenceDefEntry("D", null)});
347       manager.addPrecedence(def);
348       outputOverAll(manager);
349
350       def = new PrecedenceDef("4",new PrecedenceDefEntry[]{
351             new PrecedenceDefEntry("C", null),
352             new PrecedenceDefEntry("E", null)});
353       manager.addPrecedence(def);
354       outputOverAll(manager);
355
356       def = new PrecedenceDef("5",new PrecedenceDefEntry[]{
357             new PrecedenceDefEntry("C", null),
358             new PrecedenceDefEntry("D", null)});
359       manager.addPrecedence(def);
360       outputOverAll(manager);
361
362    }
363    
364    private static void outputOverAll(AspectManager manager)
365    {
366       PrecedenceDefEntry[] entries = manager.getSortedPrecedenceDefEntries();
367       for (int i = 0 ; i < entries.length ; i++)
368       {
369          System.out.println("\t" + entries[i]);
370       }
371       System.out.println("==================================");
372    }
373 */

374 }
375
Popular Tags