KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > hook > impl > StdoutPreProcessor


1 /**************************************************************************************
2  * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.hook.impl;
9
10 import org.codehaus.aspectwerkz.hook.ClassPreProcessor;
11
12 import java.io.File JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.net.MalformedURLException JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.Enumeration JavaDoc;
19 import java.util.Hashtable JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.WeakHashMap JavaDoc;
24
25 /**
26  * A simple implementation of class preprocessor. <p/>It does not modify the bytecode. It just prints on stdout some
27  * messages.
28  *
29  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur </a>
30  */

31 public class StdoutPreProcessor implements ClassPreProcessor {
32     /**
33      * Classloaders repository, based on a synchronized weak hashmap key = classloader value = List of URL[]
34      * representing the local search path for .class files of the classloader value is completed at each class loading
35      */

36     private static Map JavaDoc classloaders;
37
38     /**
39      * ms interval betwee classloader hierarchy printing
40      */

41     private static final long stepms = 15000;
42
43     private static transient long lastPrinted = 0;
44
45     private void log(String JavaDoc s) {
46         System.out.println(Thread.currentThread().getName() + ": StdoutPreProcessor: " + s);
47     }
48
49     public void initialize() {
50         log("initialize");
51         log("loaded by " + this.getClass().getClassLoader());
52         classloaders = Collections.synchronizedMap(new WeakHashMap JavaDoc());
53
54         // register the classloader - except bootstrapCL
55
registerClassLoader(this.getClass().getClassLoader(), this.getClass().getName());
56     }
57
58     public byte[] preProcess(String JavaDoc klass, byte[] abyte, ClassLoader JavaDoc caller) {
59         // emulate a -verbose:class mode
60
klass = klass.replace('.', '/') + ".class";
61         URL JavaDoc u = caller.getResource(klass);
62         log("> " + klass + " [" + ((u == null) ? "?" : u.toString()) + "] [" + caller + "]");
63
64         /*
65          * URL uRoot = null; if (u!=null) { // u =
66          * jar:file:/C:/bea/weblogic81/server/lib/weblogic.jar!/weblogic/t3/srvr/T3Srvr.class // getPath =
67          * file:/C:/bea/weblogic81/server/lib/weblogic.jar!/weblogic/t3/srvr/T3Srvr.class // getFile =
68          * file:/C:/bea/weblogic81/server/lib/weblogic.jar!/weblogic/t3/srvr/T3Srvr.class int i =
69          * u.toString().indexOf('!'); if (i > 0) { try { uRoot = new URL(u.toString().substring(0, i)+"!/"); } catch
70          * (MalformedURLException e) { ; } } }
71          */

72         // register the classloader
73
registerClassLoader(caller, klass);
74
75         // complete the url path of the classloader
76
registerSearchPath(caller, klass);
77
78         // dump the hierarchy if needed
79
if (System.currentTimeMillis() > (lastPrinted + stepms)) {
80             lastPrinted = System.currentTimeMillis();
81             log("*******************************");
82             log("size=" + classloaders.size());
83             dumpHierarchy(null, "");
84             log("*******************************");
85         }
86         return abyte;
87     }
88
89     /**
90      * Register a weak reference on the classloader Looks for META-INF/manifest.mf resource and log a line
91      *
92      * @param loader
93      * @param firstClassLoaded
94      */

95     private void registerClassLoader(ClassLoader JavaDoc loader, String JavaDoc firstClassLoaded) {
96         if (loader != null) {
97             if (!classloaders.containsKey(loader)) {
98                 // register the loader and the parent hierarchy if not already registered
99
registerClassLoader(loader.getParent(), loader.getClass().getName());
100                 registerSearchPath(loader.getParent(), loader.getClass().getName());
101                 URL JavaDoc u = null;
102
103                 // *** THIS IS NOT WORKING for other than .class files
104
// *** since manifest.mf can be several time
105
// *** but getResource follow parent first delegation model
106
// try to locate the first META-INF/manifest.mf (should be the aw.xml)
107
// case sensitive of META-INF, meta-inf, Meta-Inf, Meta-inf ? YES IT IS
108
//u = loader.getResource("META-INF/MANIFEST.MF");
109
// *** THIS could be enough for early registration
110
// add resources in some struct, allow multiple deploy of same resource
111
// if in parallel CL hierarchy - got it ?
112
try {
113                     //@todo - case sensitive stuff is dangerous
114
// we could merge all aw.xml in META-INF and WEB-INF and meta-inf ...
115
Enumeration JavaDoc ue = loader.getResources("META-INF/MANIFEST.MF");
116                     if (ue.hasMoreElements()) {
117                         log("--- in scope for " + loader);
118                     }
119                     while (ue.hasMoreElements()) {
120                         log("--- " + ue.nextElement().toString());
121                     }
122                 } catch (IOException JavaDoc e) {
123                     ;
124                 }
125
126                 // register this loader
127
log("****" + loader + " [" + ((u == null) ? "?" : u.toString()) + "] [" + firstClassLoaded + ']');
128                 classloaders.put(loader, new ArrayList JavaDoc());
129             }
130
131             // register search path based on firstClassLoaded
132
}
133     }
134
135     /**
136      * Dumps on stdout the registered classloader hierarchy child of "parent" Using the depth to track recursivity level
137      */

138     private void dumpHierarchy(ClassLoader JavaDoc parent, String JavaDoc depth) {
139         // do a copy of the registered CL to allow access on classloaders structure
140
List JavaDoc cl = new ArrayList JavaDoc(classloaders.keySet());
141         ClassLoader JavaDoc current = null;
142         for (Iterator JavaDoc i = cl.iterator(); i.hasNext();) {
143             current = (ClassLoader JavaDoc) i.next();
144             if (current.getParent() == parent) {
145                 log(depth + current + '[' + classloaders.get(current));
146
147                 // handcheck for duplicate path (?)
148
List JavaDoc path = (List JavaDoc) classloaders.get(current);
149                 ClassLoader JavaDoc currentParent = current.getParent();
150                 while (currentParent != null) {
151                     for (Iterator JavaDoc us = path.iterator(); us.hasNext();) {
152                         URL JavaDoc u = (URL JavaDoc) us.next();
153                         if (((List JavaDoc) classloaders.get(currentParent)).contains(u)) {
154                             log("!!!! duplicate detected for " + u + " in " + current);
155                         }
156                     }
157                     currentParent = currentParent.getParent();
158                 }
159                 dumpHierarchy(current, depth + " ");
160             }
161         }
162     }
163
164     private void registerSearchPath(final ClassLoader JavaDoc loader, final String JavaDoc klass) {
165         // bootCL
166
if (loader == null) {
167             return;
168         }
169
170         // locate the klass
171
String JavaDoc klassFile = klass.replace('.', '/') + ".class";
172         URL JavaDoc uKlass = loader.getResource(klassFile);
173         if (uKlass == null) {
174             return;
175         }
176
177         // retrieve the location root (jar/zip or directory)
178
URL JavaDoc uRoot = null;
179         int i = uKlass.toString().indexOf('!');
180         if (i > 0) {
181             // jar/zip
182
try {
183                 // remove the jar: zip: prefix
184
//@todo !! zip: seems to be BEA specific
185
uRoot = (new File JavaDoc(uKlass.toString().substring(4, i))).getCanonicalFile().toURL();
186
187                 //uRoot = new URL(uKlass.toString().substring(0, i)+"!/");
188
} catch (MalformedURLException JavaDoc e) {
189                 e.printStackTrace();
190                 return;
191             } catch (IOException JavaDoc e2) {
192                 e2.printStackTrace();
193                 return;
194             }
195         } else {
196             // directory
197
i = uKlass.toString().indexOf(klassFile);
198             try {
199                 uRoot = (new File JavaDoc(uKlass.toString().substring(0, i))).getCanonicalFile().toURL();
200             } catch (MalformedURLException JavaDoc e) {
201                 e.printStackTrace();
202                 return;
203             } catch (IOException JavaDoc e2) {
204                 e2.printStackTrace();
205                 return;
206             }
207         }
208
209         // check if the location is not in a parent
210
ClassLoader JavaDoc parent = loader.getParent();
211         while (parent != null) {
212             if (((List JavaDoc) classloaders.get(parent)).contains(uRoot)) {
213                 return;
214             }
215             parent = parent.getParent();
216         }
217
218         // add the location if not already registered
219
// @todo !! not thread safe
220
List JavaDoc path = (List JavaDoc) classloaders.get(loader);
221         if (!path.contains(uRoot)) {
222             log("adding path " + uRoot + " to " + loader);
223             path.add(uRoot);
224         }
225     }
226
227     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
228         URL JavaDoc u = new URL JavaDoc(
229                 "jar:file:/C:/bea/user_projects/domains/mydomain/myserver/.wlnotdelete/gallery/gallery-rar.jar!/"
230         );
231
232         // differ from a "/./"
233
URL JavaDoc u2 = new URL JavaDoc(
234                 "jar:file:/C:/bea/user_projects/domains/mydomain/./myserver/.wlnotdelete/gallery/gallery-rar.jar!/"
235         );
236         if (u.sameFile(u2)) {
237             System.out.println("same");
238         } else {
239             System.out.println("differ");
240         }
241     }
242 }
Popular Tags