Skip to content

Commit

Permalink
Add an api that can take bpm content as a parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
yusu committed Aug 4, 2023
1 parent eb2787c commit 2e02259
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 85 deletions.
28 changes: 16 additions & 12 deletions src/main/java/com/alibaba/compileflow/engine/ProcessEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,8 @@ public interface ProcessEngine<T extends FlowModel> {

Map<String, Object> execute(String code, Map<String, Object> context);

/**
* @param code: flow code
* @param tag: flow node tag
* @param context
*/
Map<String, Object> trigger(String code, String tag, Map<String, Object> context);

/**
* @param code: flow code
* @param tag: flow node tag
* @param context
*/
Map<String, Object> trigger(String code, String tag, String event, Map<String, Object> context);

@Deprecated
Expand All @@ -47,12 +37,26 @@ public interface ProcessEngine<T extends FlowModel> {

void preCompile(ClassLoader classLoader, String... codes);

void reload(String code);

T load(String code);

String getJavaCode(String code);

String getTestCode(String code);

Map<String, Object> execute(String code, Map<String, Object> context, String content);

Map<String, Object> trigger(String code, String tag, Map<String, Object> context, String content);

Map<String, Object> trigger(String code, String tag, String event, Map<String, Object> context, String content);

void preCompile(Map<String, String> code2ContentMap);

void preCompile(ClassLoader classLoader, Map<String, String> code2ContentMap);

T load(String code, String content);

String getJavaCode(String code, String content);

String getTestCode(String code, String content);

}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public static URL[] getResources(String resourceName, Class referrer) {
}

public static URL[] getResources(String resourceName, ClassLoader classLoader) {
LinkedList urls = new LinkedList();
List urls = new LinkedList();

getResources(urls, resourceName, classLoader, classLoader == null);

Expand Down Expand Up @@ -137,15 +137,15 @@ private static boolean getResources(List urlSet, String resourceName, ClassLoade
return false;
}

private static URL[] getDistinctURLs(LinkedList<URL> urls) {
private static URL[] getDistinctURLs(List<URL> urls) {
if ((urls == null) || (urls.size() == 0)) {
return new URL[0];
}

Set<URL> urlSet = new HashSet<>(urls.size());

for (Iterator i = urls.iterator(); i.hasNext(); ) {
URL url = (URL) i.next();
for (Iterator<URL> i = urls.iterator(); i.hasNext(); ) {
URL url = i.next();

if (urlSet.contains(url)) {
i.remove();
Expand All @@ -154,7 +154,7 @@ private static URL[] getDistinctURLs(LinkedList<URL> urls) {
}
}

return urls.toArray(new URL[urls.size()]);
return urls.toArray(new URL[0]);
}

public static URL getResource(String resourceName) {
Expand All @@ -163,7 +163,7 @@ public static URL getResource(String resourceName) {
}

ClassLoader classLoader = getContextClassLoader();
URL url = null;
URL url;

if (classLoader != null) {
url = classLoader.getResource(resourceName);
Expand Down Expand Up @@ -194,8 +194,8 @@ public static URL getResource(String resourceName, Class referrer) {
ClassLoader classLoader = getReferrerClassLoader(referrer);

return (classLoader == null)
? ClassLoaderUtils.class.getClassLoader().getResource(resourceName)
: classLoader.getResource(resourceName);
? ClassLoaderUtils.class.getClassLoader().getResource(resourceName)
: classLoader.getResource(resourceName);
}

public static URL getResource(String resourceName, ClassLoader classLoader) {
Expand All @@ -204,8 +204,8 @@ public static URL getResource(String resourceName, ClassLoader classLoader) {
}

return (classLoader == null)
? ClassLoaderUtils.class.getClassLoader().getResource(resourceName)
: classLoader.getResource(resourceName);
? ClassLoaderUtils.class.getClassLoader().getResource(resourceName)
: classLoader.getResource(resourceName);
}

public static InputStream getResourceAsStream(String resourceName) {
Expand All @@ -215,8 +215,8 @@ public static InputStream getResourceAsStream(String resourceName) {
if (url != null) {
return url.openStream();
}
} catch (IOException ignored) {
logger.error("Failed to getResourceAsStream, resourceName is " + resourceName, ignored);
} catch (IOException e) {
logger.error("Failed to getResourceAsStream, resourceName is " + resourceName, e);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@
import com.alibaba.compileflow.engine.common.CompileFlowException;
import com.alibaba.compileflow.engine.common.DirectedGraph;
import com.alibaba.compileflow.engine.common.constant.FlowModelType;
import com.alibaba.compileflow.engine.common.extension.ExtensionInvoker;
import com.alibaba.compileflow.engine.common.extension.filter.ReduceFilter;
import com.alibaba.compileflow.engine.common.util.ArrayUtils;
import com.alibaba.compileflow.engine.common.util.MapUtils;
import com.alibaba.compileflow.engine.definition.common.EndElement;
import com.alibaba.compileflow.engine.definition.common.FlowModel;
import com.alibaba.compileflow.engine.definition.common.TransitionNode;
import com.alibaba.compileflow.engine.definition.common.TransitionSupport;
import com.alibaba.compileflow.engine.process.preruntime.converter.FlowModelConverter;
import com.alibaba.compileflow.engine.process.preruntime.converter.impl.parser.model.FlowStreamSource;
import com.alibaba.compileflow.engine.process.preruntime.converter.impl.parser.model.ResourceFlowStreamSource;
import com.alibaba.compileflow.engine.process.preruntime.loader.FlowSourceLoader;
import com.alibaba.compileflow.engine.runtime.impl.AbstractProcessRuntime;
import org.apache.commons.collections4.CollectionUtils;

Expand Down Expand Up @@ -58,33 +61,51 @@ public void preCompile(ClassLoader classLoader, String... codes) {
}

for (String code : codes) {
AbstractProcessRuntime runtime = getProcessRuntime(code);
runtime.compile(classLoader);
preCompile(classLoader, code);
}
}

@Override
public void reload(String code) {
AbstractProcessRuntime runtime = runtimeCache.computeIfPresent(code, (k, v) -> getRuntimeFromSource(code));
runtime.recompile(code);
public void preCompile(Map<String, String> code2ContentMap) {
preCompile(null, code2ContentMap);
}

@Override
public void preCompile(ClassLoader classLoader, Map<String, String> code2ContentMap) {
if (MapUtils.isEmpty(code2ContentMap)) {
return;
}
code2ContentMap.forEach((code, content) -> preCompile(classLoader, code, content));
}

@SuppressWarnings("unchecked")
protected <R extends AbstractProcessRuntime> R getProcessRuntime(String code) {
return getProcessRuntime(code, null);
}

protected <R extends AbstractProcessRuntime> R getProcessRuntime(String code, String content) {
String cacheKey = getCacheKey(code);
AbstractProcessRuntime runtime = runtimeCache.computeIfAbsent(cacheKey, c ->
getCompiledRuntime(code));
getCompiledRuntime(code, content));
return (R) runtime;
}

private AbstractProcessRuntime getCompiledRuntime(String code) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code);
private void preCompile(ClassLoader classLoader, String code) {
preCompile(classLoader, code, null);
}

private void preCompile(ClassLoader classLoader, String code, String content) {
AbstractProcessRuntime runtime = getProcessRuntime(code, content);
runtime.compile(classLoader);
}

private AbstractProcessRuntime getCompiledRuntime(String code, String content) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code, content);
runtime.compile();
return runtime;
}

private AbstractProcessRuntime getRuntimeFromSource(String code) {
T flowModel = load(code);
private AbstractProcessRuntime getRuntimeFromSource(String code, String content) {
T flowModel = load(code, content);
AbstractProcessRuntime runtime = getRuntimeFromModel(flowModel);
runtime.init();
return runtime;
Expand All @@ -93,7 +114,12 @@ private AbstractProcessRuntime getRuntimeFromSource(String code) {
@Override
@SuppressWarnings("unchecked")
public T load(String code) {
FlowStreamSource flowStreamSource = loadFlowSource(code);
return load(code, null);
}

public T load(String code, String content) {
FlowStreamSource flowStreamSource = ExtensionInvoker.getInstance().invoke(FlowSourceLoader.EXT_LOAD_FLOW_SOURCE_CODE,
ReduceFilter.first(), code, content, getFlowModelType());

T flowModel = (T) getFlowModelConverter().convertToModel(flowStreamSource);
if (flowModel == null) {
Expand All @@ -109,32 +135,24 @@ public T load(String code) {

@Override
public String getJavaCode(String code) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code);
return runtime.generateJavaCode();
return getJavaCode(code, null);
}

@Override
public String getTestCode(String code) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code);
return runtime.generateTestCode();
}

private FlowStreamSource loadFlowSource(String code) {
String filePath = convertToFilePath(code);
return ResourceFlowStreamSource.of(filePath);
public String getJavaCode(String code, String content) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code, content);
return runtime.generateJavaCode();
}

private String convertToFilePath(String code) {
String path = code.replace(".", "/");
FlowModelType flowModelType = getFlowModelType();
return path + getBpmFileSuffix(flowModelType);
@Override
public String getTestCode(String code) {
return getTestCode(code, null);
}

private String getBpmFileSuffix(FlowModelType flowModelType) {
if (FlowModelType.BPMN.equals(flowModelType)) {
return ".bpmn20";
}
return ".bpm";
@Override
public String getTestCode(String code, String content) {
AbstractProcessRuntime runtime = getRuntimeFromSource(code, content);
return runtime.generateTestCode();
}

private void checkContinuous(T flowModel) {
Expand Down Expand Up @@ -166,20 +184,20 @@ private void checkCycle(T flowModel) {
List<TransitionNode> outgoingNodes = node.getOutgoingNodes();
if (CollectionUtils.isNotEmpty(outgoingNodes)) {
outgoingNodes.forEach(
outgoingNode -> directedGraph.add(DirectedGraph.Edge.of(node, outgoingNode)));
outgoingNode -> directedGraph.add(DirectedGraph.Edge.of(node, outgoingNode)));
}
}
List<TransitionNode> cyclicVertexList = directedGraph.findCyclicVertexList();
if (CollectionUtils.isNotEmpty(cyclicVertexList)) {
throw new CompileFlowException("Cyclic nodes found in flow " + flowModel.getCode()
+ " check node [" + cyclicVertexList.stream().map(TransitionNode::getId)
.collect(Collectors.joining(",")) + "]");
+ " check node [" + cyclicVertexList.stream().map(TransitionNode::getId)
.collect(Collectors.joining(",")) + "]");
}
}

private void sortTransition(T flowModel) {
flowModel.getAllNodes().forEach(node -> node.getTransitions()
.sort(Comparator.comparing(TransitionSupport::getPriority).reversed()));
.sort(Comparator.comparing(TransitionSupport::getPriority).reversed()));
}

private String getCacheKey(String code) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ public Map<String, Object> start(String code, Map<String, Object> context) {
return runtime.start(context);
}

@Override
public Map<String, Object> execute(String code, Map<String, Object> context, String content) {
BpmnProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.start(context);
}

@Override
public Map<String, Object> trigger(String code, String tag, Map<String, Object> context, String content) {
BpmnProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.trigger(tag, context);
}

@Override
public Map<String, Object> trigger(String code, String tag, String event, Map<String, Object> context, String content) {
BpmnProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.trigger(tag, event, context);
}

@Override
protected FlowModelType getFlowModelType() {
return FlowModelType.BPMN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ public Map<String, Object> start(String code, Map<String, Object> context) {
return runtime.start(context);
}

@Override
public Map<String, Object> execute(String code, Map<String, Object> context, String content) {
TbbpmProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.start(context);
}

@Override
public Map<String, Object> trigger(String code, String tag, Map<String, Object> context, String content) {
TbbpmProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.trigger(tag, context);
}

@Override
public Map<String, Object> trigger(String code, String tag, String event, Map<String, Object> context, String content) {
TbbpmProcessRuntime runtime = getProcessRuntime(code, content);
return runtime.trigger(tag, event, context);
}

@Override
protected FlowModelType getFlowModelType() {
return FlowModelType.TBBPM;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
*/
public class CompilerImpl implements Compiler {

private static final JavaCompiler JAVA_COMPILER = new EcJavaCompiler();

@Override
public Class<?> compileJavaCode(String fullClassName, String sourceCode, ClassLoader classLoader) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static FlowUrlClassLoader getInstance() {
try {
URL url = new URL("file:///" + CompileConstants.FLOW_COMPILE_CLASS_DIR);
instance = new FlowUrlClassLoader(new URL[]{url},
FlowUrlClassLoader.class.getClassLoader());
FlowUrlClassLoader.class.getClassLoader());
} catch (Exception e) {
throw new CompileFlowException(e);
}
Expand All @@ -33,7 +33,7 @@ public static FlowUrlClassLoader getInstance() {
return instance;
}

public void clearCache() {
public void reset() {
instance = null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.alibaba.compileflow.engine.process.preruntime.converter.impl.parser.model;

/**
* @author yusu <[email protected]>
* Created on 2022-12-08
*/
public abstract class AbstractFlowSource<T> implements FlowSource<T> {

private String code;

@Override
public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

}
Loading

0 comments on commit 2e02259

Please sign in to comment.