/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.core;

import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.DOMElementHelper;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.util.XMLLoader;

public class Startup
{
  /*--------------------------------------------------------------------------------
   * Static data values
   *--------------------------------------------------------------------------------
   */

  private static Category logger = Category.getInstance(Startup.class);

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  private Startup()
  { // this class cannot be created
  } // end constructor

  /*--------------------------------------------------------------------------------
   * External static operations
   *--------------------------------------------------------------------------------
   */

  public static VeniceEngine createEngine(String configname, String app_root)
      throws ConfigException, DataException
  {
    XMLLoader loader = XMLLoader.get();

    // load the configuration data
    Document config = loader.loadConfigDocument(configname);

    // find the classname of the engine
    Element root = loader.configGetRootElement(config,"venice-config");
    Element sect = loader.configGetSubSection(root,"engine");
    String cname = loader.configGetSubElementText(sect,"classname");
    if (logger.isDebugEnabled())
      logger.debug("Venice engine classname: " + cname);

    try
    { // create a new Venice engine (cast to the external interface)
      VeniceEngine engine = (VeniceEngine)(Class.forName(cname).newInstance());

      if (logger.isDebugEnabled())
	logger.debug("VeniceEngine created successfully");

      // initialize the engine
      engine.initialize(config,app_root);

      // and return it
      return engine;

    } // end try
    catch (ClassNotFoundException cnfe)
    { // the class was not found
      logger.fatal("Venice engine class \"" + cname + "\" not found",cnfe);
      throw new ConfigException("Invalid engine classname: " + cname);

    } // end catch
    catch (IllegalAccessException iae)
    { // could not access constructor or something
      logger.fatal("Can't access \"" + cname + "\" constructor: " + iae.getMessage(),iae);
      throw new ConfigException("Unable to create classname: " + cname);

    } // end catch
    catch (InstantiationException ie)
    { // could not create the instance
      logger.fatal("Can't create instance of \"" + cname + "\": " + ie.getMessage(),ie);
      throw new ConfigException("Unable to create classname: " + cname);

    } // end catch
    catch (ExceptionInInitializerError eiie)
    { // some exception while initializing class
      logger.fatal("Exception while initializing \"" + cname + "\": " + eiie.getMessage(),eiie);
      throw new ConfigException("Unable to create classname: " + cname);

    } // end catch
    catch (SecurityException se)
    { // security violation somewhere
      logger.fatal("Security violation on \"" + cname + "\": " + se.getMessage(),se);
      throw new ConfigException("Unable to create classname: " + cname);

    } // end catch
    catch (ClassCastException cce)
    { // engine could not be cast to VeniceEngine interface type
      logger.fatal("\"" + cname + "\" is not of type VeniceEngine",cce);
      throw new ConfigException("Invalid engine classname: " + cname);

    } // end catch

  } // end createEngine

} // end class Startup
