Skip to content

Commit de882e3

Browse files
committed
extended WorkflowService (Issue #948)
1 parent 7b258b3 commit de882e3

File tree

2 files changed

+207
-116
lines changed

2 files changed

+207
-116
lines changed

imixs-workflow-engine/src/main/java/org/imixs/workflow/engine/WorkflowService.java

Lines changed: 190 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,35 +1104,212 @@ public List<String> adaptTextList(String text, ItemCollection documentContext) t
11041104
@Override
11051105
public ItemCollection evalWorkflowResult(ItemCollection event, String xmlTag, ItemCollection documentContext,
11061106
boolean resolveItemValues) throws PluginException {
1107-
boolean debug = logger.isLoggable(Level.FINE);
1108-
ItemCollection result = new ItemCollection();
11091107
String workflowResult = event.getItemValueString(BPMNUtil.EVENT_ITEM_WORKFLOW_RESULT);
11101108
// support deprecated itemname
11111109
if (workflowResult.isEmpty()) {
11121110
workflowResult = event.getItemValueString("txtActivityResult");
11131111
}
1114-
if (workflowResult.trim().isEmpty()) {
1112+
return evalXMLExpression(workflowResult, xmlTag, documentContext, resolveItemValues);
1113+
}
1114+
1115+
/**
1116+
* The method evaluates the WorkflowResult for a given BPMN event and returns a
1117+
* ItemColleciton containing all item values of a specified tag name. Each tag
1118+
* definition of a WorkflowResult contains a name and a optional list of
1119+
* additional attributes. The method generates a item for each content element
1120+
* and attribute value. <br>
1121+
* e.g. <item name="comment" ignore="true">text</item> <br>
1122+
* will result in the attributes 'comment' with value 'text' and
1123+
* 'comment.ignore' with the value 'true'
1124+
* <p>
1125+
* Also embedded itemVaues can be resolved (resolveItemValues=true):
1126+
* <p>
1127+
* {@code
1128+
* <somedata>ABC<itemvalue>$uniqueid</itemvalue></somedata>
1129+
* }
1130+
* <p>
1131+
* This example will result in a new item 'somedata' with the $uniqueid prefixed
1132+
* with 'ABC'
1133+
*
1134+
* @see evalWorkflowResult(ItemCollection event, String tag, ItemCollection
1135+
* documentContext,boolean resolveItemValues)
1136+
* @param event
1137+
* @param tag - tag to be evaluated
1138+
* @param documentContext
1139+
* @return
1140+
* @throws PluginException
1141+
*/
1142+
public ItemCollection evalWorkflowResult(ItemCollection event, String tag, ItemCollection documentContext)
1143+
throws PluginException {
1144+
return evalWorkflowResult(event, tag, documentContext, true);
1145+
}
1146+
1147+
/**
1148+
* The method evaluates a XML tag from the WorkflowResult for a given BPMN
1149+
* event. The method returns a list of ItemCollecitons matching the given XML
1150+
* tag and name attribtue. A custom XML configuriaton may contain one or many
1151+
* XML tags with the same name. Each result ItemCollection holds the tag values
1152+
* of each XML tag.
1153+
*
1154+
* Example:
1155+
*
1156+
* <pre>
1157+
* {@code
1158+
* <imixs-config name="CONFIG">
1159+
* <textblock>....</textblock>
1160+
* <template>....</template>
1161+
* </imixs-config>
1162+
* }
1163+
* </pre>
1164+
*
1165+
* @param event
1166+
* @param xmlTag - xml tag to be evaluated
1167+
* @param name - value of the matching name attribute
1168+
* @param documentContext
1169+
* @param resolveItemValues - if true, itemValue tags will be resolved.
1170+
* @return list of ItemCollections
1171+
* @throws PluginException if the xml structure is invalid
1172+
*/
1173+
public List<ItemCollection> evalWorkflowResultXML(ItemCollection event, String xmlTag, String name,
1174+
ItemCollection documentContext,
1175+
boolean resolveItemValues) throws PluginException {
1176+
1177+
String workflowResult = event.getItemValueString(BPMNUtil.EVENT_ITEM_WORKFLOW_RESULT);
1178+
// support deprecated itemname
1179+
if (workflowResult.isEmpty()) {
1180+
workflowResult = event.getItemValueString("txtActivityResult");
1181+
}
1182+
1183+
try {
1184+
return evalXMLExpressionList(workflowResult, xmlTag, name, documentContext, resolveItemValues);
1185+
} catch (PluginException e) {
1186+
// no configuration found!
1187+
throw new PluginException(WorkflowService.class.getSimpleName(), INVALID_TAG_FORMAT,
1188+
"Missing XML definition '" + xmlTag + "' in Event " + event.getItemValueInteger("numprocessid")
1189+
+ "." + event.getItemValueInteger("numactivityid"));
1190+
}
1191+
1192+
}
1193+
1194+
/**
1195+
* The method evaluates a XML expression and returns a list of ItemCollecitons
1196+
* matching the given XML tag and name attribtue. A custom XML configuriaton may
1197+
* contain one or many XML tags with the same name. Each result ItemCollection
1198+
* holds the tag values of each XML tag.
1199+
*
1200+
* Example:
1201+
*
1202+
* <pre>
1203+
* {@code
1204+
* <imixs-config name="CONFIG">
1205+
* <textblock>....</textblock>
1206+
* <template>....</template>
1207+
* </imixs-config>
1208+
* }
1209+
* </pre>
1210+
*
1211+
* @param event
1212+
* @param xmlTag - xml tag to be evaluated
1213+
* @param name - value of the matching name attribute
1214+
* @param documentContext
1215+
* @param resolveItemValues - if true, itemValue tags will be resolved.
1216+
* @return list of ItemCollections
1217+
* @throws PluginException if the xml structure is invalid
1218+
*/
1219+
public List<ItemCollection> evalXMLExpressionList(String xmlExpression, String xmlTag, String name,
1220+
ItemCollection documentContext, boolean resolveItemValues) throws PluginException {
1221+
1222+
List<ItemCollection> result = new ArrayList<ItemCollection>();
1223+
// find all xml configs with the given tat name
1224+
ItemCollection configItemCol = evalXMLExpression(xmlExpression, xmlTag, documentContext, resolveItemValues);
1225+
if (configItemCol == null) {
1226+
// no configuration found!
1227+
throw new PluginException(WorkflowService.class.getSimpleName(), INVALID_TAG_FORMAT,
1228+
"Missing XML definition");
1229+
}
1230+
1231+
List<String> xmlDefinitions = configItemCol.getItemValueList(name, String.class);
1232+
if (xmlDefinitions != null) {
1233+
for (String definitionXML : xmlDefinitions) {
1234+
if (definitionXML.trim().isEmpty()) {
1235+
// no definition
1236+
continue;
1237+
}
1238+
// evaluate the definition (XML format expected here!)
1239+
ItemCollection xmlItemCol = XMLParser.parseItemStructure(definitionXML);
1240+
if (xmlItemCol != null) {
1241+
result.add(xmlItemCol);
1242+
}
1243+
}
1244+
}
1245+
1246+
return result;
1247+
1248+
}
1249+
1250+
/**
1251+
* The method evaluates a XML expression and returns a ItemColleciton containing
1252+
* all item values of a specified xml tag. Each tag definition must contain at
1253+
* least a name attribute and may contain an optional list of additional
1254+
* attributes.
1255+
* <p>
1256+
* The method generates a item for each content element and attribute value.
1257+
* e.g.:
1258+
* <p>
1259+
* {@code<item name="comment" ignore="true">text</item>}
1260+
* <p>
1261+
* This example will result in an ItemCollection with the attributes 'comment'
1262+
* with value 'text' and 'comment.ignore' with the value 'true'
1263+
* <p>
1264+
* Also embedded itemVaues can be resolved (resolveItemValues=true):
1265+
* <p>
1266+
* {@code
1267+
* <somedata>ABC<itemvalue>$uniqueid</itemvalue></somedata>
1268+
* }
1269+
* <p>
1270+
* This example will result in a new item 'somedata' with the $uniqueid prefixed
1271+
* with 'ABC'
1272+
*
1273+
* You can also activate the debug mode with the optional tag 'debug="true"'
1274+
*
1275+
* @see https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags
1276+
* @param event
1277+
* @param xmlTag - XML tag to be evaluated
1278+
* @param documentContext
1279+
* @param resolveItemValues - if true, itemValue tags will be resolved.
1280+
* @return eval itemCollection or null if no tags are contained in the workflow
1281+
* result.
1282+
* @throws PluginException if the xml structure is invalid
1283+
*/
1284+
public ItemCollection evalXMLExpression(String xmlExpression, String xmlTag, ItemCollection documentContext,
1285+
boolean resolveItemValues) throws PluginException {
1286+
boolean debug = logger.isLoggable(Level.FINE);
1287+
ItemCollection result = new ItemCollection();
1288+
1289+
if (xmlExpression.trim().isEmpty()) {
11151290
return null;
11161291
}
1292+
1293+
debug = xmlExpression.toLowerCase().contains("debug=\"ture\"");
11171294
if (xmlTag == null || xmlTag.isEmpty()) {
11181295
logger.warning("cannot eval workflow result - no tag name specified. Verify model!");
11191296
return null;
11201297
}
11211298

11221299
// if no <tag exists we skip the evaluation...
1123-
if (workflowResult.indexOf("<" + xmlTag) == -1) {
1300+
if (xmlExpression.indexOf("<" + xmlTag) == -1) {
11241301
return null;
11251302
}
11261303

11271304
// replace dynamic values?
11281305
if (resolveItemValues) {
1129-
workflowResult = adaptText(workflowResult, documentContext);
1306+
xmlExpression = adaptText(xmlExpression, documentContext);
11301307
}
11311308

11321309
boolean invalidPattern = false;
11331310
// Fast first test if the tag really exists....
11341311
Pattern patternSimple = Pattern.compile("<" + xmlTag + " (.*?)>(.*?)|<" + xmlTag + " (.*?)./>", Pattern.DOTALL);
1135-
Matcher matcherSimple = patternSimple.matcher(workflowResult);
1312+
Matcher matcherSimple = patternSimple.matcher(xmlExpression);
11361313
if (matcherSimple.find()) {
11371314
invalidPattern = true;
11381315
// we found the starting tag.....
@@ -1144,7 +1321,7 @@ public ItemCollection evalWorkflowResult(ItemCollection event, String xmlTag, It
11441321
Pattern pattern = Pattern
11451322
.compile("(?s)(?:(<" + xmlTag + "(?>\\b(?:\".*?\"|'.*?'|[^>]*?)*>)(?<=/>))|(<" + xmlTag
11461323
+ "(?>\\b(?:\".*?\"|'.*?'|[^>]*?)*>)(?<!/>))(.*?)(</" + xmlTag + "\\s*>))", Pattern.DOTALL);
1147-
Matcher matcher = pattern.matcher(workflowResult);
1324+
Matcher matcher = pattern.matcher(xmlExpression);
11481325
while (matcher.find()) {
11491326
invalidPattern = false;
11501327
// we expect up to 4 different result groups
@@ -1203,28 +1380,28 @@ public ItemCollection evalWorkflowResult(ItemCollection event, String xmlTag, It
12031380
result.appendItemValue(tagName, Integer.valueOf(content));
12041381
} catch (NumberFormatException e) {
12051382
// append 0 value
1206-
result.appendItemValue(tagName, new Integer(0));
1383+
result.appendItemValue(tagName, Integer.valueOf(0));
12071384
}
12081385
} else if ("double".equalsIgnoreCase(sType)) {
12091386
try {
12101387
result.appendItemValue(tagName, Double.valueOf(content));
12111388
} catch (NumberFormatException e) {
12121389
// append 0 value
1213-
result.appendItemValue(tagName, new Double(0));
1390+
result.appendItemValue(tagName, Double.valueOf(0));
12141391
}
12151392
} else if ("float".equalsIgnoreCase(sType)) {
12161393
try {
12171394
result.appendItemValue(tagName, Float.valueOf(content));
12181395
} catch (NumberFormatException e) {
12191396
// append 0 value
1220-
result.appendItemValue(tagName, new Float(0));
1397+
result.appendItemValue(tagName, Float.valueOf(0));
12211398
}
12221399
} else if ("long".equalsIgnoreCase(sType)) {
12231400
try {
12241401
result.appendItemValue(tagName, Long.valueOf(content));
12251402
} catch (NumberFormatException e) {
12261403
// append 0 value
1227-
result.appendItemValue(tagName, new Long(0));
1404+
result.appendItemValue(tagName, Long.valueOf(0));
12281405
}
12291406
} else if ("date".equalsIgnoreCase(sType)) {
12301407
if (content == null || content.isEmpty()) {
@@ -1234,7 +1411,7 @@ public ItemCollection evalWorkflowResult(ItemCollection event, String xmlTag, It
12341411
// convert content value to date object
12351412
try {
12361413
if (debug) {
1237-
logger.finer("......convert string into date object");
1414+
logger.info("......convert string into date object");
12381415
}
12391416
Date dateResult = null;
12401417
if (sFormat == null || sFormat.isEmpty()) {
@@ -1274,104 +1451,13 @@ public ItemCollection evalWorkflowResult(ItemCollection event, String xmlTag, It
12741451
// test for general invalid format
12751452
if (invalidPattern) {
12761453
throw new PluginException(ResultPlugin.class.getSimpleName(), INVALID_TAG_FORMAT,
1277-
"invalid <" + xmlTag + "> tag format in workflowResult: " + workflowResult
1454+
"invalid <" + xmlTag + "> tag format in workflowResult: " + xmlExpression
12781455
+ " , expected format is <"
12791456
+ xmlTag + " name=\"...\">...</item> ");
12801457
}
12811458
return result;
12821459
}
12831460

1284-
/**
1285-
* The method evaluates the WorkflowResult for a given BPMN event and returns a
1286-
* ItemColleciton containing all item values of a specified tag name. Each tag
1287-
* definition of a WorkflowResult contains a name and a optional list of
1288-
* additional attributes. The method generates a item for each content element
1289-
* and attribute value. <br>
1290-
* e.g. <item name="comment" ignore="true">text</item> <br>
1291-
* will result in the attributes 'comment' with value 'text' and
1292-
* 'comment.ignore' with the value 'true'
1293-
* <p>
1294-
* Also embedded itemVaues can be resolved (resolveItemValues=true):
1295-
* <p>
1296-
* {@code
1297-
* <somedata>ABC<itemvalue>$uniqueid</itemvalue></somedata>
1298-
* }
1299-
* <p>
1300-
* This example will result in a new item 'somedata' with the $uniqueid prefixed
1301-
* with 'ABC'
1302-
*
1303-
* @see evalWorkflowResult(ItemCollection event, String tag, ItemCollection
1304-
* documentContext,boolean resolveItemValues)
1305-
* @param event
1306-
* @param tag - tag to be evaluated
1307-
* @param documentContext
1308-
* @return
1309-
* @throws PluginException
1310-
*/
1311-
public ItemCollection evalWorkflowResult(ItemCollection event, String tag, ItemCollection documentContext)
1312-
throws PluginException {
1313-
return evalWorkflowResult(event, tag, documentContext, true);
1314-
}
1315-
1316-
/**
1317-
* The method evaluates a XML tag from the WorkflowResult for a given BPMN
1318-
* event. The method returns a list of ItemCollecitons matching the given XML
1319-
* tag and name attribtue. A custom XML configuriaton may contain one or many
1320-
* XML tags with the same name. Each result ItemCollection holds the tag values
1321-
* of each XML tag.
1322-
*
1323-
* Example:
1324-
*
1325-
* <pre>
1326-
* {@code
1327-
* <imixs-config name="CONFIG">
1328-
* <textblock>....</textblock>
1329-
* <template>....</template>
1330-
* </imixs-config>
1331-
* }
1332-
* </pre>
1333-
*
1334-
* @param event
1335-
* @param xmlTag - xml tag to be evaluated
1336-
* @param name - value of the matching name attribute
1337-
* @param documentContext
1338-
* @param resolveItemValues - if true, itemValue tags will be resolved.
1339-
* @return list of ItemCollections
1340-
* @throws PluginException if the xml structure is invalid
1341-
*/
1342-
public List<ItemCollection> evalWorkflowResultXML(ItemCollection event, String xmlTag, String name,
1343-
ItemCollection documentContext,
1344-
boolean resolveItemValues) throws PluginException {
1345-
1346-
List<ItemCollection> result = new ArrayList<ItemCollection>();
1347-
// find all xml configs with the given tat name
1348-
ItemCollection configItemCol = evalWorkflowResult(event, xmlTag, documentContext, resolveItemValues);
1349-
if (configItemCol == null) {
1350-
// no configuration found!
1351-
throw new PluginException(WorkflowService.class.getSimpleName(), INVALID_TAG_FORMAT,
1352-
"Missing XML definition '" + xmlTag + "' in Event " + event.getItemValueInteger("numprocessid")
1353-
+ "." + event.getItemValueInteger("numactivityid"));
1354-
}
1355-
1356-
List<String> xmlDefinitions = configItemCol.getItemValueList(name, String.class);
1357-
if (xmlDefinitions != null) {
1358-
for (String definitionXML : xmlDefinitions) {
1359-
if (definitionXML.trim().isEmpty()) {
1360-
// no definition
1361-
continue;
1362-
}
1363-
// evaluate the definition (XML format expected here!)
1364-
ItemCollection xmlItemCol = XMLParser.parseItemStructure(definitionXML);
1365-
if (xmlItemCol != null) {
1366-
result.add(xmlItemCol);
1367-
}
1368-
}
1369-
}
1370-
1371-
return result;
1372-
1373-
}
1374-
13751461
/**
13761462
* This method implements a flexible condition evaluation pattern:
13771463
* <ol>

0 commit comments

Comments
 (0)