Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.bpmn.runtime.task.MethodCallTask Maven / Gradle / Ivy
Go to download
The Jadex BPMN kernel provides a workflow kernel for the standardized business process modeling notation. The kernel relies on annotated BPMN diagrams, which include detailed execution information.
package jadex.bpmn.runtime.task;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import jadex.bpmn.model.IModelContainer;
import jadex.bpmn.model.MActivity;
import jadex.bpmn.model.MParameter;
import jadex.bpmn.model.MProperty;
import jadex.bpmn.model.task.ITask;
import jadex.bpmn.model.task.ITaskContext;
import jadex.bpmn.model.task.ITaskPropertyGui;
import jadex.bpmn.model.task.annotation.Task;
import jadex.bpmn.model.task.annotation.TaskProperty;
import jadex.bpmn.model.task.annotation.TaskPropertyGui;
import jadex.bpmn.runtime.task.MethodCallTask.ServiceCallTaskGui;
import jadex.bpmn.task.info.ParameterMetaInfo;
import jadex.bridge.ClassInfo;
import jadex.bridge.IInternalAccess;
import jadex.bridge.modelinfo.IModelInfo;
import jadex.bridge.modelinfo.UnparsedExpression;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.commons.SReflect;
import jadex.commons.collection.IndexMap;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.gui.PropertiesPanel;
import jadex.javaparser.SJavaParser;
/**
* Call a method.
* Class and method name may be specified as parameters.
* Rebind parameter is also supported.
* All other in and inout parameters are interpreted as method arguments.
* One out or inout parameter may be specifed to receive the call result.
* Service name may alternatively supplied as name of lane and
* method name as name of activity.
*/
@Task(description="The print task can be used for calling a component service.", properties={
@TaskProperty(name="service", clazz=String.class, description="The required service name."),
@TaskProperty(name="method", clazz=String.class, description="The required method name.")},
gui=@TaskPropertyGui(ServiceCallTaskGui.class)
// @TaskProperty(name="rebind", clazz=boolean.class, description="The rebind flag (forces a frsh search).")
)
public class MethodCallTask implements ITask
{
//-------- constants --------
/** Property for service name. */
public static final String PROPERTY_SERVICE = "service";
/** Property for method name. */
public static final String PROPERTY_METHOD = "method";
//-------- ITask interface --------
/**
* Execute the task.
* @param context The accessible values.
* @param process The process instance executing the task.
* @return To be notified, when the task has completed.
*/
public IFuture execute(final ITaskContext context, final IInternalAccess process)
{
final Future ret = new Future();
String service = (String)context.getPropertyValue(PROPERTY_SERVICE);
String method = (String)context.getPropertyValue(PROPERTY_METHOD);
String resultparam = null;
// Collect arguments and settings.
final List args = new ArrayList();
final List> argtypes = new ArrayList>();
IndexMap mparams = context.getActivity().getParameters();
if(mparams!=null)
{
for(Iterator it=mparams.values().iterator(); it.hasNext(); )
{
MParameter param = (MParameter)it.next();
if(PROPERTY_SERVICE.equals(param.getName()))
{
service = (String)context.getParameterValue(param.getName());
}
else if(PROPERTY_METHOD.equals(param.getName()))
{
method = (String)context.getParameterValue(param.getName());
}
else if(MParameter.DIRECTION_IN.equals(param.getDirection()))
{
args.add(context.getParameterValue(param.getName()));
argtypes.add(param.getClazz().getType(process.getClassLoader(), process.getModel().getAllImports()));
}
else if(MParameter.DIRECTION_INOUT.equals(param.getDirection()))
{
if(resultparam!=null)
throw new RuntimeException("Only one 'out' parameter allowed for ServiceCallTask: "+context);
resultparam = param.getName();
args.add(context.getParameterValue(param.getName()));
argtypes.add(param.getClazz().getType(process.getClassLoader(), process.getModel().getAllImports()));
}
else if(MParameter.DIRECTION_OUT.equals(param.getDirection()))
{
if(resultparam!=null)
throw new RuntimeException("Only one 'out' parameter allowed for ServiceCallTask: "+context);
resultparam = param.getName();
}
}
}
// Apply shortcuts, if necessary.
if(service==null && context.getActivity().getLane()!=null)
{
service = context.getActivity().getLane().getName();
}
if(method==null)
{
method = context.getActivity().getName();
}
if(service==null)
{
throw new RuntimeException("No 'service' specified for ServiceCallTask: "+context);
}
if(method==null)
{
throw new RuntimeException("No 'method' specified for ServiceCallTask: "+context);
}
// Fetch service and call method.
final String fservice = service;
final String fmethod = method;
final String fresultparam = resultparam;
process.getComponentFeature(IRequiredServicesFeature.class).getRequiredService(service)
.addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Object result)
{
Class> servicetype = process.getComponentFeature(IRequiredServicesFeature.class).getRequiredServiceInfo(fservice).getType().getType(process.getClassLoader(), process.getModel().getAllImports());
//Method m = SReflect.getMethod(result.getClass(), fmethod, (Class[])argtypes.toArray(new Class[argtypes.size()]));
Method[] methods = servicetype.getMethods();
Method m = null;
for (Method method : methods)
{
if (method.toString().equals(fmethod))
{
m = method;
break;
}
}
if(m==null)
{
throw new RuntimeException("MCT: "+ String.valueOf(process.getModel().getFilename()) + " Method "+fmethod+argtypes+" not found for service "+fservice+ " " + fservice + ": "+context);
}
try
{
Object val = m.invoke(result, args.toArray());
if(val instanceof IFuture)
{
((IFuture)val).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Object result)
{
if(fresultparam!=null)
context.setParameterValue(fresultparam, result);
ret.setResult(null);
}
});
}
else
{
if(fresultparam!=null)
context.setParameterValue(fresultparam, val);
ret.setResult(null);
}
}
catch(InvocationTargetException ite)
{
ret.setException((Exception)ite.getTargetException());
}
catch(Exception e)
{
ret.setException(e);
}
}
});
return ret;
}
// /**
// * Execute the task.
// * @param context The accessible values.
// * @param process The process instance executing the task.
// * @return To be notified, when the task has completed.
// */
// public IFuture execute(final ITaskContext context, final IInternalAccess process)
// {
// final Future ret = new Future();
// String service = null;
// String method = null;
// String resultparam = null;
// boolean rebind = false;
//
// // Collect arguments and settings.
// final List args = new ArrayList();
// final List argtypes = new ArrayList();
// IndexMap mparams = context.getActivity().getParameters();
// for(Iterator it=mparams.values().iterator(); it.hasNext(); )
// {
// MParameter param = (MParameter)it.next();
// if(PARAMETER_SERVICE.equals(param.getName()))
// {
// service = (String)context.getParameterValue(param.getName());
// }
// else if(PARAMETER_METHOD.equals(param.getName()))
// {
// method = (String)context.getParameterValue(param.getName());
// }
// else if(PARAMETER_REBIND.equals(param.getName()))
// {
// Object val = context.getParameterValue(param.getName());
// rebind = val!=null ? ((Boolean)val).booleanValue() : false;
// }
// else if(MParameter.DIRECTION_IN.equals(param.getDirection()))
// {
// args.add(context.getParameterValue(param.getName()));
// argtypes.add(param.getClazz().getType(process.getClassLoader(), process.getModel().getAllImports()));
// }
// else if(MParameter.DIRECTION_INOUT.equals(param.getDirection()))
// {
// if(resultparam!=null)
// throw new RuntimeException("Only one 'out' parameter allowed for ServiceCallTask: "+context);
//
// resultparam = param.getName();
// args.add(context.getParameterValue(param.getName()));
// argtypes.add(param.getClazz().getType(process.getClassLoader(), process.getModel().getAllImports()));
// }
// else if(MParameter.DIRECTION_OUT.equals(param.getDirection()))
// {
// if(resultparam!=null)
// throw new RuntimeException("Only one 'out' parameter allowed for ServiceCallTask: "+context);
//
// resultparam = param.getName();
// }
// }
//
// // Apply shortcuts, if necessary.
// if(service==null && context.getActivity().getLane()!=null)
// {
// service = context.getActivity().getLane().getName();
// }
// if(method==null)
// {
// method = context.getActivity().getName();
// }
//
// if(service==null)
// {
// throw new RuntimeException("No 'service' specified for ServiceCallTask: "+context);
// }
// if(method==null)
// {
// throw new RuntimeException("No 'method' specified for ServiceCallTask: "+context);
// }
//
// // Fetch service and call method.
// final String fservice = service;
// final String fmethod = method;
// final String fresultparam = resultparam;
// process.getServiceContainer().getRequiredService(service, rebind)
// .addResultListener(new DelegationResultListener(ret)
// {
// public void customResultAvailable(Object result)
// {
// Method m = SReflect.getMethod(result.getClass(), fmethod, (Class[])argtypes.toArray(new Class[argtypes.size()]));
// if(m==null)
// {
// throw new RuntimeException("Method "+fmethod+argtypes+" not found for service "+fservice+": "+context);
// }
// try
// {
// Object val = m.invoke(result, args.toArray());
// if(val instanceof IFuture)
// {
// ((IFuture)val).addResultListener(new DelegationResultListener(ret)
// {
// public void customResultAvailable(Object result)
// {
// if(fresultparam!=null)
// context.setParameterValue(fresultparam, result);
// ret.setResult(null);
// }
// });
// }
// else
// {
// if(fresultparam!=null)
// context.setParameterValue(fresultparam, val);
// ret.setResult(null);
// }
// }
// catch(InvocationTargetException ite)
// {
// ret.setException((Exception)ite.getTargetException());
// }
// catch(Exception e)
// {
// ret.setException(e);
// }
// }
// });
//
// return ret;
// }
/**
* Compensate in case the task is canceled.
* @return To be notified, when the compensation has completed.
*/
public IFuture cancel(IInternalAccess instance)
{
// Todo: how to compensate service call!?
return IFuture.DONE;
}
/**
* Get the extra parameters that depend on the property settings of the task.
*/
public static List getExtraParameters(Map params, IModelContainer modelcontainer, ClassLoader cl)
{
List ret = new ArrayList();
IModelInfo mi = modelcontainer.getBpmnModel().getModelInfo();
try
{
MProperty msparam = params.get(PROPERTY_SERVICE);
MProperty mmparam = params.get(PROPERTY_METHOD);
if(msparam!=null && mmparam!=null)
{
String reqname = (String)SJavaParser.evaluateExpression(msparam.getInitialValue().getValue(), mi.getAllImports(), null, cl);
String methodname = (String)SJavaParser.evaluateExpression(mmparam.getInitialValue().getValue(), mi.getAllImports(), null, cl);
if(reqname!=null && methodname!=null)
{
RequiredServiceInfo reqser = mi.getRequiredService(reqname);
if(reqser!=null)
{
Class> type = reqser.getType().getType(cl==null? MethodCallTask.class.getClassLoader(): cl, mi.getAllImports());
if(type!=null)
{
Method[] ms = type.getMethods();
// todo check parameter types?
for(Method m: ms)
{
if(m.toString().equals(methodname))
{
List names = modelcontainer.getParameterNames(m);
String retname = modelcontainer.getReturnValueName(m);
Type[] ptypes = m.getGenericParameterTypes();
Type pret = m.getGenericReturnType();
for(int j=0; j0? names.get(j): "param"+j, null, null));
}
if(!pret.equals(Void.class) && !pret.equals(void.class))
{
ret.add(new ParameterMetaInfo(ParameterMetaInfo.DIRECTION_OUT, new ClassInfo(pret), retname==null? "return": retname, null, null));
}
}
}
}
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
return ret;
}
/**
*
*/
public static class ServiceCallTaskGui implements ITaskPropertyGui
{
/** The panel. */
protected JPanel panel;
/** The model. */
protected IModelInfo model;
/** The task. */
protected MActivity task;
/** The classloader. */
protected ClassLoader cl;
/** The combo box for the service name. */
protected JComboBox cbsername;
/** The combo box for the method name. */
protected JComboBox cbmethodname;
/**
* Once called to init the component.
*/
public void init(final IModelContainer container, final MActivity task, final ClassLoader cl)
{
this.model = container.getBpmnModel().getModelInfo();
this.task = task;
this.cl = cl;
PropertiesPanel pp = new PropertiesPanel();
cbsername = pp.createComboBox("Required service name:", null);
cbmethodname = pp.createComboBox("Method name", null);
cbmethodname.setRenderer(new BasicComboBoxRenderer()
{
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
{
Method method = (Method)value;
String txt = null;
if(method!=null)
txt = SReflect.getMethodSignature(method);
return super.getListCellRendererComponent(list, txt, index, isSelected, cellHasFocus);
}
});
cbsername.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String reqname = (String)cbsername.getSelectedItem();
MProperty mprop = task.getProperties().get(PROPERTY_SERVICE);
UnparsedExpression uexp = new UnparsedExpression(null,
String.class, "\""+reqname+"\"", null);
mprop.setInitialValue(uexp);
if(reqname!=null && model.getRequiredService(reqname)!=null)
{
RequiredServiceInfo reqser = model.getRequiredService(reqname);
Class> type = reqser.getType().getType(cl==null? MethodCallTask.class.getClassLoader(): cl, model.getAllImports());
if(type!=null)
{
ActionListener[] als = cbmethodname.getActionListeners();
for(ActionListener al: als)
cbmethodname.removeActionListener(al);
DefaultComboBoxModel mo = ((DefaultComboBoxModel)cbmethodname.getModel());
mo.removeAllElements();
Method[] ms = type.getMethods();
for(Method m: ms)
{
mo.addElement(m);
}
for(ActionListener al: als)
cbmethodname.addActionListener(al);
}
}
}
});
cbmethodname.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
Method method = (Method)cbmethodname.getSelectedItem();
// System.out.println("setting: "+method);
MProperty mprop = task.getProperties().get(PROPERTY_METHOD);
UnparsedExpression uexp = new UnparsedExpression(null,
String.class, method!=null? "\""+method.toString()+"\"": "null", null);
mprop.setInitialValue(uexp);
}
});
refresh();
panel = pp;
}
/**
*
*/
protected void refresh()
{
DefaultComboBoxModel mo = ((DefaultComboBoxModel)cbsername.getModel());
mo.removeAllElements();
RequiredServiceInfo[] reqs = model.getRequiredServices();
ActionListener[] als = cbsername.getActionListeners();
for(ActionListener al: als)
cbsername.removeActionListener(al);
if(reqs!=null)
{
for(int i=0; i type = reqser.getType().getType(cl==null? MethodCallTask.class.getClassLoader(): cl, model.getAllImports());
if(type!=null)
{
Method[] ms = type.getMethods();
for(Method m: ms)
{
if(m.toString().equals(methodname))
{
cbmethodname.setSelectedItem(m);
// System.out.println("sel item2: "+methodname);
}
}
}
}
}
}
}
/**
* Informs the panel that it should stop all its computation.
*/
public void shutdown()
{
}
/**
* The component to be shown in the gui.
* @return The component to be displayed.
*/
public JComponent getComponent()
{
return panel;
}
}
}