use of com.helger.phive.api.artefact.IValidationArtefact in project phive by phax.
the class ValidationExecutorXSD method applyValidation.
@Nonnull
public ValidationResult applyValidation(@Nonnull final IValidationSourceXML aSource, @Nullable final Locale aLocale) {
ValueEnforcer.notNull(aSource, "Source");
final IValidationArtefact aVA = getValidationArtefact();
// Find the XML schema required for validation
// as we don't have a node, we need to trust the implementation class
final Schema aSchema = m_aSchemaProvider.get();
assert aSchema != null;
final ErrorList aErrorList = new ErrorList();
try {
// Apply the XML schema validation
XMLSchemaValidationHelper.validate(aSchema, aSource.getAsTransformSource(), aErrorList, aLocale);
} catch (final IllegalArgumentException ex) {
// Happens when non-XML document is trying to be parsed
if (ex.getCause() instanceof SAXParseException) {
aErrorList.add(AbstractSAXErrorHandler.getSaxParseError(EErrorLevel.FATAL_ERROR, (SAXParseException) ex.getCause()));
} else {
aErrorList.add(SingleError.builderFatalError().errorLocation(new SimpleLocation(aVA.getRuleResourcePath())).errorText("The document to be validated is not an XML document").linkedException(ex).build());
}
}
// Build result object
return new ValidationResult(aVA, aErrorList.getAllFailures());
}
use of com.helger.phive.api.artefact.IValidationArtefact in project phive by phax.
the class ValidationExecutorXSDPartial method applyValidation.
@Nonnull
public ValidationResult applyValidation(@Nonnull final IValidationSourceXML aSource, @Nullable final Locale aLocale) {
ValueEnforcer.notNull(aSource, "Source");
final IValidationArtefact aVA = getValidationArtefact();
NodeList aNodeSet;
try {
aNodeSet = (NodeList) m_aPartialContext.getXPathExpression().evaluate(aSource.getNode(), XPathConstants.NODESET);
} catch (final XPathExpressionException ex) {
throw new IllegalStateException(ex);
}
final ErrorList aErrorList = new ErrorList();
final int nMatchingNodes = aNodeSet.getLength();
if (m_aPartialContext.hasMinNodeCount())
if (nMatchingNodes < m_aPartialContext.getMinNodeCount()) {
// Too little matches found
aErrorList.add(SingleError.builderFatalError().errorLocation(aVA.getRuleResourcePath()).errorText("The minimum number of result nodes (" + m_aPartialContext.getMinNodeCount() + ") is not met").build());
}
if (m_aPartialContext.hasMaxNodeCount())
if (nMatchingNodes > m_aPartialContext.getMaxNodeCount()) {
// Too little matches found
aErrorList.add(SingleError.builderFatalError().errorLocation(aVA.getRuleResourcePath()).errorText("The maximum number of result nodes (" + m_aPartialContext.getMaxNodeCount() + ") is not met").build());
}
if (nMatchingNodes == 0) {
// No match found - nothing to do
return new ValidationResult(aVA, aErrorList);
}
// Find the XML schema required for validation
// as we don't have a node, we need to trust the implementation class
final Schema aSchema = m_aSchemaProvider.get();
assert aSchema != null;
for (int i = 0; i < aNodeSet.getLength(); ++i) {
// Build a partial source
final IValidationSourceXML aRealSource = new ValidationSourceXML(aSource.getSystemID(), aNodeSet.item(i), true);
try {
// Apply the XML schema validation
XMLSchemaValidationHelper.validate(aSchema, aRealSource.getAsTransformSource(), aErrorList, aLocale);
} catch (final IllegalArgumentException ex) {
// Happens when non-XML document is trying to be parsed
if (ex.getCause() instanceof SAXParseException) {
aErrorList.add(AbstractSAXErrorHandler.getSaxParseError(EErrorLevel.FATAL_ERROR, (SAXParseException) ex.getCause()));
} else {
aErrorList.add(SingleError.builderFatalError().errorLocation(aVA.getRuleResourcePath()).errorFieldName("Context[" + i + "]").errorText("The document to be validated is not an XML document").linkedException(ex).build());
}
}
}
// Build result object
return new ValidationResult(aVA, aErrorList.getAllFailures());
}
use of com.helger.phive.api.artefact.IValidationArtefact in project phive by phax.
the class ValidationExecutorSchematron method _createSchematronResource.
@Nonnull
private AbstractSchematronResource _createSchematronResource(@Nullable final Locale aLocale, @Nonnull final ErrorList aErrorList, @Nonnull final Consumer<ESchematronOutput> aSpecialOutputHdl) {
final IValidationArtefact aArtefact = getValidationArtefact();
// get the Schematron resource to be used for this validation artefact
final IReadableResource aSCHRes = aArtefact.getRuleResource();
final IValidationType aVT = aArtefact.getValidationArtefactType();
if (aVT == EValidationType.SCHEMATRON_PURE) {
final SchematronResourcePure aPureSCH = new SchematronResourcePure(aSCHRes);
aPureSCH.setErrorHandler(new WrappedCollectingPSErrorHandler(aErrorList));
// consecutive calls!
return aPureSCH;
}
if (aVT == EValidationType.SCHEMATRON_SCH) {
final SchematronResourceSCH aSCHSCH = new SchematronResourceSCH(aSCHRes);
aSCHSCH.setErrorListener(new WrappedCollectingTransformErrorListener(aErrorList));
if (aLocale != null && StringHelper.hasText(aLocale.getLanguage()))
aSCHSCH.setLanguageCode(aLocale.getLanguage());
return aSCHSCH;
}
if (aVT == EValidationType.SCHEMATRON_SCHXSLT) {
final SchematronResourceSchXslt_XSLT2 aSCHSCH = new SchematronResourceSchXslt_XSLT2(aSCHRes);
aSCHSCH.setErrorListener(new WrappedCollectingTransformErrorListener(aErrorList));
if (aLocale != null && StringHelper.hasText(aLocale.getLanguage()))
aSCHSCH.setLanguageCode(aLocale.getLanguage());
return aSCHSCH;
}
if (aVT == EValidationType.SCHEMATRON_XSLT) {
final SchematronResourceXSLT aSCHXSLT = new SchematronResourceXSLT(aSCHRes);
aSCHXSLT.setErrorListener(new WrappedCollectingTransformErrorListener(aErrorList));
return aSCHXSLT;
}
if (aVT == EValidationType.SCHEMATRON_OIOUBL) {
final SchematronResourceXSLT aSCHXSLT = new SchematronResourceXSLT(aSCHRes);
aSCHXSLT.setErrorListener(new WrappedCollectingTransformErrorListener(aErrorList));
// Special output layout
aSpecialOutputHdl.accept(ESchematronOutput.OIOUBL);
return aSCHXSLT;
}
throw new IllegalStateException("Unsupported Schematron validation type: " + aVT);
}
use of com.helger.phive.api.artefact.IValidationArtefact in project phive by phax.
the class ValidationExecutorSchematron method applyValidation.
@Nonnull
public ValidationResult applyValidation(@Nonnull final IValidationSourceXML aSource, @Nullable final Locale aLocale) {
ValueEnforcer.notNull(aSource, "Source");
final IValidationArtefact aArtefact = getValidationArtefact();
// Get source as XML DOM Node
Node aNode = null;
try {
aNode = SchematronResourceHelper.getNodeOfSource(aSource.getAsTransformSource(), new DOMReaderSettings().setFeatureValues(EXMLParserFeature.AVOID_XML_ATTACKS));
} catch (final Exception ex) {
throw new IllegalStateException("For Schematron validation to work, the source must be valid XML which it is not.", ex);
}
if (StringHelper.hasText(m_sPrerequisiteXPath)) {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Using Schematron prerequisite path '" + m_sPrerequisiteXPath + "'");
// Check if the artefact can be applied on the given document by
// checking the prerequisite XPath
final XPath aXPathContext = XPathHelper.createNewXPath();
if (m_aNamespaceContext != null)
aXPathContext.setNamespaceContext(m_aNamespaceContext);
try {
final Boolean aResult = XPathExpressionHelper.evalXPathToBoolean(aXPathContext, m_sPrerequisiteXPath, XMLHelper.getOwnerDocument(aNode));
if (aResult != null && !aResult.booleanValue()) {
if (LOGGER.isInfoEnabled())
LOGGER.info("Ignoring validation artefact " + aArtefact.getRuleResourcePath() + " because the prerequisite XPath expression '" + m_sPrerequisiteXPath + "' is not fulfilled.");
return ValidationResult.createIgnoredResult(aArtefact);
}
} catch (final IllegalArgumentException ex) {
// Catch errors in prerequisite XPaths - most likely because of
// missing namespace prefixes...
final String sErrorMsg = "Failed to verify if validation artefact " + aArtefact.getRuleResourcePath() + " matches the prerequisite XPath expression '" + m_sPrerequisiteXPath + "' - ignoring validation artefact.";
LOGGER.error(sErrorMsg, ex);
return new ValidationResult(aArtefact, new ErrorList(SingleError.builderError().errorText(sErrorMsg).linkedException(ex).build()));
}
}
// No prerequisite or prerequisite matched
final ErrorList aErrorList = new ErrorList();
final Wrapper<ESchematronOutput> aOutput = new Wrapper<>(ESchematronOutput.SVRL);
final AbstractSchematronResource aSCH = _createSchematronResource(aLocale, aErrorList, aOutput::set);
// Don't cache to avoid that errors in the Schematron are hidden on
// consecutive calls!
aSCH.setUseCache(m_bCacheSchematron);
try {
// Main application of Schematron
final Document aDoc = aSCH.applySchematronValidation(new DOMSource(aNode));
if (LOGGER.isDebugEnabled())
LOGGER.debug("SVRL: " + XMLWriter.getNodeAsString(aDoc));
switch(aOutput.get()) {
case SVRL:
{
final SchematronOutputType aSVRL = aDoc == null || aDoc.getDocumentElement() == null ? null : new SVRLMarshaller().read(aDoc);
if (aSVRL != null) {
// Convert failed asserts and successful reports to error objects
for (final SVRLFailedAssert aFailedAssert : SVRLHelper.getAllFailedAssertions(aSVRL)) aErrorList.add(aFailedAssert.getAsResourceError(aSource.getSystemID()));
for (final SVRLSuccessfulReport aSuccessfulReport : SVRLHelper.getAllSuccessfulReports(aSVRL)) aErrorList.add(aSuccessfulReport.getAsResourceError(aSource.getSystemID()));
} else {
// Schematron does not create SVRL!
LOGGER.warn("Failed to read the result as SVRL:" + (aDoc != null ? "\n" + XMLWriter.getNodeAsString(aDoc) : " no XML Document created"));
aErrorList.add(SingleError.builderError().errorLocation(aArtefact.getRuleResourcePath()).errorText("Internal error interpreting Schematron result").errorFieldName(aDoc != null ? XMLWriter.getNodeAsString(aDoc) : null).build());
}
break;
}
case OIOUBL:
{
if (aDoc != null && aDoc.getDocumentElement() != null) {
for (final Element eError : XMLHelper.getChildElementIterator(aDoc.getDocumentElement(), "Error")) {
// final String sContext = eError.getAttribute ("context");
final String sPattern = XMLHelper.getFirstChildElementOfName(eError, "Pattern").getTextContent();
final String sDescription = XMLHelper.getFirstChildElementOfName(eError, "Description").getTextContent();
final String sXPath = XMLHelper.getFirstChildElementOfName(eError, "Xpath").getTextContent();
aErrorList.add(new SVRLErrorBuilder(sPattern).errorLocation(new SimpleLocation(aSource.getSystemID())).errorText(sDescription).errorFieldName(sXPath).build());
}
} else {
// Schematron does not create SVRL!
LOGGER.warn("Failed to read the result as OIOUBL result:" + (aDoc != null ? "\n" + XMLWriter.getNodeAsString(aDoc) : " no XML Document created"));
aErrorList.add(SingleError.builderError().errorLocation(aArtefact.getRuleResourcePath()).errorText("Internal error - no Schematron output created for OIOUBL").build());
}
break;
}
default:
throw new IllegalStateException("Unsupported output type");
}
} catch (final Exception ex) {
// Usually an error in the Schematron
aErrorList.add(SingleError.builderError().errorLocation(aArtefact.getRuleResourcePath()).errorText(ex.getMessage()).linkedException(ex).build());
}
// Apply custom levels
if (m_aCustomErrorLevels != null && aErrorList.isNotEmpty()) {
final ErrorList aOldErrorList = aErrorList.getClone();
aErrorList.clear();
for (final IError aCurError : aOldErrorList) {
final String sErrorID = aCurError.getErrorID();
final IErrorLevel aCustomLevel = m_aCustomErrorLevels.get(sErrorID);
if (aCustomLevel != null) {
if (LOGGER.isDebugEnabled())
LOGGER.debug("Changing error level of '" + sErrorID + "' from " + aCurError.getErrorLevel().getNumericLevel() + " to " + aCustomLevel + " (" + aCustomLevel.getNumericLevel() + ")");
aErrorList.add(SingleError.builder(aCurError).errorLevel(aCustomLevel).build());
} else {
// No change
aErrorList.add(aCurError);
}
}
}
return new ValidationResult(aArtefact, aErrorList);
}
Aggregations