Skip to content

Commit

Permalink
#32 StrictXML retries upon network failures
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Saenko committed Jan 6, 2015
1 parent b66a67c commit 4c4bbf1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 12 deletions.
41 changes: 37 additions & 4 deletions src/main/java/com/jcabi/xml/StrictXML.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -192,19 +193,51 @@ private static String join(final Iterable<?> iterable, final String sep) {
private static Collection<SAXParseException> validate(final XML xml) {
final Collection<SAXParseException> errors =
new CopyOnWriteArrayList<SAXParseException>();
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) {
throw new IllegalStateException(ex);
}
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();
}

}
39 changes: 31 additions & 8 deletions src/test/java/com/jcabi/xml/StrictXMLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,28 @@
*/
public final class StrictXMLTest {

/**
* Valid xml document.
*/
private static final String VALID_XML = "<root>test</root>";
/**
* Xml schema document.
*/
private static final String XSD = StringUtils.join(
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>",
"<xs:element name='root' type='xs:string'/>",
"</xs:schema>"
);

/**
* StrictXML can pass a valid document.
* @throws Exception If something goes wrong inside
*/
@Test
public void passesValidXmlThrough() throws Exception {
new StrictXML(
new XMLDocument("<root>test</root>"),
new XSDDocument(
StringUtils.join(
"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>",
"<xs:element name='root' type='xs:string'/>",
"</xs:schema>"
)
)
new XMLDocument(VALID_XML),
new XSDDocument(XSD)
);
}

Expand Down Expand Up @@ -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)
);
}

}

0 comments on commit 4c4bbf1

Please sign in to comment.