Skip to content

Commit

Permalink
Add validation for DRGElement.name == DRGElement.variable.name and DR…
Browse files Browse the repository at this point in the history
…GElement.typeRef == DRGElement.variable.typeRef (#627)
  • Loading branch information
opatrascoiu authored Nov 16, 2023
1 parent b154a89 commit f331a1e
Showing 1 changed file with 94 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,43 @@ public static Iterable<Object[]> data() {
return testCases;
}

private static Node extractChild(Node parent, String tag) {
if (parent == null) {
return null;
}
NodeList childNodes = parent.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (tag.equals(item.getNodeName())) {
return item;
}
}
return null;
}

private static String extractStringAttribute(Node node, String attributeName) {
if (node == null) {
return null;
}
NamedNodeMap attributes = node.getAttributes();
Node attribute = attributes.getNamedItem(attributeName);
String value = null;
if (attribute != null ) {
value = attribute.getNodeValue();
}
return value;
}

private String testCaseID;

private File basedir;
private XPath xPath = XPathFactory.newInstance().newXPath();

private XPathExpression input;
private XPathExpression decision;
private XPathExpression bkm;
private XPathExpression ds;

private XPathExpression inputDataVarMissingTypeRef;
private XPathExpression bkmVariable;
private XPathExpression bkmEncapsulatedLogic;
Expand All @@ -94,6 +127,11 @@ public TestCasesFiles(String testCaseID, File basedir) {
this.testCaseID = testCaseID;
this.basedir = basedir;
try {
input = xPath.compile("/*[local-name()='definitions']/*[local-name()='inputData']");
decision = xPath.compile("/*[local-name()='definitions']/*[local-name()='decision']");
bkm = xPath.compile("/*[local-name()='definitions']/*[local-name()='businessKnowledgeModel']");
ds = xPath.compile("/*[local-name()='definitions']/*[local-name()='decisionService']");

inputDataVarMissingTypeRef = xPath.compile("/*[local-name()='definitions']/*[local-name()='inputData']/*[local-name()='variable' and not(@*[local-name()='typeRef'])]/../@*[local-name()='name']");
bkmVariable = xPath.compile("/*[local-name()='definitions']/*[local-name()='businessKnowledgeModel']/*[local-name()='variable']");
bkmEncapsulatedLogic = xPath.compile("/*[local-name()='definitions']/*[local-name()='businessKnowledgeModel']/*[local-name()='encapsulatedLogic']");
Expand All @@ -110,6 +148,7 @@ public void testDMNFileIsValid() throws Exception {
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
validator.validate(new StreamSource(dmnFile));
checkDRGElementVariable(dmnFile);
checkInputDataHasTypeRef(dmnFile);
checkBKMTypeRef(dmnFile);
}
Expand Down Expand Up @@ -167,6 +206,61 @@ private void checkInputDataHasTypeRef(File dmnFile) throws Exception {
}
}

// DRGElement.name == DRGElement.variable.name and DRGElement.typeRef == DRGElement.variable.typeRef
private void checkDRGElementVariable(File dmnFile) throws Exception {
Document xmlDocument = builder.parse(dmnFile);
List<String> problems = new ArrayList<>();
problems.addAll(checkDRGElementVariable(dmnFile, xmlDocument, input, "input"));
problems.addAll(checkDRGElementVariable(dmnFile, xmlDocument, decision, "decision"));
problems.addAll(checkDRGElementVariable(dmnFile, xmlDocument, bkm, "businessKnowledgeModel"));
problems.addAll(checkDRGElementVariable(dmnFile, xmlDocument, ds, "decisionService"));
if (!problems.isEmpty()) {
throw new RuntimeException(problems.stream().collect(Collectors.joining(", ")));
}
}

private List<String> checkDRGElementVariable(File dmnFile, Document xmlDocument, XPathExpression drgElementPath, String elementName) throws Exception {
List<String> problems = new ArrayList<>();
// For every DRG Element
NodeList xPathVariables = (NodeList) drgElementPath.evaluate(xmlDocument, XPathConstants.NODESET);
if (xPathVariables.getLength() > 0) {
for (int i = 0; i < xPathVariables.getLength(); i++) {
Node drgElementNode = xPathVariables.item(i);
// Extract and compare values
String name = extractStringAttribute(drgElementNode, "name");
String typeRef = extractStringAttribute(drgElementNode, "typeRef");
Node variableNode = extractChild(drgElementNode, "variable");
String variableName = extractStringAttribute(variableNode, "name");
String variableTypeRef = extractStringAttribute(variableNode, "typeRef");
// Check name
if (name != null && variableName != null) {
if (!name.equals(variableName)) {
String problem = String.format("%s: DRGElement node %s name '%s' is the same with the variable name '%s'",
dmnFile.getName(),
elementName,
name,
variableName);
System.err.println(problem);
problems.add(problem);
}
}
// Check typeRef
if (typeRef != null && variableTypeRef != null) {
if (!typeRef.equals(variableTypeRef)) {
String problem = String.format("%s: DRGElement node %s typeRef '%s' is the same with the variable typeRef '%s'",
dmnFile.getName(),
elementName,
name,
variableName);
System.err.println(problem);
problems.add(problem);
}
}
}
}
return problems;
}

@Test
public void testDMNFilesUniqueInNamespace() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Expand Down

0 comments on commit f331a1e

Please sign in to comment.