/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */ package javassist; import javassist.bytecode.*; import javassist.compiler.Javac; import javassist.compiler.CompileError; import javassist.CtMethod.ConstParameter; /** * A collection of static methods for creating a CtConstructor. * An instance of this class does not make any sense. * *

A class initializer (static constructor) cannot be created by the * methods in this class. Call makeClassInitializer() in * CtClass and append code snippet to the body of the class * initializer obtained by makeClassInitializer(). * * @see CtClass#addConstructor(CtConstructor) * @see CtClass#makeClassInitializer() */ public class CtNewConstructor { /** * Specifies that no parameters are passed to a super-class' * constructor. That is, the default constructor is invoked. */ public static final int PASS_NONE = 0; // call super() /** * Specifies that parameters are converted into an array of * Object and passed to a super-class' * constructor. */ public static final int PASS_ARRAY = 1; // an array of parameters /** * Specifies that parameters are passed as is * to a super-class' constructor. The signature of that * constructor must be the same as that of the created constructor. */ public static final int PASS_PARAMS = 2; /** * Compiles the given source code and creates a constructor. * The source code must include not only the constructor body * but the whole declaration. * * @param src the source text. * @param declaring the class to which the created constructor is added. */ public static CtConstructor make(String src, CtClass declaring) throws CannotCompileException { Javac compiler = new Javac(declaring); try { CtMember obj = compiler.compile(src); if (obj instanceof CtConstructor) { // a stack map table has been already created. return (CtConstructor)obj; } } catch (CompileError e) { throw new CannotCompileException(e); } throw new CannotCompileException("not a constructor"); } /** * Creates a public constructor. * * @param parameters a list of the parameter types. * @param exceptions a list of the exception types. * @param body the source text of the constructor body. * It must be a block surrounded by {}. * If it is null, the substituted * constructor body does nothing except calling * super(). * @param declaring the class to which the created method is added. */ public static CtConstructor make(CtClass[] parameters, CtClass[] exceptions, String body, CtClass declaring) throws CannotCompileException { try { CtConstructor cc = new CtConstructor(parameters, declaring); cc.setExceptionTypes(exceptions); cc.setBody(body); return cc; } catch (NotFoundException e) { throw new CannotCompileException(e); } } /** * Creates a copy of a constructor. * This is a convenience method for calling * {@link CtConstructor#CtConstructor(CtConstructor, CtClass, ClassMap) this constructor}. * See the description of the constructor for particular behavior of the copying. * * @param c the copied constructor. * @param declaring the class to which the created method is added. * @param map the hash table associating original class names * with substituted names. * It can be null. * * @see CtConstructor#CtConstructor(CtConstructor,CtClass,ClassMap) */ public static CtConstructor copy(CtConstructor c, CtClass declaring, ClassMap map) throws CannotCompileException { return new CtConstructor(c, declaring, map); } /** * Creates a default (public) constructor. * *

The created constructor takes no parameter. It calls * super(). */ public static CtConstructor defaultConstructor(CtClass declaring) throws CannotCompileException { CtConstructor cons = new CtConstructor((CtClass[])null, declaring); ConstPool cp = declaring.getClassFile2().getConstPool(); Bytecode code = new Bytecode(cp, 1, 1); code.addAload(0); try { code.addInvokespecial(declaring.getSuperclass(), "", "()V"); } catch (NotFoundException e) { throw new CannotCompileException(e); } code.add(Bytecode.RETURN); // no need to construct a stack map table. cons.getMethodInfo2().setCodeAttribute(code.toCodeAttribute()); return cons; } /** * Creates a public constructor that only calls a constructor * in the super class. The created constructor receives parameters * specified by parameters but calls the super's * constructor without those parameters (that is, it calls the default * constructor). * *

The parameters passed to the created constructor should be * used for field initialization. CtField.Initializer * objects implicitly insert initialization code in constructor * bodies. * * @param parameters parameter types * @param exceptions exception types * @param declaring the class to which the created constructor * is added. * @see CtField.Initializer#byParameter(int) */ public static CtConstructor skeleton(CtClass[] parameters, CtClass[] exceptions, CtClass declaring) throws CannotCompileException { return make(parameters, exceptions, PASS_NONE, null, null, declaring); } /** * Creates a public constructor that only calls a constructor * in the super class. The created constructor receives parameters * specified by parameters and calls the super's * constructor with those parameters. * * @param parameters parameter types * @param exceptions exception types * @param declaring the class to which the created constructor * is added. */ public static CtConstructor make(CtClass[] parameters, CtClass[] exceptions, CtClass declaring) throws CannotCompileException { return make(parameters, exceptions, PASS_PARAMS, null, null, declaring); } /** * Creates a public constructor. * *

If howto is PASS_PARAMS, * the created constructor calls the super's constructor with the * same signature. The superclass must contain * a constructor taking the same set of parameters as the created one. * *

If howto is PASS_NONE, * the created constructor calls the super's default constructor. * The superclass must contain a constructor taking no parameters. * *

If howto is PASS_ARRAY, * the created constructor calls the super's constructor * with the given parameters in the form of an array of * Object. The signature of the super's constructor * must be: * *

* *

Here, cvalue is the constant value specified * by cparam. * *

If cparam is null, the signature * must be: * *

* *

If body is not null, a copy of that method is * embedded in the body of the created constructor. * The embedded method is executed after * the super's constructor is called and the values of fields are * initialized. Note that body must not * be a constructor but a method. * *

Since the embedded method is wrapped * in parameter-conversion code * as in CtNewMethod.wrapped(), * the constructor parameters are * passed in the form of an array of Object. * The method specified by body must have the * signature shown below: * *

* *

If cparam is null, the signature * must be: * *

* *

Although the type of the returned value is Object, * the value must be always null. * *

Example: * *

* *

where the class Sample is as follows: * *

* *

This program produces the following class: * *

* * @param parameters a list of the parameter types * @param exceptions a list of the exceptions * @param howto how to pass parameters to the super-class' * constructor (PASS_NONE, * PASS_ARRAY, * or PASS_PARAMS) * @param body appended body (may be null). * It must be not a constructor but a method. * @param cparam constant parameter (may be null.) * @param declaring the class to which the created constructor * is added. * * @see CtNewMethod#wrapped(CtClass,String,CtClass[],CtClass[],CtMethod,CtMethod.ConstParameter,CtClass) */ public static CtConstructor make(CtClass[] parameters, CtClass[] exceptions, int howto, CtMethod body, ConstParameter cparam, CtClass declaring) throws CannotCompileException { return CtNewWrappedConstructor.wrapped(parameters, exceptions, howto, body, cparam, declaring); } }