package com.zi.mwms.solution.workflow.expression;

import com.cim.idm.flowpackage.expression.ExtendedFunction;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.framework.exception.IDMFrameErrorSignal;
import com.cim.idm.framework.exception.ext.LocalizedException;
import com.cim.idm.framework.orm.ObjectAttributeDef;
import com.cim.idm.framework.orm.info.access.ObjectValueUserColumnsAccessor;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.cim.idm.framework.util.xml.JdomUtils;
import com.cim.idm.wmsextend.generic.util.ConvertUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jaxen.Context;
import org.jaxen.Function;
import org.jaxen.FunctionCallException;
import org.jaxen.XPathFunctionContext;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.xpath.XPath;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;


public class CustomExpression extends ExtendedFunction implements ApplicationContextAware {

	private static Log log = LogFactory.getLog(CustomExpression.class);
	private ApplicationContext 		context = null;

	/*
	 * Name : setApplicationContext
	 * Desc : This function is setApplicationContext
	 * Author : BOE CIM Dev.
	 * Date : 2015.01.17
	 */
	public void setApplicationContext(ApplicationContext ctx) throws BeansException
	{
		this.context = ctx;
	}

	/*
	 * Name : isConcurrentBpelExecutionContextAware
	 * Desc : This function is isConcurrentBpelExecutionContextAware
	 * Author : BOE CIM Dev.
	 * Date : 2015.01.17
	 */
	public boolean isConcurrentBpelExecutionContextAware() {
		return true;
	}

	/*
	 * Name : CustomExpression
	 * Desc : This function is CustomExpression
	 * Author : BOE CIM Dev.
	 * Date : 2014.12.01
	 */
	public CustomExpression(){

	}

	/*
	 * Name : registerFunctions
	 * Desc : This function is registerFunctions
	 * Author : ZXY IDM Team
	 * Date : 2011.01.17
	 */
	@Override
	public void registerFunctions(XPathFunctionContext functionContext) {
		functionContext.registerFunction(null, "matches", new Matches());
		functionContext.registerFunction(null, "sum", new Sum());
		functionContext.registerFunction(null, "appendString", new AppendString());
		functionContext.registerFunction(null, "minus", new Minus());
		functionContext.registerFunction(null, "isBig", new Big());
		functionContext.registerFunction(null, "isSame", new Same());
		functionContext.registerFunction(null, "createDocument", new CreateDocument());
		functionContext.registerFunction(null, "createElement", new CreateElement());
		functionContext.registerFunction(null, "removeElement", new RemoveElement());
		functionContext.registerFunction(null, "getField", new GetField());
		functionContext.registerFunction(null, "setField", new SetField());
		functionContext.registerFunction(null, "getCurrentTime", new GetCurrentTime());
		functionContext.registerFunction(null, "getMapListForElement", new GetMapListForElement());
		functionContext.registerFunction(null, "getXmlData", new GetXmlData());
		functionContext.registerFunction(null, "getXmlAttributeData", new GetXmlAttributeData());
		functionContext.registerFunction(null, "getXmlDataList", new GetXmlDataList());
		functionContext.registerFunction(null, "getElement", new GetElement());
		functionContext.registerFunction(null, "getElementList", new GetElementList());
		functionContext.registerFunction(null, "getPropertyData", new GetPropertyData());
		functionContext.registerFunction(null, "setXmlData", new SetXmlData());
		functionContext.registerFunction(null, "isNull", new isNull());
		functionContext.registerFunction(null, "toDouble", new ToDouble());
		functionContext.registerFunction(null, "toTotal", new ToTotal());
		functionContext.registerFunction(null, "toInt", new ToInteger());
		functionContext.registerFunction(null, "toLong", new ToLong());
		functionContext.registerFunction(null, "getXmlAttributeArray", new GetXmlAttributeArray());
		functionContext.registerFunction(null, "getXmlChildNodeValueArray", new GetXmlChildNodeValueArray());
		functionContext.registerFunction(null, "getEventInfo", new GetEventInfo());
		functionContext.registerFunction(null, "getNamedValue", new GetNamedValue());
		functionContext.registerFunction(null, "getXmlDataTimeStamp", new GetXmlDataTimeStamp());
		functionContext.registerFunction(null, "getXmlDataInt", new GetXmlDataInt());
//		functionContext.registerFunction(null, "getProductPGS", new GetProductPGS());
//		functionContext.registerFunction(null, "getProductU", new GetProductU());
		functionContext.registerFunction(null, "getXmlElement", new GetXmlElement());
		functionContext.registerFunction(null, "getArrayValue", new GetArrayValue());
		functionContext.registerFunction(null, "getLength", new GetLength());
		functionContext.registerFunction(null, "getXmlArraySize", new GetXMLArraySize());
		functionContext.registerFunction(null, "getXmlArrayValue", new GetXMLArrayValue());
		functionContext.registerFunction(null, "getXMLArrayElement", new GetXMLArrayElement());
		functionContext.registerFunction(null, "getXMLBodyElement", new GetXMLBodyElement());
		functionContext.registerFunction(null, "setNVSeq", new SetNVSeq());
		functionContext.registerFunction(null, "getObjectData", new GetObjectData());
		functionContext.registerFunction(null, "getDataVariable", new GetDataVariable());
		functionContext.registerFunction(null, "setDataVariable", new SetDataVariable());

		functionContext.registerFunction(null, "toString", new ToString());
		functionContext.registerFunction(null, "append", new Append());
		functionContext.registerFunction(null, "getXmlElementChildList", new GetXmlElementChildList());
		functionContext.registerFunction(null, "getXmlElementChildArray", new GetXmlElementChildArray());
		functionContext.registerFunction(null, "getElementChildText", new GetElementChildText());
		functionContext.registerFunction(null, "getElementTextList", new GetElementTextList());

		functionContext.registerFunction(null, "detachXmlNode", new DetachXmlNode());
		functionContext.registerFunction(null, "getDifferTimeInSecond", new GetDifferTimeInSecond());
		functionContext.registerFunction(null, "getChildElement", new GetChildElement());
//		functionContext.registerFunction(null, "isDiffLotFeildState", new IsSameLotFieldState());
//		functionContext.registerFunction(null, "isAccordLotFieldState", new IsAccordLotFieldState());
		functionContext.registerFunction(null, "setEmpty", new SetEmpty());
		functionContext.registerFunction(null, "getObjectFieldData", new GetObjectFieldData());
		functionContext.registerFunction(null, "getXmlElementChildrenList", new GetXmlElementChildrenList());

		functionContext.registerFunction(null, "setElement", new SetElement());
		functionContext.registerFunction(null, "addElement", new AddElement());
		functionContext.registerFunction(null, "getMapData", new GetMapData());
		functionContext.registerFunction(null, "getUdfs", new GetUdfs());
		functionContext.registerFunction(null, "setUdfs", new SetUdfs());
		functionContext.registerFunction(null, "getUdfsData", new GetUdfsData());
		functionContext.registerFunction(null, "setUdfsData", new SetUdfsData());
		functionContext.registerFunction(null, "getXmlElementData", new GetXmlElementData());
		functionContext.registerFunction(null, "getCurrTimeStampSQL", new GetCurrTimeStampSQL());
		functionContext.registerFunction(null, "addMap", new AddMap());
		functionContext.registerFunction(null, "getTimeKey", new GetTimeKey());
		functionContext.registerFunction(null, "convertToTimeStamp", new ConvertToTimeStamp());
		functionContext.registerFunction(null, "getChildNodesText", new GetChildNodesTextFunction());
		functionContext.registerFunction(null, "getChildNodeTextList", new GetChildNodesTextFunction());
		functionContext.registerFunction(null, "addList", new AddListFunction());
		functionContext.registerFunction(null, "containsList", new ContainsListFunction());
	}

