This is an automated email from the ASF dual-hosted git repository.

fjtiradosarti pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git


The following commit(s) were added to refs/heads/main by this push:
     new 1b22fbe742 [incubator-kie-issues-1108] Add capability to create node 
instances (node states) from the nodes (#3482)
1b22fbe742 is described below

commit 1b22fbe742634139a229ae4b845f1573f3f95cb9
Author: Enrique <[email protected]>
AuthorDate: Fri Apr 26 11:17:49 2024 +0200

    [incubator-kie-issues-1108] Add capability to create node instances (node 
states) from the nodes (#3482)
---
 .../impl/CodegenNodeInstanceFactoryRegistry.java   |   3 +-
 .../instance/impl/NodeInstanceFactory.java         |   2 +
 ...ctory.java => NodeInstanceFactoryProvider.java} |   9 +-
 .../instance/impl/NodeInstanceFactoryRegistry.java | 178 +++------------------
 .../impl/factory/AbstractNodeInstanceFactory.java} |  32 ++--
 .../impl/factory/DefaultNodeInstanceFactory.java}  |  32 ++--
 .../DefaultNodeInstanceFactoryProvider.java        | 104 ++++++++++++
 .../impl/factory/SingletonNodeInstanceFactory.java |  60 +++++++
 ...kflow.instance.impl.NodeInstanceFactoryProvider |   1 +
 .../instance/node/MockNodeInstanceFactory.java     |   5 +
 10 files changed, 228 insertions(+), 198 deletions(-)

diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CodegenNodeInstanceFactoryRegistry.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CodegenNodeInstanceFactoryRegistry.java
index 0854d82ac0..e7c89eda05 100644
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CodegenNodeInstanceFactoryRegistry.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CodegenNodeInstanceFactoryRegistry.java
@@ -19,6 +19,7 @@
 package org.jbpm.workflow.instance.impl;
 
 import org.jbpm.workflow.core.node.SubProcessNode;
+import org.jbpm.workflow.instance.impl.factory.DefaultNodeInstanceFactory;
 import org.jbpm.workflow.instance.node.LambdaSubProcessNodeInstance;
 
 public class CodegenNodeInstanceFactoryRegistry extends 
