diff --git a/.github/workflows/build-project.yml b/.github/workflows/build-project.yml
index 96d9281..f2a41a2 100644
--- a/.github/workflows/build-project.yml
+++ b/.github/workflows/build-project.yml
@@ -22,6 +22,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
+ with:
+ submodules: 'true'
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
@@ -48,9 +50,5 @@ jobs:
with:
output_file: custom_maven_settings.xml
servers: '[{ "id": "github-packages-compas", "username": "OWNER", "password": "${{ secrets.GITHUB_TOKEN }}" }]'
- - name: Build Native with Maven
- if: ${{ github.event_name == 'pull_request' }}
- run: ./mvnw -s custom_maven_settings.xml -B -Pnative clean verify
- name: Build with Maven
- if: ${{ github.event_name == 'push' }}
run: ./mvnw -s custom_maven_settings.xml -B clean verify
diff --git a/.github/workflows/release-project.yml b/.github/workflows/release-project.yml
index a879bf3..dcb14e3 100644
--- a/.github/workflows/release-project.yml
+++ b/.github/workflows/release-project.yml
@@ -16,6 +16,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
+ with:
+ submodules: 'true'
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
@@ -57,6 +59,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy with Maven to GitHub Packages and Docker Hub
- run: ./mvnw -B -s custom_maven_settings.xml -Prelease,native clean deploy
+ run: ./mvnw -B -s custom_maven_settings.xml -Prelease clean deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml
index 3b3b6f8..f122906 100644
--- a/.github/workflows/sonarcloud-analysis.yml
+++ b/.github/workflows/sonarcloud-analysis.yml
@@ -29,6 +29,7 @@ jobs:
uses: actions/checkout@v3
with:
fetch-depth: 0
+ submodules: 'true'
- name: Set up JDK 1.11
uses: actions/setup-java@v3
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..d9bdeff
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,24 @@
+# SPDX-FileCopyrightText: 2022 Alliander N.V.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+#
+# Remark: the option to ignore 'untracked' files is needed, because the submodules don't contain a file '.gitignore'.
+# This cause the target directories to be untracked.
+#
+[submodule "riseclipse/riseclipse-developer"]
+ path = riseclipse/riseclipse-developer
+ url = git@github.com:riseclipse/riseclipse-developer.git
+ ignore = dirty
+[submodule "riseclipse/riseclipse-main"]
+ path = riseclipse/riseclipse-main
+ url = git@github.com:riseclipse/riseclipse-main.git
+ ignore = dirty
+[submodule "riseclipse/riseclipse-metamodel-scl2003"]
+ path = riseclipse/riseclipse-metamodel-scl2003
+ url = git@github.com:riseclipse/riseclipse-metamodel-scl2003.git
+ ignore = dirty
+[submodule "riseclipse/riseclipse-ocl-constraints-scl2003"]
+ path = riseclipse/riseclipse-ocl-constraints-scl2003
+ url = git@github.com:riseclipse/riseclipse-ocl-constraints-scl2003.git
+ ignore = dirty
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
new file mode 100644
index 0000000..27e2f4c
--- /dev/null
+++ b/DEVELOPMENT.md
@@ -0,0 +1,82 @@
+
+
+# Development
+
+## Git
+
+If the project is already cloned and a submodule is added use the following commands, first `git submodule init` and
+next `git submodule update`.
+
+More about Git Submodules can be found [here](https://git-scm.com/book/en/v2/Git-Tools-Submodules).
+
+**Remark**: The URLs to the submodules are configured in the file `.gitmodules`, but these are using the SSH URLs. There
+is a way described [here](https://git-scm.com/book/en/v2/Git-Tools-Submodules) that the URL can be overwritten locally
+with an HTTPS URL of the GIT Repository. Because of the subdirectory where the submodules are in, this doesn't work
+exactly that way. Use the following commands to update the URLs locally to HTTPS.
+
+```
+git config submodule.riseclipse/riseclipse-developer.url https://github.com/riseclipse/riseclipse-developer.git
+git config submodule.riseclipse/riseclipse-main.url https://github.com/riseclipse/riseclipse-main.git
+git config submodule.riseclipse/riseclipse-metamodel-scl2003.url https://github.com/riseclipse/riseclipse-metamodel-scl2003.git
+git config submodule.riseclipse/riseclipse-ocl-constraints-scl2003.url https://github.com/riseclipse/riseclipse-ocl-constraints-scl2003.git
+
+git submodule init
+git submodule update
+```
+
+## IntelliJ
+
+Importing the project is a bit harder for the SCL Validator then normal. It's caused because of the submodules that are
+needed from RiseClipse. These projects are Eclipse projects using Eclipse Tycho to build and Eclipse project structure.
+
+A way to make everything work in IntelliJ is importing the project in the following way.
+
+- First step is to just import everything like it are Maven projects;
+- Next step is to re-import the RiseClipse Submodule as Eclipse;
+ - In IntelliJ select "File" -> "New" -> "Module from Existing Sources...";
+ - Select one of the RiseClipse Submodules, for instance "riseclipse-metamodel-scl2003";
+ - Next select "Eclipse" by "Import module from External Model";
+ - Follow the rest of the wizard, only to remember to select all subprojects that are available in the directory;
+
+Now the module should be correctly imported in IntelliJ to be used. Check the Module Settings of one of the subprojects
+to check if the directory "src" is a Java Source Directory, for instance the module
+"riseclipse/riseclipse-metamodel-scl2003/fr.centralesupelec.edf.riseclipse.iec61850.scl.utilities".
+
+## Eclipse
+
+Example about how to use Eclipse OCL was found
+[here](https://help.eclipse.org/latest/index.jsp?topic=%2Forg.eclipse.ocl.doc%2Fhelp%2FPivotStandalone.html).
+
+## Running the application in dev mode
+
+You can run your application in dev mode that enables live coding using:
+
+```shell script
+./mvnw package io.quarkus:quarkus-maven-plugin::dev
+```
+
+> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
+
+## Packaging and running the application
+
+The application can be packaged using:
+
+```shell script
+./mvnw package
+```
+
+It produces the `quarkus-run.jar` file in the `app/target/quarkus-app/` directory. Be aware that it’s not an _über-jar_
+as the dependencies are copied into the `app/target/quarkus-app/lib/` directory.
+
+If you want to build an _über-jar_, execute the following command:
+
+```shell script
+./mvnw package -Dquarkus.package.type=uber-jar
+```
+
+The application is now runnable using `java -jar app/target/quarkus-app/quarkus-run.jar`.
+
diff --git a/README.md b/README.md
index b0afaf7..efc1a15 100644
--- a/README.md
+++ b/README.md
@@ -14,27 +14,38 @@ SPDX-License-Identifier: Apache-2.0
Service to validate SCL Files.
+## Development
+
+For the RiseClipse implementation of the validator parts of the RiseClipse project are being used. Currently, these
+parts aren't distributed to any Maven Repository, so the Git Repositories need to be included. This is done using Git
+Submodules.
+
+To clone the project or update the project this means that the Git commands are sometimes a little different. To clone
+the project use the following command `git clone --recurse-submodules git@github.com:com-pas/compas-scl-validator.git`.
+This will also clone the submodules.
+
+Tip: The URL to the submodules are configured in the file `.gitmodules`, but these are using the SSH URL. There is a way
+described in the URL above that the URL can be overwritten locally with an HTTPS URL of the GIT Repository.
+
+Check the [Development](DEVELOPMENT.md) page for more detail information how to work with this repository, because of
+the mixture with RiseClipse.
## Common Environment variables
-Below environment variable(s) can be used to configure which claims and information are used to fill the UserInfo
-response.
+Below environment variable(s) can be used to configure the validator.
-| Environment variable | Java Property | Description | Example |
-| -------------------------------- | ------------------------------- | ----------------------------------------------------------- | ---------------- |
-| USERINFO_NAME_CLAIMNAME | compas.userinfo.name.claimname | The Name of the user logged in. | name |
-| USERINFO_WHO_CLAIMNAME | compas.userinfo.who.claimname | The Name of the user used in the Who History. | name |
-| USERINFO_SESSION_WARNING | compas.userinfo.session.warning | Number of minutes a Session Warning can be displayed. | 20 |
-| USERINFO_SESSION_EXPIRES | compas.userinfo.session.expires | Number of minutes a Session Expires to display in Frontend. | 30 |
+| 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 |
## Security
To use most of the endpoints the users needs to be authenticated using JWT in the authorization header. There are 4
environment variables that can be set in the container to configure the validation/processing of the JWT.
-| Environment variable | Java Property | Description | Example |
-| -------------------------------- | -------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------- |
-| JWT_VERIFY_KEY | smallrye.jwt.verify.key.location | Location of certificates to verify the JWT. | http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs |
-| JWT_VERIFY_ISSUER | mp.jwt.verify.issuer | The issuer of the JWT. | http://localhost:8089/auth/realms/compas |
-| JWT_VERIFY_CLIENT_ID | mp.jwt.verify.audiences | The Client ID that should be in the "aud" claim. | scl-validator |
-| JWT_GROUPS_PATH | smallrye.jwt.path.groups | The JSON Path where to find the roles of the user. | resource_access/scl-validator/roles |
+| Environment variable | Java Property | Description | Example |
+|----------------------|----------------------------------|----------------------------------------------------|------------------------------------------------------------------------|
+| JWT_VERIFY_KEY | smallrye.jwt.verify.key.location | Location of certificates to verify the JWT. | http://localhost:8089/auth/realms/compas/protocol/openid-connect/certs |
+| JWT_VERIFY_ISSUER | mp.jwt.verify.issuer | The issuer of the JWT. | http://localhost:8089/auth/realms/compas |
+| JWT_VERIFY_CLIENT_ID | mp.jwt.verify.audiences | The Client ID that should be in the "aud" claim. | scl-validator |
+| JWT_GROUPS_PATH | smallrye.jwt.path.groups | The JSON Path where to find the roles of the user. | resource_access/scl-validator/roles |
diff --git a/app/pom.xml b/app/pom.xml
index 30f2594..d9ac269 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -86,6 +86,12 @@ SPDX-License-Identifier: Apache-2.0
test-jar
test
+
+ org.lfenergy.compas.scl.validator
+ validator-riseclipse
+ test-jar
+ test
+
io.quarkus
@@ -112,6 +118,11 @@ SPDX-License-Identifier: Apache-2.0
quarkus-jacoco
test
+
+ org.mockito
+ mockito-junit-jupiter
+ test
+
com.openpojo
openpojo
@@ -156,8 +167,13 @@ SPDX-License-Identifier: Apache-2.0
native
- true
- true
+
+ true
+
+ true
+
+ --allow-incomplete-classpath
+
@@ -174,8 +190,12 @@ SPDX-License-Identifier: Apache-2.0
- ${project.build.directory}/${project.build.finalName}-runner
- org.jboss.logmanager.LogManager
+
+ ${project.build.directory}/${project.build.finalName}-runner
+
+
+ org.jboss.logmanager.LogManager
+
${maven.home}
@@ -201,8 +221,8 @@ SPDX-License-Identifier: Apache-2.0
release
-
true
+
true
latest
diff --git a/app/src/main/docker/Dockerfile.jvm b/app/src/main/docker/Dockerfile.jvm
index fcd9ec4..fcbad5c 100644
--- a/app/src/main/docker/Dockerfile.jvm
+++ b/app/src/main/docker/Dockerfile.jvm
@@ -48,6 +48,12 @@ COPY --chown=1001 target/quarkus-app/*.jar /deployments/
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/temp \
+ && chown -R 1001 /data \
+ && chmod -R "g+rwX" /data
+VOLUME /data/ocl
+
EXPOSE 8080
USER 1001
diff --git a/app/src/main/docker/Dockerfile.native b/app/src/main/docker/Dockerfile.native
index 211c60f..286bd97 100644
--- a/app/src/main/docker/Dockerfile.native
+++ b/app/src/main/docker/Dockerfile.native
@@ -21,6 +21,12 @@ RUN chown 1001 /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
+RUN mkdir -p /data/ocl \
+ && mkdir -p /data/temp \
+ && chown -R 1001 /data \
+ && chmod -R "g+rwX" /data
+VOLUME /data/ocl
+
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 dd9dd26..eefef07 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
@@ -4,6 +4,9 @@
package org.lfenergy.compas.scl.validator.rest;
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.impl.SclRiseClipseValidator;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
@@ -17,4 +20,17 @@ public class CompasSclValidatorConfiguration {
public ElementConverter createElementConverter() {
return new ElementConverter();
}
+
+ @Produces
+ @ApplicationScoped
+ public OclFileCollector createOclFileCollector(ValidatorProperties properties) {
+ return new CompasOclFileCollector(properties.oclCustomDirectory());
+ }
+
+ @Produces
+ @ApplicationScoped
+ public SclRiseClipseValidator createSclRiseClipseValidator(OclFileCollector oclFileCollector,
+ ValidatorProperties properties) {
+ return new SclRiseClipseValidator(oclFileCollector, properties.tempDirectory());
+ }
}
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
new file mode 100644
index 0000000..ae11818
--- /dev/null
+++ b/app/src/main/java/org/lfenergy/compas/scl/validator/rest/ValidatorProperties.java
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: 2021 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest;
+
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithName;
+
+import java.nio.file.Path;
+
+@ConfigMapping(prefix = "compas.validator")
+public interface ValidatorProperties {
+ @WithName("ocl.custom.directory")
+ String oclCustomDirectory();
+
+ @WithName("temp.directory")
+ Path tempDirectory();
+}
diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties
index 0ead43d..d98a2e6 100644
--- a/app/src/main/resources/application.properties
+++ b/app/src/main/resources/application.properties
@@ -2,7 +2,8 @@
#
# SPDX-License-Identifier: Apache-2.0
-compas.userinfo.who.claimname = ${USERINFO_WHO_CLAIMNAME:name}
+compas.validator.ocl.custom.directory = /data/ocl
+compas.validator.temp.directory = /data/temp
quarkus.http.cors = false
quarkus.http.root-path = /compas-scl-validator/
@@ -11,18 +12,11 @@ quarkus.http.limits.max-body-size = 150M
quarkus.log.level = INFO
quarkus.log.category."org.lfenergy.compas.scl.validator".level = INFO
-# Add scanning these dependencies for scanning, also used by native compilation.
-quarkus.index-dependency.scl2007b4.group-id=org.lfenergy.compas.core
-quarkus.index-dependency.scl2007b4.artifact-id=commons
-
-quarkus.index-dependency.jaxb-api.group-id=org.jboss.spec.javax.xml.bind
-quarkus.index-dependency.jaxb-api.artifact-id=jboss-jaxb-api_2.3_spec
-
-# Settings needed for native compilation of the project.
-quarkus.native.resources.includes=ConvergenceLibrary/*.*,*.css
-
# Dev Profile overrides.
-%dev.quarkus.http.port = 9092
+%dev.compas.validator.ocl.custom.directory = ./src/test/data/ocl
+%dev.compas.validator.temp.directory = ./target/data/temp
+
+%dev.quarkus.http.port = 9093
%dev.quarkus.http.cors = true
%dev.quarkus.log.level = DEBUG
diff --git a/app/src/test/data/ocl/Busbar.ocl b/app/src/test/data/ocl/Busbar.ocl
new file mode 100644
index 0000000..f6a2785
--- /dev/null
+++ b/app/src/test/data/ocl/Busbar.ocl
@@ -0,0 +1,40 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+
+/*
+*************************************************************************
+** Copyright (c) 2016-2021 CentraleSupélec & EDF.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v2.0
+** which accompanies this distribution, and is available at
+** https://www.eclipse.org/legal/epl-v20.html
+**
+** This file is part of the RiseClipse tool
+**
+** Contributors:
+** Computer Science Department, CentraleSupélec
+** EDF R&D
+** Contacts:
+** dominique.marcadet@centralesupelec.fr
+** aurelie.dehouck-neveu@edf.fr
+** Web site:
+** https://riseclipse.github.io/
+*************************************************************************
+*/
+
+import scl: 'http://www.iec.ch/61850/2003/SCL'
+
+package scl
+
+context Bay
+-- extends EquipmentContainer
+
+ -- The name attribute is verified in Naming.ocl
+ inv Busbar_nothing
+ :
+ true
+
+
+endpackage
+
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasOclFileCollectorFromJarTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasOclFileCollectorFromJarTest.java
new file mode 100644
index 0000000..5a6c641
--- /dev/null
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasOclFileCollectorFromJarTest.java
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.rest;
+
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.validator.collector.AbstractCompasOclFileCollectorTest;
+import org.lfenergy.compas.scl.validator.collector.CompasOclFileCollector;
+
+/**
+ * This test is added in this project to check if loading the OCL Files from a JAR File is also working.
+ * Loading works in a different way from the module itself and from another module through a JAR File.
+ */
+class CompasOclFileCollectorFromJarTest extends AbstractCompasOclFileCollectorTest {
+ @Test
+ void getDefaultOclFiles_WhenCalledWithoutCustomDirectory_ThenListReturned() {
+ assertValidateOclFileCollector(new CompasOclFileCollector(null), 226);
+ }
+
+ @Test
+ void getDefaultOclFiles_WhenCalledWithCustomDirectory_ThenListReturned() {
+ assertValidateOclFileCollector(new CompasOclFileCollector("./src/test/data/ocl"), 227);
+ }
+}
diff --git a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfigurationTest.java b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfigurationTest.java
index e0c264e..b3932ba 100644
--- a/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfigurationTest.java
+++ b/app/src/test/java/org/lfenergy/compas/scl/validator/rest/CompasSclValidatorConfigurationTest.java
@@ -4,12 +4,45 @@
package org.lfenergy.compas.scl.validator.rest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.lfenergy.compas.scl.validator.collector.OclFileCollector;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.*;
+@ExtendWith(MockitoExtension.class)
class CompasSclValidatorConfigurationTest {
+ @Mock
+ private ValidatorProperties validatorProperties;
+ @Mock
+ private OclFileCollector oclFileCollector;
+
@Test
void createElementConverter_WhenCalled_ThenObjectReturned() {
assertNotNull(new CompasSclValidatorConfiguration().createElementConverter());
}
-}
\ No newline at end of file
+
+ @Test
+ void createOclFileCollector_WhenCalled_ThenObjectReturned() {
+ when(validatorProperties.oclCustomDirectory()).thenReturn("/somedirectory");
+
+ assertNotNull(new CompasSclValidatorConfiguration().createOclFileCollector(validatorProperties));
+
+ verify(validatorProperties, times(1)).oclCustomDirectory();
+ }
+
+ @Test
+ void createSclRiseClipseValidator_WhenCalled_ThenObjectReturned() {
+ when(validatorProperties.tempDirectory()).thenReturn(Path.of("./target/tempdirectory"));
+
+ assertNotNull(new CompasSclValidatorConfiguration().createSclRiseClipseValidator(
+ oclFileCollector,
+ validatorProperties));
+
+ verify(validatorProperties, times(1)).tempDirectory();
+ }
+}
diff --git a/pom.xml b/pom.xml
index 1a2c801..6051fe0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,7 +33,7 @@ SPDX-License-Identifier: Apache-2.0
validator
- validator-riseclipse
+ riseclipse
service
app
@@ -51,6 +51,9 @@ SPDX-License-Identifier: Apache-2.0
github-packages-compas
Github Packages CoMPAS
https://maven.pkg.github.com/com-pas/*
+
+ false
+
@@ -114,6 +117,12 @@ SPDX-License-Identifier: Apache-2.0
${project.version}
test-jar
+
+ org.lfenergy.compas.scl.validator
+ validator-riseclipse
+ ${project.version}
+ test-jar
+
com.openpojo
@@ -139,6 +148,9 @@ SPDX-License-Identifier: Apache-2.0
org.apache.maven.plugins
maven-surefire-plugin
${surefire-plugin.version}
+
+ false
+
diff --git a/riseclipse/pom.xml b/riseclipse/pom.xml
new file mode 100644
index 0000000..1a47cce
--- /dev/null
+++ b/riseclipse/pom.xml
@@ -0,0 +1,116 @@
+
+
+
+ 4.0.0
+
+ org.lfenergy.compas.scl.validator
+ compas-scl-validator
+ local-SNAPSHOT
+
+
+ riseclipse
+ pom
+
+
+ riseclipse-developer
+ riseclipse-main
+ riseclipse-metamodel-scl2003
+ validator-riseclipse
+
+
+
+ 3.16.0
+ 2.25.0
+ 2.23.0
+ 1.17.0
+ 3.2.0
+ 1.1.0-SNAPSHOT
+
+ ${project.basedir}/riseclipse-developer
+
+
+
+
+ local-eclipse-p2-mirror
+
+ file:///${riseclipse.developer.root}/fr.centralesupelec.edf.riseclipse.developer.p2_to_m2/target/maven/repository/final
+
+
+
+
+
+
+
+ fr.centralesupelec.edf.riseclipse
+ fr.centralesupelec.edf.riseclipse.iec61850.scl
+ ${riseclipse.version}
+
+
+
+ org.eclipse.core
+ org.eclipse.core.resources
+ ${eclipse.core.resources.version}
+
+
+
+ org.eclipse.emf
+ org.eclipse.emf.common
+ ${eclipse.emf.common.version}
+
+
+ org.eclipse.emf
+ org.eclipse.emf.ecore
+ ${eclipse.emf.ecore.version}
+
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.pivot
+ ${eclipse.ocl.version}
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.xtext.completeocl
+ ${eclipse.ocl.version}
+
+
+ org.antlr
+ antlr-runtime
+
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.pivot.uml
+
+
+
+ org.eclipse.emf
+ org.eclipse.emf.codegen
+
+
+
+ org.eclipse.platform
+ org.eclipse.equinox.common
+
+
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.xtext.oclstdlib
+ ${eclipse.ocl.version}
+
+
+
+ org.antlr.runtime
+ org.antlr.runtime
+ ${antlr.runtime.version}
+
+
+
+
diff --git a/riseclipse/riseclipse-developer b/riseclipse/riseclipse-developer
new file mode 160000
index 0000000..e889e0c
--- /dev/null
+++ b/riseclipse/riseclipse-developer
@@ -0,0 +1 @@
+Subproject commit e889e0cfc6e245abba13e98ff652b8ebf119a831
diff --git a/riseclipse/riseclipse-main b/riseclipse/riseclipse-main
new file mode 160000
index 0000000..de05dba
--- /dev/null
+++ b/riseclipse/riseclipse-main
@@ -0,0 +1 @@
+Subproject commit de05dba3434591303437d3ec34d88ecdc7a3af09
diff --git a/riseclipse/riseclipse-metamodel-scl2003 b/riseclipse/riseclipse-metamodel-scl2003
new file mode 160000
index 0000000..63e5fe4
--- /dev/null
+++ b/riseclipse/riseclipse-metamodel-scl2003
@@ -0,0 +1 @@
+Subproject commit 63e5fe4526aa1f3834d7ec947094de4451a2f570
diff --git a/riseclipse/riseclipse-ocl-constraints-scl2003 b/riseclipse/riseclipse-ocl-constraints-scl2003
new file mode 160000
index 0000000..484205c
--- /dev/null
+++ b/riseclipse/riseclipse-ocl-constraints-scl2003
@@ -0,0 +1 @@
+Subproject commit 484205cd33bc5b543bfeb215fdf8679effe4641f
diff --git a/riseclipse/validator-riseclipse/pom.xml b/riseclipse/validator-riseclipse/pom.xml
new file mode 100644
index 0000000..6f92e11
--- /dev/null
+++ b/riseclipse/validator-riseclipse/pom.xml
@@ -0,0 +1,122 @@
+
+
+
+ 4.0.0
+
+ org.lfenergy.compas.scl.validator
+ riseclipse
+ local-SNAPSHOT
+
+
+ validator-riseclipse
+ jar
+
+
+ ${project.basedir}/../riseclipse-developer
+
+
+
+
+ org.lfenergy.compas.scl.validator
+ validator
+
+
+
+ fr.centralesupelec.edf.riseclipse
+ fr.centralesupelec.edf.riseclipse.iec61850.scl
+
+
+
+ org.eclipse.core
+ org.eclipse.core.resources
+
+
+
+ org.eclipse.emf
+ org.eclipse.emf.common
+
+
+ org.eclipse.emf
+ org.eclipse.emf.ecore
+
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.pivot
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.xtext.completeocl
+
+
+ org.eclipse.ocl
+ org.eclipse.ocl.xtext.oclstdlib
+
+
+
+ org.antlr.runtime
+ org.antlr.runtime
+
+
+
+
+ org.mockito
+ mockito-junit-jupiter
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+
+
+
+
+ maven-resources-plugin
+ 3.2.0
+
+
+ copy-resources
+
+ validate
+
+ copy-resources
+
+
+ ${project.build.outputDirectory}/ocl
+
+
+
+ ../riseclipse-ocl-constraints-scl2003/fr.centralesupelec.edf.riseclipse.iec61850.scl.ocl
+
+ false
+
+ .project
+
+
+
+
+
+
+
+
+
+ org.jboss.jandex
+ jandex-maven-plugin
+
+
+
+
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/AbstractFileCollector.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/AbstractFileCollector.java
new file mode 100644
index 0000000..57fc4c2
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/AbstractFileCollector.java
@@ -0,0 +1,104 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.collector;
+
+import org.eclipse.emf.common.util.URI;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_CUSTOM_OCL_FILES_FAILED;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_OCL_FILES_FAILED;
+
+/**
+ * Abstract class to support retrieving default files from the ClassPath or from a Directory.
+ */
+public abstract class AbstractFileCollector implements OclFileCollector {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFileCollector.class);
+
+ private static final String DEFAULT_OCL_DIRECTORY = "/ocl/";
+
+ /**
+ * Search for all files (with extension ocl) in the directory 'ocl' on the classpath.
+ *
+ * @return The List of Default OCL Files as URI that Compas uses to validate with RiseClipse.
+ * @throws SclValidatorException Thrown when there is some I/O or URI Syntax Error.
+ */
+ protected List getDefaultOclFilesFromClasspath() {
+ Predicate filter = path -> path.toString().endsWith(".ocl");
+
+ try {
+ LOGGER.debug("Using Thread to search for Resource");
+ var resource = Thread.currentThread().getContextClassLoader().getResource(DEFAULT_OCL_DIRECTORY);
+ if (resource == null) {
+ LOGGER.debug("Using Class to search for Resource");
+ resource = getClass().getResource(DEFAULT_OCL_DIRECTORY);
+ }
+ if (resource != null) {
+ var uri = resource.toURI();
+ LOGGER.debug("Resource '{}' found with schema '{}'.", uri, uri.getScheme());
+ // The directory is in a JAR, search will be different.
+ if (uri.getScheme().equals("jar")) {
+ try (FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
+ var oclDirectoryPath = fileSystem.getPath(DEFAULT_OCL_DIRECTORY);
+ try (var walk = Files.walk(oclDirectoryPath)) {
+ return walk.filter(filter)
+ .map(path -> URI.createURI(path.toUri().toString()))
+ .collect(Collectors.toList());
+ }
+ }
+ } else {
+ var oclDirectoryPath = Paths.get(uri);
+ try (var walk = Files.walk(oclDirectoryPath)) {
+ return walk.filter(filter)
+ .map(Path::toFile)
+ .filter(File::isFile)
+ .map(file -> URI.createFileURI(file.getAbsolutePath()))
+ .collect(Collectors.toList());
+ }
+ }
+ } else {
+ LOGGER.error("No Resource '{}' found!", DEFAULT_OCL_DIRECTORY);
+ }
+ return Collections.emptyList();
+ } catch (URISyntaxException | IOException exp) {
+ throw new SclValidatorException(LOADING_OCL_FILES_FAILED, "Error loading OCL Files", exp);
+ }
+ }
+
+ /**
+ * Search (recursively) for all files in the directory passed. The filter can be used to filter files from the List.
+ *
+ * @param directoryName The directory in which top search for files (recursively).
+ * @param filter The filter used to filter the list of file, use '(path) -> true' to return them all.
+ * @return The list of Files as URI found.
+ */
+ protected List getFilesFromDirectory(String directoryName, Predicate filter) {
+ try {
+ File directory = new File(directoryName);
+ if (directory.exists() && directory.isDirectory()) {
+ var oclDirectoryPath = Paths.get(directory.toURI());
+ try (var walk = Files.walk(oclDirectoryPath)) {
+ return walk.filter(filter)
+ .map(Path::toFile)
+ .filter(File::isFile)
+ .map(file -> URI.createFileURI(file.getAbsolutePath()))
+ .collect(Collectors.toList());
+ }
+ }
+ return Collections.emptyList();
+ } catch (IOException exp) {
+ throw new SclValidatorException(LOADING_CUSTOM_OCL_FILES_FAILED, "Error loading Custom OCL Files", exp);
+ }
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollector.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollector.java
new file mode 100644
index 0000000..947ef71
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollector.java
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.collector;
+
+import org.eclipse.emf.common.util.URI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * OCL File collector which combines the default OCL Files from the Classpath with all files found in a custom
+ * directory configured.
+ */
+public class CompasOclFileCollector extends AbstractFileCollector {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CompasOclFileCollector.class);
+
+ private final String oclCustomDirectory;
+
+ public CompasOclFileCollector(String oclCustomDirectory) {
+ this.oclCustomDirectory = oclCustomDirectory;
+ }
+
+ @Override
+ public List getOclFiles() {
+ LOGGER.debug("Searching for OCL Files in classpath.");
+
+ var oclFiles = new ArrayList<>(getDefaultOclFilesFromClasspath());
+ if (oclCustomDirectory != null) {
+ LOGGER.debug("Searching for OCL Files in custom directory '{}'.", oclCustomDirectory);
+ oclFiles.addAll(getFilesFromDirectory(oclCustomDirectory, path -> path.toString().endsWith(".ocl")));
+ }
+ return oclFiles;
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/OclFileCollector.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/OclFileCollector.java
new file mode 100644
index 0000000..ddb4996
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/collector/OclFileCollector.java
@@ -0,0 +1,15 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.collector;
+
+import org.eclipse.emf.common.util.URI;
+
+import java.util.List;
+
+/**
+ * Interface used to collect OCL Files for use in the SCL Validator.
+ */
+public interface OclFileCollector {
+ List getOclFiles();
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/OclFileLoader.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/OclFileLoader.java
new file mode 100644
index 0000000..320f828
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/OclFileLoader.java
@@ -0,0 +1,108 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import fr.centralesupelec.edf.riseclipse.iec61850.scl.SclPackage;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
+import org.eclipse.ocl.pivot.resource.CSResource;
+import org.eclipse.ocl.pivot.utilities.OCL;
+import org.eclipse.ocl.pivot.validation.ComposedEValidator;
+import org.eclipse.ocl.xtext.completeocl.validation.CompleteOCLEObjectValidator;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.*;
+
+public class OclFileLoader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(OclFileLoader.class);
+
+ private final Path oclTempFile;
+ private final OCL ocl;
+
+ public OclFileLoader(OCL ocl, Path tempDirectoryPath) {
+ this.ocl = ocl;
+
+ // *.ocl Complete OCL documents support required
+ org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup.doSetup();
+ // *.oclstdlib OCL Standard Library support required
+ org.eclipse.ocl.xtext.oclstdlib.OCLstdlibStandaloneSetup.doSetup();
+
+ // First make sure the directory for temporary file exists.
+ var tempDirectory = tempDirectoryPath.toFile();
+ if (!tempDirectory.exists() && !tempDirectory.mkdirs()) {
+ throw new SclValidatorException(CREATE_OCL_TEMP_DIR_FAILED, "Unable to create temporary directory");
+ }
+
+ try {
+ oclTempFile = Files.createTempFile(tempDirectoryPath, "allConstraints", ".ocl");
+ } catch (IOException exp) {
+ throw new SclValidatorException(CREATE_OCL_TEMP_FILES_FAILED, "Unable to create temporary file", exp);
+ }
+ }
+
+ public void addOCLDocument(URI oclUri) {
+ if (oclUri == null) {
+ throw new SclValidatorException(NO_URI_PASSED, "Unable to create URI for temporary file");
+ }
+
+ // We want to check the validity of OCL files
+ // So, we have to do it now, before concatenating it to oclTempFile
+ CSResource oclResource;
+ try {
+ oclResource = ocl.getCSResource(oclUri);
+ if (!oclResource.getErrors().isEmpty()) {
+ logErrorMessage(oclUri, oclResource.getErrors());
+ } else {
+ appendToTempFile(oclUri);
+ }
+ } catch (IOException exp) {
+ LOGGER.error("Unable to read OCL file '{}'", oclUri, exp);
+ }
+ }
+
+ private void appendToTempFile(URI oclUri) {
+ try {
+ BufferedWriter o = Files.newBufferedWriter(oclTempFile, StandardOpenOption.APPEND);
+ o.write("import '" + oclUri + "'\n");
+ o.close();
+ } catch (IOException exp) {
+ throw new SclValidatorException(WRITE_TO_OCL_TEMP_FILES_FAILED, "Unable to write temporary OCL file", exp);
+ }
+ }
+
+ private void logErrorMessage(URI oclUri, List errors) {
+ StringBuilder message = new StringBuilder("Syntax error in '" + oclUri + "':\n");
+ for (Diagnostic error : errors) {
+ message.append("Error: ").append(error.getMessage()).append("\n");
+ }
+ if (LOGGER.isErrorEnabled()) {
+ LOGGER.error(message.toString());
+ }
+ }
+
+ public void prepareValidator(ComposedEValidator validator) {
+ URI uri = URI.createFileURI(oclTempFile.toFile().getAbsolutePath());
+ CompleteOCLEObjectValidator oclValidator = new CompleteOCLEObjectValidator(SclPackage.eINSTANCE, uri);
+ validator.addChild(oclValidator);
+ }
+
+ public void cleanup() {
+ try {
+ if (!Files.deleteIfExists(oclTempFile)) {
+ LOGGER.warn("Unable to remove temporary file '{}'.", oclTempFile);
+ }
+ } catch (IOException exp) {
+ LOGGER.warn("Unable to remove temporary file '{}'.", oclTempFile, exp);
+ }
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclModelLoader.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclModelLoader.java
new file mode 100644
index 0000000..092050c
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclModelLoader.java
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import fr.centralesupelec.edf.riseclipse.iec61850.scl.util.SclResourceFactoryImpl;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.ocl.pivot.utilities.OCL;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.UUID;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_SCL_FILE_ERROR_CODE;
+
+public class SclModelLoader {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SclModelLoader.class);
+
+ private final ResourceSet resourceSet;
+ private final HashMap options;
+
+ public SclModelLoader(OCL ocl) {
+ this.resourceSet = ocl.getResourceSet();
+
+ // Register the appropriate resource factory to handle all file extensions.
+ this.resourceSet.getResourceFactoryRegistry()
+ .getExtensionToFactoryMap()
+ .put(Resource.Factory.Registry.DEFAULT_EXTENSION, new SclResourceFactoryImpl());
+
+ this.options = new HashMap<>();
+ this.options.put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
+ }
+
+ public Resource load(String sclData) {
+ LOGGER.debug("Loading SCL Data in RiseClipse.");
+ try {
+ UUID uuid = UUID.randomUUID();
+ Resource resource = resourceSet.createResource(URI.createURI(uuid.toString()));
+ resource.load(new ByteArrayInputStream(sclData.getBytes(StandardCharsets.UTF_8)), options);
+ return resource;
+ } catch (Exception exp) {
+ throw new SclValidatorException(LOADING_SCL_FILE_ERROR_CODE, "Problem loading SCL Data", exp);
+ }
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidator.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidator.java
new file mode 100644
index 0000000..828945d
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidator.java
@@ -0,0 +1,132 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import fr.centralesupelec.edf.riseclipse.iec61850.scl.SclPackage;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.util.EObjectValidator;
+import org.eclipse.ocl.pivot.utilities.OCL;
+import org.eclipse.ocl.pivot.validation.ComposedEValidator;
+import org.lfenergy.compas.scl.extensions.model.SclFileType;
+import org.lfenergy.compas.scl.validator.SclValidator;
+import org.lfenergy.compas.scl.validator.collector.OclFileCollector;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+import org.lfenergy.compas.scl.validator.model.ValidationError;
+import org.lfenergy.compas.scl.validator.util.OclFileUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.OCL_MODEL_PACKAGE_NOT_FOUND;
+import static org.lfenergy.compas.scl.validator.util.MessageUtil.cleanupMessage;
+
+public class SclRiseClipseValidator implements SclValidator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SclRiseClipseValidator.class);
+
+ private final List oclFiles = new ArrayList<>();
+ private final Path tempDirectory;
+
+ public SclRiseClipseValidator(OclFileCollector oclFileCollector, Path tempDirectory) {
+ this.oclFiles.addAll(oclFileCollector.getOclFiles());
+ this.tempDirectory = tempDirectory;
+
+ // Check if the SclPackage can be initialized.
+ var sclPck = SclPackage.eINSTANCE;
+ if (sclPck == null) {
+ throw new SclValidatorException(OCL_MODEL_PACKAGE_NOT_FOUND, "SCL package not found");
+ }
+ }
+
+ @Override
+ public List validate(SclFileType type, String sclData) {
+ // List with Validation Error Results if there are any.
+ var validationErrors = new ArrayList();
+
+ // Create an EPackage.Registry for the SclPackage.
+ var registry = new EPackageRegistryImpl();
+ registry.put(SclPackage.eNS_URI, SclPackage.eINSTANCE);
+ // Create an OCL that creates a ResourceSet using the minimal EPackage.Registry
+ var ocl = OCL.newInstance(registry);
+
+ OclFileLoader oclFileLoader = new OclFileLoader(ocl, tempDirectory);
+ try {
+ // Load all the OCL Files, adding them to the OCL Instance.
+ LOGGER.info("Loading OCL Files for type '{}'.", type);
+ oclFiles.stream()
+ .filter(uri -> OclFileUtil.includeOnType(uri, type))
+ .forEach(oclFileLoader::addOCLDocument);
+
+ // Create the validator and prepare it with the OCL Files.
+ var validator = ComposedEValidator.install(SclPackage.eINSTANCE);
+ oclFileLoader.prepareValidator(validator);
+
+ // Load the SCL File as Resource ready to be processed.
+ LOGGER.info("Loading SCL Data for type '{}'.", type);
+ var sclLoader = new SclModelLoader(ocl);
+ var resource = sclLoader.load(sclData);
+
+ LOGGER.info("Validating SCL Data for type '{}'.", type);
+ var diagnostician = new CompasDiagnostician();
+ var diagnostic = diagnostician.validate(resource);
+ processDiagnostic(diagnostic, validationErrors);
+ } finally {
+ oclFileLoader.cleanup();
+ }
+
+ return validationErrors;
+ }
+
+ private void processDiagnostic(Diagnostic diagnostic, List validationErrors) {
+ // If there are children in the diagnostic there are validation errors to be processed.
+ for (Diagnostic childDiagnostic : diagnostic.getChildren()) {
+ var validationError = new ValidationError();
+ validationErrors.add(validationError);
+
+ String message = cleanupMessage(childDiagnostic.getMessage());
+ validationError.setMessage(message);
+ LOGGER.debug("SCL Validation Error '{}'", message);
+
+ // Also process the children of the children.
+ processDiagnostic(childDiagnostic, validationErrors);
+ }
+ }
+
+ /**
+ * Simple extension of the Diagnostician to make working with the Resource easier.
+ */
+ private static class CompasDiagnostician extends Diagnostician {
+ /**
+ * Create a basic diagnostic instance from the resource.
+ *
+ * @param resource The Resource to be processed.
+ * @return The Diagnostic to which the results are added.
+ */
+ public BasicDiagnostic createDefaultDiagnostic(Resource resource) {
+ return new BasicDiagnostic(EObjectValidator.DIAGNOSTIC_SOURCE, 0, "", new Object[]{resource});
+ }
+
+ /**
+ * Validate the passed Resource.
+ *
+ * @param resource The Resource to be validated.
+ * @return The Diagnostic containing the results of the validation.
+ */
+ public Diagnostic validate(Resource resource) {
+ BasicDiagnostic diagnostics = createDefaultDiagnostic(resource);
+ for (EObject eObject : resource.getContents()) {
+ super.validate(eObject, diagnostics);
+ }
+ return diagnostics;
+ }
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/MessageUtil.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/MessageUtil.java
new file mode 100644
index 0000000..1206669
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/MessageUtil.java
@@ -0,0 +1,19 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+public class MessageUtil {
+ MessageUtil() {
+ throw new UnsupportedOperationException("MessageUtil class");
+ }
+
+ public static String cleanupMessage(String message) {
+ String cleanedMessage = message;
+ if (cleanedMessage != null
+ && cleanedMessage.toUpperCase().startsWith("ERROR:")) {
+ cleanedMessage = cleanedMessage.substring(6);
+ }
+ return cleanedMessage;
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/OclFileUtil.java b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/OclFileUtil.java
new file mode 100644
index 0000000..e2f56f9
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/util/OclFileUtil.java
@@ -0,0 +1,34 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+import org.eclipse.emf.common.util.URI;
+import org.lfenergy.compas.scl.extensions.model.SclFileType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.io.File.separator;
+
+public class OclFileUtil {
+ private static final Logger LOGGER = LoggerFactory.getLogger(OclFileUtil.class);
+
+ private static final String FILE_SPECIFICS_DIR_NAME = "FileSpecifics";
+ private static final String COMMON_DIR_NAME = "Common";
+
+ OclFileUtil() {
+ throw new UnsupportedOperationException("OclFileUtil class");
+ }
+
+ public static boolean includeOnType(URI uri, SclFileType type) {
+ var fullPath = uri.path();
+ // OCL Files that are not in the directory 'FileSpecifics' will always be included.
+ // In the directory 'FileSpecifics' only the OCL Files that are in the directory 'Common' and
+ // from the directory for the requested SCL File, for instance 'CID', will be included.
+ var include = fullPath.contains(separator + FILE_SPECIFICS_DIR_NAME + separator + type + separator)
+ || fullPath.contains(separator + FILE_SPECIFICS_DIR_NAME + separator + COMMON_DIR_NAME + separator)
+ || !fullPath.contains(separator + FILE_SPECIFICS_DIR_NAME + separator);
+ LOGGER.debug("Full Path '{}' will be included: {}", fullPath, include);
+ return include;
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/data/ocl/Busbar.ocl b/riseclipse/validator-riseclipse/src/test/data/ocl/Busbar.ocl
new file mode 100644
index 0000000..fe27d68
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/data/ocl/Busbar.ocl
@@ -0,0 +1,42 @@
+/*
+ SPDX-FileCopyrightText: 2022 Alliander N.V.
+
+ SPDX-License-Identifier: Apache-2.0
+*/
+
+/*
+*************************************************************************
+** Copyright (c) 2016-2021 CentraleSupélec & EDF.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v2.0
+** which accompanies this distribution, and is available at
+** https://www.eclipse.org/legal/epl-v20.html
+**
+** This file is part of the RiseClipse tool
+**
+** Contributors:
+** Computer Science Department, CentraleSupélec
+** EDF R&D
+** Contacts:
+** dominique.marcadet@centralesupelec.fr
+** aurelie.dehouck-neveu@edf.fr
+** Web site:
+** https://riseclipse.github.io/
+*************************************************************************
+*/
+
+import scl: 'http://www.iec.ch/61850/2003/SCL'
+
+package scl
+
+context Bay
+-- extends EquipmentContainer
+
+ -- The name attribute is verified in Naming.ocl
+ inv Busbar_nothing
+ :
+ true
+
+
+endpackage
+
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/AbstractCompasOclFileCollectorTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/AbstractCompasOclFileCollectorTest.java
new file mode 100644
index 0000000..1bc9b3f
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/AbstractCompasOclFileCollectorTest.java
@@ -0,0 +1,16 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.collector;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public abstract class AbstractCompasOclFileCollectorTest {
+ protected void assertValidateOclFileCollector(OclFileCollector collector, int expectedFiles) {
+ var result = collector.getOclFiles();
+
+ assertNotNull(result);
+ assertEquals(expectedFiles, result.size());
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollectorTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollectorTest.java
new file mode 100644
index 0000000..c90d1eb
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/collector/CompasOclFileCollectorTest.java
@@ -0,0 +1,18 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.collector;
+
+import org.junit.jupiter.api.Test;
+
+class CompasOclFileCollectorTest extends AbstractCompasOclFileCollectorTest {
+ @Test
+ void getDefaultOclFiles_WhenCalledWithoutCustomDirectory_ThenListReturned() {
+ assertValidateOclFileCollector(new CompasOclFileCollector(null), 226);
+ }
+
+ @Test
+ void getDefaultOclFiles_WhenCalledWithCustomDirectory_ThenListReturned() {
+ assertValidateOclFileCollector(new CompasOclFileCollector("./src/test/data/ocl"), 227);
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/OclFileLoaderTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/OclFileLoaderTest.java
new file mode 100644
index 0000000..597618d
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/OclFileLoaderTest.java
@@ -0,0 +1,89 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.ocl.pivot.validation.ComposedEValidator;
+import org.eclipse.ocl.xtext.completeocl.validation.CompleteOCLEObjectValidator;
+import org.junit.jupiter.api.AfterEach;
+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.exception.SclValidatorException;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.NO_URI_PASSED;
+import static org.lfenergy.compas.scl.validator.util.TestSupportUtil.createSclOcl;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class OclFileLoaderTest {
+ private OclFileLoader loader;
+ private Path tempFile;
+
+ @BeforeEach
+ void setup() throws IOException {
+ var tempDirectory = "./target/data/temp";
+ var tempDirectoryPath = Path.of(tempDirectory);
+ loader = new OclFileLoader(createSclOcl(), tempDirectoryPath);
+ tempFile = Files.walk(tempDirectoryPath)
+ .filter(path -> path.toString().contains(File.separator + "allConstraints"))
+ .findFirst()
+ .orElseThrow();
+ }
+
+ @Test
+ void addOCLDocument_WhenCalledWithNull_ThenExceptionThrown() {
+ var exception = assertThrows(SclValidatorException.class,
+ () -> loader.addOCLDocument(null));
+
+ assertEquals(NO_URI_PASSED, exception.getErrorCode());
+ }
+
+ @Test
+ void addOCLDocument_WhenCalledWithValidOcl_ThenOclFileIsAddedToTempFile() throws IOException {
+ var oclFile = findOCL("example.ocl");
+
+ loader.addOCLDocument(oclFile);
+
+ assertEquals(1, Files.lines(tempFile).count());
+ }
+
+ @Test
+ void addOCLDocument_WhenCalledWithInvalidOcl_ThenOclFileIsNotAddedToTempFile() throws IOException {
+ var oclFile = findOCL("invalid.ocl");
+
+ loader.addOCLDocument(oclFile);
+
+ assertEquals(0, Files.lines(tempFile).count());
+ }
+
+ @Test
+ void prepareValidator_whenCalledWithValidator_ThenValidatorIsAdded() {
+ var validator = mock(ComposedEValidator.class);
+ loader.prepareValidator(validator);
+
+ verify(validator, times(1)).addChild(any(CompleteOCLEObjectValidator.class));
+ }
+
+ @AfterEach
+ void cleanup() {
+ loader.cleanup();
+ }
+
+ private URI findOCL(String filename) {
+ var url = getClass().getResource("/ocl-testfiles/" + filename);
+ if (url != null) {
+ return URI.createFileURI(url.getPath());
+ }
+ throw new NullPointerException("File /ocl/" + filename + " not found!");
+ }
+}
\ No newline at end of file
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclModelLoaderTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclModelLoaderTest.java
new file mode 100644
index 0000000..61e81e1
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclModelLoaderTest.java
@@ -0,0 +1,43 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.validator.exception.SclValidatorException;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.lfenergy.compas.scl.validator.exception.SclValidatorErrorCode.LOADING_SCL_FILE_ERROR_CODE;
+import static org.lfenergy.compas.scl.validator.util.TestSupportUtil.createSclOcl;
+import static org.lfenergy.compas.scl.validator.util.TestSupportUtil.readSCL;
+
+class SclModelLoaderTest {
+ private SclModelLoader loader;
+
+ @BeforeEach
+ void setup() {
+ loader = new SclModelLoader(createSclOcl());
+ }
+
+ @Test
+ void load_WhenCalledWithValidSCXML_ThenResourceLoaded() throws IOException {
+ var sclData = readSCL("example.scd");
+
+ var result = loader.load(sclData);
+
+ assertNotNull(result);
+ }
+
+ @Test
+ void load_WhenCalledWithInvalidSCXML_ThenExceptionThrown() throws IOException {
+ var sclData = readSCL("invalid.scd");
+
+ var exception = assertThrows(SclValidatorException.class,
+ () -> loader.load(sclData));
+
+ assertEquals(LOADING_SCL_FILE_ERROR_CODE, exception.getErrorCode());
+ }
+}
\ No newline at end of file
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidatorTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidatorTest.java
new file mode 100644
index 0000000..3b35e5b
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseClipseValidatorTest.java
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.impl;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.extensions.model.SclFileType;
+import org.lfenergy.compas.scl.validator.collector.CompasOclFileCollector;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.lfenergy.compas.scl.validator.util.TestSupportUtil.readSCL;
+
+class SclRiseClipseValidatorTest {
+ private SclRiseClipseValidator sclValidator;
+
+ @BeforeEach
+ public void setup() {
+ var oclFileCollector = new CompasOclFileCollector(null);
+ this.sclValidator = new SclRiseClipseValidator(oclFileCollector, Path.of("./target/data/temp"));
+ }
+
+ @Test
+ void validate_WhenCalled_ThenEmptyListReturned() throws IOException {
+ var type = SclFileType.CID;
+ var sclData = readSCL("example.scd");
+
+ var result = sclValidator.validate(type, sclData);
+
+ assertNotNull(result);
+ assertEquals(15, result.size());
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/MessageUtilTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/MessageUtilTest.java
new file mode 100644
index 0000000..d39b0cc
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/MessageUtilTest.java
@@ -0,0 +1,41 @@
+// 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 static org.junit.jupiter.api.Assertions.*;
+import static org.lfenergy.compas.scl.validator.util.MessageUtil.cleanupMessage;
+
+class MessageUtilTest {
+ @Test
+ void constructor_WhenConstructorCalled_ThenShouldThrowExceptionCauseForbidden() {
+ assertThrows(UnsupportedOperationException.class, MessageUtil::new);
+ }
+
+ @Test
+ void cleanupMessage_WhenCalledWithNullMessage_ThenNullIsReturned() {
+ var result = cleanupMessage(null);
+
+ assertNull(result);
+ }
+
+ @Test
+ void cleanupMessage_WhenCalledWithAlreadyCleanMessage_ThenSameMessageIsReturned() {
+ var expectedMessage = "Some validation message";
+
+ var result = cleanupMessage(expectedMessage);
+
+ assertEquals(expectedMessage, result);
+ }
+
+ @Test
+ void cleanupMessage_WhenCalledWithMessageThatStartWithError_ThenCleanedMessageIsReturned() {
+ var expectedMessage = "Some validation message";
+
+ var result = cleanupMessage("ERROR:" + expectedMessage);
+
+ assertEquals(expectedMessage, result);
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/OclFileUtilTest.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/OclFileUtilTest.java
new file mode 100644
index 0000000..b883c54
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/OclFileUtilTest.java
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+import org.eclipse.emf.common.util.URI;
+import org.junit.jupiter.api.Test;
+import org.lfenergy.compas.scl.extensions.model.SclFileType;
+import org.lfenergy.compas.scl.validator.collector.CompasOclFileCollector;
+import org.lfenergy.compas.scl.validator.collector.OclFileCollector;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class OclFileUtilTest {
+ private OclFileCollector collector = new CompasOclFileCollector(null);
+
+ @Test
+ void constructor_WhenConstructorCalled_ThenShouldThrowExceptionCauseForbidden() {
+ assertThrows(UnsupportedOperationException.class, OclFileUtil::new);
+ }
+
+ @Test
+ void includeOnType_WhenCalledWithExpectedSclFileTypeUri_ThenReturnTrue() {
+ assertTrue(executeTest("/ocl/FileSpecifics/CID/ExtRef.ocl"));
+ }
+
+ @Test
+ void includeOnType_WhenCalledWithUnexpectedSclFileTypeUri_ThenReturnFalse() {
+ assertFalse(executeTest("/ocl/FileSpecifics/ICD/DOType.ocl"));
+ }
+
+ @Test
+ void includeOnType_WhenCalledWithCommonUri_ThenReturnTrue() {
+ assertTrue(executeTest("/ocl/FileSpecifics/Common/ReportControl.ocl"));
+ }
+
+ @Test
+ void includeOnType_WhenCalledWithNoFileSpecificUri_ThenReturnTrue() {
+ assertTrue(executeTest("/ocl/SemanticConstraints/Server.ocl"));
+ }
+
+ private boolean executeTest(String oclFileName) {
+ var uri = getResource(oclFileName);
+ return OclFileUtil.includeOnType(uri, SclFileType.CID);
+ }
+
+ private URI getResource(String oclFileName) {
+ return collector.getOclFiles()
+ .stream()
+ .filter(uri -> uri.toFileString().endsWith(oclFileName))
+ .findFirst()
+ .orElseThrow();
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
new file mode 100644
index 0000000..142f2a9
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/util/TestSupportUtil.java
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: 2022 Alliander N.V.
+//
+// SPDX-License-Identifier: Apache-2.0
+package org.lfenergy.compas.scl.validator.util;
+
+import fr.centralesupelec.edf.riseclipse.iec61850.scl.SclPackage;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+import org.eclipse.ocl.pivot.utilities.OCL;
+
+import java.io.IOException;
+
+public final class TestSupportUtil {
+ TestSupportUtil() {
+ throw new UnsupportedOperationException("FileTestUtil class");
+ }
+
+ public static String readSCL(String filename) throws IOException {
+ var inputStream = TestSupportUtil.class.getResourceAsStream("/scl/" + filename);
+ assert inputStream != null;
+
+ return new String(inputStream.readAllBytes());
+ }
+
+ public static OCL createSclOcl() {
+ // Create an EPackage.Registry for the SclPackage.
+ var registry = new EPackageRegistryImpl();
+ registry.put(SclPackage.eNS_URI, SclPackage.eINSTANCE);
+ // Create an OCL that creates a ResourceSet using the minimal EPackage.Registry
+ return OCL.newInstance(registry);
+ }
+}
diff --git a/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/example.ocl b/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/example.ocl
new file mode 100644
index 0000000..fe27d68
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/example.ocl
@@ -0,0 +1,42 @@
+/*
+ SPDX-FileCopyrightText: 2022 Alliander N.V.
+
+ SPDX-License-Identifier: Apache-2.0
+*/
+
+/*
+*************************************************************************
+** Copyright (c) 2016-2021 CentraleSupélec & EDF.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v2.0
+** which accompanies this distribution, and is available at
+** https://www.eclipse.org/legal/epl-v20.html
+**
+** This file is part of the RiseClipse tool
+**
+** Contributors:
+** Computer Science Department, CentraleSupélec
+** EDF R&D
+** Contacts:
+** dominique.marcadet@centralesupelec.fr
+** aurelie.dehouck-neveu@edf.fr
+** Web site:
+** https://riseclipse.github.io/
+*************************************************************************
+*/
+
+import scl: 'http://www.iec.ch/61850/2003/SCL'
+
+package scl
+
+context Bay
+-- extends EquipmentContainer
+
+ -- The name attribute is verified in Naming.ocl
+ inv Busbar_nothing
+ :
+ true
+
+
+endpackage
+
diff --git a/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/invalid.ocl b/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/invalid.ocl
new file mode 100644
index 0000000..33288ab
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/resources/ocl-testfiles/invalid.ocl
@@ -0,0 +1,42 @@
+/*
+ SPDX-FileCopyrightText: 2022 Alliander N.V.
+
+ SPDX-License-Identifier: Apache-2.0
+*/
+
+/*
+*************************************************************************
+** Copyright (c) 2016-2021 CentraleSupélec & EDF.
+** All rights reserved. This program and the accompanying materials
+** are made available under the terms of the Eclipse Public License v2.0
+** which accompanies this distribution, and is available at
+** https://www.eclipse.org/legal/epl-v20.html
+**
+** This file is part of the RiseClipse tool
+**
+** Contributors:
+** Computer Science Department, CentraleSupélec
+** EDF R&D
+** Contacts:
+** dominique.marcadet@centralesupelec.fr
+** aurelie.dehouck-neveu@edf.fr
+** Web site:
+** https://riseclipse.github.io/
+*************************************************************************
+*/
+
+import scl: 'http://www.iec.ch/61850/2003/SCL'
+
+package scl
+
+context Bay
+-- extends EquipmentContainer
+
+ -- The name attribute is verified in Naming.ocl
+ inv Busbar_nothing
+ :
+ true
+
+
+endpackage_invalid
+
diff --git a/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd b/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd
new file mode 100644
index 0000000..4dc2b38
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/resources/scl/example.scd
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IEC 61850-7-3:2007B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IEC 61850-8-1:2003
+
+
+
+
+ IEC 61850-8-1:2003
+
+
+
+
+ IEC 61850-8-1:2003
+
+
+ Completed
+ Cancelled
+ New adjustments
+ AnotherValue
+
+
+ Va
+ Vb
+ Vc
+ Aa
+ Ab
+ Ac
+ Vab
+ Vbc
+ Vca
+ AnotherValue
+
+
+
\ No newline at end of file
diff --git a/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd b/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd
new file mode 100644
index 0000000..61fba55
--- /dev/null
+++ b/riseclipse/validator-riseclipse/src/test/resources/scl/invalid.scd
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/validator-riseclipse/pom.xml b/validator-riseclipse/pom.xml
deleted file mode 100644
index e9a91ae..0000000
--- a/validator-riseclipse/pom.xml
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
- 4.0.0
-
- org.lfenergy.compas.scl.validator
- compas-scl-validator
- local-SNAPSHOT
-
-
- validator-riseclipse
- jar
-
-
-
- org.lfenergy.compas.scl.validator
- validator
-
-
-
-
- org.mockito
- mockito-junit-jupiter
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- test
-
-
- org.slf4j
- slf4j-simple
- test
-
-
-
-
-
-
- org.jboss.jandex
- jandex-maven-plugin
-
-
-
-
diff --git a/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidator.java b/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidator.java
deleted file mode 100644
index 7b2d10b..0000000
--- a/validator-riseclipse/src/main/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidator.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Alliander N.V.
-//
-// SPDX-License-Identifier: Apache-2.0
-package org.lfenergy.compas.scl.validator.impl;
-
-import org.lfenergy.compas.scl.extensions.model.SclFileType;
-import org.lfenergy.compas.scl.validator.SclValidator;
-import org.lfenergy.compas.scl.validator.model.ValidationError;
-
-import javax.enterprise.context.ApplicationScoped;
-import java.util.Collections;
-import java.util.List;
-
-@ApplicationScoped
-public class SclRiseclipseValidator implements SclValidator {
- @Override
- public List validate(SclFileType type, String sclData) {
- return Collections.emptyList();
- }
-}
diff --git a/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidatorTest.java b/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidatorTest.java
deleted file mode 100644
index 674ed68..0000000
--- a/validator-riseclipse/src/test/java/org/lfenergy/compas/scl/validator/impl/SclRiseclipseValidatorTest.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-FileCopyrightText: 2022 Alliander N.V.
-//
-// SPDX-License-Identifier: Apache-2.0
-package org.lfenergy.compas.scl.validator.impl;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.lfenergy.compas.scl.extensions.model.SclFileType;
-import org.mockito.junit.jupiter.MockitoExtension;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-@ExtendWith(MockitoExtension.class)
-class SclRiseclipseValidatorTest {
- private SclRiseclipseValidator sclValidator = new SclRiseclipseValidator();
-
- @Test
- void validate_WhenCalled_ThenEmptyListReturned() {
- var type = SclFileType.CID;
- var sclData = "Some String";
-
- var result = sclValidator.validate(type, sclData);
-
- assertNotNull(result);
- assertEquals(0, result.size());
- }
-}
\ No newline at end of file
diff --git a/validator/pom.xml b/validator/pom.xml
index ad222e3..157a8c7 100644
--- a/validator/pom.xml
+++ b/validator/pom.xml
@@ -27,11 +27,6 @@ SPDX-License-Identifier: Apache-2.0
scl-extension
-
- jakarta.enterprise
- jakarta.enterprise.cdi-api
-
-
org.eclipse.microprofile.openapi
microprofile-openapi-api
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 c7b0532..249706b 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
@@ -9,4 +9,14 @@ public class SclValidatorErrorCode {
}
public static final String NO_SCL_ELEMENT_FOUND_ERROR_CODE = "SVS-0001";
+ public static final String LOADING_SCL_FILE_ERROR_CODE = "SVS-0002";
+
+ public static final String LOADING_OCL_FILES_FAILED = "SVS-1001";
+ public static final String LOADING_CUSTOM_OCL_FILES_FAILED = "SVS-1002";
+
+ public static final String CREATE_OCL_TEMP_FILES_FAILED = "SVS-2001";
+ public static final String CREATE_OCL_TEMP_DIR_FAILED = "SVS-2002";
+ 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";
}
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorException.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorException.java
index 51c9a26..49a31d8 100644
--- a/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorException.java
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/exception/SclValidatorException.java
@@ -9,4 +9,8 @@ public class SclValidatorException extends CompasException {
public SclValidatorException(String errorCode, String message) {
super(errorCode, message);
}
+
+ public SclValidatorException(String errorCode, String msg, Throwable throwable) {
+ super(errorCode, msg, throwable);
+ }
}
diff --git a/validator/src/main/java/org/lfenergy/compas/scl/validator/model/ValidationError.java b/validator/src/main/java/org/lfenergy/compas/scl/validator/model/ValidationError.java
index e42a449..c7aac63 100644
--- a/validator/src/main/java/org/lfenergy/compas/scl/validator/model/ValidationError.java
+++ b/validator/src/main/java/org/lfenergy/compas/scl/validator/model/ValidationError.java
@@ -3,17 +3,23 @@
// SPDX-License-Identifier: Apache-2.0
package org.lfenergy.compas.scl.validator.model;
-public class ValidationError {
- private String code;
- private String message;
+import org.eclipse.microprofile.openapi.annotations.media.Schema;
- public String getCode() {
- return code;
- }
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
- public void setCode(String code) {
- this.code = code;
- }
+import static org.lfenergy.compas.scl.validator.SclValidatorConstants.SCL_VALIDATOR_SERVICE_V1_NS_URI;
+
+@Schema(description = "Single validation error containing the message.")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ValidationError {
+ @Schema(description = "The message of the validation error that occurred.",
+ example = "ERROR:[SemanticConstraints] Terminal (name=T1) (line 27) does not refer an existing ConnectivityNode")
+ @XmlElement(name = "Message",
+ namespace = SCL_VALIDATOR_SERVICE_V1_NS_URI,
+ required = true)
+ private String message;
public String getMessage() {
return message;
diff --git a/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/SclValidatorExceptionTest.java b/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/SclValidatorExceptionTest.java
index 79bf10a..6ebbbd1 100644
--- a/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/SclValidatorExceptionTest.java
+++ b/validator/src/test/java/org/lfenergy/compas/scl/validator/exception/SclValidatorExceptionTest.java
@@ -15,4 +15,15 @@ void constructor_WhenCalledWithOnlyMessage_ThenMessageCanBeRetrieved() {
Assertions.assertEquals(SclValidatorErrorCode.NO_SCL_ELEMENT_FOUND_ERROR_CODE, exception.getErrorCode());
Assertions.assertEquals(expectedMessage, exception.getMessage());
}
+
+ @Test
+ void constructor_WhenCalledWithMessageAndExceptionm_ThenMessageAndExceptionCanBeRetrieved() {
+ var expectedMessage = "The message";
+ var expectedException = new RuntimeException();
+ var exception = new SclValidatorException(SclValidatorErrorCode.NO_SCL_ELEMENT_FOUND_ERROR_CODE, expectedMessage, expectedException);
+
+ Assertions.assertEquals(SclValidatorErrorCode.NO_SCL_ELEMENT_FOUND_ERROR_CODE, exception.getErrorCode());
+ Assertions.assertEquals(expectedMessage, exception.getMessage());
+ Assertions.assertEquals(expectedException, exception.getCause());
+ }
}
\ No newline at end of file