	private class AddMap implements Function{

		@Override
		public Object call(Context context, List list)
				throws FunctionCallException {
			Map map = (Map)list.get(0);
			String name = (String) list.get(1);
			Object value = (Object) list.get(2);
			map.put(name, value);
			return map;
		}

	}

	private class CreateElement implements Function{

		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context context, List list)
				throws FunctionCallException {
			String nodeName = (String) list.get(0);
			Element element = new Element(nodeName);
			if(list.size() == 2) {
				element.setText((String) list.get(1));
			}
			return element;
		}

	}


	private class CreateDocument implements Function{


		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context context, List list)
				throws FunctionCallException {
			String nodeName = (String) list.get(0);
			Document doc = new Document(new Element(nodeName));
			return doc;
		}

	}



	private class SetUdfs implements Function
	{

		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String udfsData = String.valueOf(args.get(1));

			ObjectValueUserColumnsAccessor udf = (ObjectValueUserColumnsAccessor)getBpelExecutionContext().getVariableData().getValue(variableName);
			Map udfs = (Map)getBpelExecutionContext().getVariableData().getValue(udfsData);

			try {
				udf.setUserColumns(udfs);

				return null;
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class SetUdfsData implements Function
	{

		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object variableObject = String.valueOf(args.get(0));
			String udfsName = String.valueOf(args.get(1));
			String udfsValue = String.valueOf(args.get(2));

			Map udf;
			if(variableObject instanceof String){
				udf = (Map)getBpelExecutionContext().getVariableData().getValue((String) variableObject);
			}
			else{
				udf = (Map) variableObject;
			}

			try
			{
				if(udfsValue == null || udfsValue.isEmpty()){
					udf.put(udfsName, udfsValue);
				}else{
					udf.put(udfsName, udfsValue);
				}

				return null;
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}



	private class GetChildNodesTextFunction implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context xpath, List list) throws FunctionCallException
		{
			try
			{
				Object obj = list.get(0);

				String path = (String) list.get(1);

				if ( obj instanceof String )
					obj = getBpelExecutionContext().getVariableData().getValue((String)obj);

				Element node = (Element) XPath.selectSingleNode(obj, path);
				List<Element> children = node.getChildren();
				List<String> textList = new ArrayList<String>();
				for (Element element : children) {
					textList.add(element.getTextTrim());
				}

				return textList;
			}
			catch ( Exception ex )
			{
				throw new FunctionCallException( ex );
			}
		}
	}


	private class ContainsListFunction implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context xpath, List list) throws FunctionCallException
		{
			try
			{
				Object obj1 = list.get(0);
				Object obj2 = list.get(1);

				List list1 = null;

				if ( obj1 instanceof String ) {
					list1 = (List) getBpelExecutionContext().getVariableData().getValue((String)obj1);
				}else {
					list1 = (List) obj1;
				}
				boolean contains = list1.contains(obj2);
				return contains;
			}
			catch ( Exception ex )
			{
				throw new FunctionCallException( ex );
			}
		}
	}


	private class AddListFunction implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context xpath, List list) throws FunctionCallException
		{
			try
			{
				Object obj1 = list.get(0);
				Object obj2 = list.get(1);

				List list1 = null;
				List list2 = null;

				if ( obj1 instanceof String ) {
					list1 = (List) getBpelExecutionContext().getVariableData().getValue((String)obj1);
				}else {
					list1 = (List) obj1;
				}
				if ( obj2 instanceof String ) {
					list2 = (List) getBpelExecutionContext().getVariableData().getValue((String)obj2);
				}else {
					list2 = (List) obj2;
				}

				if(list1 == null) {
					list1 = new ArrayList(list2);
				}else {
					list1.addAll(list2);
				}
				return list1;
			}
			catch ( Exception ex )
			{
				throw new FunctionCallException( ex );
			}
		}
	}


	private class AddElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			try {
				if(args.size() == 4 || args.size() == 3) {
					String variableName = (String) args.get(0);
					String xpath = (String) args.get(1);
					Element newElement;
					if(args.get(2) instanceof Element) {
						newElement = (Element) args.get(2);
					}else {
						String nodeName = (String) args.get(2);
						String nodeText = (String) args.get(3);
						newElement = new Element(nodeName);
						newElement.setText(nodeText);
					}

					Object document = getBpelExecutionContext().getVariableData().getValue(variableName);
					Element element;
					try {
						if(xpath.isEmpty()) {
							if(document instanceof Document) {
								element = ((Document) document).getRootElement();
							}else {
								element = (Element) document;
							}
						}else {
							element = (Element) XPath.selectSingleNode(document, xpath);
						}
					} catch (JDOMException e) {
						log.error(e);
						return null;
					}

					element.addContent(newElement);

					return document;
				}
				else if(args.size() == 2) {
					Element parentElement = (Element) getBpelExecutionContext().getVariableData().getValue((String) args.get(0));
					Element element = (Element) args.get(1);
					parentElement.addContent(element);
					return parentElement;
				}
				else if(args.size() == 6)
				{
					Object document = getBpelExecutionContext().getVariableData().getValue((String)args.get(0));
					String path = (String) args.get(1);

					Element element;
					element = (Element) XPath.selectSingleNode(document, path);


					Element operationSet = new Element("OPERATION");

					String nodeNameNum1 = (String) args.get(2);
					String nodeTextVal1 = (String) args.get(3);
					String nodeNameNum2 = (String) args.get(4);
					String nodeTextVal2 = (String) args.get(5);

					Element newElement = new Element(nodeNameNum1);
					newElement.setText(nodeTextVal1);
					Element newElement2 = new Element(nodeNameNum2);
					newElement2.setText(nodeTextVal2);

					operationSet.addContent(newElement);
					operationSet.addContent(newElement2);

					element.addContent(operationSet);

					return document;
				}
				return null;

			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class AddElementForList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			try {
				if(args.size() == 4 || args.size() == 3) {
					String variableName = (String) args.get(0);
					String xpath = (String) args.get(1);
					Element newElement;
					if(args.get(2) instanceof Element) {
						newElement = (Element) args.get(2);
					}else {
						String nodeName = (String) args.get(2);
						String nodeText = (String) args.get(3);
						newElement = new Element(nodeName);
						newElement.setText(nodeText);
					}

					Object document = getBpelExecutionContext().getVariableData().getValue(variableName);

					Element element;
					try {
						element = (Element) XPath.selectSingleNode(document, xpath);
					} catch (JDOMException e) {
						log.error(e);
						return null;
					}

					element.addContent(newElement);

					return document;
				}
				else if(args.size() == 2) {
					Element parentElement = (Element) getBpelExecutionContext().getVariableData().getValue((String) args.get(0));
					Element element = (Element) args.get(1);
					parentElement.addContent(element);
					return parentElement;
				}
				return null;

			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class SetElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = (String) args.get(0);
			String xpath = (String) args.get(1);
			String nodeText = (String) args.get(2);

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);

			Element element;
			try {
				Document document;
				if(jdom instanceof Element){
					document = new Document();

					Element clone = (Element) ((Element)jdom).clone();
					document.setRootElement(clone);
				}
				else{
					document = (Document) jdom;
				}
				element = (Element) XPath.selectSingleNode(document, xpath);
			} catch (JDOMException e) {
				log.error(e);
				return null;
			}
			element.setText(nodeText);

			return jdom;

		}
	}


	private class RemoveElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = (String) args.get(0);
			String xpath = (String) args.get(1);

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);

			Element element;
			try {
				Document document;
				if(jdom instanceof Element){
					document = new Document();

					Element clone = (Element) ((Element)jdom).clone();
					document.setRootElement(clone);
				}
				else{
					document = (Document) jdom;
				}
				element = (Element) XPath.selectSingleNode(document, xpath);
				element.detach();
			} catch (JDOMException e) {
				log.error(e);
				return null;
			}

			return jdom;

		}
	}


	private class GetCurrTimeStampSQL implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			try {
				Timestamp timestamp = ConvertUtil.getCurrTimeStampSQL();
				return timestamp;
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class ConvertToTimeStamp implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String textTime = String.valueOf(args.get(0));

			try {
				Timestamp timestamp = ConvertUtil.convertToTimeStamp(textTime);
				return timestamp;
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class GetUdfs implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			ObjectValueUserColumnsAccessor udf = (ObjectValueUserColumnsAccessor)getBpelExecutionContext().getVariableData().getValue(variableName);

			try {
				return udf.getUserColumns();
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class GetMapData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object variableName = args.get(0);
			String udfsName = args.get(1).toString();

			try {
				Map udfs = (Map) variableName;

				Object object = udfs.get(udfsName);
				return object == null ? null:object.toString();
			} catch (Exception e) {
				log.error(e);
				return null;
			}
		}
	}

	private class GetPropertyData implements Function
	{

		@Override
		public Object call(Context context, List args)
				throws FunctionCallException {
			Object obj = args.get(0);
			String propertyName = args.get(1).toString();
			Field field = null;
			try {
				field = obj.getClass().getDeclaredField(propertyName);
				field.setAccessible(true);
				return field.get(obj);
			} catch (SecurityException e) {
				log.debug(e);
			} catch (NoSuchFieldException e) {
				log.error(e);
			} catch (IllegalArgumentException e) {
				log.error(e);
			} catch (IllegalAccessException e) {
				log.error(e);
			}
			return null;
		}

	}

	private class GetUdfsData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object variableObject = args.get(0);
			String udfsName = args.get(1).toString();
			Map<String, String> udfs;
			try {
				if(variableObject instanceof String){
					udfs = (Map<String, String>) getBpelExecutionContext().getVariableData().getValue((String) variableObject);
				}
				else{
					udfs = (Map<String, String>) variableObject;
				}
				return udfs.get(udfsName);
			} catch (Exception e) {
				log.error(e);
				return null;
			}
		}
	}



	private class GetXmlElementChildrenList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object xmlObject = getBpelExecutionContext().getVariableData().getValue(variableName);

			Element replyElement = null;
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					replyElement = JdomUtils.getNode(xmlObject, locationPath, index);

					List<Element> list= replyElement.getChildren();

					List<Element> rlist = new ArrayList<Element>();

					for(Element subElement : list){
						rlist.add(subElement);
					}

					return rlist;
				}
				else
				{
					replyElement = JdomUtils.getNode(xmlObject, locationPath);

					List<Element> list= replyElement.getChildren();

					List<Element> rlist = new ArrayList<Element>();

					for(Element subElement : list){
						rlist.add(subElement);
					}

					return rlist;
				}
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}


	private class GetObjectFieldData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String objectType = String.valueOf(args.get(0));
			String keyName = String.valueOf(args.get(1));
			String fieldName = String.valueOf(args.get(2));

			try {

//				if ( objectType.equals("Alarm"))
//				{
//					AlarmKey key = new AlarmKey();
//					key.setAlarmId(keyName);
//					Alarm data = AlarmServiceProxy.getAlarmService().selectByKey(key);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//				}
//				else if ( objectType.equals("Consumable"))
//				{
//					ConsumableKey consumableKey = new ConsumableKey();
//					consumableKey.setConsumableName(keyName);
//					Consumable data = ConsumableServiceProxy.getConsumableService().selectByKey(consumableKey);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//
//				}
//				else
				/*if ( objectType.equals("Durable"))
				{
					DurableKey durableKey = new DurableKey();
					durableKey.setDurableName(keyName);
					Durable data = DurableServiceProxy.getDurableService().selectByKey(durableKey);
					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
					if(fieldValue instanceof String){
						return (String)fieldValue;
					}else{
						return "";
					}*/
				//}
				/*else if ( objectType.equals("Lot"))
				{
					LotKey lotKey = new LotKey();
					lotKey.setLotName(keyName);
					Lot data = LotServiceProxy.getLotService().selectByKey(lotKey);
					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
					if(fieldValue instanceof String){
						return (String)fieldValue;
					}else{
						return "";
					}
				}*/
				/*else if ( objectType.equals("Product"))
				{

					ProductKey productKey = new ProductKey();
					productKey.setProductName(keyName);
					Product data = ProductServiceProxy.getProductService().selectByKey(productKey);
					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
					if(fieldValue instanceof String){
						return (String)fieldValue;
					}else{
						return "";
					}
				}*/
//				else if ( objectType.equals("ProductRequest"))
//				{
//
//					ProductRequestKey productRequestKey = new ProductRequestKey();
//					productRequestKey.setProductRequestName(keyName);
//					ProductRequest data = ProductRequestServiceProxy.getProductRequestService().selectByKey(productRequestKey);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//				}
//				else if ( objectType.equals("TransportGroup"))
//				{
//					TransportGroupKey transportGroupKey = new TransportGroupKey();
//					transportGroupKey.setTransportGroupName(keyName);
//
//					TransportGroup data = TransportGroupServiceProxy.getTransportGroupService().selectByKey(transportGroupKey);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//				}
				/*else if ( objectType.equals("PackingGroup"))
				{
					PackingGroupKey packingGroupKey = new PackingGroupKey();

					packingGroupKey.setPackingGroupName(keyName);
					packingGroupKey.setSiteName(GenericServiceProxy.getConstantMap().SiteName_B8);
					PackingGroup data = PackingServiceProxy.getPackingGroupService().selectByKey(packingGroupKey);
					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
					if(fieldValue instanceof String){
						return (String)fieldValue;
					}else{
						return "";
					}
				}*/
				/*else if ( objectType.equals("UserInfo"))
				{
					UserInfoKey userInfoKey = new UserInfoKey();
					userInfoKey.setUserId(keyName);
					UserInfo data = UserServiceProxy.getUserInfoService().selectByKey(userInfoKey);
					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
					if(fieldValue instanceof String){
						return (String)fieldValue;
					}else{
						return "";
					}
				}*/
//				else if ( objectType.equals("Machine"))
//				{
//					MachineKey machineKey = new MachineKey();
//					machineKey.setMachineName(keyName);
//					Machine data = MachineServiceProxy.getMachineService().selectByKey(machineKey);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//				}
//				else if ( objectType.equals("Port"))
//				{
//					PortKey portKey = new PortKey();
//					portKey.setMachineName(keyName);
//					portKey.setPortName(String.valueOf(args.get(2)));
//					Port data = PortServiceProxy.getPortService().selectByKey(portKey);
//					Object fieldValue = ObjectUtil.getFieldValue(data, fieldName);
//					if(fieldValue instanceof String){
//						return (String)fieldValue;
//					}else{
//						return "";
//					}
//				}
				/*else
				{*/
				return "";
				//}
			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}
	}


	private class SetEmpty implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));

			Object obj = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);

			if(obj instanceof String){
				String var = (String)obj;
				var="";
				getBpelExecutionContext().getVariableData().setValue(variableName, var);
			}else if(obj instanceof Integer){
				int var = ((Integer)obj).intValue();
				var=0;
				getBpelExecutionContext().getVariableData().setValue(variableName, var);
			}else if(obj instanceof Long){
				long var = ((Long)obj).longValue();
				var=0L;
				getBpelExecutionContext().getVariableData().setValue(variableName, var);
			}else if(obj instanceof Double){
				double var = ((Double)obj).doubleValue();
				var=0D;
				getBpelExecutionContext().getVariableData().setValue(variableName, var);
			}else if(obj instanceof List){
				List list = (List)obj;
				for(int i=0; i<list.size();i++){
					list.remove(i);
				}
				getBpelExecutionContext().getVariableData().setValue(variableName, list);
			}else if(obj instanceof Map){
				Map map = (Map)obj;
				for(Object key : map.keySet()){
					map.remove(key);
				}
				getBpelExecutionContext().getVariableData().setValue(variableName, map);
			}else{
				getBpelExecutionContext().getVariableData().setValue(variableName, null);
			}

			return null;
		}
	}


	/*private class IsAccordLotFieldState implements Function
	{

		* Name : call
		* Desc : This function is Object call
		* Author : ZXY IDM Team
		* Date : 2011.01.17

		public Object call(Context context, List args) throws RuntimeException
		{
			String listName = String.valueOf(args.get(0));
			String fieldName = String.valueOf(args.get(1));
			String StateValue = String.valueOf(args.get(2));

			List<String> lotNamelist = (List)getBpelExecutionContext().getVariableData().getValue(listName);
			List lotlist = ParsingUtil.GetExtractLotInfo(lotNamelist, fieldName);
			int differentPoint = StateCheckUtil.AccordCheck(lotlist, StateValue);
			return (differentPoint > -1) ? "false" : "true";

		}
	}
	*/

