//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010  huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.willow.deploy;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;

import org.apache.commons.digester.Digester;
import org.huihoo.commons.jdbc.Store;
import org.huihoo.willow.Globals;
import org.huihoo.willow.startup.DigesterFactory;
import org.huihoo.willow.util.NamingStore;
import org.huihoo.willow.util.PluginEntry;
import org.huihoo.willow.xmlrules.PluginRuleSet;
import org.huihoo.workflow.SchemaContext;
import org.xml.sax.InputSource;

public class PluginRepository
{
	protected static PluginRepository pluginRepository = null;

	public static PluginRepository getInstance()
	{
		return pluginRepository;
	}

	public static void loadOnStartup(String pluginXml)
	{
		pluginRepository = new PluginRepository(pluginXml);
	}

	public static void loadOnStartup(InputStream istream)
	{
		pluginRepository = new PluginRepository(istream);
	}

	//---------------------------------------------------
	protected PluginRepositoryHelper pluginHelper = new PluginRepositoryHelper();
	protected SchemaContext schemaContext = null;

	protected PluginRepository(String pluginXml)
	{
		load(pluginXml);
	}

	protected PluginRepository(InputStream istream)
	{
		load(istream);
	}

	public SchemaContext getSchemaContext()
	{
		return schemaContext;
	}

	public Store findStore(String storeNAME)
	{
		return pluginHelper.findStore(storeNAME);
	}

	//---------------------------------------------------------------
	//----------------------------------------------------------------	
	protected void load(String pluginXml)
	{
		if (pluginXml == null || pluginXml.length() == 0)
		{
			File schemaFile = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), Globals.DefaultSchemaProperties);
			if (schemaFile.exists() && schemaFile.isFile())
			{
				schemaContext = new SchemaContext(schemaFile.getAbsolutePath());
			}
			else
			{
				schemaContext = new SchemaContext();
			}
			return;
		}

		File pluginFile = new File(pluginXml);
		if (!pluginFile.isAbsolute())
		{
			pluginFile = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), pluginXml);
		}

		if (!pluginFile.exists() || !pluginFile.isFile())
		{
			String sysPropDatabase = System.getProperty(Constants.PROPS_WILLOW_PLUGIN);
			if (sysPropDatabase == null)
			{
				pluginFile = null;
			}
			else
			{
				pluginFile = new File(sysPropDatabase);
			}
		}

		if (pluginFile == null || !pluginFile.exists() || !pluginFile.isFile())
		{
			return;
		}

		InputStream istream = null;

		try
		{
			istream = new FileInputStream(pluginFile);
			load(istream);
		}
		catch (Throwable t)
		{
			System.out.println("PluginRepository.loadOnStartup: " + t);
			t.printStackTrace(System.out);

			try
			{
				if (istream != null)
				{
					istream.close();
				}
			}
			catch (IOException e)
			{

			}
		}

	}
	protected void load(InputStream istream)
	{
		File schemaFile = new File(System.getProperty(Globals.PROPS_WILLOW_HOME), Globals.DefaultSchemaProperties);
		if (schemaFile.exists() && schemaFile.isFile())
		{
			schemaContext = new SchemaContext(schemaFile.getAbsolutePath());
		}
		else
		{
			schemaContext = new SchemaContext();
		}

		if (istream == null)
		{
			return;
		}

		Digester dbDigester = DigesterFactory.newDigester(false, false, new PluginRuleSet());
		ClassLoader clazzLoader = PluginRepository.class.getClassLoader();
		dbDigester.setClassLoader(clazzLoader);
		dbDigester.setUseContextClassLoader(false);

		InputSource inputSource = new InputSource();

		try
		{
			inputSource.setByteStream(istream);
			dbDigester.push(pluginHelper);
			dbDigester.parse(inputSource);
		}
		catch (Exception e)
		{
			System.out.println("PluginRepository.loadOnStartup: " + e);
			e.printStackTrace(System.out);
		}
	}

	class PluginRepositoryHelper
	{
		public Hashtable storeHash = new Hashtable();

		public void addStore(NamingStore store)
		{
			storeHash.put(store.getName(), store);
		}

		public Store findStore(String storeNAME)
		{
			return (Store) storeHash.get(storeNAME);
		}

		public void addPlugin(PluginEntry pluginEntry)
		{
			String className = pluginEntry.getClassName();
			if (className != null)
			{
				try
				{
					ClassLoader clazzLoader = PluginRepository.class.getClassLoader();
					Class clazz = clazzLoader.loadClass(className);
					clazz.newInstance();
				}
				catch (Throwable e)
				{
					System.out.println("PluginRepository.addPlugin: " + e);
				}
			}
		}
	}
}
