169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.tools.rmi;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.*;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.lang.reflect.Method;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Hashtable;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtMethod.ConstParameter;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A stub-code generator.  It is used for producing a proxy class.
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The proxy class for class A is as follows:
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>public class A implements Proxy, Serializable {
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   private ObjectImporter importer;
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   private int objectId;
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   public int _getObjectId() { return objectId; }
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   public A(ObjectImporter oi, int id) {
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *     importer = oi; objectId = id;
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   }
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   ... the same methods that the original class A declares ...
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }</pre></ul>
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Instances of the proxy class is created by an
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>ObjectImporter</code> object.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class StubGenerator implements Translator {
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String fieldImporter = "importer";
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String fieldObjectId = "objectId";
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String accessorObjectId = "_getObjectId";
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String sampleClass = "javassist.tools.rmi.Sample";
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private ClassPool classPool;
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Hashtable proxyClasses;
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtMethod forwardMethod;
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtMethod forwardStaticMethod;
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass[] proxyConstructorParamTypes;
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass[] interfacesForProxy;
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass[] exceptionForProxy;
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs a stub-code generator.
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public StubGenerator() {
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxyClasses = new Hashtable();
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Initializes the object.
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This is a method declared in javassist.Translator.
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.Translator#start(ClassPool)
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void start(ClassPool pool) throws NotFoundException {
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        classPool = pool;
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass c = pool.get(sampleClass);
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        forwardMethod = c.getDeclaredMethod("forward");
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        forwardStaticMethod = c.getDeclaredMethod("forwardStatic");
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxyConstructorParamTypes
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = pool.get(new String[] { "javassist.tools.rmi.ObjectImporter",
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                         "int" });
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        interfacesForProxy
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = pool.get(new String[] { "java.io.Serializable",
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                         "javassist.tools.rmi.Proxy" });
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        exceptionForProxy
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = new CtClass[] { pool.get("javassist.tools.rmi.RemoteException") };
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Does nothing.
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * This is a method declared in javassist.Translator.
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.Translator#onLoad(ClassPool,String)
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void onLoad(ClassPool pool, String classname) {}
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns <code>true</code> if the specified class is a proxy class
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * recorded by <code>makeProxyClass()</code>.
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param name              a fully-qualified class name
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean isProxyClass(String name) {
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return proxyClasses.get(name) != null;
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Makes a proxy class.  The produced class is substituted
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * for the original class.
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param clazz             the class referenced
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                          through the proxy class.
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @return          <code>false</code> if the proxy class
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                  has been already produced.
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public synchronized boolean makeProxyClass(Class clazz)
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException, NotFoundException
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String classname = clazz.getName();
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (proxyClasses.get(classname) != null)
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return false;
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else {
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CtClass ctclazz = produceProxyClass(classPool.get(classname),
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                                clazz);
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            proxyClasses.put(classname, ctclazz);
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            modifySuperclass(ctclazz);
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return true;
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass produceProxyClass(CtClass orgclass, Class orgRtClass)
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException, NotFoundException
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int modify = orgclass.getModifiers();
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (Modifier.isAbstract(modify) || Modifier.isNative(modify)
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            || !Modifier.isPublic(modify))
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new CannotCompileException(orgclass.getName()
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        + " must be public, non-native, and non-abstract.");
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass proxy = classPool.makeClass(orgclass.getName(),
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              orgclass.getSuperclass());
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.setInterfaces(interfacesForProxy);
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtField f
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = new CtField(classPool.get("javassist.tools.rmi.ObjectImporter"),
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                          fieldImporter, proxy);
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        f.setModifiers(Modifier.PRIVATE);
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.addField(f, CtField.Initializer.byParameter(0));
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        f = new CtField(CtClass.intType, fieldObjectId, proxy);
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        f.setModifiers(Modifier.PRIVATE);
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.addField(f, CtField.Initializer.byParameter(1));
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.addMethod(CtNewMethod.getter(accessorObjectId, f));
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.addConstructor(CtNewConstructor.defaultConstructor(proxy));
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtConstructor cons
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = CtNewConstructor.skeleton(proxyConstructorParamTypes,
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                        null, proxy);
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        proxy.addConstructor(cons);
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            addMethods(proxy, orgRtClass.getMethods());
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return proxy;
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (SecurityException e) {
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new CannotCompileException(e);
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass toCtClass(Class rtclass) throws NotFoundException {
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String name;
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (!rtclass.isArray())
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            name = rtclass.getName();
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else {
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            StringBuffer sbuf = new StringBuffer();
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            do {
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                sbuf.append("[]");
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                rtclass = rtclass.getComponentType();
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } while(rtclass.isArray());
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            sbuf.insert(0, rtclass.getName());
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            name = sbuf.toString();
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return classPool.get(name);
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private CtClass[] toCtClass(Class[] rtclasses) throws NotFoundException {
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int n = rtclasses.length;
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass[] ctclasses = new CtClass[n];
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < n; ++i)
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ctclasses[i] = toCtClass(rtclasses[i]);
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return ctclasses;
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* ms must not be an array of CtMethod.  To invoke a method ms[i]
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * on a server, a client must send i to the server.
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void addMethods(CtClass proxy, Method[] ms)
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException, NotFoundException
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtMethod wmethod;
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (int i = 0; i < ms.length; ++i) {
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            Method m = ms[i];
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int mod = m.getModifiers();
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (m.getDeclaringClass() != Object.class
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        && !Modifier.isFinal(mod))
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (Modifier.isPublic(mod)) {
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    CtMethod body;
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (Modifier.isStatic(mod))
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        body = forwardStaticMethod;
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    else
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        body = forwardMethod;
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    wmethod
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        = CtNewMethod.wrapped(toCtClass(m.getReturnType()),
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              m.getName(),
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              toCtClass(m.getParameterTypes()),
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              exceptionForProxy,
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              body,
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              ConstParameter.integer(i),
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                              proxy);
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    wmethod.setModifiers(mod);
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    proxy.addMethod(wmethod);
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else if (!Modifier.isProtected(mod)
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                         && !Modifier.isPrivate(mod))
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    // if package method
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    throw new CannotCompileException(
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        "the methods must be public, protected, or private.");
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Adds a default constructor to the super classes.
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void modifySuperclass(CtClass orgclass)
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws CannotCompileException, NotFoundException
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass superclazz;
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        for (;; orgclass = superclazz) {
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            superclazz = orgclass.getSuperclass();
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (superclazz == null)
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                superclazz.getDeclaredConstructor(null);
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                break;  // the constructor with no arguments is found.
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (NotFoundException e) {
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            superclazz.addConstructor(
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        CtNewConstructor.defaultConstructor(superclazz));
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
256