//	private class IsSameLotFieldState implements Function
//	{
//		/*
//		* Name : call
//		* Desc : This function is Object call
//		* Author : ZXY IDM Team
//		* Date : 2011.01.17
//		*/
//		public Object call(Context context, List args) throws RuntimeException
//		{
//			String listName = String.valueOf(args.get(0));
//			String fieldName = String.valueOf(args.get(1));
//
//			List<String> lotNamelist = (List)getBpelExecutionContext().getVariableData().getValue(listName);
//			List lotlist = ParsingUtil.GetExtractLotInfo(lotNamelist, fieldName);
//			int differentPoint = StateCheckUtil.differentCheck(lotlist);
//			return (differentPoint > 0) ? "false" : "true";
//		}
//	}


	private class GetXmlElementData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Element ele = (Element)getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					String reply = JdomUtils.getNodeText(ele, locationPath, index);
					return reply;
				}
				else
				{
					String reply = JdomUtils.getNodeText(ele, locationPath);
					return reply;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return "";
			}
		}
	}


	private class Minus implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List list)
				throws FunctionCallException {
			long total = ((Number) list.get(0)).longValue();
			for (int i = 1; i < list.size(); i++) {
				total -= ((Number)list.get(i)).longValue();
			}
			return total;
		}

	}


	private class Big implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List list)
				throws FunctionCallException {
			long num1 = ((Number) list.get(0)).longValue();
			long num2 = ((Number) list.get(1)).longValue();

			return num1>num2;
		}

	}


	private class Same implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List list)
				throws FunctionCallException {
			boolean b = list.get(0).equals(list.get(1));

			return b;
		}

	}


	private class Sum implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List list)
				throws FunctionCallException {
			long total = 0L;
			for (Object object : list) {
				Number num = (Number) object;
				total += num.longValue();
			}
			return total;
		}

	}


	private class Matches implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List args)
				throws FunctionCallException {
			String value = String.valueOf(args.get(0));
			String regex = String.valueOf(args.get(1));
			boolean matches = value.matches(regex);
			return matches;
		}

	}


	private class AppendString implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context arg0, List list)
				throws FunctionCallException {
			StringBuilder sb = new StringBuilder();
			for (Object object : list) {
				sb.append(object);
			}
			return sb.toString();
		}

	}


	private class SetField implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call( Context xpath, List list ) throws FunctionCallException
		{
			try
			{
				Object obj = list.get( 0 );

				if ( obj instanceof String ) {
					obj = getBpelExecutionContext().getVariableData().getValue(( String )list.get(0));
				}
				String setMethod = ( String )list.get( 1 );
				String upperCase = setMethod.substring(0, 1).toUpperCase();
				setMethod = "set"+upperCase+setMethod.substring(1);
				Object value = list.get( 2 );
				Method method = null;
				if(value.getClass().getName().equals("java.lang.Long")){
					try{
						method = obj.getClass().getMethod(setMethod, long.class);
					}catch(NoSuchMethodException e){
						method = obj.getClass().getMethod(setMethod, value.getClass());
					}
				}else if(value.getClass().getName().equals("java.lang.Integer")){
					try{
						method = obj.getClass().getMethod(setMethod, int.class);
					}catch(NoSuchMethodException e){
						method = obj.getClass().getMethod(setMethod, value.getClass());
					}
				}else if(value.getClass().getName().equals("java.lang.Double")){
					try{
						method = obj.getClass().getMethod(setMethod, double.class);
					}catch(NoSuchMethodException e){
						method = obj.getClass().getMethod(setMethod, value.getClass());
					}
				}else if(value.getClass().getName().equals("java.lang.Float")){
					try{
						method = obj.getClass().getMethod(setMethod, float.class);
					}catch(NoSuchMethodException e){
						method = obj.getClass().getMethod(setMethod, value.getClass());
					}
				}else{
					method = obj.getClass().getMethod(setMethod, value.getClass());
				}
				method.invoke(obj, value);

				return obj;
			}
			catch ( Exception ex )
			{
				throw new FunctionCallException( ex );
			}
		}

		/*
		 * Name : getFieldValue
		 * Desc : This function is getFieldValue
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Object getFieldValue( Object obj, String[] fieldNames ) throws NoSuchFieldException, IllegalAccessException
		{
			Field field = null;

			for ( String fieldName : fieldNames )
			{
				field = getField( obj, fieldName );
				obj = field.get( obj );
			}

			return obj;
		}

		/*
		 * Name : getField
		 * Desc : This function is getField
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Field getField( Object obj, String fieldName )
		{
			Field field;
			field = findField(obj.getClass(),fieldName );

			field.setAccessible( true );

			return field;
		}

		/*
		 * Name : getField
		 * Desc : This function is getField
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Field findField(Class clazz, String fieldName) {
			if(clazz == null) {
				return null;
			}
			Field field = null;
			try {
				field = clazz.getDeclaredField(fieldName);
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				return findField(clazz.getSuperclass(), fieldName);
			}
			return field;
		}
	}


	private class GetField implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call( Context xpath, List list ) throws FunctionCallException
		{
			try
			{
				Object obj = list.get( 0 );

				if ( obj instanceof String )
					obj = getBpelExecutionContext().getVariableData().getValue(( String )list.get(0));

				String fields = ( String )list.get( 1 );
				String[] fieldNames =  fields.split("\\." );

				Object fieldValue = getFieldValue( obj, fieldNames );
				return fieldValue;
			}
			catch ( Exception ex )
			{
				throw new FunctionCallException( ex );
			}
		}

		/*
		 * Name : getFieldValue
		 * Desc : This function is getFieldValue
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Object getFieldValue( Object obj, String[] fieldNames ) throws NoSuchFieldException, IllegalAccessException
		{
			Field field = null;

			for ( String fieldName : fieldNames )
			{
				field = getField( obj, fieldName );
				obj = field.get( obj );
			}

			return obj;
		}

		/*
		 * Name : getField
		 * Desc : This function is getField
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Field getField( Object obj, String fieldName )
		{
			Field field;
			field = findField(obj.getClass(),fieldName );

			field.setAccessible( true );

			return field;
		}

		/*
		 * Name : findField
		 * Desc : This function is findField
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		private Field findField(Class clazz, String fieldName) {
			if(clazz == null) {
				return null;
			}
			Field field = null;
			try {
				field = clazz.getDeclaredField(fieldName);
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				return findField(clazz.getSuperclass(), fieldName);
			}
			return field;
		}
	}


	private class GetCurrentTime implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context context, List list)
				throws FunctionCallException {
			return ConvertUtil.getCurrTime();
		}

	}



	private class GetMapListForElement implements Function{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		@Override
		public Object call(Context context, List args)
				throws FunctionCallException {
			Element element = (Element) args.get(0);
			if(element == null) {
				return null;
			}
			List children = element.getChildren();
			List<Map<String, String>> mapList = new ArrayList<Map<String,String>>();
			for (Object object : children) {
				Element child = (Element) object;
				List children2 = child.getChildren();
				Map<String, String> map = new HashMap<String, String>();
				for (Object object2 : children2) {
					Element keyElement = (Element) object2;
					String key = keyElement.getName();
					String value = keyElement.getTextTrim();
					map.put(key, value);
				}
				mapList.add(map);
			}
			return mapList;
		}

	}


	private class GetElementList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				Document document;
				if(jdom instanceof Element){
					document = new Document();

					Element clone = (Element) ((Element)jdom).clone();
					document.setRootElement(clone);
				}
				else{
					document = (Document) jdom;
				}
				Object reply = XPath.selectNodes(document, locationPath);
				return reply;

			} catch (Exception ex) {
				log.warn(ex);
				return new ArrayList();
			}
		}
	}



	private class GetElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				Document document;
				if(jdom instanceof Element){
					document = new Document();

					Element clone = (Element) ((Element)jdom).clone();
					document.setRootElement(clone);
				}
				else{
					document = (Document) jdom;
				}
				Object reply = XPath.selectSingleNode(document, locationPath);
				return reply;

			} catch (Exception ex) {
				log.warn(ex);
				return null;
			}
		}
	}



	private class GetXmlDataList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					String reply = JdomUtils.getNodeText(jdom, locationPath, index);
					return reply;
				}
				else
				{
					Document document;
					if(jdom instanceof Element){
						document = new Document();

						Element clone = (Element) ((Element)jdom).clone();
						document.setRootElement(clone);
					}
					else{
						document = (Document) jdom;
					}
					List<String> nodeTextList = JdomUtils.getNodeTextList(document, locationPath);
					return nodeTextList;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return null;
			}
		}
	}



	private class GetXmlAttributeData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			String attName = String.valueOf(args.get(2));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			try {

				Document document;
				if(jdom instanceof Element){
					document = new Document();

					Element clone = (Element) ((Element)jdom).clone();
					document.setRootElement(clone);
				}
				else{
					document = (Document) jdom;
				}
				String reply = JdomUtils.getNode(document, locationPath).getAttributeValue(attName);
//					System.out.println(reply);
				return reply;
			} catch (Exception ex) {
				log.warn(ex);
				return "";
			}
		}
	}



	private class GetXmlData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					String reply = JdomUtils.getNodeText(jdom, locationPath, index);
//					System.out.println(reply);
					return reply;
				}
				else
				{
					Document document;
					if(jdom instanceof Element){
						document = new Document();

						Element clone = (Element) ((Element)jdom).clone();
						document.setRootElement(clone);
					}
					else{
						document = (Document) jdom;
					}
					String reply = JdomUtils.getNodeText(document, locationPath);
//					System.out.println(reply);
					return reply;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return "";
			}
		}
	}



	private class SetXmlData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			String value = String.valueOf(args.get(2));

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);

			try {
				if(args.size() == 3)
				{
					JdomUtils.setNodeText(jdom, locationPath, value);
				}
				else if(args.size() > 3)
				{
					String nodeValue = String.valueOf(args.get(3));

					// jdom, parentPath, nodename, nodevalue
					JdomUtils.setNodeText(jdom, locationPath, value, nodeValue);
				}

				return null;

			} catch (Exception ex) {
				log.warn(ex);
				return null;
			}
		}
	}



	private class isNull implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List list) throws FunctionCallException
		{
			if (list.get(0) == null) return "true";
			double length = 0.0;
			String variableName = String.valueOf(list.get(0));
			Object variable = getBpelExecutionContext().getVariableData().getValue(variableName);
			length = ExpressionUtils.getTypesLength(variable);
			return (length == 0) ? "true" : "false";
		}
	}



	private class ToTotal implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			try {
				double total = 0;
				for (Object object : args) {
					total += ((Number)object).doubleValue();
				}
				return total;
			} catch (Exception e) {
				log.error("Could not convert double [" + e.getMessage() + "]");
				return args.get(0);
			}
		}
	}



	private class ToDouble implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String value = "";
			try {
				value = args.get(0).toString();
				return Double.valueOf(value);
			} catch (Exception e) {
				log.error("Could not convert double [" + e.getMessage() + "]");
				return args.get(0);
			}
		}
	}


	private class ToInteger implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String value = "";
			try {
				value = args.get(0).toString();

				int index = value.indexOf( "." );
				if ( index > 0 )
					value = value.substring( 0, index );

				return Integer.valueOf(value);
			} catch (Exception e) {
				log.error("Could not convert integer [" + e.getMessage() + "]");
				return args.get(0);
			}
		}
	}

	private class ToLong implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String value = "";
			try {
				value = args.get(0).toString();

				int index = value.indexOf( "." );
				if ( index > 0 )
					value = value.substring( 0, index );

				return (long)Long.valueOf(value);
			} catch (Exception e) {
				log.error("Could not convert long [" + e.getMessage() + "]");
				return args.get(0);
			}
		}
	}


	private class GetXmlAttributeArray implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			Object[] object = null;
			try {
				List<String> list = JdomUtils.getNodeTextList(jdom,locationPath);

				object = new Object[list.size()];

				for( int i=0; i< list.size(); i++ )
				{
					object[i] = list.get(i);
				}
				return object;

			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}
	}



	private class GetXmlChildNodeValueArray implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			Object[] objList = null;

			try
			{
				List<Element> list =  JdomUtils.getNode(jdom, locationPath).getChildren();

				if( list.size() != 0 )
				{
					objList = new Object[list.size()];

					for( int i=0; i<list.size(); i++ )
					{
						objList[i] = list.get(i).getValue();
					}
				}

				return objList;
			}
			catch (Exception ex)
			{
				throw new RuntimeException(ex);
			}
		}
	}


	private class GetEventInfo implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public EventInfo call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath1 = String.valueOf(args.get(1));
			String locationPath2 = String.valueOf(args.get(2));

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);

			try
			{
				List<String> user =  JdomUtils.getNodeTextList(jdom, locationPath1);
				List<String> comment =  JdomUtils.getNodeTextList(jdom, locationPath2);

				EventInfo eventInfo = new EventInfo();

				if( user.size() != 0 )
					eventInfo.setEventUser(user.get(0));
				if( comment.size() != 0)
					eventInfo.setEventComment(comment.get(0));

				eventInfo.setEventName( "" );
				eventInfo.setBehaviorName( "" );
				eventInfo.setReasonCodeType( "" );
				eventInfo.setReasonCode( "" );
				eventInfo.setEventTime( TimeStampUtil.getCurrentTimestamp());

				return eventInfo;
			}
			catch (Exception ex)
			{
				throw new RuntimeException(ex);
			}
		}
	}


	private class GetNamedValue implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Map<String, String>  call(Context context, List args) throws RuntimeException

		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			Map<String, String> udfs = null;

			try
			{
				Element E = JdomUtils.getNode(jdom, locationPath);

				if( E != null)
				{
					List<Element> list =  JdomUtils.getNode(jdom, locationPath).getChildren();

					if( list.size() != 0 )
					{
						udfs = new HashMap<String, String>(list.size());

						for( int i=0; i<list.size(); i++ )
						{
							udfs.put(list.get(i).getName(), list.get(i).getText());
						}
					}
				}
				else
					udfs = new HashMap<String, String>();

				return udfs;
			}
			catch (Exception ex)
			{
				throw new RuntimeException(ex);
			}
		}
	}


	private class GetXmlDataTimeStamp implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Timestamp call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Timestamp call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			Timestamp timeStamp =null;

			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					String reply = JdomUtils.getNodeText(jdom, locationPath, index);

					timeStamp = ConvertUtil.convertToTimeStamp(reply);
					return timeStamp;
				}
				else
				{
					String reply = JdomUtils.getNodeText(jdom, locationPath);
					timeStamp = ConvertUtil.convertToTimeStamp(reply);
					return timeStamp;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return timeStamp;
			}
		}
	}


	private class GetXmlDataInt implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Integer call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Integer call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			int iReply=0;
			Document jdom = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					String reply = JdomUtils.getNodeText(jdom, locationPath, index);

					iReply = Integer.parseInt(reply);
					return iReply;
				}
				else
				{
					String reply = JdomUtils.getNodeText(jdom, locationPath);
					iReply = Integer.parseInt(reply);
					return iReply;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return iReply;
			}
		}
	}


//	private class GetProductPGS implements Function
//	{
//		/*
//		* Name : call
//		* Desc : This function is ProductPGS[] call
//		* Author : ZXY IDM Team
//		* Date : 2011.01.17
//		*/
//		public ProductPGS[] call(Context context, List args) throws RuntimeException
//		{
//			String variableName = String.valueOf(args.get(0));
//			String locationPath = String.valueOf(args.get(1));
//			String udfNode = String.valueOf(args.get(2));
//
//			org.jdom.Document jdom = (org.jdom.Document)getBpelExecutionContext().getVariableData().getValue(variableName);
//			ProductPGS[] productPGS = null;
//
//			try
//			{
//			   List<Element> list = JdomUtils.getList(jdom, locationPath);
//
//			   if( list.size() > 0 )
//			      productPGS = new ProductPGS[list.size()];
//			   else
//			   {
//				   productPGS = new ProductPGS[]{new ProductPGS()};
//				   productPGS[0].setUdfs(IDMFrameServiceProxy.getObjectAttributeDef().get("Product"));
//
//			   }
//
//		       for( int i=0; i<list.size(); i++ )
//		       {
//		    	   productPGS[i] = new ProductPGS();
//
//		    	   productPGS[i].setProductName(JdomUtils.getChildValue(list.get(i), 0));
//		    	   productPGS[i].setPosition(Integer.parseInt( JdomUtils.getChildValue(list.get(i), 1).toString()));
//		    	   productPGS[i].setProductGrade(JdomUtils.getChildValue(list.get(i), 2));
//		    	   productPGS[i].setSubProductGrades1(JdomUtils.getChildValue(list.get(i), 3));
//		    	   productPGS[i].setSubProductGrades2(JdomUtils.getChildValue(list.get(i), 4));
//		    	   productPGS[i].setUdfs(IDMFrameServiceProxy.getObjectAttributeDef().get("Product"));
//
//		    	   if( list.get(i).getChild(udfNode) != null)
//		    	   {
//		    		   for ( int j=0; j < list.get(i).getChild(udfNode).getChildren().size(); j++ )
//		    		   {
//		    			   productPGS[i].getUdfs().put(((Element) list.get(i).getChild(udfNode).getChildren().get(j)).getName(),
//		    					   JdomUtils.getChildValue(list.get(i).getChild(udfNode),j).toString());
//		    		   }
//		    	   }
//		       }
//
//			   return productPGS;
//		    }
//			catch (Exception ex)
//			{
//			   throw new RuntimeException(ex);
//		    }
//		}
//	}



