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 test.aopc;
9   
10  import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
11  
12  import java.io.File;
13  import java.lang.reflect.Array;
14  import java.lang.reflect.Method;
15  import java.net.MalformedURLException;
16  import java.net.URL;
17  import java.net.URLClassLoader;
18  
19  /***
20   * Test helper for AspectContainer, emulates a ClassLoader hierarchy sys/sub/ sys/sub/a sys/sub/b
21   *
22   * FIXME - rewrite with ASM
23   *
24   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
25   */
26  public class ClassCreator {
27      /***
28       * ClassLoader.defineClass(name, bytes, from, to)
29       */
30      private static Method CLASSLOADER_DEFINECLASS_METHOD;
31  
32      static {
33          try {
34              Object b = Array.newInstance(byte.class, 1);
35              CLASSLOADER_DEFINECLASS_METHOD = ClassLoader.class.getDeclaredMethod(
36                      "defineClass",
37                      new Class[]{
38                          String.class, b.getClass(), int.class, int.class
39                      }
40              );
41              CLASSLOADER_DEFINECLASS_METHOD.setAccessible(true);
42          } catch (Throwable t) {
43              t.printStackTrace();
44          }
45      }
46  
47      public static Object createInstance(String name, Class classPrototype, ClassLoader loader) {
48          try {
49              return createClass(name, classPrototype, loader).newInstance();
50          } catch (Throwable t) {
51              throw new WrappedRuntimeException(t);
52          }
53      }
54  
55      public static Class createClass(String name, Class classPrototype, ClassLoader loader) {
56          return classPrototype;
57  //        try {
58  //            ClassPool cp = new ClassPool(null);
59  //            cp.appendClassPath(new LoaderClassPath(loader));
60  //            CtClass prototype = cp.get(classPrototype.getName());
61  //            prototype.setName(name);
62  //            return define(prototype.toBytecode(), name, loader);
63  //        } catch (Throwable throwable) {
64  //            throw new WrappedRuntimeException(throwable);
65  //        }
66      }
67  
68      public static void main(String[] a) throws Throwable {
69          ClassLoader myCL = new URLClassLoader(
70                  new URL[]{
71                      getPathFor(Callable.class.getResource("META-INF/aop.xml"))
72                  }, ClassLoader.getSystemClassLoader()
73          );
74          ClassLoader mySubCLA = new URLClassLoader(
75                  new URL[]{
76                      getPathFor(Callable.class.getResource("a/META-INF/aop.xml"))
77                  }, myCL
78          );
79          Callable ca = (Callable) (createClass("test.aopc.a.Callee", CallablePrototype.class, mySubCLA)).newInstance();
80          ca.methodAround();
81          ca.debug();
82          ClassLoader mySubCLB = new URLClassLoader(new URL[]{}, myCL);
83          Callable cb = (Callable) (createClass("test.aopc.b.Callee", CallablePrototype.class, mySubCLB)).newInstance();
84          cb.methodAround();
85          cb.debug();
86      }
87  
88      public static URL getPathFor(URL definition) {
89          try {
90              System.out.println(definition);
91              System.out.println(definition.getFile());
92              File f = new File(definition.getFile());
93              if (!f.exists()) {
94                  System.err.println("<WARN> could not find " + f);
95              }
96              String path = new File(f.getParent()).getParent();
97              File testExists = new File(path);
98              if (!testExists.isDirectory()) {
99                  System.err.println("<WARN> could not find " + path);
100             }
101             return new File(path).toURL();
102         } catch (MalformedURLException e) {
103             throw new WrappedRuntimeException(e);
104         }
105     }
106 
107     /***
108      * Helper to define a Class within a specific ClassLoader
109      *
110      * @param b
111      * @param name
112      * @param loader
113      * @return @throws Throwable
114      */
115     public static Class define(byte[] b, String name, ClassLoader loader) throws Throwable {
116         Object k = CLASSLOADER_DEFINECLASS_METHOD.invoke(
117                 loader, new Object[]{
118                     name, b, new Integer(0), new Integer(b.length)
119                 }
120         );
121         return (Class) k;
122     }
123 }