/*
 * 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.File;
import java.util.Enumeration;
import java.util.Vector;

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.lib.BeanNaming;

/**
 *  This class allows to generate the sources 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,
 *  and the extended class of the Bean for persistence in case of entity with CMP,
 * of a given Enterprise Java Bean.
 */
public class BeanSources {

    // Home interface. May be null if not defined. (for David)
    private String ejbHomeFileName = null;

    // Remote interface. May be null if not defined. (for David)
    private String ejbRemoteFileName = null;

    // EJBObject (Remote). May be null if no Remote interface.
    private String wrpRemoteFileName = null;

    // EJBLocalObject (Local). May be null if no Local interface.
    private String wrpLocalFileName = null;

    // Home. May be null if no Home interface.
    private String wrpHomeFileName  = null;

    // LocalHome. May be null if no LocalHome interface.
    private String wrpLocalHomeFileName = null;

    // Handle (for Entity only)
    private String wrpHandleFileName = null;

    // Bean (for CMP Entity only)
    private String wrpBeanFileName = null;

    // Source objects used to generate classes
    private Vector sources;

    private String outdir = null; // directory where to place the generated files
    private BeanDesc dd = null;	// Bean Deployment Description
    private BeanNaming bn = null;  // Holds all names used for GenIC/EJBServer

    /**
     * GenIC Constructor
     *
     * @param     beanDescr      deployment descriptor of the bean
     * @param     dirOutputName  path of the directory where to place the generated files
     *                           (empty string "" if the output directory is the current directory)
     * @exception GenICException In error case
     */
    public BeanSources(BeanDesc beanDesc, String dirOutputName) throws GenICException {

	dd = beanDesc;
	outdir = dirOutputName;
	sources = new Vector();
	bn = new BeanNaming(dd);

	// Create and initialize the Velocity Engine
	String jonasRoot = System.getProperty("install.root");
	if (jonasRoot == null) {
	    throw new GenICException("System property 'install.root' not set");
	}
	String path2Tmpl = new String(jonasRoot + File.separatorChar + "templates"
					    + File.separatorChar + "genic");

	VelocityEngine ve = new VelocityEngine();
        ve.setProperty(VelocityEngine.VM_LIBRARY, "");
        ve.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
	ve.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, path2Tmpl);
	try {
	    ve.init();
	} catch (Exception e) {
	    throw new GenICException("Cannot initialize the Velocity engine ("
				     +e+")");
	}

