From 2a0a15e1ef639f1848b6bb4e8676e6ec5032f7c7 Mon Sep 17 00:00:00 2001 From: jyjang Date: Mon, 19 Mar 2018 10:55:19 +0900 Subject: [PATCH] Addition of many Event Types and correction of Naming --- .../bpmn/importer/OpenGraphAdapter.java | 6 +- .../bpmn/importer/TBoundaryEventAdapter.java | 30 +++- .../TEscalationEventDefinitionAdapter.java | 28 ++- .../bpmn/importer/TEventAdapter.java | 2 + .../kernel/bpmn/view/MessageFlowView.java | 7 - .../java/org/uengine/kernel/AbstractFlow.java | 43 ++++- .../java/org/uengine/kernel/Activity.java | 23 ++- .../uengine/kernel/CatchingMessageEvent.java | 45 ++++- .../kernel/DefaultProcessInstance.java | 41 ++++- .../java/org/uengine/kernel/MessageFlow.java | 13 +- .../org/uengine/kernel/ProcessDefinition.java | 23 +++ .../org/uengine/kernel/ScopeActivity.java | 4 + .../org/uengine/kernel/ScriptActivity.java | 49 ++++- .../kernel/bpmn/ConditionalCatchEvent.java | 50 +++++- .../org/uengine/kernel/bpmn/EndEvent.java | 162 ++--------------- .../EscalationIntermediateCatchEvent.java | 2 +- .../EscalationIntermediateThrowEvent.java | 2 +- .../java/org/uengine/kernel/bpmn/Event.java | 2 - .../kernel/bpmn/EventBasedGateway.java | 8 +- .../uengine/kernel/bpmn/ExclusiveGateway.java | 43 ++++- .../org/uengine/kernel/bpmn/FlowActivity.java | 5 +- .../bpmn/MessageIntermediateCatchEvent.java | 2 +- .../bpmn/MessageIntermediateThrowEvent.java | 2 +- .../org/uengine/kernel/bpmn/SequenceFlow.java | 49 ++--- .../org/uengine/kernel/bpmn/ServiceTask.java | 38 +++- .../kernel/bpmn/SignalEventInstance.java | 24 ++- .../bpmn/SignalIntermediateCatchEvent.java | 101 +++++------ .../kernel/bpmn/TerminateEndEvent.java | 168 +----------------- .../org/uengine/kernel/bpmn/TimerEvent.java | 59 ++++-- .../uengine/kernel/bpmn/TimerEventJob.java | 2 +- .../kernel/bpmn/TimerIntermediateEvent.java | 15 +- .../uengine/kernel/bpmn/TimerStartEvent.java | 2 +- .../processmanager/ProcessManagerBean.java | 2 +- 33 files changed, 578 insertions(+), 474 deletions(-) diff --git a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/OpenGraphAdapter.java b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/OpenGraphAdapter.java index 97d1e94f..619d90c7 100644 --- a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/OpenGraphAdapter.java +++ b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/OpenGraphAdapter.java @@ -63,7 +63,7 @@ public void findSubProcessActivityInformation(List activityList, List< } - public void createOpenGraphInformation() { + public void createOpenGraphInformation() { //TODO: why this is needed? for(SequenceFlow sequenceFlow : getAllSequenceFlowList()) { StringBuffer values = new StringBuffer(); @@ -73,8 +73,8 @@ public void createOpenGraphInformation() { } } sequenceFlow.getRelationView().setValue(values.toString().substring(0, values.length() - 1).replace("@", ",")); - sequenceFlow.getRelationView().setGeom(createGEOM(values.toString().substring(0, values.length() - 1))); - sequenceFlow.getRelationView().setStyle(createStyle()); +// sequenceFlow.getRelationView().setGeom(createGEOM(values.toString().substring(0, values.length() - 1))); +// sequenceFlow.getRelationView().setStyle(createStyle()); } } diff --git a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TBoundaryEventAdapter.java b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TBoundaryEventAdapter.java index 125ba83b..ca68b4e9 100644 --- a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TBoundaryEventAdapter.java +++ b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TBoundaryEventAdapter.java @@ -1,18 +1,38 @@ package org.uengine.processpublisher.bpmn.importer; import org.omg.spec.bpmn._20100524.model.TBoundaryEvent; +import org.omg.spec.bpmn._20100524.model.TEventDefinition; +import org.uengine.kernel.bpmn.Event; import org.uengine.kernel.bpmn.TimerEvent; +import org.uengine.processpublisher.Adapter; +import org.uengine.processpublisher.BPMNUtil; +import javax.xml.bind.JAXBElement; import java.util.Hashtable; -public class TBoundaryEventAdapter extends TFlowNodeAdapter { +public class TBoundaryEventAdapter extends TFlowNodeAdapter { @Override - public TimerEvent createActivity(TBoundaryEvent src, Hashtable keyedContext){ -// String eventDefinitionClassName = eventDefinition.getClass().getName(); -// String eventTypeName = eventDefinitionClassName.substring(0, eventDefinitionClassName.length() - "Definition".length()); + public Event createActivity(TBoundaryEvent src, Hashtable keyedContext){ + + for(JAXBElement element : src.getEventDefinition()){ + + TEventDefinition eventDefinition = element.getValue(); + + Adapter adapter = BPMNUtil.getAdapter(eventDefinition.getClass(), true); + keyedContext.put("eventType", "Intermediate"); + keyedContext.put("catching", true); + try { + Event event = (Event) adapter.convert(eventDefinition, keyedContext); + event.setAttachedToRef(src.getAttachedToRef().getLocalPart()); + return event; + } catch (Exception e) { + e.printStackTrace(); + } + } + + throw new RuntimeException("There's no adaptor to convert Event type: " + src.getClass()); - return new TimerEvent(); } diff --git a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEscalationEventDefinitionAdapter.java b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEscalationEventDefinitionAdapter.java index 311113b0..cb4238da 100644 --- a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEscalationEventDefinitionAdapter.java +++ b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEscalationEventDefinitionAdapter.java @@ -9,7 +9,8 @@ public class TEscalationEventDefinitionAdapter implements Adapter { @Override public Event convert(TEscalationEventDefinition src, Hashtable keyedContext) throws Exception { - Event event = new Event(); + Event event = createEvent(keyedContext); + if(src.getEscalationRef()!=null) { String escalationCode = src.getEscalationRef().getLocalPart(); @@ -18,4 +19,29 @@ public Event convert(TEscalationEventDefinition src, Hashtable keyedContext) thr return event; } + + private static Event createEvent(Hashtable keyedContext) throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Event event; + + String eventClassName = "Escalation"; + + String eventType = (String) keyedContext.get("eventType"); + + if(eventType == null){ + eventType = "Intermediate"; + } + + eventClassName += eventType; + + if(new Boolean(true).equals(keyedContext.get("catching"))){ + eventClassName += "Catch"; + }else{ + eventClassName += "Throw"; + } + + eventClassName += "Event"; + + event = (Event) Thread.currentThread().getContextClassLoader().loadClass("org.uengine.kernel.bpmn." + eventClassName).newInstance(); + return event; + } } \ No newline at end of file diff --git a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEventAdapter.java b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEventAdapter.java index ba5f7105..8399e2bc 100644 --- a/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEventAdapter.java +++ b/bpmn-model/src/main/java/org/uengine/processpublisher/bpmn/importer/TEventAdapter.java @@ -14,4 +14,6 @@ public Event createActivity(TEvent src, Hashtable keyedContext){ return event; } + + } diff --git a/uengine-bpmn-modeler/src/main/java/org/uengine/kernel/bpmn/view/MessageFlowView.java b/uengine-bpmn-modeler/src/main/java/org/uengine/kernel/bpmn/view/MessageFlowView.java index 6b8e2f96..cc702c4d 100644 --- a/uengine-bpmn-modeler/src/main/java/org/uengine/kernel/bpmn/view/MessageFlowView.java +++ b/uengine-bpmn-modeler/src/main/java/org/uengine/kernel/bpmn/view/MessageFlowView.java @@ -1,13 +1,6 @@ package org.uengine.kernel.bpmn.view; -import org.metaworks.EventContext; -import org.metaworks.annotation.ServiceMethod; -import org.uengine.kernel.MessageSequenceFlow; -import org.uengine.kernel.bpmn.SequenceFlow; import org.uengine.modeling.IRelation; -import org.uengine.modeling.RelationPropertiesView; -import org.uengine.modeling.Symbol; -import org.uengine.modeling.modeler.symbol.ConnectorSymbol; public class MessageFlowView extends SequenceFlowView { diff --git a/uengine-core/src/main/java/org/uengine/kernel/AbstractFlow.java b/uengine-core/src/main/java/org/uengine/kernel/AbstractFlow.java index 6541b2e6..03d6f4cc 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/AbstractFlow.java +++ b/uengine-core/src/main/java/org/uengine/kernel/AbstractFlow.java @@ -1,7 +1,46 @@ package org.uengine.kernel; +import org.metaworks.annotation.Hidden; +import org.metaworks.annotation.Id; +import org.uengine.modeling.Relation; + /** * Created by uengine on 2018. 3. 2.. */ -public class AbstractFlow { -} +public abstract class AbstractFlow extends Relation implements java.io.Serializable { + private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; + + private String sourceRef; + + @Hidden + public String getSourceRef() { + return sourceRef; + } + + public void setSourceRef(String source) { + this.sourceRef = source; + } + + private String targetRef; + + @Hidden + public String getTargetRef() { + return targetRef; + } + + public void setTargetRef(String target) { + this.targetRef = target; + } + + String tracingTag; + + @Id + @Hidden + public String getTracingTag() { + return tracingTag; + } + + public void setTracingTag(String tag) { + tracingTag = tag; + } +} \ No newline at end of file diff --git a/uengine-core/src/main/java/org/uengine/kernel/Activity.java b/uengine-core/src/main/java/org/uengine/kernel/Activity.java index 211cb5d7..b4dd6d63 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/Activity.java +++ b/uengine-core/src/main/java/org/uengine/kernel/Activity.java @@ -13,6 +13,7 @@ import java.lang.reflect.Method; import java.util.*; +import org.codehaus.jackson.map.ObjectMapper; import org.metaworks.ContextAware; import org.metaworks.MetaworksContext; import org.metaworks.annotation.Face; @@ -90,6 +91,7 @@ public abstract class Activity implements IElement, Validatable, java.io.Seriali final public static String PVKEY_LOOPBACK_CNT = "_loopBackCnt"; public static final String STATUS_RESERVED = "Reserved"; + static ObjectMapper objectMapper = new ObjectMapper(); transient MetaworksContext metaworksContext; @@ -573,8 +575,6 @@ protected void afterComplete(ProcessInstance instance) throws Exception{ instance.getProcessTransactionContext().addExecutedActivityInstanceContext(new ActivityInstanceContext(this, instance)); // - if(!(this instanceof ProcessDefinition)) - instance.getActivityCompletionHistory().add(getTracingTag()); } /** @@ -738,6 +738,10 @@ protected void onChanged(ProcessInstance instance) throws Exception{ * In the other hand, if you implement a asynchronous job of activity, you calls this fireComplete() after done (or after receiving the result). */ public void fireComplete(ProcessInstance instance) throws Exception{ + //This must be before than the onEvent since connected activity would not recognize this is completed. + if(!(this instanceof ProcessDefinition)) + instance.getActivityCompletionHistory().add(getTracingTag()); + setTokenCount(instance, 0); onEvent(ACTIVITY_DONE, instance, this); } @@ -1256,6 +1260,7 @@ private int evaluateContent_(ProcessInstance instance, String expression, Valida int pos; int endpos; String key; + while((pos = expression.indexOf(starter, oldpos)) > -1){ pos += starter.length(); endpos = expression.indexOf(ending, pos); @@ -1272,8 +1277,18 @@ private int evaluateContent_(ProcessInstance instance, String expression, Valida System.out.println("Activity:: evaluateContent: key="+key); Object val = Activity.getSpecialKeyValues(this, instance, key, validationContext); // System.out.println("EMailActivity:: parseContent: val:"+val); - if(val!=null) - generating.append("" + val); + + if(val!=null) { + if(val instanceof Map) { + try { + generating.append(objectMapper.writeValueAsString(val)); + } catch (IOException e) { + throw new RuntimeException("failed to convert to JSON", e); + } + }else + + generating.append("" + val); + } } oldpos = endpos + ending.length(); } diff --git a/uengine-core/src/main/java/org/uengine/kernel/CatchingMessageEvent.java b/uengine-core/src/main/java/org/uengine/kernel/CatchingMessageEvent.java index d8a3b1fc..cd0756a8 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/CatchingMessageEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/CatchingMessageEvent.java @@ -3,6 +3,7 @@ import com.jayway.jsonpath.JsonPath; import org.codehaus.jackson.JsonNode; import org.uengine.kernel.bpmn.Event; +import org.uengine.kernel.bpmn.ServiceTask; import org.uengine.processdesigner.mapper.TransformerMapping; import org.uengine.uml.model.ObjectInstance; @@ -22,7 +23,7 @@ public CatchingMessageEvent(){ @Override protected void executeActivity(ProcessInstance instance) throws Exception { - //start listens... + if(checkLocalCall(instance)) return; System.out.print("inside " + getClass().getName()); } @@ -44,6 +45,48 @@ public void setDataOutputMapping(ParameterContext[] dataOutputMapping) { this.dataOutputMapping = dataOutputMapping; } + private boolean checkLocalCall(ProcessInstance instance) throws Exception { + + ProcessDefinition processDefinition = getProcessDefinition(); + + Activity localCallSource = null; + + if(processDefinition.getMessageFlows()!=null && processDefinition.getMessageFlows().size() > 0) + for(MessageFlow messageFlow : processDefinition.getMessageFlows()){ + + if(getTracingTag().equals(messageFlow.getTargetRef()) && messageFlow.isLocalCall()){ + //this is local call + localCallSource = processDefinition.getActivity(messageFlow.getSourceRef()); + + break; + } + } + + if(localCallSource!=null){ + + // only when the execution token has been triggered by the source activity of message flow + if(instance.getActivityCompletionHistory().contains(localCallSource.getTracingTag())) { + + //if the message has been consumed already in this thread, pass this request: preventing recursive loop + if(instance.getProcessTransactionContext().getSharedContext("_messageConsumed_" + getTracingTag())!=null){ + return true; + } + + if (localCallSource instanceof ServiceTask) { + ServiceTask serviceTask = (ServiceTask) localCallSource; + String data = serviceTask.getInputPayloadTemplate(); + } + + instance.getProcessTransactionContext().setSharedContext("_messageConsumed_" + getTracingTag(), new Boolean(true)); + + onMessage(instance, null /* TODO: must be calculated from source activity and parameter input */); + + return true; + } + } + + return false; + } public boolean onMessage(ProcessInstance instance, Object payload) throws Exception { diff --git a/uengine-core/src/main/java/org/uengine/kernel/DefaultProcessInstance.java b/uengine-core/src/main/java/org/uengine/kernel/DefaultProcessInstance.java index 5be91960..20a829e2 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/DefaultProcessInstance.java +++ b/uengine-core/src/main/java/org/uengine/kernel/DefaultProcessInstance.java @@ -1,5 +1,7 @@ package org.uengine.kernel; +import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.beanutils.PropertyUtils; import org.uengine.processmanager.ProcessTransactionContext; import org.uengine.processmanager.SimulatorTransactionContext; import org.uengine.util.ActivityForLoop; @@ -8,6 +10,7 @@ import org.uengine.webservices.worklist.WorkList; import java.io.Serializable; +import java.lang.reflect.Method; import java.util.*; /** @@ -256,8 +259,9 @@ public void setSourceValue(String scopeByTracingTag, String key, Serializable va // .append("key: " + key) // .append("val: " + val) // .append("instance id: " + getInstanceId()); -// +// jh // System.out.println(sb); + val = formatValue(key, val); String fullKeyName = createFullKey(scopeByTracingTag, key, false); if(val==null) @@ -267,6 +271,29 @@ public void setSourceValue(String scopeByTracingTag, String key, Serializable va //repository.put(getInstanceId()+":"+scopeByTracingTag+":"+key, val); } + private Serializable formatValue(String key, Serializable val) throws Exception { + + ProcessDefinition definition = getProcessDefinition(); + ProcessVariable variable = definition.getProcessVariable(key); + + if(variable!=null && variable.getTypeClassName()!=null){ + if(variable.getTypeClassName().startsWith("java.lang.")){ + Class type = Thread.currentThread().getContextClassLoader().loadClass(variable.getTypeClassName()); + + if(!val.getClass().isAssignableFrom(type)) { //need to convert + + try { + val = (Serializable) ConvertUtils.convert(val, type); + }catch (Exception e){ + + } + } + } + } + + return val; + } + public Serializable get(String scopeByTracingTag, String key) throws Exception{ String firstPart = key; @@ -309,11 +336,15 @@ protected Serializable resolveParts(Serializable sourceValue, String key) throws try { int indexOfDot = key.indexOf("."); - if (indexOfDot > 0 && sourceValue instanceof BeanPropertyResolver) { - + if (indexOfDot > 0){ String beanPath = key.substring(indexOfDot + 1); - return (Serializable) ((BeanPropertyResolver) sourceValue).getBeanProperty(beanPath); + if(sourceValue instanceof BeanPropertyResolver) { + + return (Serializable) ((BeanPropertyResolver) sourceValue).getBeanProperty(beanPath); + }else{ + return (Serializable) PropertyUtils.getProperty(sourceValue, beanPath); + } } }catch(ClassCastException e){ throw new Exception("Process variable's property value must be serializable", e); @@ -335,6 +366,8 @@ protected Serializable resolveParts(Serializable sourceValue, String key) throws } } } + + return sourceValue; } diff --git a/uengine-core/src/main/java/org/uengine/kernel/MessageFlow.java b/uengine-core/src/main/java/org/uengine/kernel/MessageFlow.java index 25424f15..ad274ba3 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/MessageFlow.java +++ b/uengine-core/src/main/java/org/uengine/kernel/MessageFlow.java @@ -1,8 +1,13 @@ package org.uengine.kernel; -import org.uengine.kernel.bpmn.SequenceFlow; - -public class MessageFlow extends SequenceFlow { - +public class MessageFlow extends AbstractFlow { + + boolean localCall; + public boolean isLocalCall() { + return localCall; + } + public void setLocalCall(boolean localCall) { + this.localCall = localCall; + } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/ProcessDefinition.java b/uengine-core/src/main/java/org/uengine/kernel/ProcessDefinition.java index 44f110d2..b7d3c62a 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/ProcessDefinition.java +++ b/uengine-core/src/main/java/org/uengine/kernel/ProcessDefinition.java @@ -141,6 +141,17 @@ public void addServiceDefinition(ServiceDefinition sd){ setServiceDefinitions(newSDs); } + ArrayList messageFlows; + public ArrayList getMessageFlows() { + return messageFlows; + } + + public void setMessageFlows(ArrayList messageFlows) { + this.messageFlows = messageFlows; + } + + + boolean isGlobal; @Hidden public boolean isGlobal() { @@ -405,6 +416,14 @@ public void setShortDescription(String shortDescription) { getShortDescription().setText(shortDescription); } + String instanceNamePattern; + public String getInstanceNamePattern() { + return instanceNamePattern; + } + public void setInstanceNamePattern(String instanceNamePattern) { + this.instanceNamePattern = instanceNamePattern; + } + boolean initiateByFirstWorkitem = false; public boolean isInitiateByFirstWorkitem() { return initiateByFirstWorkitem; @@ -952,6 +971,10 @@ public String getTracingTag() { public void beforeSerialization() { registerToProcessDefinition(true, false); +// if(getInstanceNamePattern()==null){ +// setInstanceNamePattern(getId() + "_<%=instance.id%>"); +// } + super.beforeSerialization(); // //if(true || GlobalContext.isDesignTime()){ diff --git a/uengine-core/src/main/java/org/uengine/kernel/ScopeActivity.java b/uengine-core/src/main/java/org/uengine/kernel/ScopeActivity.java index 87696ad5..9662a944 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/ScopeActivity.java +++ b/uengine-core/src/main/java/org/uengine/kernel/ScopeActivity.java @@ -29,6 +29,10 @@ public ProcessVariable[] getProcessVariables(){ } @Hidden public ProcessVariable getProcessVariable(String pvName) { + + if(pvName==null) + return null; + String pvNameLower = pvName.toLowerCase(); if(pvName.indexOf('.') > -1){ String[] parts = pvNameLower.replace('.','@').split("@"); diff --git a/uengine-core/src/main/java/org/uengine/kernel/ScriptActivity.java b/uengine-core/src/main/java/org/uengine/kernel/ScriptActivity.java index 6e777625..90ac1a1d 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/ScriptActivity.java +++ b/uengine-core/src/main/java/org/uengine/kernel/ScriptActivity.java @@ -6,6 +6,8 @@ */ package org.uengine.kernel; +import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -19,6 +21,9 @@ import org.metaworks.Type; import org.metaworks.inputter.RadioInput; import org.metaworks.inputter.SelectInput; +import org.mozilla.javascript.NativeObject; +import org.springframework.beans.BeanUtils; +import org.uengine.util.TreeVisitor; /** * @author Jinyoung Jang @@ -88,7 +93,11 @@ public Object scriptEngine(String scriptSmt) throws BSFException{ } protected void executeActivity(ProcessInstance instance) throws Exception{ - if(getScript()==null) return; + if(getScript()==null){ + fireComplete(instance); + + return; + } Object result=null; @@ -167,8 +176,42 @@ protected void executeActivity(ProcessInstance instance) throws Exception{ } } - if(getOut()!=null) - getOut().set(instance, "", (java.io.Serializable)result); + if(getOut()!=null) { + + if(result instanceof NativeObject){ + NativeObject nativeObject = (NativeObject) result; + + Map valueMap = new HashMap(); + +// TreeVisitor treeVisitor = new TreeVisitor() { +// @Override +// public List getChild(NativeObject parent) { +// return null; +// } +// +// @Override +// public void logic(NativeObject elem) { +// Map valueMap = new HashMap(); +// valueMap.putAll(elem); +// } +// }; +// +// treeVisitor.run(nativeObject); + + valueMap.putAll(nativeObject); + + result = valueMap; //change with normal map to safely stored. + + } + + + + + getOut().set(instance, "", (java.io.Serializable) result); + + + } + fireComplete(instance); } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ConditionalCatchEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ConditionalCatchEvent.java index b6f28b89..00ed57e6 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ConditionalCatchEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ConditionalCatchEvent.java @@ -1,7 +1,55 @@ package org.uengine.kernel.bpmn; +import org.uengine.kernel.Condition; +import org.uengine.kernel.NeedArrangementToSerialize; +import org.uengine.kernel.ProcessInstance; + /** * Created by uengine on 2018. 3. 4.. */ -public class ConditionalCatchEvent { +public class ConditionalCatchEvent extends TimerEvent implements NeedArrangementToSerialize{ + public ConditionalCatchEvent() { + super(); + setExpression("5"); + setScheduleType("sec"); + } + + Condition condition; + public Condition getCondition() { + return condition; + } + public void setCondition(Condition condition) { + this.condition = condition; + } + + int pollingIntervalInSecond; + public int getPollingIntervalInSecond() { + return pollingIntervalInSecond; + } + public void setPollingIntervalInSecond(int pollingIntervalInSecond) { + this.pollingIntervalInSecond = pollingIntervalInSecond; + } + + @Override + public boolean onMessage(ProcessInstance instance, Object payload) throws Exception { + if(getCondition().isMet(instance, "")) + return super.onMessage(instance, payload); + else + return false; + } + + + @Override + public void beforeSerialization() { + + } + + @Override + public void afterDeserialization() { + + if(getPollingIntervalInSecond()==0) setPollingIntervalInSecond(5); + + setExpression(""+getPollingIntervalInSecond()); + setScheduleType("sec"); + } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EndEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EndEvent.java index fbd2ecb6..f1222db1 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EndEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EndEvent.java @@ -19,86 +19,15 @@ public class EndEvent extends StartEvent { private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; - -// public final static int STATUS_STOPPED = 1; -// public final static int STATUS_CANCELLED = 2; -// public final static int STATUS_FAULT = 3; -// public final static int STATUS_COMPLETED = 4; -// -// public static void metaworksCallback_changeMetadata(Type type){ -// FieldDescriptor fd = null; -// -// fd = type.getFieldDescriptor("Status"); -// fd.setDisplayName("Terminate Status"); -// fd.setInputter( -// new RadioInput( -// new String[] { -// "Stopped", -// "Cancelled", -// "Failed", -// "Completed" -// }, -// new Object[] { -// EndEvent.STATUS_STOPPED, -// org.uengine.kernel.bpmn.EndEvent.STATUS_CANCELLED, -// org.uengine.kernel.bpmn.EndEvent.STATUS_FAULT, -// org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED -// } -// ) -// ); -// -// type.removeFieldDescriptor("TerminateStatus"); -// } -// -// boolean escalate = false; -// public boolean isEscalate() { -// return escalate; -// } -// public void setEscalate(boolean escalate) { -// this.escalate = escalate; -// } -// -// int escalationLevel; -// public int getEscalationLevel() { -// return escalationLevel; -// } -// public void setEscalationLevel(int escalationLevel) { -// this.escalationLevel = escalationLevel; -// } -// -// boolean terminateRunAndForgetSubProcess = false; -// public boolean isTerminateRunAndForgetSubProcess() { -// return terminateRunAndForgetSubProcess; -// } -// public void setTerminateRunAndForgetSubProcess(boolean terminateRunAndForgetSubProcess) { -// this.terminateRunAndForgetSubProcess = terminateRunAndForgetSubProcess; -// } -// -// /** -// * @deprecated rather use status -// */ -// @Deprecated -// String terminateStatus; -// @Deprecated -// public String getTerminateStatus() { -// return terminateStatus; -// } -// @Deprecated -// public void setTerminateStatus(String terminateStatus) { -// this.terminateStatus = terminateStatus; -// } -// -// int status; -// public int getStatus() { -// if (this.status == 0 ) { -// return org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED; -// } -// return status; -// } -// public void setStatus(int status) { -// this.status = status; -// } - + + boolean stopAllTokens; + public boolean isStopAllTokens() { + return stopAllTokens; + } + public void setStopAllTokens(boolean stopAllTokens) { + this.stopAllTokens = stopAllTokens; + } + public EndEvent() { // TODO: 확인해야함 //super("terminate"); @@ -106,72 +35,19 @@ public EndEvent() { } public void executeActivity(ProcessInstance instance) throws Exception{ - -// String terminateStatus = null; -// if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_STOPPED) { -// terminateStatus = Activity.STATUS_STOPPED; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_CANCELLED) { -// terminateStatus = Activity.STATUS_CANCELLED; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_FAULT) { -// terminateStatus = Activity.STATUS_FAULT; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED) { -// terminateStatus = Activity.STATUS_COMPLETED; -// } -// -// if ((isEscalate() || getEscalationLevel() > 0) && instance.isSubProcess()) { -// Long targetProcessInstanceId; -// ProcessInstance targetPI = null; -// -// if (!isEscalate()) { -// targetPI = instance; -// for (int escalatedCnt = getEscalationLevel(); escalatedCnt > -1; escalatedCnt--) { -// targetPI = instance.getMainProcessInstance(); -// if (targetPI == null) { -// throw new UEngineException("Can't find the parent process located in the " + getEscalationLevel() + "th higher level. Check the Process Definition."); -// } -// } -// targetProcessInstanceId = new Long(targetPI.getInstanceId()); -// } else { -// targetProcessInstanceId = new Long(instance.getRootProcessInstanceId()); -// } -// -// ProcessInstanceDAOType piDAOF = ProcessInstanceDAOType.getInstance(instance.getProcessTransactionContext()); -// ProcessInstanceDAO piDAO = piDAOF.getSiblingProcessInstances(targetProcessInstanceId, this.isTerminateRunAndForgetSubProcess()); -// -// Hashtable options = new Hashtable(); -// options.put("ptc", instance.getProcessTransactionContext()); -// -// while (piDAO.next()) { -// ProcessInstance theInstance = ProcessInstance.create().getInstance(piDAO.getInstId().toString(), options); -// theInstance.stop(terminateStatus); -// if (targetPI != null && targetPI.isSubProcess()) { -// targetPI.getProcessDefinition().returnToMainProcess(targetPI); -// } -// } -// -// } else { -// instance.stop(terminateStatus); -// if (instance != null && instance.isSubProcess()) { -// instance.getProcessDefinition().returnToMainProcess(instance); -// } -// } - super.executeActivity(instance); - } - -// @Override -// public ValidationContext validate(Map options) { -// ValidationContext vc = super.validate(options); -// -// if (this.getStatus() == 0) { -// vc.add("Select a terminate Status"); -// } -// -// return vc; -// } + // TODO Auto-generated method stub + if (instance != null && instance.isSubProcess()) { + instance.getProcessDefinition().returnToMainProcess(instance); + } + if(isStopAllTokens()){ + instance.getRootProcessInstance().stop(); + } - + instance.setInfo(getName()); + fireComplete(instance); + } } \ No newline at end of file diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateCatchEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateCatchEvent.java index dbede53d..083cb7be 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateCatchEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateCatchEvent.java @@ -3,5 +3,5 @@ /** * Created by uengine on 2018. 3. 18.. */ -public class EscalationIntermediateCatchEvent { +public class EscalationIntermediateCatchEvent extends EscalationEvent { } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateThrowEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateThrowEvent.java index 083cb7be..ded1f2f0 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateThrowEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EscalationIntermediateThrowEvent.java @@ -3,5 +3,5 @@ /** * Created by uengine on 2018. 3. 18.. */ -public class EscalationIntermediateCatchEvent extends EscalationEvent { +public class EscalationIntermediateThrowEvent extends EscalationEvent { } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/Event.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/Event.java index 89be06d4..c783e25c 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/Event.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/Event.java @@ -81,8 +81,6 @@ public boolean onMessage(ProcessInstance instance, Object payload) throws Except return true; } - - } return false; diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EventBasedGateway.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EventBasedGateway.java index 755ef5e3..069aa4e5 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/EventBasedGateway.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/EventBasedGateway.java @@ -1,12 +1,10 @@ package org.uengine.kernel.bpmn; -import org.uengine.kernel.bpmn.Gateway; +public class EventBasedGateway extends Gateway { -public class InclusiveGateway extends Gateway { - - public InclusiveGateway() { - super("Inclusive"); + public EventBasedGateway() { + super("Event-based"); } } \ No newline at end of file diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ExclusiveGateway.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ExclusiveGateway.java index 80091d7d..a6bcf5fc 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ExclusiveGateway.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ExclusiveGateway.java @@ -1,8 +1,11 @@ package org.uengine.kernel.bpmn; +import org.uengine.kernel.Activity; import org.uengine.kernel.ProcessInstance; -import org.uengine.kernel.bpmn.Gateway; + +import java.util.ArrayList; +import java.util.List; public class ExclusiveGateway extends Gateway { @@ -17,4 +20,42 @@ protected boolean isCompletedAllOfPreviousActivities(ProcessInstance instance) t return true; } + @Override + public List getPossibleNextActivities(ProcessInstance instance, String scope) throws Exception { + + //return only the first (only-one) matching out-sequence flow + + List inclusiveNextActivities = super.getPossibleNextActivities(instance, scope); + + List exclusiveNextActivities = new ArrayList<>(); + + if(inclusiveNextActivities==null || inclusiveNextActivities.size()==0) + return exclusiveNextActivities; + + Activity theOnlyOneActivity = null; + int minPriority = 10000; + + for(Activity nextActivity : inclusiveNextActivities){ + SequenceFlow theSequenceFlow = null; + + for(SequenceFlow sequenceFlow : getOutgoingSequenceFlows()){ + if(nextActivity.getTracingTag().equals(sequenceFlow.getTargetRef())){ + theSequenceFlow = sequenceFlow; + break; + } + } + + if(theSequenceFlow==null) continue; + + if(theSequenceFlow.getPriority() < minPriority){ + minPriority = theSequenceFlow.getPriority(); + theOnlyOneActivity = nextActivity; + } + } + + if(theOnlyOneActivity!=null) + exclusiveNextActivities.add(theOnlyOneActivity); + + return exclusiveNextActivities; + } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/FlowActivity.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/FlowActivity.java index 12304d56..dc04583b 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/FlowActivity.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/FlowActivity.java @@ -30,7 +30,7 @@ public void beforeSerialization() { private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; - public ArrayList sequenceFlows; + ArrayList sequenceFlows; @Hidden public ArrayList getSequenceFlows() { if (this.sequenceFlows == null) { @@ -145,6 +145,9 @@ public List getStartActivities() throws UEngineException { child = (Activity) it.next(); if (child.getIncomingSequenceFlows().size() == 0) { + if(child instanceof IntermediateEvent) + continue; + if(child instanceof Event && !(child instanceof StartEvent || child instanceof CatchingMessageEvent) && ((Event) child).getAttachedToRef()!=null){ //attachted to 가 있다는 이야기는 조건 이벤트가 왔을때만 실행하는 것이기 때문에 Start 로 인식하면 안된다. continue; } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateCatchEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateCatchEvent.java index a0f377d8..733e166d 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateCatchEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateCatchEvent.java @@ -3,5 +3,5 @@ /** * Created by uengine on 2018. 3. 3.. */ -public class MessageIntermediateCatchEvent { +public class MessageIntermediateCatchEvent extends CatchingRestMessageEvent implements IntermediateEvent { } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateThrowEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateThrowEvent.java index 17b58704..9f4048d2 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateThrowEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/MessageIntermediateThrowEvent.java @@ -3,5 +3,5 @@ /** * Created by uengine on 2018. 3. 1.. */ -public class MessageIntermediateThrowEvent { +public class MessageIntermediateThrowEvent extends ServiceTask implements IntermediateEvent{ } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SequenceFlow.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SequenceFlow.java index 140f8f6c..0db6a10c 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SequenceFlow.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SequenceFlow.java @@ -1,12 +1,8 @@ package org.uengine.kernel.bpmn; import org.metaworks.annotation.Available; -import org.metaworks.annotation.Face; import org.metaworks.annotation.Hidden; -import org.metaworks.annotation.Id; import org.uengine.kernel.*; -import org.uengine.kernel.bpmn.face.ConditionFace; -import org.uengine.modeling.Relation; import org.uengine.modeling.RelationView; import org.uengine.util.UEngineUtil; @@ -14,39 +10,25 @@ import java.util.List; -public class SequenceFlow extends Relation implements java.io.Serializable, NeedArrangementToSerialize { +public class SequenceFlow extends AbstractFlow implements java.io.Serializable, NeedArrangementToSerialize { private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; - private String sourceRef; private boolean feedback; - - @Hidden - public String getSourceRef() { - return sourceRef; - } - public void setSourceRef(String source) { - this.sourceRef = source; - } - - private String targetRef; - @Hidden - public String getTargetRef() { - return targetRef; + public void setFeedback(boolean feedback) { + this.feedback = feedback; } - public void setTargetRef(String target) { - this.targetRef = target; + public boolean isFeedback() { + return feedback; } - - String tracingTag; - @Id - @Hidden - public String getTracingTag() { - return tracingTag; + + int priority; + public int getPriority() { + return priority; } - public void setTracingTag(String tag) { - tracingTag = tag; + public void setPriority(int priority) { + this.priority = priority; } - + Condition condition; //@Face(faceClass=ConditionFace.class) @Available(condition = "!otherwise") @@ -196,11 +178,4 @@ public void afterDeserialization() { } - public void setFeedback(boolean feedback) { - this.feedback = feedback; - } - - public boolean isFeedback() { - return feedback; - } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ServiceTask.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ServiceTask.java index 3c453fb1..b217b9e0 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/ServiceTask.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/ServiceTask.java @@ -40,12 +40,16 @@ protected void executeActivity(ProcessInstance instance) throws Exception { * 4. try searching from EUREKA server by the role name. * ******/ + if(checkLocalCall(instance)){ + return; + } + Role role = getRole(); String fullURITemplate = null; String serviceId = null; - if (role == null || getUriTemplate().startsWith("http")) { + if (role == null || (getUriTemplate() != null && getUriTemplate().startsWith("http"))) { fullURITemplate = getUriTemplate(); } else { RoleMapping roleMapping = getRole().getMapping(instance); @@ -75,7 +79,7 @@ protected void executeActivity(ProcessInstance instance) throws Exception { if (serviceInstance != null) { String baseUrl = serviceInstance.getUri().toString(); - fullURITemplate = baseUrl + getUriTemplate(); + fullURITemplate = baseUrl + (getUriTemplate().startsWith("/") ? getUriTemplate() : "/" + getUriTemplate()); } } } @@ -169,6 +173,33 @@ protected void executeActivity(ProcessInstance instance) throws Exception { super.executeActivity(instance); } + private boolean checkLocalCall(ProcessInstance instance) throws Exception { + + ProcessDefinition processDefinition = getProcessDefinition(); + + Activity localCallTarget = null; + + if(processDefinition.getMessageFlows()!=null && processDefinition.getMessageFlows().size() > 0) + for(MessageFlow messageFlow : processDefinition.getMessageFlows()){ + + if(getTracingTag().equals(messageFlow.getSourceRef()) && messageFlow.isLocalCall()){ + //this is local call + localCallTarget = processDefinition.getActivity(messageFlow.getTargetRef()); + + break; + } + } + + if(localCallTarget!=null){ + fireComplete(instance); + instance.execute(localCallTarget.getTracingTag()); // this must be after the fireComplete + + return true; + } + + return false; + } + Role role; public Role getRole() { return role; @@ -218,4 +249,7 @@ public boolean isSkipIfNotFound() { public void setSkipIfNotFound(boolean skipIfNotFound) { this.skipIfNotFound = skipIfNotFound; } + + + } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalEventInstance.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalEventInstance.java index 07063f0c..878f8e1a 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalEventInstance.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalEventInstance.java @@ -1,7 +1,29 @@ package org.uengine.kernel.bpmn; +import java.io.Serializable; + /** * Created by uengine on 2018. 3. 11.. */ -public class SignalEventInstance { +public class SignalEventInstance implements Serializable { + + String activityRef; + + String signalName; + + public String getActivityRef() { + return activityRef; + } + + public void setActivityRef(String activityRef) { + this.activityRef = activityRef; + } + + public String getSignalName() { + return signalName; + } + + public void setSignalName(String signalName) { + this.signalName = signalName; + } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalIntermediateCatchEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalIntermediateCatchEvent.java index d8a3b1fc..6be3ae57 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalIntermediateCatchEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/SignalIntermediateCatchEvent.java @@ -1,90 +1,73 @@ -package org.uengine.kernel; +package org.uengine.kernel.bpmn; -import com.jayway.jsonpath.JsonPath; -import org.codehaus.jackson.JsonNode; -import org.uengine.kernel.bpmn.Event; +import org.uengine.kernel.*; import org.uengine.processdesigner.mapper.TransformerMapping; -import org.uengine.uml.model.ObjectInstance; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; -public class CatchingMessageEvent extends Event implements MessageListener { +public class SignalIntermediateCatchEvent extends CatchingMessageEvent implements IntermediateEvent{ - public static final String DIRECT_VALUE = "[direct].value"; + public static final String SIGNAL_EVENTS = "signalEvents"; - public CatchingMessageEvent(){ + public SignalIntermediateCatchEvent(){ super(); - if( this.getName() == null ){ - setName(this.getClass().getSimpleName()); - } } - @Override - protected void executeActivity(ProcessInstance instance) throws Exception { - //start listens... - - System.out.print("inside " + getClass().getName()); - } - - ProcessVariable dataOutput; - public ProcessVariable getDataOutput() { - return dataOutput; + String signalType; + public String getSignalType() { + return signalType; } - public void setDataOutput(ProcessVariable dataOutput) { - this.dataOutput = dataOutput; + public void setSignalType(String signalType) { + this.signalType = signalType; } - ParameterContext[] dataOutputMapping; - public ParameterContext[] getDataOutputMapping() { - return dataOutputMapping; - } - public void setDataOutputMapping(ParameterContext[] dataOutputMapping) { - this.dataOutputMapping = dataOutputMapping; - } + @Override + protected void executeActivity(ProcessInstance instance) throws Exception { + super.executeActivity(instance); + //TODO: need to introduce global activity reference space (tag@tag@tag) - public boolean onMessage(ProcessInstance instance, Object payload) throws Exception { + Map signals = getSignalEvents(instance); - if(getDataOutput()!=null) - getDataOutput().set(instance, "", (Serializable) payload); + if(!signals.containsKey(getName())) { - if (getDataOutputMapping()!=null && payload instanceof BeanPropertyResolver) { + SignalEventInstance signalEventInstance = new SignalEventInstance(); + signalEventInstance.setActivityRef(getTracingTag()); + signalEventInstance.setSignalName(getName()); - BeanPropertyResolver payload_ = (BeanPropertyResolver) payload; + signals.put(getName(), signalEventInstance); - for (ParameterContext parameterContext : getDataOutputMapping()) { - Object value = payload_.getBeanProperty( - parameterContext.getArgument().getText() - ); + setSignalEvents(instance, signals); + } - HashMap options = new HashMap<>(); + } - if(parameterContext.getTransformerMapping()!=null && parameterContext.getTransformerMapping().getTransformer()!=null){ - TransformerMapping transformerMapping = parameterContext.getTransformerMapping(); - if(transformerMapping.getTransformer().getArgumentSourceMap()==null || transformerMapping.getTransformer().getArgumentSourceMap().size() < transformerMapping.getTransformer().getInputArguments().length){ - transformerMapping.getTransformer().setArgumentSourceMap(new HashMap()); - options.put(DIRECT_VALUE, value); - transformerMapping.getTransformer().getArgumentSourceMap().put(transformerMapping.getTransformer().getInputArguments()[0], DIRECT_VALUE); - } + public static Map getSignalEvents(ProcessInstance instance) throws Exception { + Map signals = (Map) instance.getProperty("", SIGNAL_EVENTS); - value = transformerMapping.getTransformer().letTransform(instance, options); - } + if(signals==null) signals = new HashMap<>(); + return signals; + } - if(parameterContext.getVariable()==null) - throw new UEngineException("Mapping variable is not set"); + public static void setSignalEvents(ProcessInstance instance, Map signals) throws Exception { + instance/*.getRootProcessInstance()*/.setProperty("", SIGNAL_EVENTS, (Serializable) signals); + } - parameterContext.getVariable().set(instance, "", (Serializable) value!=null ? value.toString(): null); - } - } + @Override + protected void afterComplete(ProcessInstance instance) throws Exception { + + // remove signal + Map signals = getSignalEvents(instance); + signals.remove(getName()); + setSignalEvents(instance, signals); - fireComplete(instance); - return true; - } - public String getMessage() { - return this.getName(); + super.afterComplete(instance); } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TerminateEndEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TerminateEndEvent.java index fbd2ecb6..96e42347 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TerminateEndEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TerminateEndEvent.java @@ -1,177 +1,17 @@ package org.uengine.kernel.bpmn; -import org.metaworks.FieldDescriptor; -import org.metaworks.Type; -import org.metaworks.inputter.RadioInput; -import org.uengine.kernel.Activity; import org.uengine.kernel.ProcessInstance; -import org.uengine.kernel.UEngineException; -import org.uengine.kernel.ValidationContext; -import org.uengine.persistence.processinstance.ProcessInstanceDAO; -import org.uengine.persistence.processinstance.ProcessInstanceDAOType; - -import java.util.Hashtable; -import java.util.Map; /** * @author Jinyoung Jang */ -public class EndEvent extends StartEvent { +public class TerminateEndEvent extends EndEvent { private static final long serialVersionUID = org.uengine.kernel.GlobalContext.SERIALIZATION_UID; - -// public final static int STATUS_STOPPED = 1; -// public final static int STATUS_CANCELLED = 2; -// public final static int STATUS_FAULT = 3; -// public final static int STATUS_COMPLETED = 4; -// -// public static void metaworksCallback_changeMetadata(Type type){ -// FieldDescriptor fd = null; -// -// fd = type.getFieldDescriptor("Status"); -// fd.setDisplayName("Terminate Status"); -// fd.setInputter( -// new RadioInput( -// new String[] { -// "Stopped", -// "Cancelled", -// "Failed", -// "Completed" -// }, -// new Object[] { -// EndEvent.STATUS_STOPPED, -// org.uengine.kernel.bpmn.EndEvent.STATUS_CANCELLED, -// org.uengine.kernel.bpmn.EndEvent.STATUS_FAULT, -// org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED -// } -// ) -// ); -// -// type.removeFieldDescriptor("TerminateStatus"); -// } -// -// boolean escalate = false; -// public boolean isEscalate() { -// return escalate; -// } -// public void setEscalate(boolean escalate) { -// this.escalate = escalate; -// } -// -// int escalationLevel; -// public int getEscalationLevel() { -// return escalationLevel; -// } -// public void setEscalationLevel(int escalationLevel) { -// this.escalationLevel = escalationLevel; -// } -// -// boolean terminateRunAndForgetSubProcess = false; -// public boolean isTerminateRunAndForgetSubProcess() { -// return terminateRunAndForgetSubProcess; -// } -// public void setTerminateRunAndForgetSubProcess(boolean terminateRunAndForgetSubProcess) { -// this.terminateRunAndForgetSubProcess = terminateRunAndForgetSubProcess; -// } -// -// /** -// * @deprecated rather use status -// */ -// @Deprecated -// String terminateStatus; -// @Deprecated -// public String getTerminateStatus() { -// return terminateStatus; -// } -// @Deprecated -// public void setTerminateStatus(String terminateStatus) { -// this.terminateStatus = terminateStatus; -// } -// -// int status; -// public int getStatus() { -// if (this.status == 0 ) { -// return org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED; -// } -// return status; -// } -// public void setStatus(int status) { -// this.status = status; -// } - - public EndEvent() { - // TODO: 확인해야함 - //super("terminate"); - setName("End"); - } - public void executeActivity(ProcessInstance instance) throws Exception{ - -// String terminateStatus = null; -// if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_STOPPED) { -// terminateStatus = Activity.STATUS_STOPPED; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_CANCELLED) { -// terminateStatus = Activity.STATUS_CANCELLED; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_FAULT) { -// terminateStatus = Activity.STATUS_FAULT; -// } else if (this.getStatus() == org.uengine.kernel.bpmn.EndEvent.STATUS_COMPLETED) { -// terminateStatus = Activity.STATUS_COMPLETED; -// } -// -// if ((isEscalate() || getEscalationLevel() > 0) && instance.isSubProcess()) { -// Long targetProcessInstanceId; -// ProcessInstance targetPI = null; -// -// if (!isEscalate()) { -// targetPI = instance; -// for (int escalatedCnt = getEscalationLevel(); escalatedCnt > -1; escalatedCnt--) { -// targetPI = instance.getMainProcessInstance(); -// if (targetPI == null) { -// throw new UEngineException("Can't find the parent process located in the " + getEscalationLevel() + "th higher level. Check the Process Definition."); -// } -// } -// targetProcessInstanceId = new Long(targetPI.getInstanceId()); -// } else { -// targetProcessInstanceId = new Long(instance.getRootProcessInstanceId()); -// } -// -// ProcessInstanceDAOType piDAOF = ProcessInstanceDAOType.getInstance(instance.getProcessTransactionContext()); -// ProcessInstanceDAO piDAO = piDAOF.getSiblingProcessInstances(targetProcessInstanceId, this.isTerminateRunAndForgetSubProcess()); -// -// Hashtable options = new Hashtable(); -// options.put("ptc", instance.getProcessTransactionContext()); -// -// while (piDAO.next()) { -// ProcessInstance theInstance = ProcessInstance.create().getInstance(piDAO.getInstId().toString(), options); -// theInstance.stop(terminateStatus); -// if (targetPI != null && targetPI.isSubProcess()) { -// targetPI.getProcessDefinition().returnToMainProcess(targetPI); -// } -// } -// -// } else { -// instance.stop(terminateStatus); -// if (instance != null && instance.isSubProcess()) { -// instance.getProcessDefinition().returnToMainProcess(instance); -// } -// } - super.executeActivity(instance); + @Override + public boolean isStopAllTokens() { + return true; } - -// @Override -// public ValidationContext validate(Map options) { -// ValidationContext vc = super.validate(options); -// -// if (this.getStatus() == 0) { -// vc.add("Select a terminate Status"); -// } -// -// return vc; -// } - - - - - } \ No newline at end of file diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEvent.java index 361e7c2f..4b6b0208 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEvent.java @@ -4,11 +4,13 @@ import org.metaworks.dwr.MetaworksRemoteService; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; +import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; import org.uengine.kernel.ProcessInstance; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.JobKey.jobKey; +import static org.quartz.SimpleScheduleBuilder.simpleSchedule; import static org.quartz.TriggerBuilder.newTrigger; import static org.quartz.utils.Key.DEFAULT_GROUP; @@ -32,13 +34,34 @@ public void setExpression(String expression) { } + String scheduleType; // sec, min, hour, milisec, cron (if null) + public String getScheduleType() { + return scheduleType; + } + public void setScheduleType(String scheduleType) { + this.scheduleType = scheduleType; + } + + @Override protected void executeActivity(ProcessInstance instance) throws Exception { + String jobId = createJobId(instance); + + JobDetail job = newJob(TimerEventJob.class) + .withIdentity(jobId, SCHEDULER_GROUP_ID) + .build(); + + job.getJobDataMap().put("instanceId", instance.getInstanceId()); + + if(instance.getExecutionScopeContext()!=null) + job.getJobDataMap().put("executionScope", instance.getExecutionScopeContext().getExecutionScope()); + + job.getJobDataMap().put("tracingTag", getTracingTag()); + StdSchedulerFactory schedulerFactoryBean = MetaworksRemoteService.getComponent(StdSchedulerFactory.class); - Scheduler sched = schedulerFactoryBean.getScheduler(); - String jobId = createJobId(instance); + Scheduler sched = schedulerFactoryBean.getScheduler(); try { JobKey jobKey = new JobKey(jobId, SCHEDULER_GROUP_ID); @@ -51,23 +74,26 @@ protected void executeActivity(ProcessInstance instance) throws Exception { } - JobDetail job = newJob(TimerEventJob.class) - .withIdentity(jobId, SCHEDULER_GROUP_ID) - .build(); + Trigger trigger = null; - job.getJobDataMap().put("instanceId", instance.getInstanceId()); + if("sec".equals(getScheduleType())){ + int second = Integer.valueOf(getExpression()); - if(instance.getExecutionScopeContext()!=null) - job.getJobDataMap().put("executionScope", instance.getExecutionScopeContext().getExecutionScope()); + trigger = newTrigger() + .withIdentity(jobId, SCHEDULER_GROUP_ID) + .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(second)) + .build(); - job.getJobDataMap().put("tracingTag", getTracingTag()); + }else{ //treat as cron expression - StringBuffer cronExpression = evaluateContent(instance, getExpression()); + StringBuffer cronExpression = evaluateContent(instance, getExpression()); - CronTrigger trigger = newTrigger() - .withIdentity(jobId, SCHEDULER_GROUP_ID) - .withSchedule(cronSchedule(cronExpression.toString())) - .build(); + trigger = newTrigger() + .withIdentity(jobId, SCHEDULER_GROUP_ID) + .withSchedule(cronSchedule(cronExpression.toString())) + .build(); + + } sched.scheduleJob(job, trigger); @@ -75,6 +101,7 @@ protected void executeActivity(ProcessInstance instance) throws Exception { sched.start(); } + } private String createJobId(ProcessInstance instance) { @@ -96,7 +123,7 @@ protected void afterComplete(ProcessInstance instance) throws Exception { @Override public boolean onMessage(ProcessInstance instance, Object payload) throws Exception { - return super.onMessage(instance, payload); + return super.onMessage(instance, getTracingTag()); } @Override @@ -107,7 +134,7 @@ public void afterUnregistered(ProcessInstance instance) throws Exception{ } - private void unschedule(ProcessInstance instance) { + protected void unschedule(ProcessInstance instance) { StdSchedulerFactory schedulerFactoryBean = MetaworksRemoteService.getComponent(StdSchedulerFactory.class); try { diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEventJob.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEventJob.java index 51ae95aa..cf73b1ea 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEventJob.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerEventJob.java @@ -45,7 +45,7 @@ public void fireEvent(JobDataMap jobDataMap) throws Exception { processManagerRemote.sendMessage( instanceId + (executionScope != null ? "@" + executionScope : ""), - "event", + "onTime", //it is important! --> org.uengine.five.overriding.ProcessManagerBean.sendMessage(..) will check this as key tracingTag ); diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerIntermediateEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerIntermediateEvent.java index 0ccda865..8ea030c9 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerIntermediateEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerIntermediateEvent.java @@ -1,7 +1,20 @@ package org.uengine.kernel.bpmn; +import org.uengine.kernel.ProcessInstance; + /** * Created by uengine on 2018. 3. 1.. */ -public class TimerStartEvent extends TimerEvent { +public class TimerIntermediateEvent extends TimerEvent implements IntermediateEvent{ + + @Override + public boolean onMessage(ProcessInstance instance, Object payload) throws Exception { + if(super.onMessage(instance, payload)){ + unschedule(instance); //IntermediateEvent should triggered only once + + return true; + } + + return false; + } } diff --git a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerStartEvent.java b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerStartEvent.java index 7e6bc9cf..0ccda865 100644 --- a/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerStartEvent.java +++ b/uengine-core/src/main/java/org/uengine/kernel/bpmn/TimerStartEvent.java @@ -3,5 +3,5 @@ /** * Created by uengine on 2018. 3. 1.. */ -public class TimerStartEvent { +public class TimerStartEvent extends TimerEvent { } diff --git a/uengine-core/src/main/java/org/uengine/processmanager/ProcessManagerBean.java b/uengine-core/src/main/java/org/uengine/processmanager/ProcessManagerBean.java index c63ebe8b..c23b10ba 100644 --- a/uengine-core/src/main/java/org/uengine/processmanager/ProcessManagerBean.java +++ b/uengine-core/src/main/java/org/uengine/processmanager/ProcessManagerBean.java @@ -223,7 +223,7 @@ public void ejbCreate() { transactionContext = new ProcessTransactionContext(this); } - private ProcessInstance getInstance(String instId) throws Exception{ + protected ProcessInstance getInstance(String instId) throws Exception{ HashMap options = new HashMap(); //System.out.println("instId = " + instId);