//----------------------------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.workflow.coreImpl.xpdl.parser;
import java.io.IOException;
import java.io.Reader;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.digester.Digester;
import org.huihoo.workflow.coreImpl.xpdl.parser.converters.JoinTypeConverter;
import org.huihoo.workflow.coreImpl.xpdl.parser.converters.ParameterModeConverter;
import org.huihoo.workflow.coreImpl.xpdl.parser.converters.SplitTypeConverter;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.ActivityRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.ApplicationRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.DataFieldRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.PackageHeaderRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.PackageRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.ProcessHeaderRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.ProcessRuleSet;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.SetAliasPropertyRule;
import org.huihoo.workflow.coreImpl.xpdl.parser.xmlrules.TransitionRuleSet;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.activity.JoinType;
import org.huihoo.workflow.xpdl.activity.SplitType;
import org.huihoo.workflow.xpdl.parameter.ParameterMode;
import org.huihoo.workflow.xpdl.parser.XPDLParseException;
import org.huihoo.workflow.xpdl.parser.XPDLParserTools;

import org.huihoo.commons.beanutils.ClassConverter;

public class XPDLParserIO
{
	public static WorkflowPackage parseReader(DefaultXPDLParser parser, Reader inputReader)
		throws XPDLParseException, IOException
	{
		WorkflowPackage result = null;
		Digester digester = null;
		try
		{
			digester = createXPDLDigester(parser);
			digester.parse(inputReader);
			result = (WorkflowPackage) digester.getRoot();
			if (parser.isXPDLValidating())
			{
				parser.errorList = XPDLParserTools.internalValidate(result);
				XPDLParserTools.dumpErrorList(parser.errorList,System.err);
			}
			XPDLParserTools.internalFormat(result);
		}
		catch (Exception e)
		{
			XPDLParseException ex = new XPDLParseException("Parse  XPDL from XML");
			ex.setRootCause(e);
			throw ex;
		}
		return result;
	}

	private static Digester createXPDLDigester(DefaultXPDLParser parser)
	{
		// Initialize the digester
		Digester digester = DigesterFactory.newDigester(parser.isValidating(),parser.isNamespaceAware(),null);
		digester.setClassLoader(XPDLParserIO.class.getClassLoader());
		
		ConvertUtils.register(new ParameterModeConverter(), ParameterMode.class);
		ConvertUtils.register(new JoinTypeConverter(), JoinType.class);
		ConvertUtils.register(new SplitTypeConverter(), SplitType.class);
		ConvertUtils.register(new ClassConverter(), Class.class);
		
		//-----------------------Package    
		digester.addObjectCreate("Package", "org.huihoo.workflow.coreImpl.xpdl.WorkflowPackageImpl");
		digester.addRule("Package", new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule("Package", new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new PackageRuleSet("Package/"));
		//  -----------------------PackageHeader 
		digester.addRuleSet(new PackageHeaderRuleSet("Package/PackageHeader/"));
		//  -----------------------DataField
		//	digester.addRule("Package/DataFields/DataField",new SetAliasPropertyRule("isArray","IsArray"));
		digester.addRule("Package/DataFields/DataField", new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule("Package/DataFields/DataField", new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new DataFieldRuleSet("Package/DataFields/DataField/"));
		//  -----------------------WorkflowProcess
		digester.addRule("Package/WorkflowProcesses/WorkflowProcess", new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule("Package/WorkflowProcesses/WorkflowProcess", new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new ProcessRuleSet("Package/WorkflowProcesses/WorkflowProcess/"));
		//  -----------------------ProcessHeader   
		digester.addSetProperties("Package/WorkflowProcesses/WorkflowProcess/ProcessHeader");
		digester.addRuleSet(new ProcessHeaderRuleSet("Package/WorkflowProcesses/WorkflowProcess/ProcessHeader/"));
		//  -----------------------WorkflowActivity
		//  We need use SetTransitionActivityRule,so we must put these here
		digester.addRule(
			"Package/WorkflowProcesses/WorkflowProcess/Activities/Activity",
			new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule(
			"Package/WorkflowProcesses/WorkflowProcess/Activities/Activity",
			new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new ActivityRuleSet("Package/WorkflowProcesses/WorkflowProcess/Activities/Activity/"));
		//  -----------------------WorkflowTransition
		digester.addRule(
			"Package/WorkflowProcesses/WorkflowProcess/Transitions/Transition",
			new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule(
			"Package/WorkflowProcesses/WorkflowProcess/Transitions/Transition",
			new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new TransitionRuleSet("Package/WorkflowProcesses/WorkflowProcess/Transitions/Transition/"));
		//  -----------------------WorkflowApplication
		digester.addRule("Package/Applications/Application", new SetAliasPropertyRule("UUID", "Id"));
		digester.addRule("Package/Applications/Application", new SetAliasPropertyRule("name", "Name"));
		digester.addRuleSet(new ApplicationRuleSet("Package/Applications/Application/"));
		return (digester);
	}
}