//	private class GetProductU implements Function
//	{
//		/*
//		* Name : call
//		* Desc : This function is ProductU[] call
//		* Author : ZXY IDM Team
//		* Date : 2011.01.17
//		*/
//		public ProductU[] call(Context context, List args) throws RuntimeException
//		{
//			String variableName = String.valueOf(args.get(0));
//			String locationPath = String.valueOf(args.get(1));
//			String udfNode = String.valueOf(args.get(2));
//
//			org.jdom.Document jdom = (org.jdom.Document)getBpelExecutionContext().getVariableData().getValue(variableName);
//			ProductU[] productU = null;
//
//			try
//			{
//			   List<Element> list = JdomUtils.getList(jdom, locationPath);
//
//			   if( list.size() > 0 )
//				   productU = new ProductU[list.size()];
//			   else
//			   {
//				   productU = new ProductU[]{new ProductU()};
//				   productU[0].setUdfs(IDMFrameServiceProxy.getObjectAttributeDef().get("Product"));
//
//			   }
//
//		       for( int i=0; i<list.size(); i++ )
//		       {
//		    	   productU[i] = new ProductU();
//		    	   productU[i].setProductName(JdomUtils.getChildValue(list.get(i), 0));
//		    	   productU[0].setUdfs(IDMFrameServiceProxy.getObjectAttributeDef().get("Product"));
//
//		    	   if( list.get(i).getChild(udfNode) != null)
//		    	   {
//		    		   for ( int j=0; j < list.get(i).getChild(udfNode).getChildren().size(); j++ )
//		    		   {
//		    			   productU[i].getUdfs().put(((Element) list.get(i).getChild(udfNode).getChildren().get(j)).getName(),
//		    					   JdomUtils.getChildValue(list.get(i).getChild(udfNode),j).toString());
//		    		   }
//		    	   }
//		       }
//
//			   return productU;
//		    }
//			catch (Exception ex)
//			{
//			   throw new RuntimeException(ex);
//		    }
//		}
//	}



	private class GetXmlElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);
			Element replyElement = null;
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					replyElement = JdomUtils.getNode(jdom, locationPath, index);

					return replyElement;
				}
				else
				{
					replyElement = (Element)XPath.selectSingleNode(jdom, locationPath);
					//replyElement = JdomUtils.getNode(jdom, locationPath);

					return replyElement;
				}
			} catch (Exception ex) {
				log.warn(ex);
				return replyElement;
			}
		}
	}



	private class GetArrayValue implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			int idx1 = 0, idx2 = 0;
			try {
				idx1 = ConvertUtil.Object2Int(args.get(1));
				idx2 = ConvertUtil.Object2Int(args.get(2));
			} catch (Exception e) {
				idx2 = -1;
			}
			Object vValue = null;
			try {
				vValue = getBpelExecutionContext().getVariableData().getValue(variableName);
			} catch (Exception e) {
				variableName = variableName + "[" + String.valueOf(idx1) + "]";
				if (idx2 >= 0)
					variableName = variableName + "[" + String.valueOf(idx2) + "]";
				try {
					vValue = getBpelExecutionContext().getVariableData().getValue(variableName);
				} catch (Exception ex) {}
			}

			try {
				if (vValue instanceof String)
				{
					log.info(vValue.toString() + " is by " + variableName);
					return vValue;
				}
				else if (vValue instanceof String[])
				{
					log.info(((String[])vValue)[idx1] + " is by " + variableName + "[" + idx1 + "]");
					return ((String[])vValue)[idx1];
				}
				else if (vValue instanceof String[][])
				{
					log.info(((String[][])vValue)[idx1][idx2] + " is by " + variableName + "[" + idx1 + "][" + idx2 + "]");
					return ((String[][])vValue)[idx1][idx2];
				}
				else if (vValue instanceof List)
				{
					log.info(((List)vValue).get(idx1) + " is by " + variableName + "[" + idx1 + "]");
					return ((List)vValue).get(idx1);
				}
				else {
					log.error("no matched input index : variable [" + variableName + "]");
					return "";
				}
			} catch (Exception e) {
				log.error(e);
				return null;
			}
		}
	}



	private class GetObjectData implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String objectType = String.valueOf(args.get(0));
			String keyName = String.valueOf(args.get(1));

			try {

//				if ( objectType.equals("Alarm"))
//				{
//					AlarmKey key = new AlarmKey();
//					key.setAlarmId(keyName);
//					Alarm data = AlarmServiceProxy.getAlarmService().selectByKey(key);
//					return data;
//				}
//				else if ( objectType.equals("Consumable"))
//				{
//					ConsumableKey consumableKey = new ConsumableKey();
//					consumableKey.setConsumableName(keyName);
//					Consumable data = ConsumableServiceProxy.getConsumableService().selectByKey(consumableKey);
//
//					return data;
//
//				}
//				else
				/*if ( objectType.equals("Durable"))
				{
					DurableKey durableKey = new DurableKey();
					durableKey.setDurableName(keyName);
					Durable data = DurableServiceProxy.getDurableService().selectByKey(durableKey);

					return data;
				}*/
//				else if ( objectType.equals("Lot"))
//				{
//					LotKey lotKey = new LotKey();
//					lotKey.setLotName(keyName);
//					Lot data = LotServiceProxy.getLotService().selectByKey(lotKey);
//					return data;
//				}
				/*else if ( objectType.equals("Product"))
				{

					ProductKey productKey = new ProductKey();
					productKey.setProductName(keyName);
					productKey.setSiteName("B8");
					Product data = ProductServiceProxy.getProductService().selectByKey(productKey);
					return data;
				}*/
				/*else if ( objectType.equals("ProductRequest"))
				{

					ProductRequestKey productRequestKey = new ProductRequestKey();
					productRequestKey.setProductRequestName(keyName);
					ProductRequest data = ProductRequestServiceProxy.getProductRequestService().selectByKey(productRequestKey);

					return data;
				}*/
				/*else if ( objectType.equals("TransportGroup"))
				{
					TransportGroupKey transportGroupKey = new TransportGroupKey();
					transportGroupKey.setTransportGroupName(keyName);

					TransportGroup data = TransportGroupServiceProxy.getTransportGroupService().selectByKey(transportGroupKey);
					return data;
				}*/
				/*else if ( objectType.equals("PackingGroup"))
				{
					PackingGroupKey packingGroupKey = new PackingGroupKey();
					packingGroupKey.setSiteName("B8");
					packingGroupKey.setPackingGroupName(keyName);
					PackingGroup data = PackingServiceProxy.getPackingGroupService().selectByKey(packingGroupKey);
					return data;
				}*/
				/*else if ( objectType.equals("UserInfo"))
				{
					UserInfoKey userInfoKey = new UserInfoKey();
					userInfoKey.setUserId(keyName);
					UserInfo data = UserServiceProxy.getUserInfoService().selectByKey(userInfoKey);
					return data;
				}*/
//				else if ( objectType.equals("Machine"))
//				{
//					MachineKey machineKey = new MachineKey();
//					machineKey.setMachineName(keyName);
//					Machine data = MachineServiceProxy.getMachineService().selectByKey(machineKey);
//					return data;
//				}
//				else if ( objectType.equals("Port"))
//				{
//					PortKey portKey = new PortKey();
//					portKey.setMachineName(keyName);
//					portKey.setPortName(String.valueOf(args.get(2)));
//					Port data = PortServiceProxy.getPortService().selectByKey(portKey);
//					return data;
//				}
				/*else
				{*/
				return null;
				//}
			} catch (LocalizedException ex)
			{
				throw ex;
			} catch (IDMFrameErrorSignal ex)
			{
				throw ex;
			} catch (Exception ex) {
				throw null;
			}
		}
	}



	private class GetDataVariable implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object objectData   = args.get(0);
			String variableName = String.valueOf(args.get(1));

			try
			{
				String className =  objectData.getClass().getName().toString();
				Class clazz = Class.forName(className);

				Field [] fields = objectData.getClass().getDeclaredFields();
				AccessibleObject.setAccessible(fields, true);
				Object fieldData =	null;

				for ( int i = 0; i < fields.length; i++ )
				{
					if ( fields[i].getName().equals(variableName))
					{
						fieldData =  fields[i].get(objectData);
						break;
					}
				}


				if ( fieldData.getClass().getName().equals("java.lang.String"))
				{
					String data = fieldData.toString();
					return data;
				}
				else if ( fieldData.getClass().getName().equals("long"))
				{
					long data = Long.parseLong(fieldData.toString());
					return data;
				}
				else if ( fieldData.getClass().getName().equals("java.lang.Long"))
				{
					long data = Long.parseLong(fieldData.toString());
					return data;
				}
				else if ( fieldData.getClass().getName().equals("double"))
				{
					double data = Double.parseDouble(fieldData.toString());
					return data;
				}
				else if ( fieldData.getClass().getName().equals("java.lang.Double"))
				{
					double data = Double.parseDouble(fieldData.toString());
					return data;
				}
				else if ( fieldData.getClass().getName().equals("java.sql.Timestamp"))
				{
					Timestamp data = Timestamp.valueOf(fieldData.toString());

					return data;
				}
				else
				{
					return null;
				}

			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}
	}



	private class SetDataVariable implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object objectData = args.get(0);
			String variableName = String.valueOf(args.get(1));
			Object variableValue = args.get(2);

			try
			{
				Field [] fields = objectData.getClass().getDeclaredFields();
				AccessibleObject.setAccessible(fields, true);

				for (int i = 0; i < fields.length; i++)
				{
					if (fields[i].getName().equals(variableName))
					{
						fields[i].set(objectData, variableValue);

						break;
					}
				}

				return null;
			} catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}
	}



	private class GetLength implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{

			if (args.get(0) == null) return Double.valueOf("0");

			String variableName = String.valueOf(args.get(0));
			boolean isRegister = getBpelExecutionContext().getVariableData().getVariables().containsKey(variableName);

			Object variable = getBpelExecutionContext().getVariableData().getValue(variableName);

			if (variable instanceof String[][])
			{
				String[][] objResult = (String[][])variable;

				try {
					String indx = String.valueOf(args.get(1));
					return ExpressionUtils.toDouble(objResult[Integer.valueOf(indx)].length);

				} catch (Exception e) {
					return ExpressionUtils.toDouble(objResult.length);
				}

			}
			return ExpressionUtils.getTypesLength(variable);
		}
	}



	private class GetXMLArraySize implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Document doc = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);

			int size;
			try {
				size = XPath.selectNodes(doc, locationPath).size();
			} catch (JDOMException e) {
				size = -1;
			}
			return Integer.parseInt(String.valueOf(size));
		}
	}



	private class GetXMLBodyElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));

			Element child = null;
			try {
				Document doc = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
				child = doc.getRootElement().getChild("body");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return child;
		}
	}



	private class GetXMLArrayElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			String index 		= String.valueOf(args.get(2));

			Document doc = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);
			locationPath += String.format("[%s]", index);

			Element element = null;

			try {
				element =  JdomUtils.getNode(doc, locationPath);
			} catch (Exception e) {
				e.printStackTrace();
			}

			return element;
		}
	}



	private class GetXMLArrayValue implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			String index 		= String.valueOf(args.get(2));
			String nodeName 	= String.valueOf(args.get(3));

			Document doc = (Document)getBpelExecutionContext().getVariableData().getValue(variableName);

			locationPath += String.format("[%s]/%s", index , nodeName);

			try {
				return ((Element)XPath.selectSingleNode(doc, locationPath)).getValue();
			} catch (Exception e) {
				return "";
			}
		}
	}



	private class SetNVSeq implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context ctx, List args) throws RuntimeException
		{
			String objectType   = String.valueOf(args.get(0));
			String variableName = String.valueOf(args.get(1));

			Element element = (Element)getBpelExecutionContext().getVariableData().getValue(variableName);

			Map<String, String> map = new HashMap<String, String>();

			ArrayList<ObjectAttributeDef> objectAttributeDefs
					= ( ArrayList<ObjectAttributeDef> )IDMFrameServiceProxy.getObjectAttributeMap().getAttributeNames(objectType, "ExtendedC");

			if ( objectAttributeDefs != null )
			{
				String name = "";
				String value = "";

				for ( int i = 0; i < objectAttributeDefs.size(); i++ )
				{
					name = objectAttributeDefs.get(i).getAttributeName();

					if ( element != null )
					{
						for ( int j = 0; j < element.getContentSize(); j++ )
						{
							if ( element.getChildText(objectAttributeDefs.get(i).getAttributeName()) != null )
							{
								value = element.getChildText(objectAttributeDefs.get(i).getAttributeName());
							}
						}
					}else
					{
						value = "";
					}
					if ( name.equals("") != true )
						map.put( name, value );
				}
			}
			return map;
		}
	}



	private class GetChildElement implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String childNodeName = String.valueOf(args.get(1));

			Element xmlElement = (Element)getBpelExecutionContext().getVariableData().getValue(variableName);

			try {

				return xmlElement.getChild(childNodeName);

			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}



	private class DetachXmlNode implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));
			Object jdom = getBpelExecutionContext().getVariableData().getValue(variableName);

			try {
				Element detachElement =
						JdomUtils.getNode(jdom, locationPath);

				if(detachElement.getChildren().size() > 0)
					detachElement.detach();
				return null;

			} catch (Exception ex) {
				log.error(ex);
				return "";
			}
		}
	}



	private class GetXmlElementChildList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object xmlObject = getBpelExecutionContext().getVariableData().getValue(variableName);

			Element replyElement = null;
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					replyElement = JdomUtils.getNode(xmlObject, locationPath, index);

					return replyElement.getChildren();
				}
				else
				{
					replyElement = JdomUtils.getNode(xmlObject, locationPath);
					if(replyElement!=null)
						return replyElement.getChildren();
					else
						return null;
				}
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}



	private class GetXmlElementChildArray implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String locationPath = String.valueOf(args.get(1));

			Object xmlObject = getBpelExecutionContext().getVariableData().getValue(variableName);

			Element replyElement = null;
			try {
				if(args.size() > 2)
				{
					int index = ExpressionUtils.getIntValue(args.get(2));

					replyElement = JdomUtils.getNode(xmlObject, locationPath, index);

					return replyElement.getChildren().toArray(new Element[0]);
				}
				else
				{
					replyElement = JdomUtils.getNode(xmlObject, locationPath);
					return replyElement.getChildren().toArray(new Element[0]);
				}
			} catch (Exception ex) {
				log.error(ex);
				return null;
			}
		}
	}



	private class GetElementTextList implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String xpath = String.valueOf(args.get(1));
			Object value = getBpelExecutionContext().getVariableData().getValue(variableName);
			List<Element> selectNodes;
			try {
				selectNodes = XPath.selectNodes(value, xpath);
			} catch (JDOMException e) {
				log.error(e);
				return null;
			}
			List<String> list = new ArrayList<String>();
			for (Element element : selectNodes) {
				list.add(element.getText());
			}
			return list;
		}
	}



	private class GetElementChildText implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			String variableName = String.valueOf(args.get(0));
			String childNodeName = String.valueOf(args.get(1));

			Element xmlElement = (Element)getBpelExecutionContext().getVariableData().getValue(variableName);

			try {

				return xmlElement.getChildText(childNodeName);

			} catch (Exception ex) {
				log.error(ex);
				return "";
			}
		}
	}



	private class Append implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			try
			{
				Object prefix = (String)args.get(0);
				Object suffix = (String)args.get(1);

				return String.valueOf(prefix) + String.valueOf(suffix);
			}
			catch(Exception ex)
			{
				log.error(ex);

				return "";
			}
		}
	}



	private class ToString implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object value = null;
			try {
				value = args.get(0);
				if(value  == null)
				{
					return "";
				}
				else
				{
					if( value instanceof String)
					{
						String variableName = value.toString();
						value = getBpelExecutionContext().getVariableData().getValue(variableName);
						return String.valueOf(value);
					}
					else if (value instanceof Timestamp)
					{
						return ConvertUtil.toString((Timestamp)value);
					}
					else if(value instanceof Double)
					{
						String tempVariableStr = String.valueOf(value);
						int delemiterPos = StringUtils.indexOf(tempVariableStr, '.');
						if(delemiterPos != -1)
						{
							return StringUtils.substringBefore(tempVariableStr, ".");
						}
						else
						{
							return tempVariableStr;
						}
					}
					else
					{
						return String.valueOf(value);
					}
				}


			} catch (Exception e) {
				log.error(e);
				return args.get(0);
			}
		}
	}



	private class GetTimeKey implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			return ConvertUtil.getCurrTimeKey();
		}
	}


	private class GetDifferTimeInSecond implements Function
	{
		/*
		 * Name : call
		 * Desc : This function is Object call
		 * Author : ZXY IDM Team
		 * Date : 2011.01.17
		 */
		public Object call(Context context, List args) throws RuntimeException
		{
			Object firstTime = args.get(0);
			Object secondTime = args.get(1);

			try {
				if(firstTime instanceof Timestamp && secondTime instanceof Timestamp)
				{
					Timestamp tempFTimeStamp = (Timestamp)firstTime;
					Timestamp tempSTimeStamp = (Timestamp)secondTime;
					return (tempFTimeStamp.getTime() - tempSTimeStamp.getTime()) / 1000;

				}
				else if(firstTime instanceof Date && secondTime instanceof Date)
				{
					Date tempFTimeStamp = (Date)firstTime;
					Date tempSTimeStamp = (Date)secondTime;
					return (tempFTimeStamp.getTime() - tempSTimeStamp.getTime()) / 1000;
				}
				else
				{
					return null;
				}
			} catch (Exception e) {
				log.error(e);
				return null;
			}
		}
	}

}