NodeInstanceFactoryRegistry {
@@ -26,7 +27,7 @@ public class CodegenNodeInstanceFactoryRegistry extends 
NodeInstanceFactoryRegis
     @Override
     protected NodeInstanceFactory get(Class<?> clazz) {
         if (SubProcessNode.class == clazz) {
-            return factory(LambdaSubProcessNodeInstance::new);
+            return new DefaultNodeInstanceFactory(SubProcessNode.class, 
LambdaSubProcessNodeInstance::new);
         }
         return super.get(clazz);
     }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
index eb2e267924..8ab35b38f5 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
@@ -25,6 +25,8 @@ import org.kie.api.runtime.process.NodeInstanceContainer;
 
 public interface NodeInstanceFactory {
 
+    Class<? extends Node> forClass();
+
     NodeInstance getNodeInstance(Node node, WorkflowProcessInstance 
processInstance, NodeInstanceContainer nodeInstanceContainer);
 
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryProvider.java
old mode 100755
new mode 100644
similarity index 69%
copy from 
jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
copy to 
jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryProvider.java
index eb2e267924..e7dbce6476
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactory.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryProvider.java
@@ -18,13 +18,10 @@
  */
 package org.jbpm.workflow.instance.impl;
 
-import org.jbpm.workflow.instance.WorkflowProcessInstance;
-import org.kie.api.definition.process.Node;
-import org.kie.api.runtime.process.NodeInstance;
-import org.kie.api.runtime.process.NodeInstanceContainer;
+import java.util.List;
 
-public interface NodeInstanceFactory {
+public interface NodeInstanceFactoryProvider {
 
-    NodeInstance getNodeInstance(Node node, WorkflowProcessInstance 
processInstance, NodeInstanceContainer nodeInstanceContainer);
+    List<NodeInstanceFactory> provide();
 
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
index 991932f3f1..7fc1f2038a 100755
--- 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
@@ -18,67 +18,17 @@
  */
 package org.jbpm.workflow.instance.impl;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.function.Supplier;
+import java.util.ServiceLoader;
 
-import org.jbpm.workflow.core.node.ActionNode;
-import org.jbpm.workflow.core.node.AsyncEventNode;
-import org.jbpm.workflow.core.node.AsyncEventNodeInstance;
-import org.jbpm.workflow.core.node.BoundaryEventNode;
-import org.jbpm.workflow.core.node.CatchLinkNode;
-import org.jbpm.workflow.core.node.CompositeContextNode;
-import org.jbpm.workflow.core.node.CompositeNode;
-import org.jbpm.workflow.core.node.DynamicNode;
-import org.jbpm.workflow.core.node.EndNode;
-import org.jbpm.workflow.core.node.EventNode;
-import org.jbpm.workflow.core.node.EventSubProcessNode;
-import org.jbpm.workflow.core.node.FaultNode;
-import org.jbpm.workflow.core.node.ForEachNode;
-import org.jbpm.workflow.core.node.HumanTaskNode;
-import org.jbpm.workflow.core.node.Join;
-import org.jbpm.workflow.core.node.MilestoneNode;
-import org.jbpm.workflow.core.node.RuleSetNode;
-import org.jbpm.workflow.core.node.Split;
-import org.jbpm.workflow.core.node.StartNode;
-import org.jbpm.workflow.core.node.StateNode;
-import org.jbpm.workflow.core.node.SubProcessNode;
-import org.jbpm.workflow.core.node.ThrowLinkNode;
-import org.jbpm.workflow.core.node.TimerNode;
-import org.jbpm.workflow.core.node.WorkItemNode;
-import org.jbpm.workflow.instance.WorkflowProcessInstance;
-import org.jbpm.workflow.instance.node.ActionNodeInstance;
-import org.jbpm.workflow.instance.node.BoundaryEventNodeInstance;
-import org.jbpm.workflow.instance.node.CatchLinkNodeInstance;
-import org.jbpm.workflow.instance.node.CompositeContextNodeInstance;
-import org.jbpm.workflow.instance.node.CompositeNodeInstance;
-import org.jbpm.workflow.instance.node.DynamicNodeInstance;
-import org.jbpm.workflow.instance.node.EndNodeInstance;
-import org.jbpm.workflow.instance.node.EventNodeInstance;
-import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance;
-import org.jbpm.workflow.instance.node.FaultNodeInstance;
-import org.jbpm.workflow.instance.node.ForEachNodeInstance;
-import org.jbpm.workflow.instance.node.HumanTaskNodeInstance;
-import org.jbpm.workflow.instance.node.JoinInstance;
-import org.jbpm.workflow.instance.node.MilestoneNodeInstance;
-import org.jbpm.workflow.instance.node.RuleSetNodeInstance;
-import org.jbpm.workflow.instance.node.SplitInstance;
-import org.jbpm.workflow.instance.node.StartNodeInstance;
-import org.jbpm.workflow.instance.node.StateNodeInstance;
-import org.jbpm.workflow.instance.node.SubProcessNodeInstance;
-import org.jbpm.workflow.instance.node.ThrowLinkNodeInstance;
-import org.jbpm.workflow.instance.node.TimerNodeInstance;
-import org.jbpm.workflow.instance.node.WorkItemNodeInstance;
+import org.jbpm.util.JbpmClassLoaderUtil;
 import org.kie.api.definition.process.Node;
 import org.kie.api.runtime.Environment;
-import org.kie.api.runtime.process.NodeInstance;
-import org.kie.api.runtime.process.NodeInstanceContainer;
-import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.jbpm.ruleflow.core.Metadata.CUSTOM_ASYNC;
-
 public class NodeInstanceFactoryRegistry {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(NodeInstanceFactoryRegistry.class);
     private static final NodeInstanceFactoryRegistry INSTANCE = new 
NodeInstanceFactoryRegistry();
@@ -96,11 +46,26 @@ public class NodeInstanceFactoryRegistry {
 
     protected NodeInstanceFactoryRegistry() {
         this.registry = new HashMap<>();
+        initRegistry();
+    }
+
+    private void initRegistry() {
+        ServiceLoader.load(NodeInstanceFactoryProvider.class, 
JbpmClassLoaderUtil.findClassLoader())
+                .stream()
+                .map(ServiceLoader.Provider::get)
+                .map(NodeInstanceFactoryProvider::provide)
+                .flatMap(Collection::stream)
+                .forEach(this::register);
+    }
+
+    private void register(NodeInstanceFactory nodeInstanceFactory) {
+        LOGGER.debug("registering new node instance factory for {} set by {}", 
nodeInstanceFactory.forClass(), 
nodeInstanceFactory.getClass().getCanonicalName());
+        this.registry.put(nodeInstanceFactory.forClass(), nodeInstanceFactory);
     }
 
-    public void register(Class<? extends Node> cls,
-            NodeInstanceFactory factory) {
-        this.registry.put(cls, factory);
+    public void register(Class<? extends Node> forClass, NodeInstanceFactory 
nodeInstanceFactory) {
+        LOGGER.debug("override new node instance factory for {} set by {}", 
forClass, nodeInstanceFactory.getClass().getCanonicalName());
+        this.registry.put(forClass, nodeInstanceFactory);
     }
 
     public NodeInstanceFactory getProcessNodeInstanceFactory(Node node) {
@@ -112,111 +77,12 @@ public class NodeInstanceFactoryRegistry {
             }
             clazz = clazz.getSuperclass();
         }
+        LOGGER.debug("node instance factory not found for node {}", 
node.getClass().getName());
         return null;
     }
 
     protected NodeInstanceFactory get(Class<?> clazz) {
-        // hard wired nodes:
-        if (RuleSetNode.class == clazz) {
-            return factory(RuleSetNodeInstance::new);
-        }
-        if (Split.class == clazz) {
-            return factory(SplitInstance::new);
-        }
-        if (Join.class == clazz) {
-            return factoryOnce(JoinInstance::new);
-        }
-        if (StartNode.class == clazz) {
-            return factory(StartNodeInstance::new);
-        }
-        if (EndNode.class == clazz) {
-            return factory(EndNodeInstance::new);
-        }
-        if (MilestoneNode.class == clazz) {
-            return factory(MilestoneNodeInstance::new);
-        }
-        if (SubProcessNode.class == clazz) {
-            return factory(SubProcessNodeInstance::new);
-        }
-        if (ActionNode.class == clazz) {
-            return factory(ActionNodeInstance::new);
-        }
-        if (WorkItemNode.class == clazz) {
-            return factory(WorkItemNodeInstance::new);
-        }
-        if (TimerNode.class == clazz) {
-            return factory(TimerNodeInstance::new);
-        }
-        if (FaultNode.class == clazz) {
-            return factory(FaultNodeInstance::new);
-        }
-        if (EventSubProcessNode.class == clazz) {
-            return factory(EventSubProcessNodeInstance::new);
-        }
-        if (CompositeNode.class == clazz) {
-            return factory(CompositeNodeInstance::new);
-        }
-        if (CompositeContextNode.class == clazz) {
-            return factory(CompositeContextNodeInstance::new);
-        }
-        if (HumanTaskNode.class == clazz) {
-            return factory(HumanTaskNodeInstance::new);
-        }
-        if (ForEachNode.class == clazz) {
-            return factory(ForEachNodeInstance::new);
-        }
-        if (EventNode.class == clazz) {
-            return factory(EventNodeInstance::new);
-        }
-        if (StateNode.class == clazz) {
-            return factory(StateNodeInstance::new);
-        }
-        if (DynamicNode.class == clazz) {
-            return factory(DynamicNodeInstance::new);
-        }
-        if (BoundaryEventNode.class == clazz) {
-            return factory(BoundaryEventNodeInstance::new);
-        }
-        if (CatchLinkNode.class == clazz) {
-            return factory(
-                    CatchLinkNodeInstance::new);
-        }
-        if (ThrowLinkNode.class == clazz) {
-            return factory(
-                    ThrowLinkNodeInstance::new);
-        }
-        if (AsyncEventNode.class == clazz) {
-            return factory(
-                    AsyncEventNodeInstance::new);
-        }
-
         return this.registry.get(clazz);
     }
 
-    protected NodeInstanceFactory factoryOnce(Supplier<NodeInstanceImpl> 
supplier) {
-        return (node, processInstance, nodeInstanceContainer) -> {
-            NodeInstance result = 
((org.jbpm.workflow.instance.NodeInstanceContainer) 
nodeInstanceContainer).getFirstNodeInstance(node.getId());
-            if (result != null) {
-                return result;
-            } else {
-                LOGGER.debug("creating node {} with identifier {}", node, 
node.getId());
-                return createInstance(supplier.get(), node, processInstance, 
nodeInstanceContainer);
-            }
-        };
-    }
-
-    protected NodeInstanceFactory factory(Supplier<NodeInstanceImpl> supplier) 
{
-        return (node, processInstance, nodeInstanceContainer) -> 
createInstance(supplier.get(), node, processInstance, nodeInstanceContainer);
-    }
-
-    private static NodeInstance createInstance(NodeInstanceImpl nodeInstance, 
Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer 
nodeInstanceContainer) {
-        nodeInstance.setNodeId(node.getId());
-        nodeInstance.setNodeInstanceContainer((KogitoNodeInstanceContainer) 
nodeInstanceContainer);
-        nodeInstance.setProcessInstance(processInstance);
-        nodeInstance.setMetaData(CUSTOM_ASYNC, 
node.getMetaData().get(CUSTOM_ASYNC));
-
-        int level = ((org.jbpm.workflow.instance.NodeInstanceContainer) 
nodeInstanceContainer).getLevelForNode(node.getUniqueId());
-        nodeInstance.setLevel(level);
-        return nodeInstance;
-    }
 }
diff --git 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/AbstractNodeInstanceFactory.java
old mode 100755
new mode 100644
similarity index 56%
copy from 
jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
copy to 
jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/AbstractNodeInstanceFactory.java
index 19611f70bf..6816197ed9
--- 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/AbstractNodeInstanceFactory.java
@@ -16,35 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * 
- */
-package org.jbpm.workflow.instance.node;
+
+package org.jbpm.workflow.instance.impl.factory;
 
 import org.jbpm.workflow.instance.WorkflowProcessInstance;
 import org.jbpm.workflow.instance.impl.NodeInstanceFactory;
+import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.kie.api.definition.process.Node;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.api.runtime.process.NodeInstanceContainer;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
 
-public class MockNodeInstanceFactory implements NodeInstanceFactory {
-
-    private MockNodeInstance instance;
+import static org.jbpm.ruleflow.core.Metadata.CUSTOM_ASYNC;
 
-    public MockNodeInstanceFactory(MockNodeInstance instance) {
-        this.instance = instance;
-    }
+public abstract class AbstractNodeInstanceFactory implements 
NodeInstanceFactory {
 
-    public MockNodeInstance getMockNodeInstance() {
-        return this.instance;
-    }
+    protected NodeInstance createInstance(NodeInstanceImpl nodeInstance, Node 
node, WorkflowProcessInstance processInstance, NodeInstanceContainer 
nodeInstanceContainer) {
+        nodeInstance.setNodeId(node.getId());
+        nodeInstance.setNodeInstanceContainer((KogitoNodeInstanceContainer) 
nodeInstanceContainer);
+        nodeInstance.setProcessInstance(processInstance);
+        nodeInstance.setMetaData(CUSTOM_ASYNC, 
node.getMetaData().get(CUSTOM_ASYNC));
 
-    public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance 
processInstance, NodeInstanceContainer nodeInstanceContainer) {
-        instance.setNodeId(node.getId());
-        instance.setProcessInstance(processInstance);
-        instance.setNodeInstanceContainer((KogitoNodeInstanceContainer) 
nodeInstanceContainer);
-        return instance;
+        int level = ((org.jbpm.workflow.instance.NodeInstanceContainer) 
nodeInstanceContainer).getLevelForNode(node.getUniqueId());
+        nodeInstance.setLevel(level);
+        return nodeInstance;
     }
-
 }
diff --git 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactory.java
old mode 100755
new mode 100644
similarity index 59%
copy from 
jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
copy to 
jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactory.java
index 19611f70bf..9dfb1e41de
--- 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactory.java
@@ -16,35 +16,35 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * 
- */
-package org.jbpm.workflow.instance.node;
+package org.jbpm.workflow.instance.impl.factory;
+
+import java.util.function.Supplier;
 
+import org.jbpm.workflow.core.impl.NodeImpl;
 import org.jbpm.workflow.instance.WorkflowProcessInstance;
-import org.jbpm.workflow.instance.impl.NodeInstanceFactory;
+import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.kie.api.definition.process.Node;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.api.runtime.process.NodeInstanceContainer;
-import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
 
-public class MockNodeInstanceFactory implements NodeInstanceFactory {
+public class DefaultNodeInstanceFactory extends AbstractNodeInstanceFactory {
 
-    private MockNodeInstance instance;
+    private Class<? extends NodeImpl> nodeDefinition;
+    private Supplier<NodeInstanceImpl> nodeInstanceSupplier;
 
-    public MockNodeInstanceFactory(MockNodeInstance instance) {
-        this.instance = instance;
+    @Override
+    public Class<? extends Node> forClass() {
+        return nodeDefinition;
     }
 
-    public MockNodeInstance getMockNodeInstance() {
-        return this.instance;
+    public DefaultNodeInstanceFactory(Class<? extends NodeImpl> 
nodeDefinition, Supplier<NodeInstanceImpl> supplier) {
+        this.nodeDefinition = nodeDefinition;
+        this.nodeInstanceSupplier = supplier;
     }
 
+    @Override
     public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance 
processInstance, NodeInstanceContainer nodeInstanceContainer) {
-        instance.setNodeId(node.getId());
-        instance.setProcessInstance(processInstance);
-        instance.setNodeInstanceContainer((KogitoNodeInstanceContainer) 
nodeInstanceContainer);
-        return instance;
+        return createInstance(nodeInstanceSupplier.get(), node, 
processInstance, nodeInstanceContainer);
     }
 
 }
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactoryProvider.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactoryProvider.java
new file mode 100644
index 0000000000..f2b345fa26
--- /dev/null
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/DefaultNodeInstanceFactoryProvider.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.workflow.instance.impl.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jbpm.workflow.core.node.ActionNode;
+import org.jbpm.workflow.core.node.AsyncEventNode;
+import org.jbpm.workflow.core.node.AsyncEventNodeInstance;
+import org.jbpm.workflow.core.node.BoundaryEventNode;
+import org.jbpm.workflow.core.node.CatchLinkNode;
+import org.jbpm.workflow.core.node.CompositeContextNode;
+import org.jbpm.workflow.core.node.CompositeNode;
+import org.jbpm.workflow.core.node.DynamicNode;
+import org.jbpm.workflow.core.node.EndNode;
+import org.jbpm.workflow.core.node.EventNode;
+import org.jbpm.workflow.core.node.EventSubProcessNode;
+import org.jbpm.workflow.core.node.FaultNode;
+import org.jbpm.workflow.core.node.ForEachNode;
+import org.jbpm.workflow.core.node.HumanTaskNode;
+import org.jbpm.workflow.core.node.Join;
+import org.jbpm.workflow.core.node.MilestoneNode;
+import org.jbpm.workflow.core.node.RuleSetNode;
+import org.jbpm.workflow.core.node.Split;
+import org.jbpm.workflow.core.node.StartNode;
+import org.jbpm.workflow.core.node.StateNode;
+import org.jbpm.workflow.core.node.SubProcessNode;
+import org.jbpm.workflow.core.node.ThrowLinkNode;
+import org.jbpm.workflow.core.node.TimerNode;
+import org.jbpm.workflow.core.node.WorkItemNode;
+import org.jbpm.workflow.instance.impl.NodeInstanceFactory;
+import org.jbpm.workflow.instance.impl.NodeInstanceFactoryProvider;
+import org.jbpm.workflow.instance.node.ActionNodeInstance;
+import org.jbpm.workflow.instance.node.BoundaryEventNodeInstance;
+import org.jbpm.workflow.instance.node.CatchLinkNodeInstance;
+import org.jbpm.workflow.instance.node.CompositeContextNodeInstance;
+import org.jbpm.workflow.instance.node.CompositeNodeInstance;
+import org.jbpm.workflow.instance.node.DynamicNodeInstance;
+import org.jbpm.workflow.instance.node.EndNodeInstance;
+import org.jbpm.workflow.instance.node.EventNodeInstance;
+import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance;
+import org.jbpm.workflow.instance.node.FaultNodeInstance;
+import org.jbpm.workflow.instance.node.ForEachNodeInstance;
+import org.jbpm.workflow.instance.node.HumanTaskNodeInstance;
+import org.jbpm.workflow.instance.node.JoinInstance;
+import org.jbpm.workflow.instance.node.MilestoneNodeInstance;
+import org.jbpm.workflow.instance.node.RuleSetNodeInstance;
+import org.jbpm.workflow.instance.node.SplitInstance;
+import org.jbpm.workflow.instance.node.StartNodeInstance;
+import org.jbpm.workflow.instance.node.StateNodeInstance;
+import org.jbpm.workflow.instance.node.SubProcessNodeInstance;
+import org.jbpm.workflow.instance.node.ThrowLinkNodeInstance;
+import org.jbpm.workflow.instance.node.TimerNodeInstance;
+import org.jbpm.workflow.instance.node.WorkItemNodeInstance;
+
+public class DefaultNodeInstanceFactoryProvider implements 
NodeInstanceFactoryProvider {
+
+    @Override
+    public List<NodeInstanceFactory> provide() {
+        List<NodeInstanceFactory> nodeInstanceFactoryList = new ArrayList<>();
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(RuleSetNode.class, RuleSetNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(Split.class, SplitInstance::new));
+        nodeInstanceFactoryList.add(new 
SingletonNodeInstanceFactory(Join.class, JoinInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(StartNode.class, StartNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(EndNode.class, EndNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(MilestoneNode.class, MilestoneNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(SubProcessNode.class, SubProcessNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(ActionNode.class, ActionNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(WorkItemNode.class, WorkItemNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(TimerNode.class, TimerNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(FaultNode.class, FaultNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(EventSubProcessNode.class, 
EventSubProcessNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(CompositeNode.class, CompositeNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(CompositeContextNode.class, 
CompositeContextNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(HumanTaskNode.class, HumanTaskNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(ForEachNode.class, ForEachNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(EventNode.class, EventNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(StateNode.class, StateNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(DynamicNode.class, DynamicNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(BoundaryEventNode.class, 
BoundaryEventNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(CatchLinkNode.class, CatchLinkNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(ThrowLinkNode.class, ThrowLinkNodeInstance::new));
+        nodeInstanceFactoryList.add(new 
DefaultNodeInstanceFactory(AsyncEventNode.class, AsyncEventNodeInstance::new));
+        return nodeInstanceFactoryList;
+    }
+
+}
diff --git 
a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/SingletonNodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/SingletonNodeInstanceFactory.java
new file mode 100644
index 0000000000..57b1878a45
--- /dev/null
+++ 
b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/factory/SingletonNodeInstanceFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.workflow.instance.impl.factory;
+
+import java.util.function.Supplier;
+
+import org.jbpm.workflow.core.impl.NodeImpl;
+import org.jbpm.workflow.instance.WorkflowProcessInstance;
+import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
+import org.kie.api.definition.process.Node;
+import org.kie.api.runtime.process.NodeInstance;
+import org.kie.api.runtime.process.NodeInstanceContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SingletonNodeInstanceFactory extends AbstractNodeInstanceFactory {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(SingletonNodeInstanceFactory.class);
+
+    private Class<? extends NodeImpl> nodeDefinition;
+    private Supplier<NodeInstanceImpl> nodeInstanceSupplier;
+
+    @Override
+    public Class<? extends Node> forClass() {
+        return nodeDefinition;
+    }
+
+    public SingletonNodeInstanceFactory(Class<? extends NodeImpl> 
nodeDefinition, Supplier<NodeInstanceImpl> nodeInstanceSupplier) {
+        this.nodeDefinition = nodeDefinition;
+        this.nodeInstanceSupplier = nodeInstanceSupplier;
+    }
+
+    @Override
+    public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance 
processInstance, NodeInstanceContainer nodeInstanceContainer) {
+        NodeInstance result = 
((org.jbpm.workflow.instance.NodeInstanceContainer) 
nodeInstanceContainer).getFirstNodeInstance(node.getId());
+        if (result != null) {
+            return result;
+        } else {
+            LOGGER.debug("creating node {} with identifier {}", node, 
node.getId());
+            return createInstance(nodeInstanceSupplier.get(), node, 
processInstance, nodeInstanceContainer);
+        }
+    }
+
+}
diff --git 
a/jbpm/jbpm-flow/src/main/resources/META-INF/services/org.jbpm.workflow.instance.impl.NodeInstanceFactoryProvider
 
b/jbpm/jbpm-flow/src/main/resources/META-INF/services/org.jbpm.workflow.instance.impl.NodeInstanceFactoryProvider
new file mode 100644
index 0000000000..236f07a277
--- /dev/null
+++ 
b/jbpm/jbpm-flow/src/main/resources/META-INF/services/org.jbpm.workflow.instance.impl.NodeInstanceFactoryProvider
@@ -0,0 +1 @@
+org.jbpm.workflow.instance.impl.factory.DefaultNodeInstanceFactoryProvider
\ No newline at end of file
diff --git 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
 
b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
index 19611f70bf..6b65cb9e8d 100755
--- 
a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
+++ 
b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
@@ -32,6 +32,11 @@ public class MockNodeInstanceFactory implements 
NodeInstanceFactory {
 
     private MockNodeInstance instance;
 
+    @Override
+    public Class<? extends Node> forClass() {
+        return this.instance.getNode().getClass();
+    }
+
     public MockNodeInstanceFactory(MockNodeInstance instance) {
         this.instance = instance;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to