/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): Nicolas Christin
 * Contributor(s): ______________________________________.
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.newbean;


import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;


/**
 * This class is a &ldquo;bean generator&rdquo;. It uses Velocity and
 * a set of template files to generate some files that can serve as a
 * startup point for the developpement of a new bean.
 */
public class NewBean {

    private static final int EXIT_SUCCESS = 0;
    private static final int EXIT_FAILURE = 1;

    private VelocityEngine  vEngine  = null;
    private VelocityContext vContext = null;


    private NewBean() {

        // Creates and initializes a Velocity engine
        vEngine = new VelocityEngine();
        vEngine.setProperty(VelocityEngine.VM_LIBRARY, "");
        vEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
        vEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH,
                            System.getProperty("install.root")
                            + "/" + "templates" + "/" + "newbean");
        try {
            vEngine.init();
        } catch (Exception e) {
            fatalError("unable to initilise Velocity engine (" + e + ")");
        }

        // Creates a Velocity context and populates it by walking
        // through the parameter set
        vContext = new VelocityContext();
        ParameterSet parameterSet = new ParameterSet(vContext);
        parameterSet.walkThrough();

        // Generates files
        generate();

    }


    /**
     * Generates files for this new bean.
     */
    private void generate() {

        // Gets some useful information from Velocity's context
        final Integer MESSAGE_DRIVEN_BEAN =
            (Integer)vContext.get("MESSAGE_DRIVEN_BEAN");
        String beanName = (String)vContext.get("beanName");
        String beanType = (String)vContext.get("beanType");
        String pkgName = (String)vContext.get("pkgName");
        String jarName = (String)vContext.get("jarName");
        Integer beanFlavor = (Integer)vContext.get("beanFlavor");


        System.out.println("Creating bean "
                           + beanName
                           + " (type "
                           + beanType
                           + ") in package "
                           + pkgName);
	
        // Generates bean files
        try {
            boolean isClientToGenerate = true;
            generate("ejb-jar.vm", jarName + ".xml");
            generate("jonas-ejb-jar.vm", "jonas-" + jarName + ".xml");
            if (beanFlavor != MESSAGE_DRIVEN_BEAN) {
                String local = "";
                Boolean isLocal = (Boolean)vContext.get("isLocal");
                if (isLocal.booleanValue()) {
                    local = "Local";
                    isClientToGenerate = false;
                }
                generate("remote.vm", beanName + local + ".java");
                generate("home.vm", beanName + local + "Home.java");
            }
            generate("bean.vm", beanName + beanType + ".java");
            if (isClientToGenerate) {
                generate("client.vm", beanName + "Client.java");
            }
            generate("build.vm", "build.xml");
            System.out.println("Your bean files have been created. You can now customize them.");
        } catch (Exception e) {
            error(e.toString());
        }
	
    }


    /**
     * Generates a file from the specified template.
     * @param templateFileName the name of the template file
     * @param targetFileName the name of the generated file
     */
    private void generate(String templateFileName,
                          String targetFileName) throws Exception, IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {
        FileWriter fileWriter = null;
        fileWriter = new FileWriter(targetFileName);
        vEngine.mergeTemplate(templateFileName, vContext, fileWriter);
        fileWriter.close();
    }

	public static HashMap	commandLine = new HashMap();

	private static void		putCmdArgsInHashmap( String[] args )
	{
		for( int i=0; i<args.length; i++ ) {
			String	key = args[i];
			if( key.startsWith("-") ) {
				String	val = null;
				if( i+1<args.length
				&&  !args[i+1].startsWith("-") ) {
					val = args[i+1];
					i++;
				}
				commandLine.put( key, val );
			}
		}
	}

    public static void	main( String[] args ) {

		if( args.length > 0 ) {
			// save the command line arguments so that we don't
			// have to be interactive when called from JOPE
			putCmdArgsInHashmap(args);
		}

        new NewBean();
    }


    /**
     * Display the specified error message.
     * @param errMsg the error message to display
     */
    static void error(String errMsg) {
        System.err.println("NewBean error: " + errMsg);
    }


    /**
     * Display the specified error message and exits with an
     * EXIT_FAILURE status.
     * @param errMsg the error message to display
     */
    static void fatalError(String errMsg) {
        System.err.println("NewBean fatal error: " + errMsg);
        System.exit(EXIT_FAILURE);
    }

}
