diff --git a/README.md b/README.md
index efc1a15..bbc9af7 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,61 @@ described in the URL above that the URL can be overwritten locally with an HTTPS
Check the [Development](DEVELOPMENT.md) page for more detail information how to work with this repository, because of
the mixture with RiseClipse.
+## Custom OCL Files
+
+There is a way to add custom OCL Files to the validator, for instance to force company specific rules. In the Docker
+Image there is a volume `/data/ocl` which can be used to add these files, see our compas-deployment project for an
+example how to.
+
+In this directory, you can use subdirectories like `SemanticConstraints` as RiseClipse is doing. And there is a special
+filter that when you create a directory `FileSpecifics`. In this directory you can create for instance a directory `CID`
+to put constraints specific for an SCL File Type. Known types are `SSD`, `IID`, `ICD`, `SCD`, `CID`, `SED`, `ISD`,
+`STD`.
+
+For instance,
+
+```
+data
+└── ocl
+ ├── FileSpecifics
+ │ └── CID
+ │ └── Busbar.ocl
+ └── SemanticConstraints
+ └── Busbar.ocl
+```
+
+If you are using the validator are library (using JAR Files) there is a property to configure the directory, see
+[Common Environment variables](#common-environment-variables)
+
+## NSDoc Files
+
+Because NSDoc File can't be distributed in an OpenSource Project these need to be added during deployment. In the Docker
+Image there is a volume `/data/nsdoc` which can be used to add these files, see our compas-deployment project for an
+example how to.
+
+Only direct files found in this directory will be processed. Invalid NSDoc Files will be ignored. A directory can look
+like this for instance,
+
+```
+data
+└── nsdoc
+ ├── IEC_61850-7-2_2007B3-en.nsdoc
+ ├── IEC_61850-7-3_2007B3-en.nsdoc
+ └── IEC_61850-7-4_2007B3-en.nsdoc
+
+```
+
+If you are using the validator are library (using JAR Files) there is a property to configure the directory, see
+[Common Environment variables](#common-environment-variables)
+
## Common Environment variables
Below environment variable(s) can be used to configure the validator.
-| Environment variable | Java Property | Description | Example |
-|---------------------------------------|---------------------------------------|---------------------------------------------------|-----------|
-| COMPAS_VALIDATOR_OCL_CUSTOM_DIRECTORY | compas.validator.ocl.custom.directory | Reference to a directory to load custom OCL Files | /data/ocl |
+| Environment variable | Java Property | Description | Example |
+|---------------------------------------|---------------------------------------|-------------------------------------------------------------|-------------|
+| COMPAS_VALIDATOR_OCL_CUSTOM_DIRECTORY | compas.validator.ocl.custom.directory | Reference to a directory to load custom OCL Files | /data/ocl |
+| COMPAS_VALIDATOR_NSDOC_DIRECTORY | compas.validator.nsdoc.directory | Reference to a directory where the NSDoc Files can be found | /data/nsdoc |
## Security
diff --git a/app/pom.xml b/app/pom.xml
index d9ac269..560e0d6 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -22,11 +22,6 @@ SPDX-License-Identifier: Apache-2.0
compas-scl-validator
-
-
-
-
-
org.lfenergy.compas.scl.validator
diff --git a/app/src/main/docker/Dockerfile.jvm b/app/src/main/docker/Dockerfile.jvm
index fcbad5c..109e45d 100644
--- a/app/src/main/docker/Dockerfile.jvm
+++ b/app/src/main/docker/Dockerfile.jvm
@@ -49,10 +49,12 @@ COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
RUN mkdir -p /data/ocl \
+ && mkdir -p /data/nsdoc \
&& mkdir -p /data/temp \
&& chown -R 1001 /data \
&& chmod -R "g+rwX" /data
VOLUME /data/ocl
+VOLUME /data/nsdoc
EXPOSE 8080
USER 1001
diff --git a/app/src/main/docker/Dockerfile.native b/app/src/main/docker/Dockerfile.native
index 286bd97..96b0f1c 100644
--- a/app/src/main/docker/Dockerfile.native
+++ b/app/src/main/docker/Dockerfile.native
@@ -22,10 +22,12 @@ RUN chown 1001 /work \
COPY --chown=1001:root target/*-runner /work/application
RUN mkdir -p /data/ocl \
+ && mkdir -p /data/nsdoc \
&& mkdir -p /data/temp \
&& chown -R 1001 /data \
&& chmod -R "g+rwX" /data
VOLUME /data/ocl
+VOLUME /data/nsdoc
EXPOSE 8080
USER 1001
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfiguration.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfiguration.java
index eefef07..eb60a4a 100644
--- a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfiguration.java
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfiguration.java
@@ -3,9 +3,11 @@
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.scl.validator.rest;
+import io.quarkus.runtime.Startup;
import org.lfenergy.compas.core.commons.ElementConverter;
import org.lfenergy.compas.scl.validator.collector.CompasOclFileCollector;
import org.lfenergy.compas.scl.validator.collector.OclFileCollector;
+import org.lfenergy.compas.scl.validator.common.NsdocFinder;
import org.lfenergy.compas.scl.validator.impl.SclRiseClipseValidator;
import javax.enterprise.context.ApplicationScoped;
@@ -33,4 +35,11 @@ public SclRiseClipseValidator createSclRiseClipseValidator(OclFileCollector oclF
ValidatorProperties properties) {
return new SclRiseClipseValidator(oclFileCollector, properties.tempDirectory());
}
+
+ @Produces
+ @Startup
+ @ApplicationScoped
+ public NsdocFinder createNsdocFinder(ValidatorProperties properties) {
+ return new NsdocFinder(properties.nsdocDirectory());
+ }
}
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/SclResourceConstants.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/SclResourceConstants.java
index 325fcbf..90037d5 100644
--- a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/SclResourceConstants.java
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/SclResourceConstants.java
@@ -9,4 +9,5 @@ public final class SclResourceConstants {
}
public static final String TYPE_PATH_PARAM = "type";
+ public static final String ID_PARAM = "id";
}
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/ValidatorProperties.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/ValidatorProperties.java
index ae11818..6c8db6d 100644
--- a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/ValidatorProperties.java
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/ValidatorProperties.java
@@ -13,6 +13,9 @@ public interface ValidatorProperties {
@WithName("ocl.custom.directory")
String oclCustomDirectory();
+ @WithName("nsdoc.directory")
+ String nsdocDirectory();
+
@WithName("temp.directory")
Path tempDirectory();
}
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandler.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandler.java
new file mode 100644
index 0000000..20f2d72
--- /dev/null
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandler.java
@@ -0,0 +1,21 @@
+// SPDX-FileCopyrightText: 2021 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.exception;
+
+import org.lfenergy.compas.core.jaxrs.model.ErrorResponse;
+import org.lfenergy.compas.scl.validator.exception.NsdocFileNotFoundException;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class NsdocNotFoundExceptionHandler implements ExceptionMapper {
+ @Override
+ public Response toResponse(NsdocFileNotFoundException exception) {
+ var response = new ErrorResponse();
+ response.addErrorMessage(exception.getErrorCode(), exception.getMessage());
+ return Response.status(Response.Status.NOT_FOUND).entity(response).build();
+ }
+}
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResource.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResource.java
new file mode 100644
index 0000000..3705a3b
--- /dev/null
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResource.java
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.v1;
+
+import io.quarkus.security.Authenticated;
+import org.lfenergy.compas.scl.validator.rest.v1.model.NsdocListResponse;
+import org.lfenergy.compas.scl.validator.service.NsdocService;
+
+import javax.enterprise.context.RequestScoped;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import java.util.UUID;
+
+import static org.lfenergy.compas.scl.validator.rest.SclResourceConstants.ID_PARAM;
+
+@Authenticated
+@RequestScoped
+@Path("/nsdoc/v1")
+public class NsdocResource {
+ private final NsdocService nsdocService;
+
+ public NsdocResource(NsdocService nsdocService) {
+ this.nsdocService = nsdocService;
+ }
+
+ @GET
+ @Consumes(MediaType.APPLICATION_XML)
+ @Produces(MediaType.APPLICATION_XML)
+ public NsdocListResponse list() {
+ NsdocListResponse response = new NsdocListResponse();
+ response.setNsdocFiles(nsdocService.list());
+ return response;
+ }
+
+ @GET
+ @Path("{" + ID_PARAM + "}")
+ @Consumes(MediaType.APPLICATION_XML)
+ @Produces(MediaType.APPLICATION_XML)
+ public String get(@PathParam(ID_PARAM) UUID id) {
+ return nsdocService.get(id);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponse.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponse.java
new file mode 100644
index 0000000..a2e3bdb
--- /dev/null
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponse.java
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.v1.model;
+
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Collection;
+
+import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
+
+@Schema(description = "The response with the list of known NSDoc Files.")
+@XmlRootElement(name = "NsdocListResponse", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
+@XmlAccessorType(XmlAccessType.FIELD)
+public class NsdocListResponse {
+ @Schema(description = "The list of known NSDoc Files")
+ @XmlElement(name = "NsdocFile", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
+ private Collection nsdocFiles;
+
+ public Collection getNsdocFiles() {
+ return nsdocFiles;
+ }
+
+ public void setNsdocFiles(Collection nsdocFiles) {
+ this.nsdocFiles = nsdocFiles;
+ }
+}
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequest.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequest.java
index d6f6069..41c88c8 100644
--- a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequest.java
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequest.java
@@ -14,11 +14,11 @@
import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
-@Schema(description = "")
+@Schema(description = "The Validation Request retrieved")
@XmlRootElement(name = "SclValidateRequest", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class SclValidateRequest {
- @Schema(description = "")
+ @Schema(description = "The SCL Data to be validated")
@NotBlank
@XmlElement(name = "SclData", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
protected String sclData;
diff --git a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponse.java b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponse.java
index 9666534..02462aa 100644
--- a/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponse.java
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponse.java
@@ -14,11 +14,11 @@
import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
-@Schema(description = "")
+@Schema(description = "The Validation Response returned")
@XmlRootElement(name = "SclValidateResponse", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public class SclValidateResponse {
- @Schema(description = "")
+ @Schema(description = "The list with Validation Errors, if any.")
@XmlElement(name = "ValidationErrors", namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI)
protected List validationErrorList;
diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties
index 8b79b95..5e088e7 100644
--- a/app/src/main/resources/application.properties
+++ b/app/src/main/resources/application.properties
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: Apache-2.0
compas.validator.ocl.custom.directory = /data/ocl
+compas.validator.nsdoc.directory = /data/nsdoc
compas.validator.temp.directory = /data/temp
quarkus.http.cors = false
@@ -14,6 +15,7 @@ quarkus.log.category."org.lfenergy.compas.scl.validator".level = INFO
# Dev Profile overrides.
%dev.compas.validator.ocl.custom.directory = ./src/test/data/ocl
+%dev.compas.validator.nsdoc.directory = ./src/test/data/nsdoc
%dev.compas.validator.temp.directory = ./target/data/temp
%dev.quarkus.http.port = 9093
@@ -24,6 +26,7 @@ quarkus.log.category."org.lfenergy.compas.scl.validator".level = INFO
# Test Profile overrides.
%test.compas.validator.ocl.custom.directory = ./src/test/data/ocl
+%test.compas.validator.nsdoc.directory = ./src/test/data/nsdoc
%test.compas.validator.temp.directory = ./target/data/temp
%test.quarkus.log.category."org.lfenergy.compas.scl.validator.collector.CompasOclFileCollector".level = WARN
@@ -43,5 +46,8 @@ quarkus.http.auth.permission.allow-quarkus-services.policy=permit
%dev.quarkus.http.auth.permission.develop-quarkus-services.paths=/compas-scl-validator/q/swagger-ui/*,/compas-scl-validator/index.html
%dev.quarkus.http.auth.permission.develop-quarkus-services.policy=permit
-quarkus.http.auth.permission.common.paths=/compas-scl-validator/validate/v1/*
-quarkus.http.auth.permission.common.policy=authenticated
+quarkus.http.auth.permission.validate.paths=/compas-scl-validator/validate/v1/*
+quarkus.http.auth.permission.validate.policy=authenticated
+
+quarkus.http.auth.permission.nsdoc.paths=/compas-scl-validator/nsdoc/v1/*
+quarkus.http.auth.permission.nsdoc.policy=authenticated
diff --git a/app/src/test/data/nsdoc/invalid.nsdoc b/app/src/test/data/nsdoc/invalid.nsdoc
new file mode 100644
index 0000000..99f4ab6
--- /dev/null
+++ b/app/src/test/data/nsdoc/invalid.nsdoc
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/app/src/test/data/nsdoc/testFile73.nsdoc b/app/src/test/data/nsdoc/testFile73.nsdoc
new file mode 100644
index 0000000..12207b3
--- /dev/null
+++ b/app/src/test/data/nsdoc/testFile73.nsdoc
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/test/data/nsdoc/testFile74.nsdoc b/app/src/test/data/nsdoc/testFile74.nsdoc
new file mode 100644
index 0000000..84e699a
--- /dev/null
+++ b/app/src/test/data/nsdoc/testFile74.nsdoc
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandlerTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandlerTest.java
new file mode 100644
index 0000000..81d548a
--- /dev/null
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/exception/NsdocNotFoundExceptionHandlerTest.java
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: 2021 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.exception;
+
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.core.jaxrs.model.ErrorResponse;
+import org.lfenergy.compas.scl.validator.exception.NsdocFileNotFoundException;
+
+import static javax.ws.rs.core.Response.Status.NOT_FOUND;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+class NsdocNotFoundExceptionHandlerTest {
+ @Test
+ void toResponse_WhenCalledWithException_ThenNotFoundReturnedWithBody() {
+ var exception = new NsdocFileNotFoundException("Some message that will only be logged");
+ var handler = new NsdocNotFoundExceptionHandler();
+
+ var result = handler.toResponse(exception);
+ assertEquals(NOT_FOUND.getStatusCode(), result.getStatus());
+ var errorMessage = ((ErrorResponse) result.getEntity()).getErrorMessages().get(0);
+ assertEquals(exception.getErrorCode(), errorMessage.getCode());
+ assertEquals(exception.getMessage(), errorMessage.getMessage());
+ assertNull(errorMessage.getProperty());
+ }
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResourceTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResourceTest.java
new file mode 100644
index 0000000..c177858
--- /dev/null
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/NsdocResourceTest.java
@@ -0,0 +1,110 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.v1;
+
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.mockito.InjectMock;
+import io.quarkus.test.security.TestSecurity;
+import io.restassured.http.ContentType;
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.core.jaxrs.JaxrsConstants;
+import org.lfenergy.compas.scl.validator.exception.NsdocFileNotFoundException;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+import org.lfenergy.compas.scl.validator.service.NsdocService;
+
+import java.util.List;
+import java.util.UUID;
+
+import static io.restassured.RestAssured.given;
+import static io.restassured.path.xml.config.XmlPathConfig.xmlPathConfig;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
+import static org.lfenergy.compas.scl.validator.rest.SclResourceConstants.ID_PARAM;
+import static org.mockito.Mockito.*;
+
+@QuarkusTest
+@TestHTTPEndpoint(NsdocResource.class)
+@TestSecurity(user = "test-user")
+class NsdocResourceTest {
+ @InjectMock
+ private NsdocService nsdocService;
+
+ @Test
+ void list_WhenCalled_ThenListReturned() {
+ when(nsdocService.list())
+ .thenReturn(List.of(new NsdocFile()));
+
+ var response = given()
+ .contentType(ContentType.XML)
+ .when()
+ .get()
+ .then()
+ .statusCode(200)
+ .extract()
+ .response();
+
+ var xmlPath = response.xmlPath()
+ .using(xmlPathConfig().declaredNamespace("svs", SCL_VALIDATOR_SERVICE_V1_NS_URI));
+ var files = xmlPath.getList("svs:NsdocListResponse.svs:NsdocFile");
+ assertNotNull(files);
+ assertEquals(1, files.size());
+ verify(nsdocService, times(1)).list();
+ }
+
+ @Test
+ void get_WhenCalled_ThenContentReturned() {
+ UUID id = UUID.randomUUID();
+ String result = "";
+
+ when(nsdocService.get(id))
+ .thenReturn(result);
+
+ var response = given()
+ .pathParam(ID_PARAM, id)
+ .contentType(ContentType.XML)
+ .when()
+ .get("/{" + ID_PARAM + "}")
+ .then()
+ .statusCode(200)
+ .extract()
+ .response();
+
+ var nsdocFile = response.asString();
+ assertNotNull(nsdocFile);
+ assertEquals(result, nsdocFile);
+ verify(nsdocService, times(1)).get(id);
+ }
+
+ @Test
+ void get_WhenCalledWithUnknownFile_Then404Returned() {
+ UUID id = UUID.randomUUID();
+
+ when(nsdocService.get(id))
+ .thenThrow(new NsdocFileNotFoundException("Some Message"));
+
+ var response = given()
+ .pathParam(ID_PARAM, id)
+ .contentType(ContentType.XML)
+ .when()
+ .get("/{" + ID_PARAM + "}")
+ .then()
+ .statusCode(404)
+ .extract()
+ .response();
+
+ var xmlPath = response.xmlPath()
+ .using(xmlPathConfig().declaredNamespace("commons", JaxrsConstants.COMPAS_COMMONS_V1_NS_URI));
+ var messages = xmlPath.getList("commons:ErrorResponse.commons:ErrorMessage");
+ assertNotNull(messages);
+ assertEquals(1, messages.size());
+
+ var code = xmlPath.getString("commons:ErrorResponse.commons:ErrorMessage.commons:Code");
+ assertEquals(SclValidatorErrorCode.NSDOC_FILE_NOT_FOUND, code);
+
+ verify(nsdocService, times(1)).get(id);
+ }
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/SclValidatorResourceTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/SclValidatorResourceTest.java
index 634c409..cdea625 100644
--- a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/SclValidatorResourceTest.java
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/SclValidatorResourceTest.java
@@ -56,8 +56,8 @@ void updateSCL_WhenCalled_ThenExpectedResponseIsRetrieved() throws IOException {
.response();
var xmlPath = response.xmlPath()
- .using(xmlPathConfig().declaredNamespace("saa", SCL_VALIDATOR_SERVICE_V1_NS_URI));
- var errors = xmlPath.getList("saa:SclValidateResponse.ValidationErrors");
+ .using(xmlPathConfig().declaredNamespace("svs", SCL_VALIDATOR_SERVICE_V1_NS_URI));
+ var errors = xmlPath.getList("svs:SclValidateResponse.svs:ValidationErrors");
assertNotNull(errors);
assertEquals(1, errors.size());
verify(sclValidatorService, times(1)).validate(sclFileTye, request.getSclData());
@@ -68,4 +68,4 @@ private String readFile() throws IOException {
var path = Paths.get(resource.getPath());
return String.join("\n", Files.readAllLines(path));
}
-}
\ No newline at end of file
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponseTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponseTest.java
new file mode 100644
index 0000000..cb4bda0
--- /dev/null
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/NsdocListResponseTest.java
@@ -0,0 +1,13 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest.v1.model;
+
+import org.lfenergy.compas.scl.validator.model.AbstractPojoTester;
+
+class NsdocListResponseTest extends AbstractPojoTester {
+ @Override
+ protected Class> getClassToBeTested() {
+ return NsdocListResponse.class;
+ }
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequestTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequestTest.java
index 9767456..a3fffec 100644
--- a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequestTest.java
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateRequestTest.java
@@ -10,4 +10,4 @@ class SclValidateRequestTest extends AbstractPojoTester {
protected Class> getClassToBeTested() {
return SclValidateRequest.class;
}
-}
\ No newline at end of file
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponseTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponseTest.java
index 29e0781..eb992e1 100644
--- a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponseTest.java
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/v1/model/SclValidateResponseTest.java
@@ -10,4 +10,4 @@ class SclValidateResponseTest extends AbstractPojoTester {
protected Class> getClassToBeTested() {
return SclValidateResponse.class;
}
-}
\ No newline at end of file
+}
diff --git a/app/src/test/resources/scl/scl-1.scd b/app/src/test/resources/scl/scl-1.scd
index de559b7..24acf04 100644
--- a/app/src/test/resources/scl/scl-1.scd
+++ b/app/src/test/resources/scl/scl-1.scd
@@ -1,5 +1,5 @@
-
+
diff --git a/riseclipse/validator-riseclipse/pom.xml b/riseclipse/validator-riseclipse/pom.xml
index 6f92e11..6d82bbb 100644
--- a/riseclipse/validator-riseclipse/pom.xml
+++ b/riseclipse/validator-riseclipse/pom.xml
@@ -65,6 +65,13 @@ SPDX-License-Identifier: Apache-2.0
+
+ org.lfenergy.compas.scl.validator
+ validator
+ test-jar
+ test
+
+
org.mockito
mockito-junit-jupiter
diff --git a/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd b/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd
index 4dc2b38..943b374 100644
--- a/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd
+++ b/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd
@@ -1,9 +1,9 @@
-
+
-
+
diff --git a/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd b/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd
index 61fba55..5e2ab08 100644
--- a/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd
+++ b/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd
@@ -1,5 +1,5 @@
-
+
diff --git a/service/pom.xml b/service/pom.xml
index f957aac..ae3f6e9 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -37,6 +37,11 @@ SPDX-License-Identifier: Apache-2.0
microprofile-openapi-api
+
+ commons-codec
+ commons-codec
+
+
org.slf4j
slf4j-api
diff --git a/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocFinder.java b/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocFinder.java
new file mode 100644
index 0000000..a447790
--- /dev/null
+++ b/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocFinder.java
@@ -0,0 +1,92 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.common;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.lfenergy.compas.scl.validator.exception.NsdocFileNotFoundException;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.CALCULATING_CHECKSUM_FAILED;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_NSDOC_FILE_FAILED;
+
+public class NsdocFinder {
+ private static final Logger LOGGER = LoggerFactory.getLogger(NsdocFinder.class);
+
+ private final String nsdocDirectory;
+ private final Map nsdocFiles;
+
+ public NsdocFinder(String nsdocDirectory) {
+ this.nsdocDirectory = nsdocDirectory;
+ this.nsdocFiles = getFilesFromDirectory(nsdocDirectory);
+ }
+
+ private Map getFilesFromDirectory(String directoryName) {
+ File directory = new File(directoryName);
+ if (directory.exists() && directory.isDirectory()) {
+ var files = directory.listFiles();
+ if (files != null) {
+ return Arrays.stream(files)
+ .filter(File::isFile)
+ .map(this::convertToNsdocFile)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toMap(NsdocFile::getId, Function.identity()));
+ }
+ }
+ return Collections.emptyMap();
+ }
+
+ private NsdocFile convertToNsdocFile(File file) {
+ try {
+ var nsdocInfo = new NsdocInfo(file);
+ var nsdocFile = new NsdocFile();
+ nsdocFile.setId(UUID.randomUUID());
+ nsdocFile.setNsdocId(nsdocInfo.getId());
+ nsdocFile.setFilename(file.getName());
+ nsdocFile.setChecksum(calculateChecksum(file));
+ return nsdocFile;
+ } catch (Exception exp) {
+ LOGGER.warn("Error loading NSDoc File '" + file.getName() + "'. Skipping file.", exp);
+ return null;
+ }
+ }
+
+ private String calculateChecksum(File file) {
+ try (var fis = new FileInputStream(file)) {
+ return DigestUtils.sha256Hex(fis);
+ } catch (IOException exp) {
+ throw new SclValidatorException(CALCULATING_CHECKSUM_FAILED, "Error calculating checksum for NSDoc File " +
+ file.getName() + "'.", exp);
+ }
+ }
+
+ public Collection getNsdocFiles() {
+ return nsdocFiles.values()
+ .stream()
+ .sorted(Comparator.comparing(NsdocFile::getNsdocId))
+ .collect(Collectors.toList());
+ }
+
+ public String getNsdocFile(UUID id) {
+ try {
+ if (nsdocFiles.containsKey(id)) {
+ var nsdocFile = nsdocFiles.get(id);
+ return Files.readString(new File(this.nsdocDirectory, nsdocFile.getFilename()).toPath());
+ }
+ throw new NsdocFileNotFoundException("NSDoc File with ID '" + id + "' not found.");
+ } catch (IOException exp) {
+ throw new SclValidatorException(LOADING_NSDOC_FILE_FAILED, "Error loading NSDoc File with ID '" + id + "'", exp);
+ }
+ }
+}
diff --git a/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocInfo.java b/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocInfo.java
new file mode 100644
index 0000000..b7908ee
--- /dev/null
+++ b/service/src/main/java/org/lfenergy/compas/scl/validator/common/NsdocInfo.java
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.common;
+
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.DETERMINING_ID_FAILED;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_NSDOC_FILE_FAILED;
+import static org.lfenergy.compas.scl.validator.util.StaxUtil.getAttributeValue;
+import static org.lfenergy.compas.scl.validator.util.StaxUtil.isElement;
+
+public class NsdocInfo {
+ private static final String NSDOC_ELEMENT_NAME = "NSDoc";
+
+ private String id = null;
+
+ public NsdocInfo(File file) {
+ try (var fis = new FileInputStream(file)) {
+ var factory = XMLInputFactory.newInstance();
+ // Completely disable external entities declarations:
+ factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
+
+ var reader = factory.createXMLEventReader(fis);
+
+ while (id == null && reader.hasNext()) {
+ processEvent(reader.nextEvent());
+ }
+ } catch (IOException | XMLStreamException exp) {
+ throw new SclValidatorException(LOADING_NSDOC_FILE_FAILED, "Error loading NSDoc File " + file.getName() + "'.", exp);
+ }
+
+ if (id == null) {
+ throw new SclValidatorException(DETERMINING_ID_FAILED, "No ID found in NSDoc File '" + file.getName() + "'.");
+ }
+ }
+
+ private void processEvent(XMLEvent nextEvent) {
+ if (nextEvent.isStartElement()) {
+ processStartElement(nextEvent.asStartElement());
+ }
+ }
+
+ private void processStartElement(StartElement element) {
+ if (isElement(element, NSDOC_ELEMENT_NAME)) {
+ id = getAttributeValue(element, "id");
+ }
+ }
+
+ public String getId() {
+ return id;
+ }
+}
diff --git a/service/src/main/java/org/lfenergy/compas/scl/validator/service/NsdocService.java b/service/src/main/java/org/lfenergy/compas/scl/validator/service/NsdocService.java
new file mode 100644
index 0000000..82d2c99
--- /dev/null
+++ b/service/src/main/java/org/lfenergy/compas/scl/validator/service/NsdocService.java
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.service;
+
+import org.lfenergy.compas.scl.validator.common.NsdocFinder;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.Collection;
+import java.util.UUID;
+
+@ApplicationScoped
+public class NsdocService {
+ private final NsdocFinder nsdocFinder;
+
+ @Inject
+ public NsdocService(NsdocFinder nsdocFinder) {
+ this.nsdocFinder = nsdocFinder;
+ }
+
+ public Collection list() {
+ return nsdocFinder.getNsdocFiles();
+ }
+
+ public String get(UUID id) {
+ return nsdocFinder.getNsdocFile(id);
+ }
+}
diff --git a/service/src/test/data/nsdoc/invalid.nsdoc b/service/src/test/data/nsdoc/invalid.nsdoc
new file mode 100644
index 0000000..99f4ab6
--- /dev/null
+++ b/service/src/test/data/nsdoc/invalid.nsdoc
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/service/src/test/data/nsdoc/testFile73.nsdoc b/service/src/test/data/nsdoc/testFile73.nsdoc
new file mode 100644
index 0000000..12207b3
--- /dev/null
+++ b/service/src/test/data/nsdoc/testFile73.nsdoc
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/service/src/test/data/nsdoc/testFile74.nsdoc b/service/src/test/data/nsdoc/testFile74.nsdoc
new file mode 100644
index 0000000..84e699a
--- /dev/null
+++ b/service/src/test/data/nsdoc/testFile74.nsdoc
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocFinderTest.java b/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocFinderTest.java
new file mode 100644
index 0000000..7f270f8
--- /dev/null
+++ b/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocFinderTest.java
@@ -0,0 +1,56 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.common;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class NsdocFinderTest {
+ private NsdocFinder finder;
+
+ @BeforeEach
+ void setup() {
+ finder = new NsdocFinder("./src/test/data/nsdoc");
+ }
+
+ @Test
+ void getNsdocFiles_WhenCalledWithConfiguredDirectory_ThenExpectCorrectNumberOfEntriesReturned() {
+ var files = finder.getNsdocFiles();
+
+ assertNotNull(files);
+ // 2 Files expected, because 1 file is invalid.
+ assertEquals(2, files.size());
+
+ var fileList = new ArrayList<>(files);
+ assertEquals("IEC 61850-7-3", fileList.get(0).getNsdocId());
+ assertEquals("IEC 61850-7-4", fileList.get(1).getNsdocId());
+ }
+
+ @Test
+ void getNsdocFiles_WhenCalledWithNonExistingDirectory_ThenNoEntriesReturned() {
+ finder = new NsdocFinder("./src/text/data/non-existing");
+ var files = finder.getNsdocFiles();
+
+ assertNotNull(files);
+ assertEquals(0, files.size());
+ }
+
+ @Test
+ void getNsdocFile_WhenUseTheIDsToRetrieveEntries_ThenContentIsReturned() {
+ var files = finder.getNsdocFiles();
+ var content = files.stream()
+ .map(NsdocFile::getId)
+ .map(id -> finder.getNsdocFile(id))
+ .findFirst()
+ .orElse(null);
+
+ assertNotNull(content);
+ }
+}
diff --git a/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocInfoTest.java b/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocInfoTest.java
new file mode 100644
index 0000000..cc022e1
--- /dev/null
+++ b/service/src/test/java/org/lfenergy/compas/scl/validator/common/NsdocInfoTest.java
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.common;
+
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+
+import java.io.File;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.DETERMINING_ID_FAILED;
+
+class NsdocInfoTest {
+ @Test
+ void getId_WhenCalledWithValidNsDocFile_ThenIdFromFileReturned() {
+ var nsdocFile = new File(getClass().getResource("/nsdoc/testFile74.nsdoc").getFile());
+
+ var nsdocInfo = new NsdocInfo(nsdocFile);
+
+ assertNotNull(nsdocInfo.getId());
+ assertEquals("IEC 61850-7-4", nsdocInfo.getId());
+ }
+
+ @Test
+ void getId_WhenCalledWithInvalidNsDocFile_ThenExceptionThrownDuringConstruction() {
+ var nsdocFile = new File(getClass().getResource("/nsdoc/invalid.nsdoc").getFile());
+
+ var exception = assertThrows(SclValidatorException.class, () -> new NsdocInfo(nsdocFile));
+ assertNotNull(DETERMINING_ID_FAILED, exception.getErrorCode());
+ }
+}
diff --git a/service/src/test/java/org/lfenergy/compas/scl/validator/service/NsdocServiceTest.java b/service/src/test/java/org/lfenergy/compas/scl/validator/service/NsdocServiceTest.java
new file mode 100644
index 0000000..51e4bf5
--- /dev/null
+++ b/service/src/test/java/org/lfenergy/compas/scl/validator/service/NsdocServiceTest.java
@@ -0,0 +1,60 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.service;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.lfenergy.compas.scl.validator.common.NsdocFinder;
+import org.lfenergy.compas.scl.validator.model.NsdocFile;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class NsdocServiceTest {
+
+ private NsdocService nsdocService;
+
+ @Mock
+ private NsdocFinder nsdocFinder;
+
+ @BeforeEach
+ void beforeEach() {
+ nsdocService = new NsdocService(nsdocFinder);
+ }
+
+ @Test
+ void list_WhenCalled_ThenEmptyListReturned() {
+ when(nsdocFinder.getNsdocFiles()).thenReturn(List.of(new NsdocFile()));
+
+ var result = nsdocService.list();
+
+ assertNotNull(result);
+ assertEquals(1, result.size());
+
+ verify(nsdocFinder, times(1)).getNsdocFiles();
+ }
+
+ @Test
+ void get_WhenCalled_ThenContentReturned() {
+ UUID id = UUID.randomUUID();
+ String content = "";
+
+ when(nsdocFinder.getNsdocFile(id)).thenReturn(content);
+
+ var result = nsdocService.get(id);
+
+ assertNotNull(result);
+ assertEquals(content, result);
+
+ verify(nsdocFinder, times(1)).getNsdocFile(id);
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/java/org/lfenergy/compas/scl/validator/service/SclValidatorServiceTest.java b/service/src/test/java/org/lfenergy/compas/scl/validator/service/SclValidatorServiceTest.java
index 4c263c7..f7fdd95 100644
--- a/service/src/test/java/org/lfenergy/compas/scl/validator/service/SclValidatorServiceTest.java
+++ b/service/src/test/java/org/lfenergy/compas/scl/validator/service/SclValidatorServiceTest.java
@@ -8,10 +8,11 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.lfenergy.compas.scl.extensions.model.SclFileType;
import org.lfenergy.compas.scl.validator.SclValidator;
+import org.lfenergy.compas.scl.validator.model.ValidationError;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
-import java.util.Collections;
+import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -31,16 +32,16 @@ void beforeEach() {
}
@Test
- void validate_WhenCalled_ThenEmptyListReturned() {
+ void validate_WhenCalled_ThenExpectedListReturned() {
var type = SclFileType.CID;
var sclData = "Some String";
- when(sclValidator.validate(type, sclData)).thenReturn(Collections.emptyList());
+ when(sclValidator.validate(type, sclData)).thenReturn(List.of(new ValidationError()));
var result = sclValidatorService.validate(type, sclData);
assertNotNull(result);
- assertEquals(0, result.size());
+ assertEquals(1, result.size());
verify(sclValidator, times(1)).validate(type, sclData);
}
diff --git a/service/src/test/resources/nsdoc/invalid.nsdoc b/service/src/test/resources/nsdoc/invalid.nsdoc
new file mode 100644
index 0000000..99f4ab6
--- /dev/null
+++ b/service/src/test/resources/nsdoc/invalid.nsdoc
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/service/src/test/resources/nsdoc/testFile74.nsdoc b/service/src/test/resources/nsdoc/testFile74.nsdoc
new file mode 100644
index 0000000..84e699a
--- /dev/null
+++ b/service/src/test/resources/nsdoc/testFile74.nsdoc
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundException.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundException.java
new file mode 100644
index 0000000..c4f17f0
--- /dev/null
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundException.java
@@ -0,0 +1,12 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.exception;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.NSDOC_FILE_NOT_FOUND;
+
+public class NsdocFileNotFoundException extends SclValidatorException {
+ public NsdocFileNotFoundException(String message) {
+ super(NSDOC_FILE_NOT_FOUND, message);
+ }
+}
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorErrorCode.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorErrorCode.java
index 249706b..7d0e377 100644
--- a/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorErrorCode.java
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorErrorCode.java
@@ -19,4 +19,9 @@ public class SclValidatorErrorCode {
public static final String WRITE_TO_OCL_TEMP_FILES_FAILED = "SVS-2003";
public static final String OCL_MODEL_PACKAGE_NOT_FOUND = "SVS-2005";
public static final String NO_URI_PASSED = "SVS-2006";
+
+ public static final String CALCULATING_CHECKSUM_FAILED = "SVS-3001";
+ public static final String DETERMINING_ID_FAILED = "SVS-3002";
+ public static final String LOADING_NSDOC_FILE_FAILED = "SVS-3003";
+ public static final String NSDOC_FILE_NOT_FOUND = "SVS-3004";
}
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/model/NsdocFile.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/model/NsdocFile.java
new file mode 100644
index 0000000..8804f2b
--- /dev/null
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/model/NsdocFile.java
@@ -0,0 +1,81 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.model;
+
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
+
+import javax.validation.constraints.NotBlank;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import java.util.UUID;
+
+import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
+
+@Schema(description = "Information about a single NSDoc file that is known by the service.")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class NsdocFile {
+ @Schema(description = "The technical id of this NSDoc File.",
+ example = "123e4567-e89b-12d3-a456-426614174000")
+ @NotBlank
+ @XmlElement(name = "Id",
+ namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI,
+ required = true)
+ private UUID id;
+
+ @Schema(description = "The id of the NSDoc File.",
+ example = "IEC 61850-7-3")
+ @NotBlank
+ @XmlElement(name = "NsdocId",
+ namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI,
+ required = true)
+ private String nsdocId;
+
+ @Schema(description = "The name of the NSDoc File.",
+ example = "OfficialFile73.nsdoc")
+ @NotBlank
+ @XmlElement(name = "Filename",
+ namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI,
+ required = true)
+ private String filename;
+
+ @Schema(description = "The checksum of the NSDoc File.")
+ @NotBlank
+ @XmlElement(name = "Checksum",
+ namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI,
+ required = true)
+ private String checksum;
+
+ public UUID getId() {
+ return id;
+ }
+
+ public void setId(UUID id) {
+ this.id = id;
+ }
+
+ public String getNsdocId() {
+ return nsdocId;
+ }
+
+ public void setNsdocId(String nsdocId) {
+ this.nsdocId = nsdocId;
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public void setFilename(String filename) {
+ this.filename = filename;
+ }
+
+ public String getChecksum() {
+ return checksum;
+ }
+
+ public void setChecksum(String checksum) {
+ this.checksum = checksum;
+ }
+}
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/util/StaxUtil.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/util/StaxUtil.java
new file mode 100644
index 0000000..cc62091
--- /dev/null
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/util/StaxUtil.java
@@ -0,0 +1,26 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.StartElement;
+
+public class StaxUtil {
+ StaxUtil() {
+ throw new UnsupportedOperationException("StaxUtil class");
+ }
+
+ public static boolean isElement(StartElement element, String elementName) {
+ return elementName.equals(element.getName().getLocalPart());
+ }
+
+ public static String getAttributeValue(StartElement element, String attributeName) {
+ Attribute attribute = element.getAttributeByName(new QName(attributeName));
+ if (attribute != null) {
+ return attribute.getValue();
+ }
+ return null;
+ }
+}
diff --git a/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundExceptionTest.java b/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundExceptionTest.java
new file mode 100644
index 0000000..17983f4
--- /dev/null
+++ b/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/NsdocFileNotFoundExceptionTest.java
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.exception;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class NsdocFileNotFoundExceptionTest {
+ @Test
+ void constructor_WhenCalledWithOnlyMessage_ThenMessageCanBeRetrieved() {
+ var expectedMessage = "The message";
+ var exception = new NsdocFileNotFoundException(expectedMessage);
+
+ Assertions.assertEquals(SclValidatorErrorCode.NSDOC_FILE_NOT_FOUND, exception.getErrorCode());
+ Assertions.assertEquals(expectedMessage, exception.getMessage());
+ }
+}
\ No newline at end of file
diff --git a/validator/src/test/java/org/lfenergy/compas/scl/validator/model/NsdocFileTest.java b/validator/src/test/java/org/lfenergy/compas/scl/validator/model/NsdocFileTest.java
new file mode 100644
index 0000000..a6d047a
--- /dev/null
+++ b/validator/src/test/java/org/lfenergy/compas/scl/validator/model/NsdocFileTest.java
@@ -0,0 +1,11 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.model;
+
+class NsdocFileTest extends AbstractPojoTester {
+ @Override
+ protected Class> getClassToBeTested() {
+ return NsdocFile.class;
+ }
+}
\ No newline at end of file
diff --git a/validator/src/test/java/org/lfenergy/compas/scl/validator/util/StaxUtilTest.java b/validator/src/test/java/org/lfenergy/compas/scl/validator/util/StaxUtilTest.java
new file mode 100644
index 0000000..23ecb9c
--- /dev/null
+++ b/validator/src/test/java/org/lfenergy/compas/scl/validator/util/StaxUtilTest.java
@@ -0,0 +1,81 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+import org.junit.jupiter.api.Test;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.StartElement;
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.lfenergy.compas.scl.validator.util.StaxUtil.getAttributeValue;
+import static org.lfenergy.compas.scl.validator.util.StaxUtil.isElement;
+
+class StaxUtilTest {
+ @Test
+ void constructor_WhenConstructorCalled_ThenShouldThrowExceptionCauseForbidden() {
+ assertThrows(UnsupportedOperationException.class, StaxUtil::new);
+ }
+
+ @Test
+ void isElement_WhenCalledWithExpectedElementName_ThenFirstElementHasCorrectElementName() throws XMLStreamException, IOException {
+ var element = getFirstElement();
+ if (element != null) {
+ var result = isElement(element, "NSDoc");
+ assertTrue(result, "No NSDoc Element Found");
+ } else {
+ fail("XML File couldn't be read.");
+ }
+ }
+
+ @Test
+ void isElement_WhenCalledWithUnknownElementName_ThenFirstElementHasIncorrectElementName() throws XMLStreamException, IOException {
+ var element = getFirstElement();
+ if (element != null) {
+ var result = isElement(element, "Unknown");
+ assertFalse(result, "Unknown Element shouldn't be Found");
+ } else {
+ fail("XML File couldn't be read.");
+ }
+ }
+
+ @Test
+ void getAttributeValue_WhenCalledWithKnownAttribute_ThenAttributeValueReturned() throws XMLStreamException, IOException {
+ var element = getFirstElement();
+ if (element != null) {
+ var result = getAttributeValue(element, "version");
+ assertEquals("1010", result);
+ } else {
+ fail("XML File couldn't be read.");
+ }
+ }
+
+ @Test
+ void getAttributeValue_WhenCalledWithUnknownAttribute_ThenNullReturned() throws XMLStreamException, IOException {
+ var element = getFirstElement();
+ if (element != null) {
+ var result = getAttributeValue(element, "unknown");
+ assertNull(result);
+ } else {
+ fail("XML File couldn't be read.");
+ }
+ }
+
+ private StartElement getFirstElement() throws XMLStreamException, IOException {
+ try (var inputStream = getClass().getResourceAsStream("/testFile74.nsdoc")) {
+ var xmlInputFactory = XMLInputFactory.newInstance();
+ var reader = xmlInputFactory.createXMLEventReader(inputStream);
+
+ while (reader.hasNext()) {
+ var nextEvent = reader.nextEvent();
+ if (nextEvent.isStartElement()) {
+ return nextEvent.asStartElement();
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java b/validator/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
similarity index 79%
rename from riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
rename to validator/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
index 0db7f6b..6cc144a 100644
--- a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
+++ b/validator/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
@@ -11,7 +11,11 @@ public final class TestSupportUtil {
}
public static String readSCL(String filename) throws IOException {
- var inputStream = TestSupportUtil.class.getResourceAsStream("/scl/" + filename);
+ return readFile("/scl/" + filename);
+ }
+
+ public static String readFile(String filename) throws IOException {
+ var inputStream = TestSupportUtil.class.getResourceAsStream(filename);
assert inputStream != null;
return new String(inputStream.readAllBytes());
diff --git a/validator/src/test/resources/testFile74.nsdoc b/validator/src/test/resources/testFile74.nsdoc
new file mode 100644
index 0000000..8895653
--- /dev/null
+++ b/validator/src/test/resources/testFile74.nsdoc
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+