KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > SuperClassesFirstWeavingStrategy


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;
23
24 import java.util.Map JavaDoc;
25
26 import org.jboss.aop.classpool.AOPClassPool;
27 import org.jboss.aop.instrument.Instrumentor;
28 import org.jboss.aop.instrument.InstrumentorFactory;
29
30 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
31 import javassist.ByteArrayClassPath;
32 import javassist.ClassPool;
33 import javassist.CtClass;
34 import javassist.NotFoundException;
35
36 /**
37  * Generated advisors need to load all the superclasses
38  * before we load the actual class.
39  *
40  * @author <a HREF="stalep@conduct.no">Stale W. Pedersen</a>
41  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
42  * @version $Revision:
43  */

44 public class SuperClassesFirstWeavingStrategy extends WeavingStrategySupport {
45
46     private boolean verbose = AspectManager.verbose;
47     public static final String JavaDoc AOP_PACKAGE = Advised.class.getPackage().getName();
48
49    public byte[] translate(AspectManager manager, String JavaDoc className, ClassLoader JavaDoc loader, byte[] classfileBuffer) throws Exception JavaDoc
50     {
51         if (isReEntry())
52         {
53             return null;
54         }
55         setReEntry();
56         manager.transformationStarted = true;
57         try
58         {
59             if (manager.isNonAdvisableClassName(className))
60             {
61                 return null;
62             }
63
64             AOPClassPool pool = (AOPClassPool) manager.registerClassLoader(loader);
65
66             CtClassTransformationInfo info = obtainCtClassInfo(pool, className, classfileBuffer);
67             CtClass clazz = instrumentClass(manager, pool, info, true);
68             if (clazz != null)
69             {
70                 pool.lockInCache(info.getClazz());
71             if (AspectManager.debugClasses)
72             {
73                info.getClazz().debugWriteFile();
74             }
75                 byte[] rtn = info.getClazz().toBytecode();
76                 if (AspectManager.getPrune()) info.getClazz().prune();
77                 return rtn;
78             }
79             else
80             {
81                 pool.soften(info.getClazz());
82             }
83             return null;
84         }
85         catch (Exception JavaDoc ex)
86         {
87             if (!(ex instanceof NotFoundException))
88             {
89                 if (verbose)
90                     ex.printStackTrace();
91                 else
92                     System.err.println("[error] " + ex.getMessage() +
93                                        ".. Do verbose mode if you want full stack trace.");
94
95             }
96             throw ex;
97         }
98         finally
99         {
100             clearReEntry();
101         }
102     }
103
104     private CtClassTransformationInfo obtainCtClassInfo(AOPClassPool pool, String JavaDoc className, byte[] classfileBuffer) throws NotFoundException
105     {
106         try
107         {
108             return new CtClassTransformationInfo(pool.getLocally(className), className);
109         }
110         catch (NotFoundException e)
111         {
112             // todo Bill Burke: this scares the shit out of me, but it must be done
113
// I think it will screw up hotdeployment at some time. Then again, maybe not ;)
114
ByteArrayClassPath cp = new ByteArrayClassPath(className, classfileBuffer);
115             pool.insertClassPath(cp);
116             return new CtClassTransformationInfo(pool.getLocally(className), className);
117         }
118       catch(Error JavaDoc e)
119       {
120          return null;
121       }
122     }
123
124     private CtClass instrumentClass(AspectManager manager, AOPClassPool pool, CtClassTransformationInfo info, boolean isLoadedClass) throws NotFoundException, Exception JavaDoc
125     {
126         try
127         {
128             CtClass superClass = info.getClazz().getSuperclass();
129             if (superClass != null && !Instrumentor.implementsAdvised(info.getClazz()))
130             {
131                 CtClassTransformationInfo superInfo = new CtClassTransformationInfo(superClass, superClass.getName());
132
133             ClassPool superPool = superClass.getClassPool();
134             if (superPool instanceof AOPClassPool)
135             {
136                AspectManager aspectManager = manager;
137                if (manager instanceof Domain && superPool != pool)
138                {
139                   //We are in a scoped classloader and the superclass is not
140
aspectManager = AspectManager.instance(superPool.getClassLoader());
141                }
142                instrumentClass(aspectManager, (AOPClassPool)superPool, superInfo, false);
143             }
144             }
145
146             if (manager.isNonAdvisableClassName(info.getClassName()))
147             {
148                 return null;
149             }
150
151             if (info.getClass().isArray())
152             {
153                 if (verbose) System.out.println("[cannot compile] isArray: " + info.getClassName());
154                 pool.flushClass(info.getClassName());
155                 return null;
156             }
157             if (info.getClazz().isInterface())
158             {
159                 if (verbose) System.out.println("[cannot compile] isInterface: " + info.getClassName());
160                 //pool.flushClass(info.getClassName());
161
info.getClazz().prune();
162                 return null;
163             }
164             if (info.getClazz().isFrozen())
165             {
166                 if(isAdvised(pool, info.getClazz()))
167                     return null;
168                 if (verbose) System.out.println("[warning] isFrozen: " + info.getClassName() + " " + info.getClazz().getClassPool());
169                 if (!isLoadedClass)
170                 {
171                     info = obtainCtClassInfo(pool, info.getClassName(), null);
172                 }
173                 else
174                     return null;
175                 //info.getClazz().defrost();
176
}
177
178          boolean transformed = info.getClazz().isModified();
179          if (!transformed)
180          {
181             ClassAdvisor advisor =
182                    AdvisorFactory.getClassAdvisor(info.getClazz(), manager);
183                 Instrumentor instrumentor = InstrumentorFactory.getInstrumentor(
184                       pool,
185                   manager,
186                   manager.dynamicStrategy.getJoinpointClassifier(),
187                   manager.dynamicStrategy.getDynamicTransformationObserver(info.getClazz()));
188
189                 if (!Instrumentor.isTransformable(info.getClazz()))
190                 {
191                     if (verbose) System.out.println("[cannot compile] implements Untransformable: " + info.getClassName());
192                     //Flushing the generated invocation classes breaks things further down the line
193
//pool.flushClass(info.getClassName());
194
return null;
195                 }
196
197             manager.attachMetaData(advisor, info.getClazz(), true);
198             manager.applyInterfaceIntroductions(advisor, info.getClazz());
199                 transformed = instrumentor.transform(info.getClazz(), advisor);
200          }
201             if (transformed)
202             {
203                 if (!isLoadedClass )
204                 {
205                     info.setTransformed(transformed);
206                 }
207                 return info.getClazz();
208             }
209             return null;
210         }
211         catch(Exception JavaDoc e)
212         {
213             throw new RuntimeException JavaDoc("Error converting class ", e);
214         }
215         finally
216         {
217         }
218     }
219
220     public boolean isAdvised(ClassPool pool, CtClass clazz) throws NotFoundException
221     {
222        CtClass[] interfaces = clazz.getInterfaces();
223        CtClass advised = pool.get(AOP_PACKAGE + ".Advised");
224        for (int i = 0; i < interfaces.length; i++)
225        {
226           if (interfaces[i].equals(advised)) return true;
227           if (interfaces[i].getName().equals(AOP_PACKAGE + ".Advised")) return true;
228        }
229        return false;
230     }
231
232
233     private class CtClassTransformationInfo
234     {
235         boolean transformed;
236         CtClass clazz;
237         String JavaDoc className;
238         private CtClassTransformationInfo(CtClass clazz, String JavaDoc className)
239         {
240             this.clazz = clazz;
241             this.className = className;
242         }
243
244         private CtClassTransformationInfo(CtClass clazz, String JavaDoc className, boolean transformed)
245         {
246             this.clazz = clazz;
247             this.className = className;
248             this.transformed = transformed;
249         }
250
251         private CtClass getClazz()
252         {
253             return clazz;
254         }
255
256         private boolean isTransformed()
257         {
258             return transformed;
259         }
260
261         private void setTransformed(boolean transformed)
262         {
263             this.transformed = transformed;
264         }
265
266         private String JavaDoc getClassName()
267         {
268             return className;
269         }
270     }
271
272
273 }
274
Popular Tags