From f264d0d7647fe7ac4b17dfbbc5704cb9578b7eb7 Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Sun, 31 May 2026 10:50:39 +0200 Subject: [PATCH 1/3] Fix item type validation test and Java 21 deprecations Generate the expected invalid item type message from the current thing description schema instead of hard-coding the full item type enumeration. This keeps the test stable when new item types are added to the XSD. Also replace deprecated Java 21 API usage for Locale and URL creation. Signed-off-by: Wouter Born --- .../test/OhInfXmlValidationCheckTest.java | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java index 80c44d2d..8c725b0f 100644 --- a/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java +++ b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java @@ -15,14 +15,23 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.openhab.tools.analysis.checkstyle.api.CheckConstants.OH_INF_PATH; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.URI; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -30,6 +39,8 @@ import org.openhab.tools.analysis.checkstyle.OhInfXmlValidationCheck; import org.openhab.tools.analysis.checkstyle.api.AbstractStaticCheckTest; import org.openhab.tools.analysis.utils.CachingHttpClient; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; import com.puppycrawl.tools.checkstyle.DefaultConfiguration; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; @@ -81,16 +92,45 @@ protected String getPackageLocation() { } private boolean isResourceAvailable; + private String thingSchema; + + private static Document parseXml(String xml) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + + try (InputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { + return factory.newDocumentBuilder().parse(inputStream); + } + } + + private static String generateInvalidItemTypeMessage(String invalidValue, String schema) throws Exception { + Document document = parseXml(schema); + XPath xpath = XPathFactory.newInstance().newXPath(); + + NodeList values = (NodeList) xpath.evaluate( + "//*[local-name()='simpleType'][@name='itemTypeName']" + "//*[local-name()='enumeration']/@value", + document, XPathConstants.NODESET); + + List itemTypes = new ArrayList<>(); + for (int i = 0; i < values.getLength(); i++) { + itemTypes.add(values.item(i).getNodeValue()); + } + + return "Value " + invalidValue + " is not facet-valid with respect to enumeration [" + + String.join(", ", itemTypes) + "]. It must be a value from the enumeration."; + } @BeforeEach @SuppressWarnings("PMD.SetDefaultLocale") public void checkConnection() { - Locale.setDefault(new Locale("en", "US")); + Locale.setDefault(Locale.US); try { - URL url = new URL(THING_SCHEMA_URL); + URL url = URI.create(THING_SCHEMA_URL).toURL(); CachingHttpClient cachingClient = new CachingHttpClient<>(String::new); - isResourceAvailable = cachingClient.get(url) != null; + thingSchema = cachingClient.get(url); + isResourceAvailable = thingSchema != null; } catch (IOException e) { + thingSchema = null; isResourceAvailable = false; } } @@ -195,17 +235,8 @@ public void testInvalidItemType() throws Exception { int lineNumber = 15; String[] expectedMessages = generateExpectedMessages(lineNumber, - "Value Invalid is not facet-valid with respect to enumeration " - + "[Call, Color, Contact, DateTime, Dimmer, Group, Image, Location, Number, Number:Acceleration, Number:AmountOfSubstance, " - + "Number:Angle, Number:Area, Number:ArealDensity, Number:CatalyticActivity, Number:Currency, Number:DataAmount, " - + "Number:DataTransferRate, Number:Density, Number:Dimensionless, Number:ElectricCapacitance, Number:ElectricCharge, " - + "Number:ElectricConductance, Number:ElectricConductivity, Number:ElectricCurrent, Number:ElectricInductance, " - + "Number:ElectricPotential, Number:ElectricResistance, Number:EmissionIntensity, Number:Energy, Number:EnergyPrice, " - + "Number:Force, Number:Frequency, Number:Illuminance, Number:Intensity, Number:Length, Number:LuminousFlux, " - + "Number:LuminousIntensity, Number:MagneticFlux, Number:MagneticFluxDensity, Number:Mass, Number:Power, Number:Pressure, " - + "Number:RadiationDoseAbsorbed, Number:RadiationDoseEffective, Number:RadiationDoseRate, Number:RadiationSpecificActivity, Number:RadioactiveActivity, " - + "Number:SolidAngle, Number:Speed, Number:Temperature, Number:Time, Number:Volume, Number:VolumePrice, " - + "Number:VolumetricFlowRate, Player, Rollershutter, String, Switch]. It must be a value from the enumeration."); + generateInvalidItemTypeMessage("Invalid", thingSchema)); + verifyWithPath("invalidItemType", RELATIVE_PATH_TO_THING, expectedMessages); } From f78629afb2fbbf6949bd5cb85664da63fc80a64d Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Sun, 31 May 2026 11:17:17 +0200 Subject: [PATCH 2/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Wouter Born --- .../checkstyle/test/OhInfXmlValidationCheckTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java index 8c725b0f..e142e7b2 100644 --- a/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java +++ b/custom-checks/checkstyle/src/test/java/org/openhab/tools/analysis/checkstyle/test/OhInfXmlValidationCheckTest.java @@ -97,6 +97,11 @@ protected String getPackageLocation() { private static Document parseXml(String xml) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setXIncludeAware(false); + factory.setExpandEntityReferences(false); try (InputStream inputStream = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))) { return factory.newDocumentBuilder().parse(inputStream); From b1c763062b03afc989cd372c2cec80dfacd1311a Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Sun, 31 May 2026 11:21:11 +0200 Subject: [PATCH 3/3] Fix URL deprecation in OhInfXmlValidationCheck Signed-off-by: Wouter Born --- .../tools/analysis/checkstyle/OhInfXmlValidationCheck.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/OhInfXmlValidationCheck.java b/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/OhInfXmlValidationCheck.java index 1c22ac98..be177863 100644 --- a/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/OhInfXmlValidationCheck.java +++ b/custom-checks/checkstyle/src/main/java/org/openhab/tools/analysis/checkstyle/OhInfXmlValidationCheck.java @@ -18,6 +18,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.util.HashMap; @@ -167,9 +168,9 @@ private void addToOhFiles(File xmlFile) { private Schema getXSD(String schemaUrlString, CachingHttpClient client) { try { - URL schemaUrl = new URL(schemaUrlString); + URL schemaUrl = URI.create(schemaUrlString).toURL(); return client.get(schemaUrl); - } catch (IOException e) { + } catch (IllegalArgumentException | IOException e) { logger.error("Unable to get XSD file {} : {}", schemaUrlString, e.getMessage(), e); return null; }