//----------------------------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.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.huihoo.workflow.coreImpl.xpdl.WorkflowActivityImpl;
import org.huihoo.workflow.coreImpl.xpdl.WorkflowProcessHeaderImpl;
import org.huihoo.workflow.coreImpl.xpdl.WorkflowTransitionImpl;
import org.huihoo.workflow.xpdl.WorkflowActivity;
import org.huihoo.workflow.xpdl.WorkflowPackage;
import org.huihoo.workflow.xpdl.WorkflowProcess;
import org.huihoo.workflow.xpdl.WorkflowProcessHeader;
import org.huihoo.workflow.xpdl.WorkflowTransition;
import org.huihoo.workflow.xpdl.XPDLSchema;
import org.huihoo.workflow.xpdl.activity.NoImplementation;
import org.huihoo.workflow.xpdl.activity.SubFlowImplementation;
import org.huihoo.workflow.xpdl.activity.ToolImplementation;
import org.huihoo.workflow.xpdl.condition.XCDATACondition;
import org.huihoo.workflow.xpdl.util.Duration;
import org.huihoo.workflow.xpdl.util.DurationUnit;

import org.huihoo.commons.jdbc.JDBCUtilities;

public class WorkflowProcessParser
{
	public static void parseWorkflowProcess(
		Connection conn,
		WorkflowPackage workflowPackage,
		WorkflowProcess workflowProcess)
		throws SQLException
	{
		parseProcessHeader(conn, workflowPackage, workflowProcess);
		parseActivities(conn, workflowPackage, workflowProcess);
		parseTransitions(conn, workflowPackage, workflowProcess);

		ExtendedAttributesParser.parseExtendedAttributes(conn, workflowPackage, workflowProcess);
	}

	public static void parseProcessHeader(
		Connection conn,
		WorkflowPackage workflowPackage,
		WorkflowProcess workflowProcess)
		throws SQLException
	{
		Statement stmt = null;
		try
		{
			String strSQL =
				"SELECT *  "
					+ "FROM "
					+ XPDLSchema.SCHEMA_PROCESSHEADER
					+ " "
					+ "WHERE    vc_packageId='"
					+ workflowPackage.getUUID()
					+ "' AND vc_processid = '"
					+ workflowProcess.getUUID()
					+ "'";
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(strSQL);
			if (rs.next())
			{
				WorkflowProcessHeader comp = new WorkflowProcessHeaderImpl();

				comp.setCreationTime(rs.getDate("dat_created"));
				comp.setValidFrom(rs.getDate("dat_validfrom"));
				comp.setValidTo(rs.getDate("dat_validto"));
				comp.setLimit(new Duration(rs.getInt("int_limit"), DurationUnit.stringToType(rs.getString("vc_durationunit"))));
				comp.setDescription(rs.getString("vc_description"));

				workflowProcess.setProcessHeader(comp);
			}
		}
		finally
		{
			JDBCUtilities.cleanupNoThrow(stmt);
		}
	}

	public static void parseActivities(Connection conn, WorkflowPackage workflowPackage, WorkflowProcess workflowProcess)
		throws SQLException
	{
		Statement stmt = null;
		try
		{
			String strSQL =
				"SELECT *  "
					+ "FROM "
					+ XPDLSchema.SCHEMA_ACTIVITY+" "
					+ "WHERE    vc_packageId='"
					+ workflowPackage.getUUID()
					+ "' AND vc_processid = '"
					+ workflowProcess.getUUID()
					+ "'";
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(strSQL);
			while (rs.next())
			{
				WorkflowActivity comp = new WorkflowActivityImpl();

				comp.setUUID(rs.getString("vc_uuid"));
				comp.setName(rs.getString("vc_name"));
				comp.setDuration(
					new Duration(rs.getInt("int_limit"), DurationUnit.stringToType(rs.getString("vc_durationunit"))));

				String implType = rs.getString("vc_impltype");
				if (XPDLSchema.IMPLEMENTATION_TOOL.equals(implType))
				{
					String implID = rs.getString("vc_implid");
					ToolImplementation toolImpl = ImplementationParse.parseToolImplementation(conn, workflowPackage, implID);
					comp.setImplementation(toolImpl);
				}
				else if (XPDLSchema.IMPLEMENTATION_SUBFLOW.equals(implType))
				{
					String implID = rs.getString("vc_implid");
					SubFlowImplementation subflowImpl =
						ImplementationParse.parseSubFlowImplementation(conn, workflowPackage, implID);
					comp.setImplementation(subflowImpl);
				}
				else
				{
					comp.setImplementation(new NoImplementation());
				}

				comp.parsePerformers(rs.getString("vc_performer"));
				comp.setJoinType(rs.getString("vc_jointype"));
				comp.setSplitType(rs.getString("vc_splittype"));
				comp.setDescription(rs.getString("vc_description"));

				workflowProcess.addActivity(comp);
				ExtendedAttributesParser.parseExtendedAttributes(conn, workflowPackage, comp);
			}
		}
		finally
		{
			JDBCUtilities.cleanupNoThrow(stmt);
		}
	}

	public static void parseTransitions(
		Connection conn,
		WorkflowPackage workflowPackage,
		WorkflowProcess workflowProcess)
		throws SQLException
	{
		Statement stmt = null;
		try
		{
			String strSQL =
				"SELECT *  "
					+ "FROM "
					+ XPDLSchema.SCHEMA_TRANSITION+" "
					+ "WHERE    vc_packageId='"
					+ workflowPackage.getUUID()
					+ "' AND vc_processid = '"
					+ workflowProcess.getUUID()
					+ "'";
			stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(strSQL);
			while (rs.next())
			{
				WorkflowTransition comp = new WorkflowTransitionImpl();

				comp.setUUID(rs.getString("vc_uuid"));
				comp.setName(rs.getString("vc_name"));
				comp.setFromActivity(workflowProcess.findActivity(rs.getString("vc_from")));
				comp.setToActivity(workflowProcess.findActivity(rs.getString("vc_to")));
				comp.setWorkflowCondition(new XCDATACondition(rs.getString("vc_condition")));
				comp.setDescription(rs.getString("vc_description"));

				workflowProcess.addTransition(comp);
				ExtendedAttributesParser.parseExtendedAttributes(conn, workflowPackage, comp);
			}
		}
		finally
		{
			JDBCUtilities.cleanupNoThrow(stmt);
		}
	}
}
