From 4c4bbf18ea66e166e949a9247b417d26844981ef Mon Sep 17 00:00:00 2001 From: Alexey Saenko Date: Wed, 7 Jan 2015 02:33:40 +0300 Subject: [PATCH] #32 StrictXML retries upon network failures --- src/main/java/com/jcabi/xml/StrictXML.java | 41 +++++++++++++++++-- .../java/com/jcabi/xml/StrictXMLTest.java | 39 ++++++++++++++---- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/jcabi/xml/StrictXML.java b/src/main/java/com/jcabi/xml/StrictXML.java index b35e707d..57b74d19 100644 --- a/src/main/java/com/jcabi/xml/StrictXML.java +++ b/src/main/java/com/jcabi/xml/StrictXML.java @@ -31,6 +31,7 @@ import com.jcabi.log.Logger; import java.io.IOException; +import java.net.SocketException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -192,14 +193,32 @@ private static String join(final Iterable iterable, final String sep) { private static Collection validate(final XML xml) { final Collection errors = new CopyOnWriteArrayList(); + final int amountOfRetries = 3; try { - final Schema schema = SchemaFactory - .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(); - final Validator validator = schema.newValidator(); + final Validator validator = newValidator(); validator.setErrorHandler( new XSDDocument.ValidationHandler(errors) ); - validator.validate(new DOMSource(xml.node())); + final DOMSource domsrc = new DOMSource(xml.node()); + for (int retry = 0; retry < amountOfRetries; ++retry) { + try { + validator.validate(domsrc); + // @checkstyle ModifiedControlVariableCheck (1 line) + retry = amountOfRetries; + } catch (final SocketException ex) { + Logger.error( + StrictXML.class, + "Try #%d of %d failed: %s: %s", + retry, + amountOfRetries, + ex.getClass().getName(), + ex.getMessage() + ); + if (amountOfRetries == retry + 1) { + throw new IllegalStateException(ex); + } + } + } } catch (final SAXException ex) { throw new IllegalStateException(ex); } catch (final IOException ex) { @@ -207,4 +226,18 @@ private static Collection validate(final XML xml) { } return errors; } + + /** + * Creates a new validator. + * @return A new validator + * @throws SAXException If fails + */ + private static Validator newValidator() throws SAXException { + final Schema schema = + SchemaFactory + .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) + .newSchema(); + return schema.newValidator(); + } + } diff --git a/src/test/java/com/jcabi/xml/StrictXMLTest.java b/src/test/java/com/jcabi/xml/StrictXMLTest.java index 3b1e0a6d..523ccf07 100644 --- a/src/test/java/com/jcabi/xml/StrictXMLTest.java +++ b/src/test/java/com/jcabi/xml/StrictXMLTest.java @@ -50,6 +50,19 @@ */ public final class StrictXMLTest { + /** + * Valid xml document. + */ + private static final String VALID_XML = "test"; + /** + * Xml schema document. + */ + private static final String XSD = StringUtils.join( + "", + "", + "" + ); + /** * StrictXML can pass a valid document. * @throws Exception If something goes wrong inside @@ -57,14 +70,8 @@ public final class StrictXMLTest { @Test public void passesValidXmlThrough() throws Exception { new StrictXML( - new XMLDocument("test"), - new XSDDocument( - StringUtils.join( - "", - "", - "" - ) - ) + new XMLDocument(VALID_XML), + new XSDDocument(XSD) ); } @@ -165,4 +172,20 @@ public Void call() throws Exception { MatcherAssert.assertThat(done.get(), Matchers.equalTo(Tv.FIFTY)); } + /** + * Passes valid xml with network problems. + * @todo #32 This test does nothing useful for the moment, to be a real test + * it needs to mock com.jcabi.xml.StrictXML.newValidator() and new mocked + * validator should throw few SocketException's while executing + * javax.xml.validation.Validator.validate(Source) in order to simulate the + * situation with network problems. For more details, see + * com.jcabi.xml.StrictXML.validate(XML) as well. + */ + @Test + public void passesValidXmlWithNetworkProblems() { + new StrictXML( + new XMLDocument(VALID_XML), new XSDDocument(XSD) + ); + } + }