class ExpressionUtils
{
	/*
	 * Name : getIntValue
	 * Desc : This function is getIntValue
	 * Author : ZXY IDM Team
	 * Date : 2011.01.17
	 */
	public static int getIntValue(Object obj)
	{
		int value;
		if(obj instanceof Number)
			value = ((Number)obj).intValue();
		else
			value = Integer.parseInt(obj.toString());
		return value;
	}

	/*
	 * Name : getTypesLength
	 * Desc : This function is getTypesLength
	 * Author : ZXY IDM Team
	 * Date : 2011.01.17
	 */
	public static double getTypesLength(Object objData)
	{
		if (objData == null) return Double.valueOf("0");
		if (objData instanceof String[][])
		{
			try {
				return ((String[][])objData)[0].length;
			} catch (Exception e) {
				return ((String[][])objData).length;
			}
		}
		else if (objData instanceof List)
			return ((List)objData).size();
		else if (objData instanceof String)
			return Double.valueOf((String.valueOf(objData).length()));
		else if(objData instanceof Object[]){
			return ((Object[])objData).length;
		} else if(objData instanceof Collection) {
			return ((Collection) objData).size();
		} else if(objData instanceof Map){
			return ((Map) objData).values().size();
		} else {
			return 1;
		}
	}

	/*
	 * Name : toDouble
	 * Desc : This function is toDouble
	 * Author : ZXY IDM Team
	 * Date : 2011.01.17
	 */
	public static Object toDouble(Object data)
	{
		try {
			return Double.valueOf(data.toString());
		} catch (Exception e) {
			return data;
		}
	}
}