/*
 * @(#)CreateMainClassHelper.java
 *
 * Copyright (C) 2003 Matt Albrecht
 * groboclown@users.sourceforge.net
 * http://groboutils.sourceforge.net
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 *  DEALINGS IN THE SOFTWARE.
 */

package net.sourceforge.groboutils.codecoverage.v2;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.Type;



/**
 * Helper for creating a main class through bytecode.
 *
 * @author    Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
 * @version   $Date: 2004/04/15 05:48:27 $
 * @since     May 2, 2003
 */
public class CreateMainClassHelper
{
    private static final Class THIS_CLASS = CreateMainClassHelper.class;
    
    private String className;
    private ClassGen cg;
    private MethodGen mg;
    
    private JavaClass jc;
    private byte[] bytecode;
    
    public ConstantPoolGen cp;
    public InstructionList il;
    public InstructionFactory factory;
    
    
    
    public CreateMainClassHelper( String className )
    {
        this.className = className;
        
        this.cg = new ClassGen( className,
            Object.class.getName(), "<generated>",
            Constants.ACC_PUBLIC | Constants.ACC_SUPER, null );
        this.cp = this.cg.getConstantPool();
        this.il = new InstructionList();
        this.mg = new MethodGen(
            Constants.ACC_STATIC | Constants.ACC_PUBLIC, // access flags
            Type.VOID,               // return type
            new Type[] {             // argument types
                new ArrayType(Type.STRING, 1) },
            new String[] { "argv" }, // arg names
            "main", "HelloWorld",    // method, class
            this.il, this.cp );
        this.factory = new InstructionFactory( this.cg );
    }
    
    
    public void close()
            throws IOException
    {
        this.mg.setMaxStack();
        this.cg.addMethod( this.mg.getMethod() );
        this.il.dispose();
        this.cg.addEmptyConstructor( Constants.ACC_PUBLIC );
        
        this.il = null;
        this.mg = null;
        this.cp = null;
        
        this.jc = cg.getJavaClass();
        
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        this.jc.dump( baos );
        this.bytecode = baos.toByteArray();
    }
    
    
    public JavaClass getJavaClass()
    {
        return this.jc;
    }
    
    
    public byte[] getBytecode()
    {
        return this.bytecode;
    }
    
    
    public Class getGenClass()
            throws ClassNotFoundException
    {
        Class cc = BytecodeLoaderUtil.loadClassFromBytecode(
            this.className, this.bytecode );
        return cc;
    }
    
}

