This is an automated email from the ASF dual-hosted git repository.
gitgabrio pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 286567b81b [incubator-kie-issues#1834] DMN: verify namespaces are
always aligned (#6259)
286567b81b is described below
commit 286567b81b85584771b0218079d95659c98d657d
Author: Gabriele Cardosi <[email protected]>
AuthorDate: Mon Feb 24 11:57:26 2025 +0100
[incubator-kie-issues#1834] DMN: verify namespaces are always aligned
(#6259)
* [incubator-kie-issues#1834] Begin work on namespace validation
* [incubator-kie-issues#1834] Implemented full tests. Fixed invalid models.
* [incubator-kie-issues#1834] Cleanup
* [incubator-kie-issues#1834] Add expected valu in namespace validation
error
---------
Co-authored-by: Gabriele-Cardosi <[email protected]>
---
.../backend/marshalling/v1x/XStreamMarshaller.java | 136 ++++++--
.../marshalling/v1x/XStreamMarshallerTest.java | 89 +++++
kie-dmn/kie-dmn-core/pom.xml | 33 ++
.../DMNv1_5/DMN-invalid-namespaces.dmn | 66 ++++
.../valid_models/DMNv1_5/ConstraintsChecks.dmn | 2 +-
.../DMNv1_5/DateToDateTimeFunction.dmn | 2 +-
.../valid_models/DMNv1_5/Importing_Named_Model.dmn | 2 +-
.../valid_models/DMNv1_5/TypeConstraintsChecks.dmn | 2 +-
.../org/kie/dmn/validation/DMNValidatorImpl.java | 359 ++++++++++++++-------
.../kie/dmn/validation/DMNValidatorImplTest.java | 122 +++++++
.../java/org/kie/dmn/validation/ValidatorTest.java | 15 +
.../dmn/validation/v1_5/DMN15ValidationsTest.java | 1 -
12 files changed, 670 insertions(+), 159 deletions(-)
diff --git
a/kie-dmn/kie-dmn-backend/src/main/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshaller.java
b/kie-dmn/kie-dmn-backend/src/main/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshaller.java
index 469a6a36ad..d3bed06845 100644
---
a/kie-dmn/kie-dmn-backend/src/main/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshaller.java
+++
b/kie-dmn/kie-dmn-backend/src/main/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshaller.java
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -22,10 +22,14 @@ import java.io.BufferedReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
+import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
+import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.thoughtworks.xstream.io.xml.QNameMap;
@@ -33,14 +37,14 @@ import com.thoughtworks.xstream.io.xml.StaxDriver;
import org.kie.dmn.api.marshalling.DMNExtensionRegister;
import org.kie.dmn.api.marshalling.DMNMarshaller;
import org.kie.dmn.backend.marshalling.CustomStaxReader;
+import org.kie.dmn.model.api.DMNModelInstrumentedBase;
import org.kie.dmn.model.api.Definitions;
-import org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XStreamMarshaller implements DMNMarshaller {
- private static Logger logger = LoggerFactory.getLogger(
XStreamMarshaller.class );
+ private static Logger logger =
LoggerFactory.getLogger(XStreamMarshaller.class);
private List<DMNExtensionRegister> extensionRegisters = new ArrayList<>();
private final
org.kie.dmn.backend.marshalling.v1_1.xstream.XStreamMarshaller xstream11;
private final
org.kie.dmn.backend.marshalling.v1_2.xstream.XStreamMarshaller xstream12;
@@ -57,7 +61,7 @@ public class XStreamMarshaller implements DMNMarshaller {
xstream15 = new
org.kie.dmn.backend.marshalling.v1_5.xstream.XStreamMarshaller();
}
- public XStreamMarshaller (List<DMNExtensionRegister> extensionRegisters) {
+ public XStreamMarshaller(List<DMNExtensionRegister> extensionRegisters) {
this.extensionRegisters.addAll(extensionRegisters);
xstream11 = new
org.kie.dmn.backend.marshalling.v1_1.xstream.XStreamMarshaller(extensionRegisters);
xstream12 = new
org.kie.dmn.backend.marshalling.v1_2.xstream.XStreamMarshaller(extensionRegisters);
@@ -69,8 +73,10 @@ public class XStreamMarshaller implements DMNMarshaller {
@Override
public Definitions unmarshal(String xml) {
try (Reader firstStringReader = new StringReader(xml);
- Reader secondStringReader = new StringReader(xml);) {
- DMN_VERSION inferDMNVersion = inferDMNVersion(firstStringReader);
+ Reader secondStringReader = new StringReader(xml)) {
+
+ Collection<String> nsContextValues =
XStreamMarshaller.getNsContextValues(firstStringReader);
+ DMN_VERSION inferDMNVersion =
XStreamMarshaller.inferDMNVersion(nsContextValues);
Definitions result;
switch (inferDMNVersion) {
@@ -91,42 +97,113 @@ public class XStreamMarshaller implements DMNMarshaller {
default:
result = xstream15.unmarshal(secondStringReader);
break;
-
}
return result;
- } catch ( Exception e ) {
- logger.error( "Error unmarshalling DMN model from reader.", e );
+ } catch (Exception e) {
+ logger.error("Error unmarshalling DMN model from reader.", e);
}
return null;
}
public enum DMN_VERSION {
- UNKNOWN, DMN_v1_1, DMN_v1_2, DMN_v1_3, DMN_v1_4, DMN_v1_5;
+ UNKNOWN(""),
+ DMN_v1_1("v1_1"),
+ DMN_v1_2("v1_2"),
+ DMN_v1_3("v1_3"),
+ DMN_v1_4("v1_4"),
+ DMN_v1_5("v1_5");
+ final String versionString;
+
+ DMN_VERSION(String versionString) {
+ this.versionString = versionString;
+ }
+
+ public String getVersionString() {
+ return versionString;
+ }
+ }
+
+ public enum URI_NAMESPACE {
+ URI_DMN("MODEL"),
+ URI_FEEL("FEEL"),
+ URI_DMNDI("DMNDI"),
+ URI_DI("DI"),
+ URI_DC("DC");
+
+ private final String identifier;
+
+ URI_NAMESPACE(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getIdentifier() {
+ return identifier;
+ }
}
- public static DMN_VERSION inferDMNVersion(Reader from) {
+ public static Collection<String> getNsContextValues(Reader from) {
+ Collection<String> toReturn = Collections.emptySet();
+ XMLStreamReader xmlReader = null;
+ CustomStaxReader customStaxReader = null;
try {
- XMLStreamReader xmlReader =
staxDriver.getInputFactory().createXMLStreamReader(from);
- CustomStaxReader customStaxReader = new CustomStaxReader(new
QNameMap(), xmlReader);
- DMN_VERSION result = DMN_VERSION.UNKNOWN;
- if
(customStaxReader.getNsContext().values().stream().anyMatch(org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
- result = DMN_VERSION.DMN_v1_5;
- } else if
(customStaxReader.getNsContext().values().stream().anyMatch(org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
- result = DMN_VERSION.DMN_v1_4;
- } else if
(customStaxReader.getNsContext().values().stream().anyMatch(org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
- result = DMN_VERSION.DMN_v1_3;
- } else if
(customStaxReader.getNsContext().values().stream().anyMatch(org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
- result = DMN_VERSION.DMN_v1_2;
- } else if
(customStaxReader.getNsContext().values().stream().anyMatch(org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
- result = DMN_VERSION.DMN_v1_1;
- }
- xmlReader.close();
- customStaxReader.close();
- return result;
+ xmlReader =
staxDriver.getInputFactory().createXMLStreamReader(from);
+ customStaxReader = new CustomStaxReader(new QNameMap(), xmlReader);
+ toReturn = customStaxReader.getNsContext().values();
} catch (Exception e) {
logger.error("Error unmarshalling DMN model from reader.", e);
+ } finally {
+ if (customStaxReader != null) {
+ customStaxReader.close();
+ }
+ if (xmlReader != null) {
+ try {
+ xmlReader.close();
+ } catch (XMLStreamException e) {
+ logger.error("Error closing xml reader.", e);
+ }
+ }
+ }
+ return toReturn;
+ }
+
+ public static DMN_VERSION inferDMNVersion(Collection<String>
nsContextValues) {
+ DMN_VERSION toReturn = DMN_VERSION.UNKNOWN;
+ if
(nsContextValues.stream().anyMatch(org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
+ toReturn = DMN_VERSION.DMN_v1_5;
+ } else if
(nsContextValues.stream().anyMatch(org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
+ toReturn = DMN_VERSION.DMN_v1_4;
+ } else if
(nsContextValues.stream().anyMatch(org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
+ toReturn = DMN_VERSION.DMN_v1_3;
+ } else if
(nsContextValues.stream().anyMatch(org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
+ toReturn = DMN_VERSION.DMN_v1_2;
+ } else if
(nsContextValues.stream().anyMatch(org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase.URI_DMN::equals))
{
+ toReturn = DMN_VERSION.DMN_v1_1;
+ }
+ return toReturn;
+ }
+
+ /**
+ *
+ * @param dmnVersion
+ * @param namespaceKind
+ * @return
+ */
+ public static String getNamespaceValueReflectively(DMN_VERSION dmnVersion,
URI_NAMESPACE namespaceKind) {
+ try {
+ String kieDMNModelInstrumentedBaseClassName =
String.format("org.kie.dmn.model.%s" +
+
".KieDMNModelInstrumentedBase",
+
dmnVersion.getVersionString());
+ Class<? extends DMNModelInstrumentedBase>
kieDMNModelInstrumentedBaseClass = (Class<?
+ extends DMNModelInstrumentedBase>)
Class.forName(kieDMNModelInstrumentedBaseClassName);
+ Field declaredField =
kieDMNModelInstrumentedBaseClass.getDeclaredField(namespaceKind.name());
+ return (String) declaredField.get(null);
+ } catch (NoSuchFieldException e) {
+ logger.warn("Could not retrieve {} value reflectively for {}",
namespaceKind,
+ dmnVersion.getVersionString());
+ return null;
+ } catch (ClassNotFoundException | IllegalAccessException |
ClassCastException e) {
+ throw new RuntimeException(e);
}
- return DMN_VERSION.UNKNOWN;
}
@Override
@@ -173,5 +250,4 @@ public class XStreamMarshaller implements DMNMarshaller {
xstream14.marshal(o, out);
}
}
-
}
diff --git
a/kie-dmn/kie-dmn-backend/src/test/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshallerTest.java
b/kie-dmn/kie-dmn-backend/src/test/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshallerTest.java
new file mode 100644
index 0000000000..146a101f02
--- /dev/null
+++
b/kie-dmn/kie-dmn-backend/src/test/java/org/kie/dmn/backend/marshalling/v1x/XStreamMarshallerTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.kie.dmn.backend.marshalling.v1x;
+
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class XStreamMarshallerTest {
+
+ public static Map<XStreamMarshaller.DMN_VERSION,
Map<XStreamMarshaller.URI_NAMESPACE, String>> mappedNamespaces;
+
+ static {
+ mappedNamespaces = new HashMap<>();
+ Map<XStreamMarshaller.URI_NAMESPACE, String> dmn11nameSpaces = new
EnumMap<>(XStreamMarshaller.URI_NAMESPACE.class);
+
dmn11nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN,
org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase.URI_DMN);
+
dmn11nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL,
org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase.URI_FEEL);
+
dmn11nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI,
null);
+
dmn11nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI,
null);
+
dmn11nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC,
null);
+ mappedNamespaces.put(XStreamMarshaller.DMN_VERSION.DMN_v1_1,
dmn11nameSpaces);
+
+ Map<XStreamMarshaller.URI_NAMESPACE, String> dmn12nameSpaces = new
EnumMap<>(XStreamMarshaller.URI_NAMESPACE.class);
+
dmn12nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN,
org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DMN);
+
dmn12nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL,
org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_FEEL);
+
dmn12nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI,
org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DMNDI);
+
dmn12nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI,
org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DI);
+
dmn12nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC,
org.kie.dmn.model.v1_2.KieDMNModelInstrumentedBase.URI_DC);
+ mappedNamespaces.put(XStreamMarshaller.DMN_VERSION.DMN_v1_2,
dmn12nameSpaces);
+
+ Map<XStreamMarshaller.URI_NAMESPACE, String> dmn13nameSpaces = new
EnumMap<>(XStreamMarshaller.URI_NAMESPACE.class);
+
dmn13nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN,
org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DMN);
+
dmn13nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL,
org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_FEEL);
+
dmn13nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI,
org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DMNDI);
+
dmn13nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI,
org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DI);
+
dmn13nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC,
org.kie.dmn.model.v1_3.KieDMNModelInstrumentedBase.URI_DC);
+ mappedNamespaces.put(XStreamMarshaller.DMN_VERSION.DMN_v1_3,
dmn13nameSpaces);
+
+ Map<XStreamMarshaller.URI_NAMESPACE, String> dmn14nameSpaces = new
EnumMap<>(XStreamMarshaller.URI_NAMESPACE.class);
+
dmn14nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN,
org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DMN);
+
dmn14nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL,
org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_FEEL);
+
dmn14nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI,
org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DMNDI);
+
dmn14nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI,
org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DI);
+
dmn14nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC,
org.kie.dmn.model.v1_4.KieDMNModelInstrumentedBase.URI_DC);
+ mappedNamespaces.put(XStreamMarshaller.DMN_VERSION.DMN_v1_4,
dmn14nameSpaces);
+
+ Map<XStreamMarshaller.URI_NAMESPACE, String> dmn15nameSpaces = new
EnumMap<>(XStreamMarshaller.URI_NAMESPACE.class);
+
dmn15nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN,
org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DMN);
+
dmn15nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL,
org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_FEEL);
+
dmn15nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI,
org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DMNDI);
+
dmn15nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI,
org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DI);
+
dmn15nameSpaces.put(org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC,
org.kie.dmn.model.v1_5.KieDMNModelInstrumentedBase.URI_DC);
+ mappedNamespaces.put(XStreamMarshaller.DMN_VERSION.DMN_v1_5,
dmn15nameSpaces);
+ }
+
+ @Test
+ void getNamespaceValueReflectively() {
+ Arrays.stream(XStreamMarshaller.DMN_VERSION.values()).forEach(version
-> {
+ if (version != XStreamMarshaller.DMN_VERSION.UNKNOWN) {
+
Arrays.stream(XStreamMarshaller.URI_NAMESPACE.values()).forEach(uri -> {
+ String retrieved =
XStreamMarshaller.getNamespaceValueReflectively(version,
+
uri);
+
assertThat(retrieved).isEqualTo(mappedNamespaces.get(version).get(uri));
+ });
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/kie-dmn/kie-dmn-core/pom.xml b/kie-dmn/kie-dmn-core/pom.xml
index ab4f01aae2..977df690c4 100644
--- a/kie-dmn/kie-dmn-core/pom.xml
+++ b/kie-dmn/kie-dmn-core/pom.xml
@@ -37,6 +37,7 @@
<properties>
<java.module.name>org.kie.dmn.core</java.module.name>
+ <dependency-plugin.version>3.6.1</dependency-plugin.version>
</properties>
<dependencyManagement>
@@ -276,5 +277,37 @@
<filtering>true</filtering>
</testResource>
</testResources>
+ <plugins>
+ <!-- Unpack DMN resources from from org.kie:kie-dmn-test-resources -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${dependency-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-dmn-test-resources</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
+ <includes>**/*.dmn
+ </includes>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
</build>
</project>
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_5/DMN-invalid-namespaces.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_5/DMN-invalid-namespaces.dmn
new file mode 100644
index 0000000000..ee8f17e06b
--- /dev/null
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_5/DMN-invalid-namespaces.dmn
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ 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.
+ -->
+
+<dmn:definitions
xmlns="http://www.trisotech.com/dmn/definitions/_09E8A38A-AD24-4C3D-8307-029C0C4D373F"
+ xmlns:dc="http://www.omg.org/spec/DMN/20180505/DC/"
+ xmlns:di="http://www.omg.org/spec/DMN/20180505/DI/"
+ xmlns:dmndi="http://www.omg.org/spec/DMN/20180505/DMNDI/"
+ xmlns:feel="http://www.omg.org/spec/FEEL/20140401"
+ xmlns:dmn="https://www.omg.org/spec/DMN/20230324/MODEL/"
+ xmlns:kie="http://www.drools.org/kie/dmn/1.2"
+ id="_A064B2A1-5F58-4C94-9B25-11A5C43E1749"
+ name="For Loop Dates Evaluate"
+ typeLanguage="http://www.omg.org/spec/DMN/20230324/FEEL/"
+
namespace="http://www.trisotech.com/dmn/definitions/_09E8A38A-AD24-4C3D-8307-029C0C4D373F">
+ <dmn:extensionElements/>
+ <dmn:itemDefinition id="_C0D7B89C-EC6A-4F03-B397-90225007E578" name="Insert
a name" isCollection="false">
+ <dmn:typeRef>Any</dmn:typeRef>
+ </dmn:itemDefinition>
+ <dmn:itemDefinition isCollection="true" label="tDates" name="tDates">
+ <dmn:typeRef>date</dmn:typeRef>
+ </dmn:itemDefinition>
+ <dmn:decision id="_4FC2D161-03F2-43D0-86EA-5653C13AFD52" name="forloopdates">
+ <dmn:extensionElements/>
+ <dmn:variable id="_4608E42A-977F-4786-AD2A-DE62804DECBA"
name="forloopdates" typeRef="tDates"/>
+ <dmn:literalExpression id="_3BC54643-D567-4148-8931-7A5892E5863F">
+ <dmn:text>for x in @"2021-01-01"..@"2021-01-03" return x +
duration("P1D")</dmn:text>
+ </dmn:literalExpression>
+ </dmn:decision>
+ <dmndi:DMNDI>
+ <dmndi:DMNDiagram id="_F5A87DF2-BE2E-4509-AD80-353EA8891F42" name="DRG">
+ <di:extension>
+ <kie:ComponentsWidthsExtension>
+ <kie:ComponentWidths
dmnElementRef="_3BC54643-D567-4148-8931-7A5892E5863F">
+ <kie:width>338</kie:width>
+ </kie:ComponentWidths>
+ </kie:ComponentsWidthsExtension>
+ </di:extension>
+ <dmndi:DMNShape id="dmnshape-drg-_4FC2D161-03F2-43D0-86EA-5653C13AFD52"
dmnElementRef="_4FC2D161-03F2-43D0-86EA-5653C13AFD52" isCollapsed="false">
+ <dmndi:DMNStyle>
+ <dmndi:FillColor red="255" green="255" blue="255"/>
+ <dmndi:StrokeColor red="0" green="0" blue="0"/>
+ <dmndi:FontColor red="0" green="0" blue="0"/>
+ </dmndi:DMNStyle>
+ <dc:Bounds x="386" y="114" width="100" height="50"/>
+ <dmndi:DMNLabel/>
+ </dmndi:DMNShape>
+ </dmndi:DMNDiagram>
+ </dmndi:DMNDI>
+</dmn:definitions>
\ No newline at end of file
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/ConstraintsChecks.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/ConstraintsChecks.dmn
index a11e9ecb38..4ba57236dd 100644
---
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/ConstraintsChecks.dmn
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/ConstraintsChecks.dmn
@@ -22,7 +22,7 @@
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"
- xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/"
+ xmlns:feel="https://www.omg.org/spec/DMN/20230324/FEEL/"
xmlns:dmn="https://www.omg.org/spec/DMN/20230324/MODEL/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exporter="DMN Modeler"
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/DateToDateTimeFunction.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/DateToDateTimeFunction.dmn
index 1c2e174ec5..1dbd59c2f6 100644
---
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/DateToDateTimeFunction.dmn
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/DateToDateTimeFunction.dmn
@@ -22,7 +22,7 @@
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
- xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/"
+ xmlns:feel="https://www.omg.org/spec/DMN/20230324/FEEL/"
id="_14BDA5CA-C87F-448D-AF75-F976A9E0EF83"
name="new-file"
typeLanguage="http://www.omg.org/spec/DMN/20230324/FEEL/"
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/Importing_Named_Model.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/Importing_Named_Model.dmn
index 9555ba23ee..1614e9277c 100644
---
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/Importing_Named_Model.dmn
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/Importing_Named_Model.dmn
@@ -22,7 +22,7 @@
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"
- xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/"
+ xmlns:feel="https://www.omg.org/spec/DMN/20230324/FEEL/"
xmlns:dmn="https://www.omg.org/spec/DMN/20230324/MODEL/"
xmlns:tc="http://www.omg.org/spec/DMN/20160719/testcase"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
diff --git
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/TypeConstraintsChecks.dmn
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/TypeConstraintsChecks.dmn
index b6ff2a5ef4..a8977422af 100644
---
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/TypeConstraintsChecks.dmn
+++
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_5/TypeConstraintsChecks.dmn
@@ -22,7 +22,7 @@
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"
- xmlns:feel="http://www.omg.org/spec/DMN/20180521/FEEL/"
+ xmlns:feel="https://www.omg.org/spec/DMN/20230324/FEEL/"
xmlns:dmn="https://www.omg.org/spec/DMN/20230324/MODEL/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exporter="DMN Modeler"
diff --git
a/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/DMNValidatorImpl.java
b/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/DMNValidatorImpl.java
index 9c7bcbb673..29562cfd0d 100644
---
a/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/DMNValidatorImpl.java
+++
b/kie-dmn/kie-dmn-validation/src/main/java/org/kie/dmn/validation/DMNValidatorImpl.java
@@ -1,4 +1,4 @@
-/**
+/*
* 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
@@ -29,12 +29,15 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
@@ -85,6 +88,7 @@ import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import static java.util.stream.Collectors.toList;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.getNamespaceValueReflectively;
import static org.kie.dmn.core.compiler.UnnamedImportUtils.mergeDefinitions;
import static
org.kie.dmn.validation.DMNValidator.Validation.ANALYZE_DECISION_TABLE;
import static
org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_COMPILATION;
@@ -92,70 +96,112 @@ import static
org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_MODEL;
import static org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_SCHEMA;
public class DMNValidatorImpl implements DMNValidator {
+
public static final Logger LOG =
LoggerFactory.getLogger(DMNValidatorImpl.class);
static final Schema schemav1_1;
+
static {
try {
schemav1_1 =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
- .newSchema(new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20151101/dmn.xsd")));
+ .newSchema(new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20151101"
+
+
"/dmn.xsd")));
} catch (SAXException e) {
throw new RuntimeException("Unable to initialize correctly
DMNValidator.", e);
}
}
+
static final Schema schemav1_2;
+
static {
try {
schemav1_2 =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
- .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521/DC.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521/DI.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521/DMNDI12.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521/DMN12.xsd"))
- });
+ .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec" +
+
"/DMN" +
+
"/20180521/DC.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521/DI"
+
+
".xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521"
+
+
"/DMNDI12.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20180521"
+
+
"/DMN12.xsd"))
+ });
} catch (SAXException e) {
throw new RuntimeException("Unable to initialize correctly
DMNValidator.", e);
}
}
+
static final Schema schemav1_3;
+
static {
try {
schemav1_3 =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
- .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111/DC.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111/DI.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111/DMNDI13.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111/DMN13.xsd"))
- });
+ .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec" +
+
"/DMN" +
+
"/20191111/DC.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111/DI"
+
+
".xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111"
+
+
"/DMNDI13.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20191111"
+
+
"/DMN13.xsd"))
+ });
} catch (SAXException e) {
throw new RuntimeException("Unable to initialize correctly
DMNValidator.", e);
}
}
+
static final Schema schemav1_4;
+
static {
try {
schemav1_4 =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
- .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108/DC.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108/DI.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108/DMNDI13.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108/DMN14.xsd"))
- });
+ .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec" +
+
"/DMN" +
+
"/20211108/DC.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108/DI"
+
+
".xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108"
+
+
"/DMNDI13.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20211108"
+
+
"/DMN14.xsd"))
+ });
} catch (SAXException e) {
throw new RuntimeException("Unable to initialize correctly
DMNValidator.", e);
}
}
static final Schema schemav1_5;
+
static {
try {
schemav1_5 =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
- .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324/DC.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324/DI.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324/DMNDI15.xsd")),
- new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324/DMN15.xsd"))
+ .newSchema(new Source[]{new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec" +
+
"/DMN" +
+
"/20230324/DC.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324/DI"
+
+
".xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324"
+
+
"/DMNDI15.xsd")),
+ new
StreamSource(DMNValidatorImpl.class.getResourceAsStream("org/omg/spec/DMN/20230324"
+
+
"/DMN15.xsd"))
});
} catch (SAXException e) {
throw new RuntimeException("Unable to initialize correctly
DMNValidator.", e);
}
}
+ static final Map<DMN_VERSION, Schema> DMNVERSION_SCHEMA_MAP;
+
+ static {
+ DMNVERSION_SCHEMA_MAP = new HashMap<>();
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.DMN_v1_1, schemav1_1);
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.DMN_v1_2, schemav1_2);
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.DMN_v1_3, schemav1_3);
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.DMN_v1_4, schemav1_4);
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.DMN_v1_5, schemav1_5);
+ DMNVERSION_SCHEMA_MAP.put(DMN_VERSION.UNKNOWN, schemav1_5);
+ }
+
private Schema overrideSchema = null;
private final List<DMNProfile> dmnProfiles = new ArrayList<>();
private final DMNCompilerConfiguration dmnCompilerConfig;
@@ -176,14 +222,16 @@ public class DMNValidatorImpl implements DMNValidator {
this.dmnProfiles.addAll(DMNAssemblerService.getDefaultDMNProfiles(localChainedProperties));
this.dmnProfiles.addAll(dmnProfiles);
final ClassLoader classLoader = cl == null ?
ClassLoaderUtil.findDefaultClassLoader() : cl;
- DMNCompilerConfigurationImpl dmnCompilerConfiguration =
DMNAssemblerService.compilerConfigWithKModulePrefs(classLoader,
+ DMNCompilerConfigurationImpl dmnCompilerConfiguration =
+ DMNAssemblerService.compilerConfigWithKModulePrefs(classLoader,
localChainedProperties,
this.dmnProfiles,
(DMNCompilerConfigurationImpl)
DMNFactory.newCompilerConfiguration());
try {
DMNAssemblerService.applyDecisionLogicCompilerFactory(classLoader,
dmnCompilerConfiguration);
} catch (Exception e) {
- throw new IllegalStateException("Unable to initialize DMNCompiler
decisionlogicCompilerFactory based on parameters provided", e);
+ throw new IllegalStateException("Unable to initialize DMNCompiler
decisionlogicCompilerFactory based on " +
+ "parameters provided", e);
}
this.dmnCompilerConfig = dmnCompilerConfiguration;
dmnDTValidator =
InternalDMNDTAnalyserFactory.newDMNDTAnalyser(this.dmnProfiles);
@@ -196,7 +244,6 @@ public class DMNValidatorImpl implements DMNValidator {
public static class ValidatorBuilderImpl implements ValidatorBuilder {
-
private final EnumSet<Validation> flags;
private final DMNValidatorImpl validator;
private ValidatorImportReaderResolver importResolver;
@@ -220,25 +267,28 @@ public class DMNValidatorImpl implements DMNValidator {
@Override
public List<DMNMessage> theseModels(File... files) {
- Resource[] array =
Arrays.stream(files).map(FileSystemResource::new).collect(Collectors.toList()).toArray(new
Resource[] {});
+ Resource[] array =
+
Arrays.stream(files).map(FileSystemResource::new).collect(Collectors.toList()).toArray(new
Resource[]{});
return theseModels(array);
}
-
+
@Override
public List<DMNMessage> theseModels(Resource... resources) {
- DMNMessageManager results = new DefaultDMNMessagesManager( null );
// this collector span multiple resources.
+ DMNMessageManager results = new DefaultDMNMessagesManager(null);
// this collector span multiple resources.
List<DMNResource> models = new ArrayList<>();
for (Resource r : resources) {
- try {
- // We get passed a Resource, which might be constructed
from a Reader, so we have only 1-time opportunity to be sure to read it
successfully,
- // we internalize the content:
- String content = readContent( r.getReader() );
+ try {
+ // We get passed a Resource, which might be constructed
from a Reader, so we have only 1-time
+ // opportunity to be sure to read it successfully,
+ // we internalize the content:
+ String content = readContent(r.getReader());
if (flags.contains(VALIDATE_SCHEMA)) {
- results.addAll(validator.validateSchema( content,
r.getSourcePath() ));
+
results.addAll(validator.validateSchemaAndNamespaces(content,
r.getSourcePath()));
}
- if (!results.hasErrors()) { // pointless to unmarshall if
failing the schema, and will eventually stop before VALIDATE_MODEL later.
+ if (!results.hasErrors()) { // pointless to unmarshall if
failing the schema, and will eventually
+ // stop before VALIDATE_MODEL later.
DMNResource dmnResource =
unmarshallDMNResource(validator.dmnCompilerConfig, r, content);
- models.add(dmnResource);
+ models.add(dmnResource);
}
} catch (Exception t) {
MsgUtil.reportMessage(LOG,
@@ -275,13 +325,14 @@ public class DMNValidatorImpl implements DMNValidator {
@Override
public List<DMNMessage> theseModels(Reader... readers) {
- Resource[] array =
Arrays.stream(readers).map(ReaderResource::new).collect(Collectors.toList()).toArray(new
Resource[] {});
+ Resource[] array =
+
Arrays.stream(readers).map(ReaderResource::new).collect(Collectors.toList()).toArray(new
Resource[]{});
return theseModels(array);
}
@Override
public List<DMNMessage> theseModels(Definitions... models) {
- DMNMessageManager results = new DefaultDMNMessagesManager( null );
+ DMNMessageManager results = new DefaultDMNMessagesManager(null);
if (flags.contains(VALIDATE_SCHEMA)) {
MsgUtil.reportMessage(LOG,
DMNMessage.Severity.ERROR,
@@ -302,7 +353,8 @@ public class DMNValidatorImpl implements DMNValidator {
Msg.VALIDATION_STOPPED);
return results.getMessages();
}
- List<DMNResource> dmnRs = Arrays.stream(models).map(d ->
wrapDefinitions(d, null)).collect(Collectors.toList());
+ List<DMNResource> dmnRs =
+ Arrays.stream(models).map(d -> wrapDefinitions(d,
null)).collect(Collectors.toList());
processDMNResourcesAndValidate(results, dmnRs);
}
return results.getMessages();
@@ -321,11 +373,14 @@ public class DMNValidatorImpl implements DMNValidator {
DMNCompilerImpl compiler = new
DMNCompilerImpl(validator.dmnCompilerConfig);
Function<String, Reader> relativeResolver = null;
if (importResolver != null) {
- relativeResolver = locationURI ->
importResolver.newReader(dmnR.getDefinitions().getNamespace(),
+ relativeResolver =
+ locationURI ->
importResolver.newReader(dmnR.getDefinitions().getNamespace(),
dmnR.getDefinitions().getName(),
locationURI);
}
- DMNModel model = compiler.compile(
dmnR.getDefinitions(), otherModelsDMNModels,
dmnR.getResAndConfig().getResource(), relativeResolver ); // must use this
internal method to ensure the Definitions model is the same (identity wise)
+ DMNModel model =
compiler.compile(dmnR.getDefinitions(), otherModelsDMNModels,
+
dmnR.getResAndConfig().getResource(), relativeResolver); //
+ // must use this internal method to ensure the
Definitions model is the same (identity wise)
if (model != null) {
results.addAll(model.getMessages());
otherModelsDMNModels.add(model);
@@ -350,15 +405,15 @@ public class DMNValidatorImpl implements DMNValidator {
}
}
}
-
}
private static List<DMNMessage> processDMNDTValidatorMessages(DMNResource
dmnR, List<DTAnalysis> vs) {
String path = dmnR.getResAndConfig().getResource().getSourcePath();
- List<DMNMessage> dtAnalysisResults = vs.stream().flatMap(a ->
a.asDMNMessages().stream()).map(m -> ((DMNMessageImpl)
m).withPath(path)).collect(Collectors.toList());
+ List<DMNMessage> dtAnalysisResults =
+ vs.stream().flatMap(a -> a.asDMNMessages().stream()).map(m ->
((DMNMessageImpl) m).withPath(path)).collect(Collectors.toList());
return dtAnalysisResults;
}
-
+
public Schema getOverrideSchema() {
return overrideSchema;
}
@@ -373,25 +428,25 @@ public class DMNValidatorImpl implements DMNValidator {
@Override
public List<DMNMessage> validate(Definitions dmnModel) {
- return validate( dmnModel, VALIDATE_MODEL );
+ return validate(dmnModel, VALIDATE_MODEL);
}
@Override
public List<DMNMessage> validate(Definitions dmnModel, Validation...
options) {
- DMNMessageManager results = new DefaultDMNMessagesManager( null );
- EnumSet<Validation> flags = EnumSet.copyOf( Arrays.asList( options ) );
- if( flags.contains( VALIDATE_SCHEMA ) ) {
- MsgUtil.reportMessage( LOG,
- DMNMessage.Severity.ERROR,
- dmnModel,
- results,
- null,
- null,
- Msg.FAILED_NO_XML_SOURCE );
+ DMNMessageManager results = new DefaultDMNMessagesManager(null);
+ EnumSet<Validation> flags = EnumSet.copyOf(Arrays.asList(options));
+ if (flags.contains(VALIDATE_SCHEMA)) {
+ MsgUtil.reportMessage(LOG,
+ DMNMessage.Severity.ERROR,
+ dmnModel,
+ results,
+ null,
+ null,
+ Msg.FAILED_NO_XML_SOURCE);
}
try {
- validateModelCompilation( wrapDefinitions(dmnModel, null),
results, flags );
- } catch ( Throwable t ) {
+ validateModelCompilation(wrapDefinitions(dmnModel, null), results,
flags);
+ } catch (Throwable t) {
MsgUtil.reportMessage(LOG,
DMNMessage.Severity.ERROR,
null,
@@ -406,7 +461,7 @@ public class DMNValidatorImpl implements DMNValidator {
@Override
public List<DMNMessage> validate(File xmlFile) {
- return validate( xmlFile, VALIDATE_MODEL );
+ return validate(xmlFile, VALIDATE_MODEL);
}
@Override
@@ -416,35 +471,36 @@ public class DMNValidatorImpl implements DMNValidator {
@Override
public List<DMNMessage> validate(Reader reader) {
- return validate( reader, VALIDATE_MODEL );
+ return validate(reader, VALIDATE_MODEL);
}
@Override
public List<DMNMessage> validate(Reader reader, Validation... options) {
return validate(new ReaderResource(reader), options);
}
-
+
@Override
public List<DMNMessage> validate(Resource resource) {
- return validate( resource, VALIDATE_MODEL );
+ return validate(resource, VALIDATE_MODEL);
}
-
+
@Override
public List<DMNMessage> validate(Resource resource, Validation... options)
{
- DMNMessageManager results = new DefaultDMNMessagesManager( resource );
- EnumSet<Validation> flags = EnumSet.copyOf( Arrays.asList( options ) );
+ DMNMessageManager results = new DefaultDMNMessagesManager(resource);
+ EnumSet<Validation> flags = EnumSet.copyOf(Arrays.asList(options));
try {
- // We get passed a Resource, which might be constructed from a
Reader, so we have only 1-time opportunity to be sure to read it successfully,
+ // We get passed a Resource, which might be constructed from a
Reader, so we have only 1-time opportunity
+ // to be sure to read it successfully,
// we internalize the content:
- String content = readContent( resource.getReader() );
- if( flags.contains( VALIDATE_SCHEMA ) ) {
- results.addAll( validateSchema( content,
resource.getSourcePath() ) );
+ String content = readContent(resource.getReader());
+ if (flags.contains(VALIDATE_SCHEMA)) {
+ results.addAll(validateSchemaAndNamespaces(content,
resource.getSourcePath()));
}
- if( flags.contains( VALIDATE_MODEL ) || flags.contains(
VALIDATE_COMPILATION ) || flags.contains( ANALYZE_DECISION_TABLE ) ) {
+ if (flags.contains(VALIDATE_MODEL) ||
flags.contains(VALIDATE_COMPILATION) || flags.contains(ANALYZE_DECISION_TABLE))
{
DMNResource dmnResource =
unmarshallDMNResource(dmnCompilerConfig, resource, content);
- validateModelCompilation( dmnResource, results, flags );
+ validateModelCompilation(dmnResource, results, flags);
}
- } catch ( Throwable t ) {
+ } catch (Throwable t) {
MsgUtil.reportMessage(LOG,
DMNMessage.Severity.ERROR,
null,
@@ -460,33 +516,38 @@ public class DMNValidatorImpl implements DMNValidator {
private static String readContent(Reader reader)
throws IOException {
char[] b = new char[32 * 1024];
- StringBuilder content = new StringBuilder( );
+ StringBuilder content = new StringBuilder();
int chars = -1;
- while( (chars = reader.read( b ) ) > 0 ) {
- content.append( b, 0, chars );
+ while ((chars = reader.read(b)) > 0) {
+ content.append(b, 0, chars);
}
return content.toString();
}
- private static DMNResource unmarshallDMNResource(DMNCompilerConfiguration
config, Resource originalResource, String content) {
- Definitions dmndefs =
DMNMarshallerFactory.newMarshallerWithExtensions(config.getRegisteredExtensions()).unmarshal(content);
+ private static DMNResource unmarshallDMNResource(DMNCompilerConfiguration
config, Resource originalResource,
+ String content) {
+ Definitions dmndefs =
+
DMNMarshallerFactory.newMarshallerWithExtensions(config.getRegisteredExtensions()).unmarshal(content);
dmndefs.normalize();
return wrapDefinitions(dmndefs, originalResource.getSourcePath());
}
-
+
private static DMNResource wrapDefinitions(Definitions dmndefs, String
path) {
- return new DMNResource(dmndefs, new ResourceWithConfigurationImpl(new
DMNValidatorResource(path), null, x -> {}, y -> {}));
+ return new DMNResource(dmndefs, new ResourceWithConfigurationImpl(new
DMNValidatorResource(path), null, x -> {
+ }, y -> {
+ }));
}
-
+
/**
- * Used only to mark a reference to the original Resource's path, so to
have the DMNMessage(s) correctly valorized using existing message-manager
infrastructure.
+ * Used only to mark a reference to the original Resource's path, so to
have the DMNMessage(s) correctly
+ * valorized using existing message-manager infrastructure.
*/
private static class DMNValidatorResource extends BaseResource {
-
+
public DMNValidatorResource() {
// intentionally blank, added for proper support of Externalizable
}
-
+
public DMNValidatorResource(String path) {
this.setSourcePath(path);
}
@@ -525,62 +586,100 @@ public class DMNValidatorImpl implements DMNValidator {
public Reader getReader() throws IOException {
throw new UnsupportedOperationException();
}
-
}
-
+
private void validateModelCompilation(DMNResource dmnModel,
DMNMessageManager results, EnumSet<Validation> flags) {
- if( flags.contains( VALIDATE_MODEL ) ) {
+ if (flags.contains(VALIDATE_MODEL)) {
results.addAll(validateModel(dmnModel, Collections.emptyList()));
}
- if( flags.contains( VALIDATE_COMPILATION ) ) {
- results.addAll( validateCompilation( dmnModel ) );
+ if (flags.contains(VALIDATE_COMPILATION)) {
+ results.addAll(validateCompilation(dmnModel));
}
- if (flags.contains( ANALYZE_DECISION_TABLE )) {
+ if (flags.contains(ANALYZE_DECISION_TABLE)) {
results.addAllUnfiltered(analyseDT(dmnModel, flags));
}
}
- private List<DMNMessage> validateSchema(String xml, String path) {
- List<DMNMessage> problems = new ArrayList<>();
+ private List<DMNMessage> validateSchemaAndNamespaces(String xml, String
path) {
+ List<DMNMessage> toReturn = new ArrayList<>();
+ try {
+ Collection<String> nsContextValues =
XStreamMarshaller.getNsContextValues(new StringReader(xml));
+ DMN_VERSION inferDMNVersion =
XStreamMarshaller.inferDMNVersion(nsContextValues);
+ Schema usingSchema = determineSchema(inferDMNVersion,
overrideSchema);
+ toReturn.addAll(validateNsContextValues(nsContextValues, path,
inferDMNVersion));
+ toReturn.addAll(validateSchema(xml, path, usingSchema));
+ } catch (Exception e) {
+ String errorMessage = String.format("%s - %s", path,
e.getMessage());
+ toReturn.add(new DMNMessageImpl(DMNMessage.Severity.ERROR,
+
MsgUtil.createMessage(Msg.FAILED_XML_VALIDATION, errorMessage),
+
Msg.FAILED_XML_VALIDATION.getType(), null, e).withPath(path));
+ }
+ return toReturn;
+ }
+
+ static List<DMNMessage> validateSchema(String xml, String path, Schema
usingSchema) {
+ List<DMNMessage> toReturn = new ArrayList<>();
try {
- DMN_VERSION inferDMNVersion =
XStreamMarshaller.inferDMNVersion(new StringReader(xml));
- Schema usingSchema = determineSchema(inferDMNVersion);
Source s = new StreamSource(new StringReader(xml));
validateSchema(s, usingSchema);
} catch (Exception e) {
String errorMessage = String.format("%s - %s", path,
e.getMessage());
- problems.add(new DMNMessageImpl(DMNMessage.Severity.ERROR,
MsgUtil.createMessage(Msg.FAILED_XML_VALIDATION, errorMessage),
Msg.FAILED_XML_VALIDATION.getType(), null, e).withPath(path));
- }
- return problems;
+ toReturn.add(new DMNMessageImpl(DMNMessage.Severity.ERROR,
+
MsgUtil.createMessage(Msg.FAILED_XML_VALIDATION, errorMessage),
+
Msg.FAILED_XML_VALIDATION.getType(), null, e).withPath(path));
+ }
+ return toReturn;
+ }
+
+ static List<DMNMessage> validateNsContextValues(Collection<String>
nsContextValues, String path, DMN_VERSION inferDMNVersion) {
+ List<DMNMessage> toReturn = new ArrayList<>();
+ Map<XStreamMarshaller.URI_NAMESPACE, String> mappedNamespaces =
getMappedNamespaces(nsContextValues);
+ mappedNamespaces.forEach((key, value) -> {
+ String expectedUri =
getNamespaceValueReflectively(inferDMNVersion, key);
+ if (!value.equals(expectedUri)) {
+ String errorMessage = String.format("Invalid %s {%s} for
version %s (expected %s) - at %s",
+ key.getIdentifier(),
+ value,
+
inferDMNVersion.getVersionString(),
+ expectedUri,
+ path);
+ toReturn.add(new DMNMessageImpl(DMNMessage.Severity.ERROR,
+
MsgUtil.createMessage(Msg.FAILED_XML_VALIDATION, errorMessage),
+
Msg.FAILED_XML_VALIDATION.getType(), null)
+ .withPath(path));
+ }
+ });
+ return toReturn;
+ }
+
+ static Map<XStreamMarshaller.URI_NAMESPACE, String>
getMappedNamespaces(Collection<String> nsContextValues) {
+ Map<XStreamMarshaller.URI_NAMESPACE, String> toReturn = new
HashMap<>();
+ Arrays.stream(XStreamMarshaller.URI_NAMESPACE.values()).forEach(uri ->
{
+ String expected = String.format("/%s/", uri.getIdentifier());
+ for (String nsContextValue : nsContextValues) {
+ if (nsContextValue.contains(expected)) {
+ toReturn.put(uri, nsContextValue);
+ }
+ }
+ });
+ return toReturn;
}
-
- private Schema determineSchema(DMN_VERSION dmnVersion) {
+
+ static Schema determineSchema(DMN_VERSION dmnVersion, Schema
overrideSchema) {
if (overrideSchema != null) {
return overrideSchema;
}
- switch (dmnVersion) {
- case DMN_v1_1:
- return schemav1_1;
- case DMN_v1_2:
- return schemav1_2;
- case DMN_v1_3:
- return schemav1_3;
- case DMN_v1_4:
- return schemav1_4;
- case DMN_v1_5:
- case UNKNOWN:
- default:
- return schemav1_5;
- }
+ return DMNVERSION_SCHEMA_MAP.containsKey(dmnVersion) ?
+ DMNVERSION_SCHEMA_MAP.get(dmnVersion) :
DMNVERSION_SCHEMA_MAP.get(DMN_VERSION.UNKNOWN);
}
- private void validateSchema(Source s, Schema using) throws SAXException,
IOException {
+ static void validateSchema(Source s, Schema using) throws SAXException,
IOException {
Validator validator = using.newValidator();
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
validator.validate(s);
}
-
+
private List<DMNMessage> validateModel(DMNResource mainModel,
List<DMNResource> otherModels) {
Definitions mainDefinitions = mainModel.getDefinitions();
List<String> unnamedImports = mainDefinitions.getImport().stream()
@@ -596,17 +695,25 @@ public class DMNValidatorImpl implements DMNValidator {
otherModelsDefinitions.add(other);
});
- StatelessKieSession kieSession = mainDefinitions instanceof
org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase ?
kb11.newStatelessKieSession() : kb12.newStatelessKieSession();
+ StatelessKieSession kieSession =
+ mainDefinitions instanceof
org.kie.dmn.model.v1_1.KieDMNModelInstrumentedBase ?
+ kb11.newStatelessKieSession() :
kb12.newStatelessKieSession();
MessageReporter reporter = new MessageReporter(mainModel);
- kieSession.setGlobal( "reporter", reporter );
+ kieSession.setGlobal("reporter", reporter);
// exclude dynamicDecisionService for validation
List<DMNModelInstrumentedBase> dmnModelElements =
allChildren(mainDefinitions)
- .filter(d -> !(d instanceof DecisionService &&
-
Boolean.parseBoolean(d.getAdditionalAttributes().get(new
QName("http://www.trisotech.com/2015/triso/modeling",
"dynamicDecisionService")))))
- .collect(toList());
-
- BatchExecutionCommand batch =
CommandFactory.newBatchExecution(Arrays.asList(CommandFactory.newInsertElements(dmnModelElements,
"DEFAULT", false, "DEFAULT"),
+ .filter(d -> !(d instanceof DecisionService &&
+
Boolean.parseBoolean(d.getAdditionalAttributes().get(new
QName("http://www.trisotech" +
+
".com/2015/triso" +
+
"/modeling",
+
"dynamicDecisionService")))))
+ .collect(toList());
+
+ BatchExecutionCommand batch =
+
CommandFactory.newBatchExecution(Arrays.asList(CommandFactory.newInsertElements(dmnModelElements,
+
"DEFAULT", false,
+
"DEFAULT"),
CommandFactory.newInsertElements(otherModelsDefinitions, "DMNImports",
false, "DMNImports")));
kieSession.execute(batch);
@@ -614,10 +721,12 @@ public class DMNValidatorImpl implements DMNValidator {
}
private List<DMNMessage> validateCompilation(DMNResource dmnR) {
- if( dmnR != null ) {
+ if (dmnR != null) {
DMNCompilerImpl compiler = new DMNCompilerImpl(dmnCompilerConfig);
- DMNModel model = compiler.compile( dmnR.getDefinitions(),
dmnR.getResAndConfig().getResource(), Collections.emptyList() ); // must use
this internal method to ensure the Definitions model is the same (identity wise)
- if( model != null ) {
+ DMNModel model = compiler.compile(dmnR.getDefinitions(),
dmnR.getResAndConfig().getResource(),
+ Collections.emptyList()); //
must use this internal method to ensure
+ // the Definitions model is the same (identity wise)
+ if (model != null) {
return model.getMessages();
} else {
throw new IllegalStateException("Compiled model is null!");
@@ -629,7 +738,9 @@ public class DMNValidatorImpl implements DMNValidator {
private List<DMNMessage> analyseDT(DMNResource dmnR, Set<Validation>
flags) {
if (dmnR != null) {
DMNCompilerImpl compiler = new DMNCompilerImpl(dmnCompilerConfig);
- DMNModel model = compiler.compile( dmnR.getDefinitions(),
dmnR.getResAndConfig().getResource(), Collections.emptyList() ); // must use
this internal method to ensure the Definitions model is the same (identity wise)
+ DMNModel model = compiler.compile(dmnR.getDefinitions(),
dmnR.getResAndConfig().getResource(),
+ Collections.emptyList()); //
must use this internal method to ensure
+ // the Definitions model is the same (identity wise)
if (model != null) {
List<DTAnalysis> vs = dmnDTValidator.analyse(model, flags);
return processDMNDTValidatorMessages(dmnR, vs);
@@ -641,7 +752,7 @@ public class DMNValidatorImpl implements DMNValidator {
}
private static Stream<DMNModelInstrumentedBase>
allChildren(DMNModelInstrumentedBase root) {
- return Stream.concat( Stream.of(root),
-
root.getChildren().stream().flatMap(DMNValidatorImpl::allChildren) );
+ return Stream.concat(Stream.of(root),
+
root.getChildren().stream().flatMap(DMNValidatorImpl::allChildren));
}
}
diff --git
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/DMNValidatorImplTest.java
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/DMNValidatorImplTest.java
new file mode 100644
index 0000000000..1223cd26b9
--- /dev/null
+++
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/DMNValidatorImplTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.kie.dmn.validation;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.validation.Schema;
+import javax.xml.validation.Validator;
+import javax.xml.validation.ValidatorHandler;
+
+import org.junit.jupiter.api.Test;
+import org.kie.api.builder.Message;
+import org.kie.dmn.api.core.DMNMessage;
+import org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DC;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DI;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMN;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_DMNDI;
+import static
org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller.URI_NAMESPACE.URI_FEEL;
+import static org.kie.dmn.validation.DMNValidatorImpl.DMNVERSION_SCHEMA_MAP;
+
+class DMNValidatorImplTest {
+
+ @Test
+ void validateNsContextValuesValid() {
+ Collection<String> nsContextValues = new HashSet<>();
+
nsContextValues.add("http://www.trisotech.com/definitions/_238bd96d-47cd-4746-831b-504f3e77b442");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/MODEL/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180521/DI/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/FEEL/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/DMNDI/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180521/DC/");
+ nsContextValues.add("http://www.w3.org/2001/XMLSchema-instance");
+ List<DMNMessage> retrieved =
DMNValidatorImpl.validateNsContextValues(nsContextValues, "path",
XStreamMarshaller.DMN_VERSION.DMN_v1_5);
+ assertThat(retrieved).isNotNull().isEmpty();
+ }
+
+ @Test
+ void validateNsContextValuesInvalid() {
+ Collection<String> nsContextValues = new HashSet<>();
+
nsContextValues.add("http://www.trisotech.com/definitions/_238bd96d-47cd-4746-831b-504f3e77b442");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/MODEL/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180505/DI/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/FEEL/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20191111/DMNDI/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180505/DC/");
+ nsContextValues.add("http://www.w3.org/2001/XMLSchema-instance");
+
+ List<DMNMessage> retrieved =
DMNValidatorImpl.validateNsContextValues(nsContextValues, "path",
XStreamMarshaller.DMN_VERSION.DMN_v1_5);
+ assertThat(retrieved).hasSize(3).allMatch(dmnMessage ->
dmnMessage.getLevel().equals(Message.Level.ERROR))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DI/"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DI/"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("https://www.omg.org/spec/DMN/20191111/DMNDI/"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DC/"));
+ }
+
+ @Test
+ void getMappedNamespaces() {
+ Collection<String> nsContextValues = new HashSet<>();
+
nsContextValues.add("http://www.trisotech.com/definitions/_238bd96d-47cd-4746-831b-504f3e77b442");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/MODEL/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180505/DI/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20230324/FEEL/");
+ nsContextValues.add("https://www.omg.org/spec/DMN/20191111/DMNDI/");
+ nsContextValues.add("http://www.omg.org/spec/DMN/20180505/DC/");
+ nsContextValues.add("http://www.w3.org/2001/XMLSchema-instance");
+ Map<XStreamMarshaller.URI_NAMESPACE, String> expected =
Map.of(URI_DMN, "https://www.omg.org/spec/DMN/20230324/MODEL/",
+
URI_FEEL, "https://www.omg.org/spec/DMN/20230324/FEEL/",
+
URI_DMNDI, "https://www.omg.org/spec/DMN/20191111/DMNDI/",
+ URI_DI,
"http://www.omg.org/spec/DMN/20180505/DI/",
+ URI_DC,
"http://www.omg.org/spec/DMN/20180505/DC/");
+ Map<XStreamMarshaller.URI_NAMESPACE, String> retrieved =
DMNValidatorImpl.getMappedNamespaces(nsContextValues);
+
assertThat(retrieved).hasSize(expected.size()).containsExactlyInAnyOrderEntriesOf(expected);
+ }
+
+ @Test
+ void determineSchemaWithoutOverride() {
+ Arrays.stream(XStreamMarshaller.DMN_VERSION.values()).forEach(version
-> assertThat(DMNValidatorImpl.determineSchema(version,
null)).isEqualTo(DMNVERSION_SCHEMA_MAP.get(version)));
+ }
+
+ @Test
+ void determineSchemaWithOverride() {
+ Schema overrideSchema = getSchema();
+ Arrays.stream(XStreamMarshaller.DMN_VERSION.values()).forEach(version
-> assertThat(DMNValidatorImpl.determineSchema(version,
overrideSchema)).isEqualTo(overrideSchema));
+ }
+
+ private Schema getSchema() {
+ return new Schema() {
+ @Override
+ public Validator newValidator() {
+ return null;
+ }
+
+ @Override
+ public ValidatorHandler newValidatorHandler() {
+ return null;
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
index 1a58820f60..dc17a4a2ef 100644
---
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
+++
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
@@ -33,6 +33,7 @@ import java.util.zip.ZipEntry;
import org.drools.io.ClassPathResource;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import org.kie.api.builder.Message;
import org.kie.api.builder.Message.Level;
import org.kie.api.io.Resource;
import org.kie.dmn.api.core.DMNMessage;
@@ -542,6 +543,20 @@ class ValidatorTest extends AbstractValidatorTest {
testDirectoryInJar(jarFile, modelFilesPath);
}
+ @Test
+ void validateInvalidNamespaceModels() {
+ String modelFilePath =
"invalid_models/DMNv1_5/DMN-invalid-namespaces.dmn";
+ Resource resource = new ClassPathResource(modelFilePath);
+ List<DMNMessage> retrieved = validatorBuilder.theseModels(resource);
+ assertThat(retrieved).isNotNull()
+ .hasSize(6) // There are other two messages
+ .allMatch(dmnMessage ->
dmnMessage.getLevel().equals(Message.Level.ERROR))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/FEEL/20140401"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DC/"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DI/"))
+ .anyMatch(dmnMessage ->
dmnMessage.getText().contains("http://www.omg.org/spec/DMN/20180505/DMNDI/"));
+ }
+
private void testDirectoryInJar(JarFile jarFile, String directory) {
List<String> allFiles = Collections.list(jarFile.entries())
.stream()
diff --git
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/v1_5/DMN15ValidationsTest.java
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/v1_5/DMN15ValidationsTest.java
index 62254f11ff..f0c4bd142a 100644
---
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/v1_5/DMN15ValidationsTest.java
+++
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/v1_5/DMN15ValidationsTest.java
@@ -49,7 +49,6 @@ public class DMN15ValidationsTest {
static final DMNValidator validator =
DMNValidatorFactory.newValidator(List.of(new ExtendedDMNProfile()));
static final DMNValidator.ValidatorBuilder validatorBuilder =
validator.validateUsing(DMNValidator.Validation.VALIDATE_SCHEMA,
DMNValidator.Validation.VALIDATE_MODEL);
-
@Test
void overridingUnnamedImportValidation() {
String importedModelFileName =
"valid_models/DMNv1_5/Imported_Model_Unamed.dmn";
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]