	// generated Home 
	if (dd.getHomeClass() != null) {
	    ejbHomeFileName = dd.getHomeClass().getName().replace('.', File.separatorChar) + ".java";
	    if (outdir.length() > 0) {
		ejbHomeFileName = outdir + File.separatorChar + ejbHomeFileName;
		wrpHomeFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullWrpHomeName());
	    } else {
		wrpHomeFileName = bn.getWrpHomeName();
	    }
	    wrpHomeFileName = wrpHomeFileName.concat(".java");
	    sources.add(new Source(dd, bn, wrpHomeFileName, Source.HOME, ve));
	    // generated Handle for Remote Entity bean
	    if (dd instanceof EntityDesc) {
		if (outdir.length() > 0) {
		    wrpHandleFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullWrpHandleName());
		} else {
		    wrpHandleFileName = bn.getWrpHandleName();
		}
		wrpHandleFileName = wrpHandleFileName.concat(".java");
		sources.add(new Source(dd, bn, wrpHandleFileName, Source.ENTITY_HANDLE, ve));
	    }
	}

	// generated EJBObject (Remote)
	if (dd.getRemoteClass() != null) {
	    ejbRemoteFileName = dd.getRemoteClass().getName().replace('.', File.separatorChar) + ".java";
	    if (outdir.length() > 0) {
		ejbRemoteFileName = outdir + File.separatorChar + ejbRemoteFileName;
		wrpRemoteFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullWrpRemoteName());
	    } else {
		wrpRemoteFileName = bn.getWrpRemoteName();
	    }
	    wrpRemoteFileName = wrpRemoteFileName.concat(".java");
	    sources.add(new Source(dd, bn, wrpRemoteFileName, Source.REMOTE, ve));
	}

	// generated LocalHome 
	if (dd.getLocalHomeClass() != null) {
	    if (outdir.length() > 0) {
		wrpLocalHomeFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullWrpLocalHomeName());
	    } else {
		wrpLocalHomeFileName = bn.getWrpLocalHomeName();
	    }
	    wrpLocalHomeFileName = wrpLocalHomeFileName.concat(".java");
	    sources.add(new Source(dd, bn, wrpLocalHomeFileName, Source.LOCAL_HOME, ve));
	}

	// generated EJBLocalObject (Local)
	if (dd.getLocalClass() != null) {
	    if (outdir.length() > 0) {
		wrpLocalFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullWrpLocalName());
	    } else {
		wrpLocalFileName = bn.getWrpLocalName();
	    }
	    wrpLocalFileName = wrpLocalFileName.concat(".java");
	    sources.add(new Source(dd, bn, wrpLocalFileName, Source.LOCAL, ve));
	}

	// generated derived bean class for Entity Bean CMP 
	if (dd instanceof EntityJdbcCmpDesc) {
	    if (outdir.length() > 0) {
		wrpBeanFileName = outdir + File.separatorChar + BeanNaming.getPath(bn.getFullDerivedBeanName());
	    } else {
		wrpBeanFileName = bn.getDerivedBeanName();
	    }
	    wrpBeanFileName = wrpBeanFileName.concat(".java");
	    sources.add(new Source(dd, bn, wrpBeanFileName, Source.ENTITY_CMP_JDBC, ve));
	}
    }

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


	// Generates the java sources
	for (Enumeration e = sources.elements() ; e.hasMoreElements() ;) {
              Source src = (Source) e.nextElement();
	      src.generate();
	}
    }

    /**
     * Return the bean's name
     */
    public String getEjbName() {
	return dd.getEjbName();
    }

    /**
     * Return the file name of the generated source for the Home
     * (null if none)
     */
    public String getWrpHomeFileName() {
	return wrpHomeFileName;
    }

    /**
     * Return the file name of the generated source for the LocalHome
     * (null if none)
     */
    public String getWrpLocalHomeFileName() {
	return wrpLocalHomeFileName;
    }

    /**
     * Return the file name of the generated source for the Remote
     * (null if none)
     */
    public String getWrpRemoteFileName() {
	return wrpRemoteFileName;
    }

    /**
     * Return the file name of the generated source for the Local
     * (null if none)
     */
    public String getWrpLocalFileName() {
	return wrpLocalFileName;
    }

    /**
     * Return the file name of the generated source for the Entity Handle
     * (null if none)
     */
    public String getWrpHandleFileName() {
	return wrpHandleFileName;
    }

    /**
     * Return the file name of the generated source for the derived class of the CMP Entity
     * (null if none)
     */
    public String getWrpBeanFileName() {
	return wrpBeanFileName;
    }

    /**
     * Return the 'pseudo' source file name of the Remote interface
     * (DAVID only used: The Stub file name depends on this name)
     */
    public String getEjbRemoteFileName() {
	return ejbRemoteFileName;
    }

    /**
     * Return the 'pseudo' source file name of the Home interface
     * (DAVID only used: The Stub file name depends on this name)
     */
    public String getEjbHomeFileName() {
	return ejbHomeFileName;
    }

    /**
     * Return the class name of the generated source for the Remote (package included)
     */
    public String getWrpRemoteClassName() {
	return bn.getFullWrpRemoteName();
    }

    /**
     * Return the class name of the generated source for the Home (package included)
     */
    public String getWrpHomeClassName() {
	return bn.getFullWrpHomeName();
    }

}
