Skip to content

Commit

Permalink
Adding XpathDoc and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Stockdill committed Jun 13, 2011
1 parent 2e2f0e2 commit 4e7baf0
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 0 deletions.
133 changes: 133 additions & 0 deletions src/main/java/knzn/xml/XpathDoc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package knzn.xml;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.xml.sax.InputSource;

public final class XpathDoc {

public static class InputStreamInputSourceHolder implements InputSourceHolder {

private final InputStream stream;

public InputStreamInputSourceHolder(final InputStream stream) {
this.stream = stream;
}

public void close() {
try {
stream.close();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Could not close stream", e);
}
}

public InputSource getInputSource() {
return new InputSource(stream);
}
}


private static class FileInputSourceHolder implements InputSourceHolder {

private final File file;
private InputStreamInputSourceHolder sourceHolder;

public FileInputSourceHolder(final File file) throws FileNotFoundException {
this.file = file;
if (!this.file.exists()) {
throw new FileNotFoundException("Not found: " + this.file);
}
}

public FileInputSourceHolder(final String xmlFile)
throws FileNotFoundException {
this(new File(xmlFile));
}

public void close() {
sourceHolder.close();
}

public InputSource getInputSource() {
try {
sourceHolder = new InputStreamInputSourceHolder(new FileInputStream(file));
return sourceHolder.getInputSource();
} catch (FileNotFoundException e) {
LOGGER.log(Level.SEVERE, "Could not find file", e);
throw new IllegalStateException(e);
}
}
}

private interface InputSourceHolder {
void close();

InputSource getInputSource();
}

private static class StringInputSourceHolder implements InputSourceHolder {

private final String text;
private InputStreamInputSourceHolder sourceHolder;

public StringInputSourceHolder(final String text) {
this.text = text;
}

public void close() {
sourceHolder.close();
}

public InputSource getInputSource() {
sourceHolder = new InputStreamInputSourceHolder(new ByteArrayInputStream(text.getBytes()));
return sourceHolder.getInputSource();
}

}

private static final Logger LOGGER = Logger.getLogger(XpathDoc.class
.getSimpleName());


public static XpathDoc newXpathDocFromFile(final File xmlFile)
throws FileNotFoundException {
return new XpathDoc(new FileInputSourceHolder(xmlFile));
}

public static XpathDoc newXpathDocFromFile(final String xmlFile)
throws FileNotFoundException {
return new XpathDoc(new FileInputSourceHolder(xmlFile));
}

public static XpathDoc newXpathDocFromString(final String xml) {
return new XpathDoc(new StringInputSourceHolder(xml));
}

private final XPath xPath;
private final InputSourceHolder inputSourceHolder;

private XpathDoc(final InputSourceHolder inputSourceHolder) {
this.inputSourceHolder = inputSourceHolder;
xPath = XPathFactory.newInstance().newXPath();
}

public String evaluate(final String expression)
throws XPathExpressionException {
final InputSource inputSource = inputSourceHolder.getInputSource();
final String result = xPath.evaluate(expression, inputSource);
inputSourceHolder.close();
return result;
}
}
73 changes: 73 additions & 0 deletions src/test/java/knzn/xml/XpathDocTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package knzn.xml;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class XpathDocTest {

private static final Logger LOGGER = Logger.getLogger(XpathDocTest.class.getSimpleName());

private static final String TEST_XML = "/knzn/xml/xpath_test.xml";

private static String readXmlFromFile() throws IOException {
final InputStream inputStream = XpathDocTest.class
.getResourceAsStream(TEST_XML);
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
IOUtils.copy(inputStream, bout);

return new String(bout.toByteArray());
}

@Test
public void testNewXpathDocFromFile() throws XPathExpressionException, FileNotFoundException {
final File file = FileUtils.toFile(
XpathDocTest.class.getResource(TEST_XML));
final String xmlFile = file.getAbsolutePath();
LOGGER.info("xmlFile: " + xmlFile);

assertXpathDoc(
XpathDoc.newXpathDocFromFile(xmlFile));

assertXpathDoc(
XpathDoc.newXpathDocFromFile(file));
}


@Test
public void testNewXpathDocFromFileMissing() throws XPathExpressionException {
try {
XpathDoc.newXpathDocFromFile("missing_file.xml");
fail("Missing file exception not thrown");
} catch (FileNotFoundException e) {
assertEquals("Exception message not correct",
"java.io.FileNotFoundException: Not found: missing_file.xml",
e.toString());
}
}

@Test
public void testNewXpathDocFromString() throws XPathExpressionException, IOException {
final String xml = readXmlFromFile();
assertXpathDoc(XpathDoc.newXpathDocFromString(xml));
}

private void assertXpathDoc(final XpathDoc xpathDoc) throws XPathExpressionException {
assertEquals("Expected name not found", "Tuck",
xpathDoc.evaluate("//wonder_pets/wonder_pet[1]/name"));
assertEquals("Expected type not found", "turtle",
xpathDoc.evaluate("//wonder_pets/wonder_pet[1]/@type"));
}
}
11 changes: 11 additions & 0 deletions src/test/resources/knzn/xml/xpath_test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<wonder_pets>
<wonder_pet type="turtle">
<name>Tuck</name>
</wonder_pet>
<wonder_pet type="guinea pig">
<name>Lenny</name>
</wonder_pet>
<wonder_pet type="boy">
<name>Jonah</name>
</wonder_pet>
</wonder_pets>

0 comments on commit 4e7baf0

Please sign in to comment.