/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

import java.io.IOException;

import org.apache.bcel.Constants;
import org.apache.bcel.generic.ALOAD;
import org.apache.bcel.generic.ASTORE;
import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GOTO;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.LocalVariableGen;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;

/**
 * Create HelloWorld class:
 * <PRE>
 * import java.io.*;
 *
 * public class HelloWorld {
 *     public static void main(String[] argv) {
 *         BufferedReader in   = new BufferedReader(new InputStreamReader(System.in));
 *         String name = null;
 * 
 *         try {
 *             System.out.print("Please enter your name> ");
 *             name = in.readLine();
 *         } catch(IOException e) { 
 *             System.out.println(e);
 *             return; 
 *         }
 * 
 *         System.out.println("Hello, " + name);
 *     }
 * }
 * </PRE>
 *
 * @version $Id$
 */
public class HelloWorldBuilder {
    public static void main(String[] argv) {
        ClassGen cg = new ClassGen("HelloWorld", "java.lang.Object",
                "<generated>", Constants.ACC_PUBLIC |
                Constants.ACC_SUPER,
                null);
        ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
        InstructionList il = new InstructionList();
        MethodGen 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
                il, cp);
        InstructionFactory factory = new InstructionFactory(cg);

        ObjectType i_stream = new ObjectType("java.io.InputStream");
        ObjectType p_stream = new ObjectType("java.io.PrintStream");

        // Create BufferedReader object and store it in local variable `in'.
        il.append(factory.createNew("java.io.BufferedReader"));
        il.append(InstructionConstants.DUP); // Use predefined constant, i.e. flyweight
        il.append(factory.createNew("java.io.InputStreamReader"));
        il.append(InstructionConstants.DUP);
        il.append(factory.createFieldAccess("java.lang.System", "in", i_stream, Constants.GETSTATIC));

        // Call constructors, i.e. BufferedReader(InputStreamReader())
        il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",
                Type.VOID, new Type[]{i_stream},
                Constants.INVOKESPECIAL));
        il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID,
                new Type[]{new ObjectType("java.io.Reader")},
                Constants.INVOKESPECIAL));

        // Create local variable `in'
        LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
        int in = lg.getIndex();
        lg.setStart(il.append(new ASTORE(in))); // `i' valid from here

        // Create local variable `name'
        lg = mg.addLocalVariable("name", Type.STRING, null, null);
        int name = lg.getIndex();
        il.append(InstructionConstants.ACONST_NULL);
        lg.setStart(il.append(new ASTORE(name))); // `name' valid from here

        // try { ...
        InstructionHandle try_start =
                il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));

        il.append(new PUSH(cp, "Please enter your name> "));
        il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID,
                new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL));
        il.append(new ALOAD(in));
        il.append(factory.createInvoke("java.io.BufferedReader", "readLine",
                Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
        il.append(new ASTORE(name));

        // Upon normal execution we jump behind exception handler, the target address is not known yet.
        GOTO g = new GOTO(null);
        InstructionHandle try_end = il.append(g);

        /* } catch() { ... }
         * Add exception handler: print exception and return from method
         */
        InstructionHandle handler =
                il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));
        // Little trick in order not to save exception object temporarily
        il.append(InstructionConstants.SWAP);

        il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[]{Type.OBJECT}, Constants.INVOKEVIRTUAL));
        il.append(InstructionConstants.RETURN);
        mg.addExceptionHandler(try_start, try_end, handler, new ObjectType("java.io.IOException"));

        // Normal code continues, now we can set the branch target of the GOTO that jumps over the handler code.
        InstructionHandle ih =
                il.append(factory.createFieldAccess("java.lang.System", "out", p_stream, Constants.GETSTATIC));
        g.setTarget(ih);

        // String concatenation compiles to StringBuffer operations.
        il.append(factory.createNew(Type.STRINGBUFFER));
        il.append(InstructionConstants.DUP);
        il.append(new PUSH(cp, "Hello, "));
        il.append(factory.createInvoke("java.lang.StringBuffer", "<init>",
                Type.VOID, new Type[]{Type.STRING},
                Constants.INVOKESPECIAL));
        il.append(new ALOAD(name));
    
        // Concatenate strings using a StringBuffer and print them.
        il.append(factory.createInvoke("java.lang.StringBuffer", "append",
                Type.STRINGBUFFER, new Type[]{Type.STRING},
                Constants.INVOKEVIRTUAL));
        il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
                Type.STRING, Type.NO_ARGS,
                Constants.INVOKEVIRTUAL));

        il.append(factory.createInvoke("java.io.PrintStream", "println",
                Type.VOID, new Type[]{Type.STRING},
                Constants.INVOKEVIRTUAL));

        il.append(InstructionConstants.RETURN);

        mg.setMaxStack(5); // Needed stack size
        cg.addMethod(mg.getMethod());

        il.dispose(); // Reuse instruction handles

        // Add public <init> method, i.e. empty constructor
        cg.addEmptyConstructor(Constants.ACC_PUBLIC);

        // Get JavaClass object and dump it to file.
        try {
            cg.getJavaClass().dump("HelloWorld.class");
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}
