Skip to content

Commit 2becc0b

Browse files
author
Rob Tjalma
authored
Merge pull request #47 from com-pas/validation-exception-handling
Add validation constraint and common exception handling.
2 parents e1cc0b4 + 80418d5 commit 2becc0b

46 files changed

Lines changed: 809 additions & 69 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

commons/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ SPDX-License-Identifier: Apache-2.0
1818
<packaging>jar</packaging>
1919

2020
<dependencies>
21+
<dependency>
22+
<groupId>jakarta.validation</groupId>
23+
<artifactId>jakarta.validation-api</artifactId>
24+
</dependency>
25+
2126
<dependency>
2227
<groupId>jakarta.xml.bind</groupId>
2328
<artifactId>jakarta.xml.bind-api</artifactId>
@@ -57,5 +62,15 @@ SPDX-License-Identifier: Apache-2.0
5762
<artifactId>slf4j-simple</artifactId>
5863
<scope>test</scope>
5964
</dependency>
65+
<dependency>
66+
<groupId>org.hibernate.validator</groupId>
67+
<artifactId>hibernate-validator</artifactId>
68+
<scope>test</scope>
69+
</dependency>
70+
<dependency>
71+
<groupId>org.glassfish</groupId>
72+
<artifactId>jakarta.el</artifactId>
73+
<scope>test</scope>
74+
</dependency>
6075
</dependencies>
6176
</project>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-FileCopyrightText: 2021 Alliander N.V.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
package org.lfenergy.compas.core.commons.constraint;
5+
6+
import org.lfenergy.compas.core.commons.constraint.impl.XmlAnyElementConstraintValidator;
7+
8+
import javax.validation.Constraint;
9+
import javax.validation.Payload;
10+
import java.lang.annotation.Documented;
11+
import java.lang.annotation.Retention;
12+
import java.lang.annotation.Target;
13+
14+
import static java.lang.annotation.ElementType.*;
15+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
16+
17+
/**
18+
* Annotation to check if a List of XML Elements (mostly annotated with XmlAnyElement) contains a specific number
19+
* of elements and also the expected Element (Name) with the correct namespace.
20+
*/
21+
@Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE, TYPE_USE})
22+
@Retention(RUNTIME)
23+
@Constraint(validatedBy = {XmlAnyElementConstraintValidator.class})
24+
@Documented
25+
public @interface XmlAnyElementValid {
26+
String message() default "{org.lfenergy.compas.XmlAnyElementValid.unexpected.message}";
27+
28+
Class<?>[] groups() default {};
29+
30+
Class<? extends Payload>[] payload() default {};
31+
32+
String elementName();
33+
34+
String elementNamespace();
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-FileCopyrightText: 2021 Alliander N.V.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
package org.lfenergy.compas.core.commons.constraint.impl;
5+
6+
import org.lfenergy.compas.core.commons.constraint.XmlAnyElementValid;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.w3c.dom.Element;
10+
11+
import javax.validation.ConstraintValidator;
12+
import javax.validation.ConstraintValidatorContext;
13+
import java.util.List;
14+
15+
/**
16+
* Validator to execute the check on fields annotated with {@link XmlAnyElementValid} to check if the number of
17+
* element are correct and also if the element(s) in the list have the correct Local Name and the correct Namespace.
18+
*/
19+
public class XmlAnyElementConstraintValidator implements ConstraintValidator<XmlAnyElementValid, List<Element>> {
20+
private static final Logger LOGGER = LoggerFactory.getLogger(XmlAnyElementConstraintValidator.class);
21+
22+
private String elementName;
23+
private String elementNamespace;
24+
25+
@Override
26+
public void initialize(XmlAnyElementValid constraintAnnotation) {
27+
LOGGER.debug("Initializing XmlAnyElementValid constraint for List of Elements");
28+
this.elementName = constraintAnnotation.elementName();
29+
this.elementNamespace = constraintAnnotation.elementNamespace();
30+
}
31+
32+
@Override
33+
public boolean isValid(List<Element> elements, ConstraintValidatorContext context) {
34+
// Check if there are elements in the List that don't match the name or namespace.
35+
var numberOfIncorrectElements =
36+
elements.stream()
37+
.filter(element ->
38+
!elementName.equals(element.getLocalName())
39+
|| !elementNamespace.equals(element.getNamespaceURI()))
40+
.count();
41+
return numberOfIncorrectElements == 0;
42+
}
43+
}

commons/src/main/java/org/lfenergy/compas/core/commons/exception/CompasErrorCode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ public class CompasErrorCode {
1919

2020
public static final String CONVERT_TO_STRING_ERROR = "CORE-1000";
2121
public static final String CONVERT_TO_ELEMENT_ERROR = "CORE-1001";
22+
23+
public static final String VALIDATION_ERROR = "CORE-8000";
24+
25+
public static final String UNKNOWN_EXCEPTION_ERROR = "CORE-9999";
2226
}

commons/src/main/java/org/lfenergy/compas/core/commons/exception/CompasValidationException.java

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// SPDX-FileCopyrightText: 2021 Alliander N.V.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
package org.lfenergy.compas.core.commons.constraint.impl;
5+
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.Test;
8+
import org.lfenergy.compas.core.commons.constraint.XmlAnyElementValid;
9+
import org.w3c.dom.Document;
10+
import org.w3c.dom.Element;
11+
12+
import javax.validation.Validation;
13+
import javax.validation.Validator;
14+
import javax.xml.parsers.DocumentBuilderFactory;
15+
import javax.xml.parsers.ParserConfigurationException;
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertTrue;
21+
22+
class XmlAnyElementConstraintValidatorTest {
23+
private static final String ELEMENT_NAME = "valid";
24+
private static final String ELEMENT_NS = "https://valid.org";
25+
26+
private Document document;
27+
private Validator validator;
28+
29+
@BeforeEach
30+
void setupValidator() throws ParserConfigurationException {
31+
var documentFactory = DocumentBuilderFactory.newInstance();
32+
var documentBuilder = documentFactory.newDocumentBuilder();
33+
document = documentBuilder.newDocument();
34+
35+
var factory = Validation.buildDefaultValidatorFactory();
36+
validator = factory.getValidator();
37+
}
38+
39+
@Test
40+
void isValid_WhenCalledWithCorrectElement_ThenNoViolations() {
41+
var simplePojo = new SimplePojo();
42+
simplePojo.getElements().add(document.createElementNS(ELEMENT_NS, ELEMENT_NAME));
43+
44+
var violations = validator.validate(simplePojo);
45+
assertTrue(violations.isEmpty());
46+
}
47+
48+
@Test
49+
void isValid_WhenCalledWithIncorrectElement_ThenViolationFound() {
50+
var simplePojo = new SimplePojo();
51+
simplePojo.getElements().add(document.createElementNS("https://OtherNS.org", "Other"));
52+
53+
var violations = validator.validate(simplePojo);
54+
assertEquals(1, violations.size());
55+
}
56+
57+
@Test
58+
void isValid_WhenCalledWithMultipleElementAndOneIncorrect_ThenViolationFound() {
59+
var simplePojo = new SimplePojo();
60+
simplePojo.getElements().add(document.createElementNS("https://OtherNS.org", "Other"));
61+
simplePojo.getElements().add(document.createElementNS(ELEMENT_NS, ELEMENT_NAME));
62+
simplePojo.getElements().add(document.createElementNS(ELEMENT_NS, ELEMENT_NAME));
63+
64+
var violations = validator.validate(simplePojo);
65+
assertEquals(1, violations.size());
66+
}
67+
68+
@Test
69+
void isValid_WhenCalledWithMultipleElementAndOneIncorrectNS_ThenViolationFound() {
70+
var simplePojo = new SimplePojo();
71+
simplePojo.getElements().add(document.createElementNS("https://OtherNS.org", ELEMENT_NAME));
72+
simplePojo.getElements().add(document.createElementNS(ELEMENT_NS, ELEMENT_NAME));
73+
simplePojo.getElements().add(document.createElementNS(ELEMENT_NS, ELEMENT_NAME));
74+
75+
var violations = validator.validate(simplePojo);
76+
assertEquals(1, violations.size());
77+
}
78+
79+
private static final class SimplePojo {
80+
@XmlAnyElementValid(elementName = ELEMENT_NAME, elementNamespace = ELEMENT_NS)
81+
private List<Element> elements = new ArrayList<>();
82+
83+
public List<Element> getElements() {
84+
return elements;
85+
}
86+
}
87+
}

commons/src/test/java/org/lfenergy/compas/core/commons/exception/CompasValidationExceptionTest.java

Lines changed: 0 additions & 31 deletions
This file was deleted.

commons/src/test/resources/invalid-configs/marshaller-invalid-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ compas:
88
scl:
99
schemas:
1010
- xsdPath: "xsd/xml-element.xsd"
11-
namespace: "https://www.lfenergy.org/compas/v1"
11+
namespace: "https://www.lfenergy.org/compas/extension/v1"

commons/src/test/resources/invalid-configs/marshaller-invalid-contextpath-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ compas:
88
scl:
99
schemas:
1010
- xsdPath: "xsd/xml-element.xsd"
11-
namespace: "https://www.lfenergy.org/compas/v1"
11+
namespace: "https://www.lfenergy.org/compas/extension/v1"
1212
contextPath: "org.lfenergy.compas.scl.extensions.model.unknown"

commons/src/test/resources/invalid-configs/marshaller-invalid-xsdpath-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ compas:
88
scl:
99
schemas:
1010
- xsdPath: "invalid/xml-element.xsd"
11-
namespace: "https://www.lfenergy.org/compas/v1"
11+
namespace: "https://www.lfenergy.org/compas/extension/v1"
1212
contextPath: "org.lfenergy.compas.scl.extensions.model"

0 commit comments

Comments
 (0)