/*
 * Created on 2004-1-23
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package workflow.wfmc.xpdl.activity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import workflow.WorkflowException;
import workflow.wfmc.rtm.WorkflowCall;
import workflow.wfmc.rtm.WorkflowCase;
import workflow.wfmc.rtm.WorkflowWork;
import workflow.wfmc.xpdl.WorkflowApplication;
import workflow.wfmc.xpdl.WorkflowPackage;
import workflow.wfmc.xpdl.WorkflowParameter;
import workflow.wfmc.xpdl.ext.ExtendedAttribute;
import workflow.wfmc.xpdl.parameter.ActualParameter;
import workflow.wfmc.xpdl.parameter.FormalParameter;
import workflow.wfmc.xpdl.parameter.ParameterMode;
/**
 * @author reic
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class ToolImplementation implements Implementation
{
	private List parameters = new ArrayList();
	private String appId;
	private String description;
	private Map attributes = new HashMap();
  
  
  
	public void execute(WorkflowWork workItem) 
  throws WorkflowException
	{
		try
		{
			WorkflowCase workflowCase=workItem.getWorkflowCase();
      WorkflowPackage pkg = workflowCase.getWorkflowProcess().getWorkflowPackage();
			WorkflowApplication app = pkg.findWorkflowApplication(appId);
			String implClassName = app.getQualifiedClassName();
			Class implClass = Class.forName(implClassName);
      
			WorkflowCall call = (WorkflowCall) implClass.newInstance();
      call.invoke(workItem,makeParamerers(workflowCase,app));
		}
		catch (Exception ex)
		{
			throw new WorkflowException(ex);
		}
	}
  
	public List getActualParameters()
	{
		return parameters;
	}
	public void addActualParameter(ActualParameter parameter)
	{
		parameters.add(parameter);
	}
	public String getApplicationID()
	{
		return appId;
	}
	public void setApplicationID(String applicationId)
	{
		this.appId = applicationId;
	}
	public String getDescription()
	{
		return (this.description);
	}
	public void setDescription(String description_)
	{
		this.description = description_;
	}
	public Map getExtendedAttributes()
	{
		return (this.attributes);
	}
	public void addExtendedAttribute(ExtendedAttribute attribute)
	{
		this.attributes.put(attribute.getName(), attribute);
	}

	//---------------------private blocks
	private WorkflowParameter[] makeParamerers(WorkflowCase workflowCase, WorkflowApplication app)
  throws CloneNotSupportedException
	{
    WorkflowParameter[] params = null;
    
		FormalParameter formalParameter = null;
		WorkflowParameter initParameter = null;
    ActualParameter actualParameter = null;
		//CallParameter parameter = null;
    
    ParameterMode paramMode=null;
    Class srcClass=null;
    Class dstClass=null;
       
		int sizeParams = app.getFormalParameters().size();
    
    params=new WorkflowParameter[sizeParams];
    
		for (int i = 0; i < sizeParams; ++i)
		{
			formalParameter = app.findFormalParameter(i);
      actualParameter=(ActualParameter)parameters.get(i);
      initParameter=workflowCase.getCaseContext().getParameter(actualParameter.getUUID()) ;
           
      srcClass=formalParameter.getType();
      dstClass=initParameter.getType();
      paramMode=formalParameter.getMode();
      
      if(dstClass.equals(srcClass) )
      {
        if(paramMode.equals(ParameterMode.MODE_IN))
        {
          params[i]=initParameter.copy();
        }
        else
        {
          params[i]=initParameter;
        }
      }
      else
      {      
        //type check failed
        throw new java.lang.IllegalArgumentException();
      }     
    }
    
		return params;
	}
}
