Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public ICommonsList <IValidationExecutor <IValidationSourceXML>> loadSchematrons

aExecutorSCH = switch (eEngine)
{
case PURE -> ValidationExecutorSchematron.createPure (aRepoRes, aNSCtx);
case PURE_XPATH -> ValidationExecutorSchematron.createPure (aRepoRes, aNSCtx);
case ISO_SCHEMATRON -> ValidationExecutorSchematron.createSCH (aRepoRes, aNSCtx);
case SCHXSLT1 -> ValidationExecutorSchematron.createSchXslt1 (aRepoRes, aNSCtx);
case SCHXSLT2 -> ValidationExecutorSchematron.createSchXslt2 (aRepoRes, aNSCtx);
Expand Down
4 changes: 4 additions & 0 deletions phive-xml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
<groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-xslt</artifactId>
</dependency>
<dependency>
<groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-isosch</artifactId>
</dependency>
<dependency>
<groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-schxslt</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
import com.helger.phive.xml.source.IValidationSourceXML;
import com.helger.schematron.AbstractSchematronResource;
import com.helger.schematron.SchematronResourceHelper;
import com.helger.schematron.pure.SchematronResourcePure;
import com.helger.schematron.pure.errorhandler.WrappedCollectingPSErrorHandler;
import com.helger.schematron.errorhandler.WrappedCollectingPSErrorHandler;
import com.helger.schematron.pure.SchematronResourcePureXPath;
import com.helger.schematron.sch.SchematronResourceSCH;
import com.helger.schematron.schxslt.xslt2.SchematronResourceSchXslt_XSLT2;
import com.helger.schematron.schxslt2.xslt.SchematronResourceSchXslt2;
Expand Down Expand Up @@ -92,21 +92,28 @@ public class ValidationExecutorSchematron extends
IValidationExecutorCacheSupport
{
public static final String IN_MEMORY_RESOURCE_NAME = "in-memory-data";
/**
* By default the SVRL created by the Schematron engine is <b>not</b> validated against the SVRL
* XML Schema, so that SVRL created by XSLTs built with a different ph-schematron version can still
* be read.
*/
public static final boolean DEFAULT_VALIDATE_SVRL = false;

private static final Logger LOGGER = LoggerFactory.getLogger (ValidationExecutorSchematron.class);

private final String m_sPrerequisiteXPath;
private final MapBasedNamespaceContext m_aNamespaceContext;
private boolean m_bCacheSchematron = IValidationExecutorCacheSupport.DEFAULT_CACHE;
private boolean m_bValidateSVRL = DEFAULT_VALIDATE_SVRL;
private ICommonsMap <String, CustomErrorDetails> m_aCustomErrorDetails;

public ValidationExecutorSchematron (@NonNull final IValidationArtefact aValidationArtefact,
@Nullable final String sPrerequisiteXPath,
@Nullable final IIterableNamespaceContext aNamespaceContext)
{
super (aValidationArtefact);
ValueEnforcer.isTrue ( () -> aValidationArtefact.getValidationType ().getBaseType ().isSchematron (),
"Artifact is not a Schematron");
ValueEnforcer.isTrue (() -> aValidationArtefact.getValidationType ().getBaseType ().isSchematron (),
"Artifact is not a Schematron");

m_sPrerequisiteXPath = sPrerequisiteXPath;
// Create a copy on demand
Expand Down Expand Up @@ -145,12 +152,40 @@ public final ValidationExecutorSchematron setCacheArtefact (final boolean bCache
return this;
}

/**
* @return <code>true</code> if the SVRL created by the Schematron engine is validated against the
* SVRL XML Schema, <code>false</code> if not. The default is
* {@link #DEFAULT_VALIDATE_SVRL}.
* @since 12.0.4
*/
public final boolean isValidateSVRL ()
{
return m_bValidateSVRL;
}

/**
* Enable or disable the validation of the created SVRL against the SVRL XML Schema. This must be
* disabled (the default) if the Schematron XSLT was created with a different ph-schematron version
* that emits SVRL not matching the currently bundled SVRL XML Schema.
*
* @param bValidateSVRL
* <code>true</code> to validate the SVRL against the XML Schema, <code>false</code> to skip
* the SVRL schema validation.
* @return this for chaining
* @since 12.0.4
*/
@NonNull
public final ValidationExecutorSchematron setValidateSVRL (final boolean bValidateSVRL)
{
m_bValidateSVRL = bValidateSVRL;
return this;
}

public void ensureItemIsInCache ()
{
if (m_bCacheSchematron)
{
final AbstractSchematronResource aRes = _createSchematronResource (null, new ErrorList (), x -> {});
aRes.setUseCache (true);
final AbstractSchematronResource aRes = _createSchematronResource (null, new ErrorList (), true, x -> {});
aRes.isValidSchematron ();
LOGGER.debug ("ValidationExecutorSchematron " +
getValidationArtefact ().getRuleResourcePath () +
Expand Down Expand Up @@ -207,59 +242,67 @@ public final ValidationExecutorSchematron addCustomErrorDetails (@Nullable final
@NonNull
private AbstractSchematronResource _createSchematronResource (@Nullable final Locale aLocale,
@NonNull final ErrorList aErrorList,
final boolean bUseCache,
@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 String sLanguageCode = aLocale != null && StringHelper.isNotEmpty (aLocale.getLanguage ()) ? aLocale
.getLanguage ()
: null;

final IValidationType aVT = aArtefact.getValidationType ();
if (aVT == EValidationType.SCHEMATRON_PURE)
{
final SchematronResourcePure aPureSCH = new SchematronResourcePure (aSCHRes);
aPureSCH.setErrorHandler (new WrappedCollectingPSErrorHandler (aErrorList));
// Don't cache to avoid that errors in the Schematron are hidden on
// consecutive calls!
return aPureSCH;
return SchematronResourcePureXPath.builder (aSCHRes)
.errorHandler (new WrappedCollectingPSErrorHandler (aErrorList))
.useCache (bUseCache)
.build ();
}
if (aVT == EValidationType.SCHEMATRON_SCH_ISO_XSLT2)
{
final SchematronResourceSCH aSCHSCH = new SchematronResourceSCH (aSCHRes);
aSCHSCH.setErrorListener (new WrappedCollectingTransformErrorListener (aErrorList));
if (aLocale != null && StringHelper.isNotEmpty (aLocale.getLanguage ()))
aSCHSCH.setLanguageCode (aLocale.getLanguage ());
return aSCHSCH;
return SchematronResourceSCH.builder (aSCHRes)
.errorListener (new WrappedCollectingTransformErrorListener (aErrorList))
.languageCode (sLanguageCode)
.useCache (bUseCache)
.build ();
}
if (aVT == EValidationType.SCHEMATRON_SCHXSLT1_XSLT2)
{
final SchematronResourceSchXslt_XSLT2 aSCHSCH = new SchematronResourceSchXslt_XSLT2 (aSCHRes);
aSCHSCH.setErrorListener (new WrappedCollectingTransformErrorListener (aErrorList));
if (aLocale != null && StringHelper.isNotEmpty (aLocale.getLanguage ()))
aSCHSCH.setLanguageCode (aLocale.getLanguage ());
return aSCHSCH;
return SchematronResourceSchXslt_XSLT2.builder (aSCHRes)
.errorListener (new WrappedCollectingTransformErrorListener (aErrorList))
.languageCode (sLanguageCode)
.useCache (bUseCache)
.build ();
}
if (aVT == EValidationType.SCHEMATRON_SCHXSLT2_XSLT3)
{
final SchematronResourceSchXslt2 aSCHSCH = new SchematronResourceSchXslt2 (aSCHRes);
aSCHSCH.setErrorListener (new WrappedCollectingTransformErrorListener (aErrorList));
if (aLocale != null && StringHelper.isNotEmpty (aLocale.getLanguage ()))
aSCHSCH.setLanguageCode (aLocale.getLanguage ());
return aSCHSCH;
return SchematronResourceSchXslt2.builder (aSCHRes)
.errorListener (new WrappedCollectingTransformErrorListener (aErrorList))
.languageCode (sLanguageCode)
.useCache (bUseCache)
.build ();
}
if (aVT == EValidationType.SCHEMATRON_XSLT2)
{
final SchematronResourceXSLT aSCHXSLT = new SchematronResourceXSLT (aSCHRes);
aSCHXSLT.setErrorListener (new WrappedCollectingTransformErrorListener (aErrorList));
return aSCHXSLT;
return SchematronResourceXSLT.builder (aSCHRes)
.errorListener (new WrappedCollectingTransformErrorListener (aErrorList))
.useCache (bUseCache)
.build ();
}
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;
return SchematronResourceXSLT.builder (aSCHRes)
.errorListener (new WrappedCollectingTransformErrorListener (aErrorList))
.useCache (bUseCache)
.build ();
}
throw new IllegalStateException ("Unsupported Schematron validation type: " + aVT);
}
Expand Down Expand Up @@ -334,11 +377,11 @@ public ValidationResult applyValidation (@NonNull final IValidationSourceXML aSo
// 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);
final AbstractSchematronResource aSCH = _createSchematronResource (aLocale,
aErrorList,
m_bCacheSchematron,
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
Expand All @@ -352,7 +395,8 @@ public ValidationResult applyValidation (@NonNull final IValidationSourceXML aSo
case SVRL:
{
final SchematronOutputType aSVRL = aDoc == null || aDoc.getDocumentElement () == null ? null
: new SVRLMarshaller ().read (aDoc);
: new SVRLMarshaller ().setUseSchema (m_bValidateSVRL)
.read (aDoc);
if (aSVRL != null)
{
// Valid Schematron - interpret result
Expand Down Expand Up @@ -482,6 +526,7 @@ public ValidationExecutorSchematron getClone ()
m_aNamespaceContext);
ret.setStopValidationOnError (isStopValidationOnError ());
ret.setCacheArtefact (m_bCacheSchematron);
ret.setValidateSVRL (m_bValidateSVRL);
if (m_aCustomErrorDetails != null)
ret.addCustomErrorDetails (m_aCustomErrorDetails.getClone ());
return ret;
Expand All @@ -496,6 +541,7 @@ public boolean equals (final Object o)
return false;
final ValidationExecutorSchematron rhs = (ValidationExecutorSchematron) o;
return m_bCacheSchematron == rhs.m_bCacheSchematron &&
m_bValidateSVRL == rhs.m_bValidateSVRL &&
EqualsHelper.equals (m_sPrerequisiteXPath, rhs.m_sPrerequisiteXPath) &&
EqualsHelper.equals (m_aNamespaceContext, rhs.m_aNamespaceContext) &&
EqualsHelper.equals (m_aCustomErrorDetails, rhs.m_aCustomErrorDetails);
Expand All @@ -506,6 +552,7 @@ public int hashCode ()
{
return HashCodeGenerator.getDerived (super.hashCode ())
.append (m_bCacheSchematron)
.append (m_bValidateSVRL)
.append (m_sPrerequisiteXPath)
.append (m_aNamespaceContext)
.append (m_aCustomErrorDetails)
Expand All @@ -517,6 +564,7 @@ public String toString ()
{
return ToStringGenerator.getDerived (super.toString ())
.append ("CacheSchematron", m_bCacheSchematron)
.append ("ValidateSVRL", m_bValidateSVRL)
.appendIfNotNull ("PrerequisiteXPath", m_sPrerequisiteXPath)
.appendIfNotNull ("NamespaceContext", m_aNamespaceContext)
.appendIfNotNull ("CustomErrorLevels", m_aCustomErrorDetails)
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<dependency>
<groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-parent-pom</artifactId>
<version>9.2.0</version>
<version>10.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down