/*
 * 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): Helene Joanin
 * Contributor(s): ______________________________________.
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.objectweb.jonas_ejb.genic;

import java.io.FileWriter;
import java.io.IOException;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import org.objectweb.jonas_ejb.deployment.api.BeanDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityDesc;
import org.objectweb.jonas_ejb.deployment.api.EntityJdbcCmpDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatefulDesc;
import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc;
import org.objectweb.jonas_ejb.lib.BeanNaming;


/**
 * This class allows to generate the source of :
 *  the class that implements the Enterprise bean's remote interface,
 *  the class that implements the Enterprise bean's home interface,
 *  the class that implements the Enterprise bean's local interface,
 *  the class that implements the Enterprise bean's localhome interface,
 *  the class of the Entity Handle in case of entity,
 *  or the extended class of the Bean for persistence in case of entity with CMP,
 * via a Velocity template of the given Enterprise Java Bean.
 */
class Source {

    static final int HOME = 0;
    static final int LOCAL_HOME = 1;
    static final int REMOTE = 2;
    static final int LOCAL = 3;
    static final int ENTITY_HANDLE = 4;
    static final int ENTITY_CMP_JDBC = 5;


    private BeanDesc dd = null;	          // Bean Deployment Description
    private String srcFileName  = null;     // Name of the generated source file
    private int srcType;                   // Generated source file type
    private VelocityEngine vEngine = null;   // Velocity engine
    private VelocityContext vctx = null;     // Velocity context

    /**
     * SrcHome Constructor
     *
     * @param     beanDescr      deployment descriptor of the bean
     * @param     fileName       name of the source file to generate
     * @param     beanNames      naming conventions for the bean
     * @param     type            source's type (HOME, LOCAL_HOME, REMOTE, ...)
     * @param     ve              Velocity engine to use
     * @exception GenICException In error case
     */
    Source(BeanDesc beanDesc, BeanNaming beanNames,
	   String fileName, int type,
	   VelocityEngine ve)
	throws GenICException {

	dd = beanDesc;
	srcFileName = fileName;
	srcType = type;
	vctx = VContextFactory.create(dd, beanNames, srcType);
	vEngine = ve;

    }

    /**
     * Generates the java source
     */
    void generate() throws GenICException {

	String tmplName = null;
	Template tmpl = null;
	FileWriter fwriter = null;

	switch(srcType) {
	case HOME:
	    if (dd instanceof EntityDesc) {
		tmplName = "JEntityHome.vm";
	    } else if (dd instanceof SessionStatefulDesc) {
		tmplName = "JStatefulHome.vm";
	    } else if (dd instanceof SessionStatelessDesc) {
		tmplName = "JStatelessHome.vm";
	    }
	    break;
	case LOCAL_HOME:
	    if (dd instanceof EntityDesc) {
		tmplName = "JEntityLocalHome.vm";
	    } else if (dd instanceof SessionStatefulDesc) {
		tmplName = "JStatefulLocalHome.vm";
	    } else if (dd instanceof SessionStatelessDesc) {
		tmplName = "JStatelessLocalHome.vm";
	    }
	    break;
	case REMOTE:
	    if (dd instanceof EntityDesc) {
		tmplName = "JEntityRemote.vm";
	    } else if (dd instanceof SessionDesc) {
		tmplName = "JSessionRemote.vm";
	    }
	    break;
	case LOCAL:
	    if (dd instanceof EntityDesc) {
		tmplName = "JEntityLocal.vm";
	    } else if (dd instanceof SessionDesc) {
		tmplName = "JSessionLocal.vm";
	    }
	    break;
	case ENTITY_HANDLE:
	    if (dd instanceof EntityDesc) {
		tmplName = "JEntityHandle.vm";
	    }
	    break;
	case ENTITY_CMP_JDBC:
	    if (dd instanceof EntityJdbcCmpDesc) {
		tmplName = "JEntityCmpJdbc.vm";
	    }
	    break;
	}
	if (tmplName == null) {
	    throw new GenICException("No template for  '"+srcFileName+" !!!'");
	}

	try {
	    tmpl = vEngine.getTemplate(tmplName);
	} catch (Exception e) {
	    throw new GenICException("Cannot get the '"+tmplName+"' template file ("
				     +e+")");
	}

	try {
	    fwriter = new FileWriter(srcFileName);
	} catch (IOException e) {
	    throw new GenICException("Cannot create the '"+srcFileName
				     +"' source file ("+e+")");
	}

	try {
	    tmpl.merge(vctx, fwriter);
	} catch (Exception e) {
	    throw new GenICException("Cannot generate the '"+srcFileName
				     +"' source from the '"+tmplName+"' template ("
				     +e+")");
	}

	try {
	    fwriter.flush();
	    fwriter.close();
	} catch (IOException e) {
	    throw new GenICException("Cannot close the '"+srcFileName
				     +"' source file ("+e+")");
	}
    }

}
