diff --git a/src/ILICheck.Web/ClientApp/src/logHierarchy.js b/src/ILICheck.Web/ClientApp/src/logHierarchy.js
index e9e451e..f5a5eaf 100644
--- a/src/ILICheck.Web/ClientApp/src/logHierarchy.js
+++ b/src/ILICheck.Web/ClientApp/src/logHierarchy.js
@@ -1,19 +1,17 @@
import groupBy from "object.groupby";
const constraintPatterns = [
- ["Mandatory Constraint", /^validate mandatory constraint (\S+)\.\.\.$/, /^Mandatory Constraint (\S+) is not true\.$/],
- [
- "Plausibility Constraint",
- /^validate plausibility constraint (\S+)\.\.\.$/,
- /^Plausibility Constraint (\S+) is not true\.$/,
- ],
- ["Existence Constraint", /^validate existence constraint (\S+)\.\.\.$/, /^Existence constraint (\S+) is violated/],
- ["Uniqueness Constraint", /^validate unique constraint (\S+)\.\.\.$/, /^Unique constraint (\S+) is violated/],
- ["Set Constraint", /^validate set constraint (\S+)\.\.\.$/, /^Set Constraint (\S+) is not true\.$/],
+ ["Mandatory Constraint", /^validate mandatory constraint (\S+)\.\.\.$/],
+ ["Plausibility Constraint", /^validate plausibility constraint (\S+)\.\.\.$/],
+ ["Existence Constraint", /^validate existence constraint (\S+)\.\.\.$/],
+ ["Uniqueness Constraint", /^validate unique constraint (\S+)\.\.\.$/],
+ ["Set Constraint", /^validate set constraint (\S+)\.\.\.$/],
];
+// e.g. "Custom message ModelA.TopicA.ClassA.ConstraintName (ILI syntax)" will result in "Custom message"
const customConstraintMessagePattern = /^(.*) (\w+\.\w+\.\w+\.\w+) \(.*\)$/;
-const constraintNamePattern = /\s(\w+\.\w+\.\w+\.\w+)\s/;
+// e.g. " ModelA.TopicA.ClassA.ConstraintName (ILI syntax) " (ILI syntax is optional and will be removed from the message)
+const constraintNamePattern = /\s(\w+\.\w+\.\w+\.\w+)(\s\(.+\))?\s/;
export function createLogHierarchy(logData) {
const [constraintEntries, otherEntries] = collectLogEntries(logData);
@@ -26,35 +24,29 @@ function collectLogEntries(entries) {
const otherErrors = new Set();
for (const entry of entries) {
- let constraintFound = false;
- for (const [name, infoPattern, errorPattern] of constraintPatterns) {
- let match;
- if (entry.type === "Info") {
- match = infoPattern.exec(entry.message);
- } else if (entry.type === "Error") {
- match = errorPattern.exec(entry.message);
- } else {
- continue;
- }
-
- if (match) {
- const constraintName = match[1];
- addOrReplaceLogEntry(constraintEntries, name, constraintName, entry);
- constraintFound = true;
- break;
+ if (entry.type === "Info") {
+ for (const [name, infoPattern] of constraintPatterns) {
+ const match = infoPattern.exec(entry.message);
+ if (match) {
+ const constraintName = match[1];
+ addOrReplaceLogEntry(constraintEntries, name, constraintName, entry);
+ break;
+ }
}
- }
-
- if (!constraintFound && entry.type !== "Info") {
- const match = customConstraintMessagePattern.exec(entry.message);
- if (match) {
- entry.message = match[1];
- const constraintName = match[2];
+ } else {
+ const customMessageMatch = customConstraintMessagePattern.exec(entry.message);
+ if (customMessageMatch) {
+ entry.message = customMessageMatch[1];
+ const constraintName = customMessageMatch[2];
addOrReplaceLogEntry(constraintEntries, "", constraintName, entry);
} else {
const nameMatch = constraintNamePattern.exec(entry.message);
if (nameMatch) {
const constraintName = nameMatch[1];
+ const iliSyntax = nameMatch[2];
+ if (iliSyntax) {
+ entry.message = entry.message.replace(iliSyntax, "");
+ }
addOrReplaceLogEntry(constraintEntries, "", constraintName, entry);
} else if (entry.type === "Error") {
otherErrors.add(entry.message);
diff --git a/src/ILICheck.Web/ClientApp/src/logHierarchy.test.js b/src/ILICheck.Web/ClientApp/src/logHierarchy.test.js
index dce0b8b..21b09d7 100644
--- a/src/ILICheck.Web/ClientApp/src/logHierarchy.test.js
+++ b/src/ILICheck.Web/ClientApp/src/logHierarchy.test.js
@@ -45,7 +45,7 @@ describe("transform log data to hierarchy", () => {
{
tid: "o3",
message:
- "Existence constraint ModelA.TopicA.ClassA.ConstraintName is violated! The value of the attribute Test of t1 was not found in the condition class.",
+ "Existence constraint ModelA.TopicA.ClassA.ConstraintName (EXISTENCE CONSTRAINT Test REQUIRED IN OtherClass:Test;) is violated! The value of the attribute Test of t1 was not found in the condition class.",
type: "Error",
},
];
diff --git a/src/ILICheck.Web/Controllers/DownloadController.cs b/src/ILICheck.Web/Controllers/DownloadController.cs
index 1a8bde1..44628b2 100644
--- a/src/ILICheck.Web/Controllers/DownloadController.cs
+++ b/src/ILICheck.Web/Controllers/DownloadController.cs
@@ -50,12 +50,12 @@ public IActionResult Download(Guid jobId, LogType logType)
}
///
- /// Gets the log of the specified in JSON format.
+ /// Gets the log data of the specified in JSON format.
///
/// The job identifier.
/// The log data for the specified .
[HttpGet("json")]
- [SwaggerResponse(StatusCodes.Status200OK, "Returns the ilivalidator log file in JSON format.", typeof(IEnumerable), new[] { "application/json" })]
+ [SwaggerResponse(StatusCodes.Status200OK, "Returns the ilivalidator log data in JSON format.", typeof(IEnumerable), new[] { "application/json" })]
[SwaggerResponse(StatusCodes.Status400BadRequest, "The server cannot process the request due to invalid or malformed request.", typeof(ValidationProblemDetails), new[] { "application/json" })]
[SwaggerResponse(StatusCodes.Status404NotFound, "The log file for the requested jobId cannot be found.", ContentTypes = new[] { "application/json" })]
public IActionResult GetJsonLog(Guid jobId)