/* * Copyright 2007 Wishnu Prasetya. * * This file is part of T2. * T2 is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License (GPL) as published by the * Free Software Foundation; either version 3 of the License, or any * later version. * * T2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * A copy of the GNU General Public License can be found in T2 distribution. * If it is missing, see http://www.gnu.org/licenses. */ package Sequenic.T2.Seq; import java.io.IOException; import java.io.NotSerializableException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.LinkedList; import java.util.List; import Sequenic.P2.StringFormater; import Sequenic.T2.Pool; import Sequenic.T2.Msg.T2Error; import Sequenic.T2.export.Visitor; /** * This represents a MkVal-step in which an object is created by calling a * constructor P. The constructor will be remembered in this step. * We also keep track of the MkVal steps needed to create the * objects needed as the parameters for P. */ public class CREATE_OBJECT extends MkValStep { private static final long serialVersionUID = 476426L; public Constructor con; public MkValStep[] params; /** * Set this to -1 if the index is still unknown. */ public int indexOfNewObject; /** * @param c The constructor used in this step. * @param ps MkVal steps needed to generate parameters for c. * @param index The Pool-ID of the newly created object. */ public CREATE_OBJECT(Constructor c, MkValStep[] ps, int index) { con = c; params = ps; indexOfNewObject = index; } /** * Execute the step. This is the worker-exec. The "args" parameter will be * filled with the actual arguments passed to the constructor. */ private Object exec(Class CUT, Pool pool, List arglist) throws InvocationTargetException { if (arglist != null) arglist.clear() ; Object[] args = new Object[params.length]; for (int i = 0; i < params.length; i++) { args[i] = params[i].exec(CUT,pool); if (arglist != null) arglist.add(args[i]) ; } Object newobject = null; con.setAccessible(true); try { newobject = con.newInstance(args); } catch (InvocationTargetException e) { if (con.getDeclaringClass() == CUT) throw new CUT_Constructor_failure(e.getCause(),this) ; else throw e ; } catch (Exception e) { // System.out.println("## " + step_.con.getName()) ; // System.out.println("## " + Show.show(e)) ; throw new T2Error("Fail to create object via constructor " + this, e); } int index = pool.put(newobject); if (indexOfNewObject == -1) { indexOfNewObject = index; } assert (index == indexOfNewObject); return newobject; } public Object exec(Class CUT, Pool pool) throws InvocationTargetException { try { return exec(CUT,pool,null) ; } catch (CUT_Constructor_failure e) { // Swallow CUT-cons failure exception, rethrow invoc-target-exc: throw new InvocationTargetException(e.getCause()) ; } catch (InvocationTargetException e) { throw e ; } } /** * Like exec, but special for producing target object. */ public ExecResult MkTargetObject(Class CUT, Pool pool, List classinvs, ReportersPool reporters) { ExecResult result = new ExecResult(CUT,this,null) ; // Execute the step: try { List arglist = new LinkedList() ; result.targetObj = exec(CUT,pool,arglist); if (arglist.size() > 0) { result.args = new Object[arglist.size()] ; for (int i=0 ; i