diff --git a/ph-schematron-pure/src/main/java/com/helger/schematron/pure/xpath/XPathLetVariableResolver.java b/ph-schematron-pure/src/main/java/com/helger/schematron/pure/xpath/XPathLetVariableResolver.java index df0a36aad..bdf79cc91 100644 --- a/ph-schematron-pure/src/main/java/com/helger/schematron/pure/xpath/XPathLetVariableResolver.java +++ b/ph-schematron-pure/src/main/java/com/helger/schematron/pure/xpath/XPathLetVariableResolver.java @@ -30,9 +30,10 @@ @NotThreadSafe public class XPathLetVariableResolver implements XPathVariableResolver { - private final ThreadLocal> m_aVariables = new ThreadLocal<> () { + private final ThreadLocal > m_aTLVariables = new ThreadLocal <> () + { @Override - protected ICommonsMap initialValue() + protected ICommonsMap initialValue () { return new CommonsHashMap <> (); } @@ -48,7 +49,7 @@ public XPathLetVariableResolver (@Nullable final XPathVariableResolver aResolver public void setVariableValue (@Nonnull final QName aVariableName, @Nullable final Object aValue) { ValueEnforcer.notNull (aVariableName, "VariableName"); - m_aVariables.get().put (aVariableName, aValue); + m_aTLVariables.get ().put (aVariableName, aValue); } /** @@ -60,7 +61,7 @@ public void setVariableValue (@Nonnull final QName aVariableName, @Nullable fina public void removeVariable (@Nullable final QName aVariableName) { if (aVariableName != null) - m_aVariables.get().remove (aVariableName); + m_aTLVariables.get ().remove (aVariableName); } @Override @@ -69,7 +70,7 @@ public Object resolveVariable (@Nullable final QName aVariableName) if (aVariableName != null) { // 1. variables - final Object result = m_aVariables.get().get (aVariableName); + final Object result = m_aTLVariables.get ().get (aVariableName); if (result != null) return result; @@ -85,7 +86,7 @@ public Object resolveVariable (@Nullable final QName aVariableName) @Override public String toString () { - return new ToStringGenerator (this).append ("Variables", m_aVariables) + return new ToStringGenerator (this).append ("Variables", m_aTLVariables.get ()) .append ("DelegatedResolver", m_aDelegatedResolver) .getToString (); } diff --git a/ph-schematron-pure/src/test/java/com/helger/schematron/pure/supplementary/Issue182Test.java b/ph-schematron-pure/src/test/java/com/helger/schematron/pure/supplementary/Issue182Test.java index 0132ba7b6..e2330b97a 100644 --- a/ph-schematron-pure/src/test/java/com/helger/schematron/pure/supplementary/Issue182Test.java +++ b/ph-schematron-pure/src/test/java/com/helger/schematron/pure/supplementary/Issue182Test.java @@ -25,6 +25,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; +import javax.annotation.Nonnull; + import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -51,17 +53,16 @@ public final class Issue182Test private static final String XML_B = "src/test/resources/external/issues/github182/testB.xml"; private SchematronResourcePure m_aSCH; - - final private AtomicInteger errorCount = new AtomicInteger(0); + private final AtomicInteger m_aErrorCount = new AtomicInteger (0); @Before - public void loadSchematron() + public void loadSchematron () { if (m_aSCH == null) m_aSCH = SchematronResourcePure.fromFile (SCH); } - public void validateAndProduceSVRL (final File aXML) throws Exception + private void _validateAndProduceSVRL (@Nonnull final File aXML) throws Exception { m_aSCH.validateCompletely (new LoggingPSErrorHandler ()); @@ -69,50 +70,52 @@ public void validateAndProduceSVRL (final File aXML) throws Exception final SchematronOutputType aSVRL = m_aSCH.applySchematronValidationToSVRL (new FileSystemResource (aXML)); assertNotNull (aSVRL); if (true) - LOGGER.info (aXML.getName() + " " + new SVRLMarshaller ().getAsString (aSVRL)); + LOGGER.info (aXML.getName () + " " + new SVRLMarshaller ().getAsString (aSVRL)); if (SVRLHelper.getAllFailedAssertionsAndSuccessfulReports (aSVRL).size () != 0) - errorCount.incrementAndGet(); + m_aErrorCount.incrementAndGet (); } @Test public void testConcurrency () throws Exception { - int numberOfThreads = 2; - ExecutorService service = Executors.newFixedThreadPool (10); - CountDownLatch startLatch = new CountDownLatch (1); - CountDownLatch finishedLatch = new CountDownLatch (numberOfThreads); - for (int i = 0; i < numberOfThreads; i += 2) { - service.execute (() -> { + // Must be a multiple of 2 + final int nNumberOfThreads = 10; + final ExecutorService aES = Executors.newFixedThreadPool (nNumberOfThreads); + final CountDownLatch aStartLatch = new CountDownLatch (1); + final CountDownLatch aFinishedLatch = new CountDownLatch (nNumberOfThreads); + for (int i = 0; i < nNumberOfThreads; i += 2) + { + aES.execute ( () -> { try { - startLatch.await (); - validateAndProduceSVRL (new File (XML_A)); + aStartLatch.await (); + _validateAndProduceSVRL (new File (XML_A)); } - catch (Exception e) + catch (final Exception e) { LOGGER.error ("Error validating XML A", e); } - finishedLatch.countDown (); + aFinishedLatch.countDown (); }); - service.execute(() -> { + aES.execute ( () -> { try { - startLatch.await (); - validateAndProduceSVRL (new File (XML_B)); + aStartLatch.await (); + _validateAndProduceSVRL (new File (XML_B)); } - catch (Exception e) + catch (final Exception e) { LOGGER.error ("Error validating XML B", e); } - finishedLatch.countDown (); + aFinishedLatch.countDown (); }); } // All threads are waiting on startLatch, release them all together - startLatch.countDown (); + aStartLatch.countDown (); // Wait until all threads are finished - finishedLatch.await (); + aFinishedLatch.await (); - assertEquals (0, errorCount.get()); + assertEquals (0, m_aErrorCount.get ()); } }