use of com.helger.schematron.pure.model.PSSchema in project ph-schematron by phax.
the class PSXPathQueryBinding method bind.
@Nonnull
public IPSBoundSchema bind(@Nonnull final PSSchema aSchema, @Nullable final String sPhase, @Nullable final IPSErrorHandler aCustomErrorListener, @Nullable final XPathVariableResolver aVariableResolver, @Nullable final XPathFunctionResolver aFunctionResolver) throws SchematronException {
ValueEnforcer.notNull(aSchema, "Schema");
final IPSErrorHandler aErrorHandler = aCustomErrorListener != null ? aCustomErrorListener : new CollectingPSErrorHandler();
if (!aSchema.isValid(aErrorHandler))
throw new SchematronBindException("The passed schema is not valid and can therefore not be bound" + (aErrorHandler == aCustomErrorListener ? ". Errors are in the provided error handler." : ": " + ((CollectingPSErrorHandler) aErrorHandler).getErrorList().toString()));
PSSchema aSchemaToUse = aSchema;
if (!aSchemaToUse.isPreprocessed()) {
// Required for parameter resolution
final PSPreprocessor aPreprocessor = PSPreprocessor.createPreprocessorWithoutInformationLoss(this);
// Apply preprocessing
aSchemaToUse = aPreprocessor.getForcedPreprocessedSchema(aSchema);
}
final PSXPathBoundSchema ret = new PSXPathBoundSchema(this, aSchemaToUse, sPhase, aCustomErrorListener, aVariableResolver, aFunctionResolver);
ret.bind();
return ret;
}
use of com.helger.schematron.pure.model.PSSchema in project ph-schematron by phax.
the class PSXPathBoundSchema method validate.
public void validate(@Nonnull final Node aNode, @Nullable final String sBaseURI, @Nonnull final IPSValidationHandler aValidationHandler) throws SchematronValidationException {
ValueEnforcer.notNull(aNode, "Node");
ValueEnforcer.notNull(aValidationHandler, "ValidationHandler");
if (m_aBoundPatterns == null)
throw new IllegalStateException("bind was never called!");
final PSSchema aSchema = getOriginalSchema();
final PSPhase aPhase = getPhase();
// Call the "start" callback method
aValidationHandler.onStart(aSchema, aPhase, sBaseURI);
// For all bound patterns
for (final PSXPathBoundPattern aBoundPattern : m_aBoundPatterns) {
final PSPattern aPattern = aBoundPattern.getPattern();
aValidationHandler.onPattern(aPattern);
// For all bound rules
rules: for (final PSXPathBoundRule aBoundRule : aBoundPattern.getAllBoundRules()) {
final PSRule aRule = aBoundRule.getRule();
// Find all nodes matching the rules
NodeList aRuleMatchingNodes = null;
try {
aRuleMatchingNodes = XPathEvaluationHelper.evaluate(aBoundRule.getBoundRuleExpression(), aNode, XPathConstants.NODESET, sBaseURI);
} catch (final XPathExpressionException ex) {
// Handle the cause, because it is usually a wrapper only
error(aRule, "Failed to evaluate XPath expression to a nodeset: '" + aBoundRule.getRuleExpression() + "'", ex.getCause() != null ? ex.getCause() : ex);
continue rules;
}
final int nRuleMatchingNodes = aRuleMatchingNodes.getLength();
if (nRuleMatchingNodes > 0) {
// For all contained assert and report elements
for (final PSXPathBoundAssertReport aBoundAssertReport : aBoundRule.getAllBoundAssertReports()) {
// XSLT does "fired-rule" for each node
aValidationHandler.onRule(aRule, aBoundRule.getRuleExpression());
final PSAssertReport aAssertReport = aBoundAssertReport.getAssertReport();
final boolean bIsAssert = aAssertReport.isAssert();
final XPathExpression aTestExpression = aBoundAssertReport.getBoundTestExpression();
// Check each node, if it matches the assert/report
for (int i = 0; i < nRuleMatchingNodes; ++i) {
final Node aRuleMatchingNode = aRuleMatchingNodes.item(i);
try {
final boolean bTestResult = ((Boolean) XPathEvaluationHelper.evaluate(aTestExpression, aRuleMatchingNode, XPathConstants.BOOLEAN, sBaseURI)).booleanValue();
if (bIsAssert) {
// It's an assert
if (!bTestResult) {
// Assert failed
if (aValidationHandler.onFailedAssert(aAssertReport, aBoundAssertReport.getTestExpression(), aRuleMatchingNode, i, aBoundAssertReport).isBreak()) {
return;
}
}
} else {
// It's a report
if (bTestResult) {
// Successful report
if (aValidationHandler.onSuccessfulReport(aAssertReport, aBoundAssertReport.getTestExpression(), aRuleMatchingNode, i, aBoundAssertReport).isBreak()) {
return;
}
}
}
} catch (final XPathExpressionException ex) {
error(aRule, "Failed to evaluate XPath expression to a boolean: '" + aBoundAssertReport.getTestExpression() + "'", ex.getCause() != null ? ex.getCause() : ex);
}
}
}
if (false) {
// the next pattern
break rules;
}
}
}
}
// Call the "end" callback method
aValidationHandler.onEnd(aSchema, aPhase);
}
use of com.helger.schematron.pure.model.PSSchema in project ph-schematron by phax.
the class PSXPathBoundSchema method bind.
@Nonnull
public PSXPathBoundSchema bind() throws SchematronBindException {
if (s_aLogger.isDebugEnabled())
s_aLogger.debug("Binding pure Schematron");
if (m_aBoundPatterns != null)
throw new IllegalStateException("bind must only be called once!");
final PSSchema aSchema = getOriginalSchema();
final PSPhase aPhase = getPhase();
// Get all "global" variables that are defined in the schema
final PSXPathVariables aGlobalVariables = new PSXPathVariables();
if (aSchema.hasAnyLet())
for (final Map.Entry<String, String> aEntry : aSchema.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in global <schema>");
if (aPhase != null) {
// Get all variables that are defined in the specified phase
for (final Map.Entry<String, String> aEntry : aPhase.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in <phase> with name '" + getPhaseID() + "'");
}
final XPath aXPathContext = _createXPathContext();
// Pre-compile all diagnostics first
final ICommonsMap<String, PSXPathBoundDiagnostic> aBoundDiagnostics = _createBoundDiagnostics(aXPathContext, aGlobalVariables);
if (aBoundDiagnostics == null)
throw new SchematronBindException("Failed to precompile the diagnostics of the supplied schema. Check the " + (isDefaultErrorHandler() ? "log output" : "error listener") + " for XPath errors!");
// Perform the pre-compilation of all XPath expressions in the patterns,
// rules, asserts/reports and the content elements
m_aBoundPatterns = _createBoundPatterns(aXPathContext, aBoundDiagnostics, aGlobalVariables);
if (m_aBoundPatterns == null)
throw new SchematronBindException("Failed to precompile the supplied schema.");
return this;
}
Aggregations