diff --git a/java/org/slub/rosetta/dps/repository/plugin/XmlFormatValidationPlugin.java b/java/org/slub/rosetta/dps/repository/plugin/XmlFormatValidationPlugin.java index 6ce4580bc21dbc7dc818939e02db7a7436959eb3..60b7d115a0394e1f21003bd6f48fe6f92a16ca61 100644 --- a/java/org/slub/rosetta/dps/repository/plugin/XmlFormatValidationPlugin.java +++ b/java/org/slub/rosetta/dps/repository/plugin/XmlFormatValidationPlugin.java @@ -51,7 +51,7 @@ import java.util.Set; */ public class XmlFormatValidationPlugin implements FormatValidationPlugin { private static final ExLogger log = ExLogger.getExLogger(XmlFormatValidationPlugin.class); - private ValidationResultHandle validationLogger; + private ValidationResultHandle resultHandle; private boolean debug; private boolean valid; private boolean wellformed; @@ -71,7 +71,7 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { Document doc = db.parse(fh); Element de = doc.getDocumentElement(); NodeList nodes = de.getElementsByTagName("entry"); - validationLogger.debug("CATALOG =" + namespaceSchemaMapFile); + resultHandle.debug("CATALOG =" + namespaceSchemaMapFile); List<String> attr_strings = List.of(new String[]{"schematype", "namespace", "schemauri"}); int nodesCount = nodes.getLength(); for (int i = 0; i <nodesCount ; i++) { @@ -81,18 +81,21 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { if (allValid) { String attr_type = attr_list.get(0); String namespace = attr_list.get(1); - String sUri = attr_list.get(2); + String sUri=""; + if (attr_list.size() == 3 ) { + sUri = attr_list.get(2); + } addtoNamespaceSchemaMap(namespaceSchemaMapFile, attr_type, namespace, sUri); } else { - validationLogger.error("invalid entry(" + i + ") in namespace schema map file " + namespaceSchemaMapFile); + resultHandle.error("invalid entry(" + i + ") in namespace schema map file " + namespaceSchemaMapFile); } } } catch (ParserConfigurationException | SAXException | IOException | URISyntaxException e) { - validationLogger.error("parsing expection parsing namespace schema map file " + namespaceSchemaMapFile + " ," + e.getMessage()); + resultHandle.error("parsing expection parsing namespace schema map file " + namespaceSchemaMapFile + " ," + e.getMessage()); } } - private void addtoNamespaceSchemaMap(String namespaceSchemaMapFile, String attr_type, String namespace, String sUrl) throws URISyntaxException, SAXException { + private void addtoNamespaceSchemaMap(String namespaceSchemaMapFile, String attr_type, String namespace, String sUri) throws URISyntaxException, SAXException { ValidationSchemaType schematype = ValidationSchemaType.nothing; switch (attr_type) { case "schema" -> schematype = ValidationSchemaType.schema; @@ -100,28 +103,49 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { case "relaxng" -> schematype = ValidationSchemaType.relaxng; case "nonvalidating" -> schematype = ValidationSchemaType.nonvalidating; default -> - validationLogger.error("attribute schematype needs to be type of schema, schematron or relaxng, but is " + attr_type); + resultHandle.error("attribute schematype needs to be type of schema, schematron or relaxng, but is " + attr_type); } + + ValidationSchema v; + if (schematype == ValidationSchemaType.nonvalidating) { + v = new ValidationSchema(namespace, schematype); + } else { + v = getValidationSchemaIfPresent(namespaceSchemaMapFile, namespace, sUri, schematype); + } + namespaceSchemaMap.add(v); + } + + + private ValidationSchema getValidationSchemaIfPresent(String namespaceSchemaMapFile, String namespace, String sUri, ValidationSchemaType schematype) throws URISyntaxException, SAXException { + ValidationSchema v; if ( - sUrl.startsWith("file:") - && !sUrl.startsWith("file://localhost/") + isWrongFileUri(sUri) ) { - validationLogger.error("attribute schemaurl should be start with: 'http://$server/path', 'https://$server/path' or 'file://localhost/path' to ensure coorect working, got: " + sUrl); + resultHandle.error("attribute schemauri should be start with: 'http://$server/path', 'https://$server/path' or 'file://localhost/path' to ensure coorect working, got: " + sUri); } URI uri; if ( - (sUrl.startsWith("http://")) - || (sUrl.startsWith("https://")) - || (sUrl.startsWith("file://")) - || (sUrl.contains("://")) + isNonRelativeUri(sUri) ) { - uri = new URI(sUrl); + uri = new URI(sUri); } else { - uri = remapUri(namespaceSchemaMapFile, sUrl); - validationLogger.debug("SCHEMACATALOG, remap to URI: " + uri); + uri = remapUri(namespaceSchemaMapFile, sUri); + resultHandle.debug("SCHEMACATALOG, remap " + sUri + " to URI: " + uri); } - ValidationSchema v = new ValidationSchema(namespace, schematype, uri); - namespaceSchemaMap.add(v); + v = new ValidationSchema(namespace, schematype, uri); + return v; + } + + private static boolean isNonRelativeUri(String sUri) { + return (sUri.startsWith("http://")) + || (sUri.startsWith("https://")) + || (sUri.startsWith("file://")) + || (sUri.contains("://")); + } + + private static boolean isWrongFileUri(String sUri) { + return sUri.startsWith("file:") + && !sUri.startsWith("file://localhost/"); } //@NotNull @@ -138,7 +162,11 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { assert ("namespace".equals(attr_strings.get(1))); assert ("schemauri".equals(attr_strings.get(2))); NamedNodeMap attributes = node.getAttributes(); - return attr_strings.stream().map(s -> attributes.getNamedItem(s).getTextContent()).toList(); + return attr_strings.stream() + .map(s -> attributes.getNamedItem(s)) + .filter( s -> s != null) + .map ( s -> s.getTextContent()) + .toList(); } private static boolean checkAttributesOfNamespaceSchemaMapFile(String attr_type) { @@ -149,8 +177,8 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { dbf.setNamespaceAware(true); dbf.setValidating(false); dbf.setExpandEntityReferences(false); - validationLogger = new ValidationResultHandle(); - validationErrorHandler = new XmlErrorHandler( validationLogger); + resultHandle = new ValidationResultHandle(); + validationErrorHandler = new XmlErrorHandler(resultHandle); } /** init params to configure the plugin via xml forms @@ -163,9 +191,9 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { String[] catalogs = new String[] { initp.get("catalog").trim() }; - validationCatalogResolver = new ValidationCatalogResolver(catalogs,validationLogger); + validationCatalogResolver = new ValidationCatalogResolver(catalogs, resultHandle); loadNamespaceSchemaMap( initp.get("schemacatalog").trim() ); - validationResourceResolver = new ValidationResourceResolver(namespaceSchemaMap, validationLogger); + validationResourceResolver = new ValidationResourceResolver(namespaceSchemaMap, resultHandle); } private XmlInfoRecord getXMLinfo(Document doc) { @@ -187,7 +215,7 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { } private Optional<ValidationSchema> assignSchema(Document doc) { XmlInfoRecord info = getXMLinfo(doc); - validationLogger.debug("check info.nameSpaceUri=" + info.nameSpaceUri); + resultHandle.debug("check info.nameSpaceUri=" + info.nameSpaceUri); Optional<ValidationSchema> optValidationSchema; /* try if a DTD is assignable */ var type = checkIfDtdIsApplicable(doc); /* returns ValidationSchemaType.dtd or ValidationSchemaType.nothing */ @@ -212,12 +240,12 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { //@NotNull private Optional<ValidationSchema> applyDtd(XmlInfoRecord info, ValidationSchemaType type) { - validationLogger.debug("found schema " + type); + resultHandle.debug("found schema " + type); ValidationSchema validationSchema = null; try { validationSchema = new ValidationSchema(null, type, new URI(info.systemID)); } catch (SAXException | URISyntaxException e) { - validationLogger.error(e.getMessage()); + resultHandle.error(e.getMessage()); } if (null != validationSchema) { return Optional.of(validationSchema); @@ -234,13 +262,13 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { if (checkIfWellformed(doc)) { //System.out.println("## is wellformed"); wellformed = true; - validationLogger.clear(); - validationLogger.info("File " + filePath + " is well formed."); + resultHandle.clear(); + resultHandle.info("File " + filePath + " is well formed."); Optional<ValidationSchema> optSchema = assignSchema(doc); //System.out.println("## schema assigned..."); if (optSchema.isEmpty()) { //System.out.println("-- empty"); - validationLogger.error("there is no related schema found in *our* catalog of allowed XML types for file " + filePath); + resultHandle.error("there is no related schema found in *our* catalog of allowed XML types for file " + filePath); valid = false; } else { ValidationSchema validationSchema = optSchema.get(); @@ -248,51 +276,51 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { } } } catch (ParserConfigurationException e) { - validationLogger.error("ParserconfExc file=" + filePath + " Exc:" + e.getMessage()); + resultHandle.error("ParserconfExc file=" + filePath + " Exc:" + e.getMessage()); } catch (IOException e) { - validationLogger.error("IOExc file=" + filePath + " Exc:" + e.getMessage()); + resultHandle.error("IOExc file=" + filePath + " Exc:" + e.getMessage()); } catch (SAXException e) { - validationLogger.error("SaxExc file=" + filePath + " Exc:" + e.getMessage()); + resultHandle.error("SaxExc file=" + filePath + " Exc:" + e.getMessage()); e.printStackTrace(); } catch (IllegalArgumentException e ) { - validationLogger.fatal( e.getMessage()); + resultHandle.fatal( e.getMessage()); } return valid; } private void validateFormatAgainstAnySchema(String filePath, ValidationSchema validationSchema) throws IOException, ParserConfigurationException, SAXException { - validationLogger.info("assigned schema of type: " + validationSchema.schemaType); - validationLogger.info("assigned schema uri: " + validationSchema.schemaURI); + resultHandle.info("assigned schema of type: " + validationSchema.schemaType); + resultHandle.info("assigned schema uri: " + validationSchema.schemaURI); var schemaType = validationSchema.schemaType; Document doc = getDocument(filePath); switch (schemaType) { case dtd -> { - ValidateDTD validator = new ValidateDTD(validationCatalogResolver, validationErrorHandler, validationLogger); + ValidateDTD validator = new ValidateDTD(validationCatalogResolver, validationErrorHandler, resultHandle); valid = validator.validateAgainst(filePath); break; } case schema -> { - ValidateSchema validator = new ValidateSchema(validationResourceResolver, validationLogger); + ValidateSchema validator = new ValidateSchema(validationResourceResolver, resultHandle); valid = validator.validateFormatAgainstSchemaRecursively(doc, validationSchema); } case nonvalidating -> { - ValidateSchema validator = new ValidateSchema(validationResourceResolver, validationLogger); + ValidateSchema validator = new ValidateSchema(validationResourceResolver, resultHandle); valid = validator.validateFormatAgainstSchemaRecursively(doc, validationSchema); } case relaxng -> { - ValidateRelaxNG validator = new ValidateRelaxNG(validationErrorHandler, validationLogger); + ValidateRelaxNG validator = new ValidateRelaxNG(validationErrorHandler, resultHandle); valid = validator.validateAgainst(doc, validationSchema.schemaURI); break; } case schematron -> { ValidateSchematron validator = new ValidateSchematron(); valid = validator.validateAgainst(doc, validationSchema.schemaURI); - validationLogger.error("unsupported schematron schema uri=" + validationSchema.schemaURI + " of type: " + validationSchema.schemaType); + resultHandle.error("unsupported schematron schema uri=" + validationSchema.schemaURI + " of type: " + validationSchema.schemaType); valid = false; break; } default -> { - validationLogger.error("unsupported schema uri=" + validationSchema.schemaURI + " of type: " + validationSchema.schemaType); + resultHandle.error("unsupported schema uri=" + validationSchema.schemaURI + " of type: " + validationSchema.schemaType); valid = false; break; } @@ -307,7 +335,7 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { if (info.systemID.endsWith(".dtd")) { result = ValidationSchemaType.dtd; } - validationLogger.debug("no dtd applicable"); + resultHandle.debug("no dtd applicable"); } return result; } @@ -316,14 +344,14 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { /* detect XML type via NS */ boolean isWellformedXml = false; XmlInfoRecord info = getXMLinfo(doc); - validationLogger.info("detect XML type via NS:" + info.nameSpaceUri); + resultHandle.info("detect XML type via NS:" + info.nameSpaceUri); /* align corresponding Schema based on systemID */ //info.print(); if ("1.0".equals(info.xmlVersion)) { isWellformedXml = true; - validationLogger.info("checked XML is wellformed"); + resultHandle.info("checked XML is wellformed"); } else { - validationLogger.error("not an expected XML 1.0 document, found " + info.xmlVersion); + resultHandle.error("not an expected XML 1.0 document, found " + info.xmlVersion); } return isWellformedXml; } @@ -340,7 +368,7 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { DocumentBuilder db = dbf.newDocumentBuilder(); db.setErrorHandler( validationErrorHandler ); //db.setEntityResolver(validationCatalogResolver); - validationLogger.debug( + resultHandle.debug( "DOCUMENT LOADER: ns aware=" + db.isNamespaceAware() + " include aware=" + db.isXIncludeAware() + " is validating=" + db.isValidating() @@ -367,12 +395,12 @@ public class XmlFormatValidationPlugin implements FormatValidationPlugin { @Override public List<String> getErrors() { - return validationLogger.getErrors(); + return resultHandle.getErrors(); } @Override public String getValidationDetails() { - return validationLogger.getLog(); + return resultHandle.getLog(); } /** stand-alone check, main file to call local installed clamd