Skip to content
Browse files

Fix SAXOutputter and JDOMResult bugs and 'cover' JDOMResult

fixes #40 on SAXOutputter - adds handling for Attributes.
fixes #39 on JDOMResult - returns a null Document for invalid content
  • Loading branch information...
1 parent 9dc73e3 commit f026e89780b3259fa049fd223ceaacfee16fce65 @rolfl rolfl committed
View
23 core/src/java/org/jdom2/output/SAXOutputter.java
@@ -958,6 +958,29 @@ private Attributes startPrefixMapping(Element element,
}
}
}
+
+ // Fire any namespace on Attributes that were not explicity added as additionals.
+ List attributes = element.getAttributes();
+ if (attributes != null) {
+ Iterator itr = attributes.iterator();
+ while (itr.hasNext()) {
+ Attribute att = (Attribute)itr.next();
+ ns = att.getNamespace();
+ String prefix = ns.getPrefix();
+ String uri = namespaces.getURI(prefix);
+ if (!ns.getURI().equals(uri)) {
+ namespaces.push(ns);
+ nsAtts = this.addNsAttribute(nsAtts, ns);
+ try {
+ contentHandler.startPrefixMapping(prefix, ns.getURI());
+ }
+ catch (SAXException se) {
+ throw new JDOMException(
+ "Exception in startPrefixMapping", se);
+ }
+ }
+ }
+ }
return nsAtts;
}
View
1 core/src/java/org/jdom2/transform/JDOMResult.java
@@ -267,6 +267,7 @@ public Document getDocument() {
catch (RuntimeException ex1) {
// Some of the result nodes are not valid children of a
// Document node. => return null.
+ return null;
}
}
}
View
5 test/src/java/org/jdom2/test/cases/Alltests.java
@@ -74,7 +74,9 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
import org.jdom2.test.cases.output.TestFormat;
import org.jdom2.test.cases.output.TestSAXOutputter;
import org.jdom2.test.cases.output.TestXMLOutputter;
+import org.jdom2.test.cases.transform.TestJDOMResult;
import org.jdom2.test.cases.transform.TestJDOMSource;
+import org.jdom2.test.cases.transform.TestJDOMTransform;
import org.jdom2.test.util.ListTest;
@@ -161,7 +163,8 @@ public static Test suite() {
// Transformer Tests
suite.addTest(new JUnit4TestAdapter(TestJDOMSource.class));
- // suite.addTest(new JUnit4TestAdapter(TestJDOMTransform.class));
+ suite.addTest(new JUnit4TestAdapter(TestJDOMResult.class));
+ suite.addTest(new JUnit4TestAdapter(TestJDOMTransform.class));
// XPath tests.
//suite.addTest(new JUnit4TestAdapter(TestJaxenXPath.class));
View
9 test/src/java/org/jdom2/test/cases/output/TestSAXOutputter.java
@@ -568,6 +568,15 @@ public void testOutputDocumentFull() {
}
@Test
+ public void testOutputDocumentRootAttNS() {
+ Document doc = new Document();
+ Element e = new Element("root");
+ e.setAttribute(new Attribute("att", "val", Namespace.getNamespace("ans", "mynamespace")));
+ doc.addContent(e);
+ roundTrip(doc);
+ }
+
+ @Test
public void testOutputDocumentFullNoLexical() throws JDOMException {
Document doc = new Document();
doc.addContent(new ProcessingInstruction("jdomtest", ""));
View
175 test/src/java/org/jdom2/test/cases/transform/TestJDOMResult.java
@@ -0,0 +1,175 @@
+package org.jdom2.test.cases.transform;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMFactory;
+import org.jdom2.ProcessingInstruction;
+import org.jdom2.Text;
+import org.jdom2.UncheckedJDOMFactory;
+import org.jdom2.transform.JDOMResult;
+import org.junit.Test;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.DefaultHandler2;
+import org.xml.sax.ext.LexicalHandler;
+
+public class TestJDOMResult {
+
+ /* *************************************************
+ * These tests cover only a small part of JDOMResult.
+ * The more complex code relates to accepting the
+ * events fired during transformation. Those calls
+ * are tested in TestJDOMTransform which puts 'real'
+ * transformations through JDOMResult.
+ * *************************************************/
+
+ @Test
+ public void testJDOMResult() {
+ JDOMResult result = new JDOMResult();
+ assertNotNull(result.getHandler());
+ assertTrue(result.getHandler() == result.getLexicalHandler());
+ }
+
+ @Test
+ public void testSetHandlerContentHandler() {
+ JDOMResult result = new JDOMResult();
+ ContentHandler handler = result.getHandler();
+ assertNotNull(handler);
+ ContentHandler toset = new DefaultHandler2();
+
+ // we do not allow others to change the handler on the JDOMResult
+ // so this should do nothing.
+ result.setHandler(toset);
+
+ assertTrue(handler == result.getHandler());
+ }
+
+ @Test
+ public void testSetLexicalHandlerLexicalHandler() {
+ JDOMResult result = new JDOMResult();
+ LexicalHandler handler = result.getLexicalHandler();
+ assertNotNull(handler);
+ LexicalHandler toset = new DefaultHandler2();
+
+ // we do not allow others to change the handler on the JDOMResult
+ // so this should do nothing.
+ result.setLexicalHandler(toset);
+
+ assertTrue(handler == result.getLexicalHandler());
+ }
+
+ @Test
+ public void testGetSetFactory() {
+ JDOMResult result = new JDOMResult();
+ JDOMFactory faca = result.getFactory();
+ assertTrue(faca == null);
+ JDOMFactory facb = new UncheckedJDOMFactory();
+ result.setFactory(facb);
+ assertTrue(facb == result.getFactory());
+ result.setFactory(null);
+ assertTrue(null == result.getFactory());
+ }
+
+ @Test
+ public void testDocumentResult() {
+ // in this context, the 'source' provides us with a document.
+ // the expectation is that getDocument() will work to retrieve the result
+ // but, getNodes will only work if called first... subsequent calls
+ // return an empty list.
+ JDOMResult result = new JDOMResult();
+ assertNull(result.getDocument());
+ assertTrue(result.getResult().isEmpty());
+
+ // OK, we expect things now.
+ Element root = new Element("root");
+ Document doc = new Document(root);
+ result.setDocument(doc);
+ // test a few times. Should not change.
+ assertTrue(doc == result.getDocument());
+ assertTrue(doc == result.getDocument());
+ assertTrue(doc == result.getDocument());
+ // after a call to getDocument, getResult should be empty.
+ assertTrue(result.getResult().isEmpty());
+ // messing with the getDocument side of things should not mess with the
+ // document tree.
+ assertTrue(root.getParent() == doc);
+
+ // OK, reset the result.
+ result.setDocument(doc);
+ // should be something there this time
+ assertTrue(result.getResult().size() == 1);
+ // but, now it is cached too. we can get the result...
+ assertTrue(root == result.getResult().get(0));
+ // using getResult() returns detached content, so....
+ assertFalse(doc.hasRootElement());
+ assertTrue(null == root.getParent());
+ // further, a successful getResult() call invalidates the getDocument()
+ // so that will now be null.
+ assertNull(result.getDocument());
+ }
+
+ @Test
+ public void testNodesResult() {
+ // In this context, the 'source' provides us with a list of Nodes.
+ // In theory, these nodes should all be legal Element content.
+ JDOMResult result = new JDOMResult();
+ assertNull(result.getDocument());
+ assertTrue(result.getResult().isEmpty());
+
+ // OK, we expect things now.
+ Element child = new Element("child");
+ Text text = new Text("text");
+ ArrayList<Object> nodes = new ArrayList<Object>(2);
+ nodes.add(child);
+ nodes.add(text);
+
+ result.setResult(nodes);
+
+ // test a few times. Should not change.
+ assertTrue(nodes == result.getResult());
+ assertTrue(!nodes.isEmpty());
+ assertTrue(nodes == result.getResult());
+ assertTrue(nodes == result.getResult());
+
+ // A call to getDocument should be null after a call to getResult().
+ assertTrue(null == result.getDocument());
+
+ // after a null call to getDocument, getResult should be unchanged.
+ assertTrue(nodes == result.getResult());
+
+ // OK, reset the result.
+ result.setResult(nodes);
+ // should still be nothing there... because Text is not valid Document content
+ assertNull(result.getDocument());
+ // but, the results are there still.
+ assertTrue(result.getResult().size() == 2);
+
+ // So, make the content valid for a Document.
+ nodes.remove(1); // get rid of text.
+ // insert a PI in front of the element.
+ nodes.add(0, new ProcessingInstruction("jdomtest", ""));
+
+ assertTrue(child.getParent() == null);
+
+ // This time we expect a document result.
+ result.setResult(nodes);
+ Document doc = result.getDocument();
+ assertNotNull(doc);
+ assertTrue (doc == child.getParent());
+
+ }
+
+
+ /* *************************************************
+ * These are the more challenging tests. *
+ * part of this file because we actually need *
+ * to fire the various events through the system *
+ * in order to test the Transformation results *
+ * *************************************************/
+
+
+
+}
View
88 test/src/java/org/jdom2/test/cases/transform/TestJDOMTransform.java
@@ -0,0 +1,88 @@
+package org.jdom2.test.cases.transform;
+
+import static org.junit.Assert.*;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.jdom2.Attribute;
+import org.jdom2.Comment;
+import org.jdom2.DocType;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.Namespace;
+import org.jdom2.ProcessingInstruction;
+import org.jdom2.Text;
+import org.jdom2.input.SAXBuilder;
+import org.jdom2.output.XMLOutputter;
+import org.jdom2.transform.JDOMResult;
+import org.jdom2.transform.JDOMSource;
+import org.junit.Test;
+
+public class TestJDOMTransform {
+
+ private static final void checkTransform(Document doc) {
+ XMLOutputter out = new XMLOutputter();
+ String expect = out.outputString(doc);
+
+ try {
+
+ Transformer t = TransformerFactory.newInstance().newTransformer();
+ StringWriter sw = new StringWriter();
+ t.transform(new JDOMSource(doc), new StreamResult(sw));
+ JDOMResult res = new JDOMResult();
+ String intermediate = sw.toString();
+ t.transform(new StreamSource(new StringReader(intermediate)), res);
+ Document redone = res.getDocument();
+ String actual = out.outputString(redone);
+ assertEquals(expect, actual);
+ } catch (TransformerException te) {
+ te.printStackTrace();
+ fail (te.getMessage());
+ }
+ }
+
+ @Test
+ public void testRootAttNS() {
+ Document doc = new Document();
+ Element e = new Element("root");
+ e.setAttribute(new Attribute("att", "val", Namespace.getNamespace("ans", "mynamespace")));
+ doc.addContent(e);
+ checkTransform(doc);
+ }
+
+
+ @Test
+ public void testSimpleDocument() {
+ checkTransform(new Document(new Element("root")));
+ }
+
+ @Test
+ public void testComplexDocument() {
+ // throw a lot of junk at the process... testing it all.
+ Document doc = new Document();
+ doc.addContent(new Comment("This is a document"));
+ doc.addContent(new ProcessingInstruction("jdomtest", ""));
+ Element root = new Element("root");
+ // messes up the ordering of things ... root.setAttribute(new Attribute("att", "val"));
+ root.setAttribute(new Attribute("att", "val", Namespace.getNamespace("ans", "attns")));
+ root.addContent(new Text(" "));
+ root.addContent(new Element("child", Namespace.getNamespace("nopfx")));
+ root.addContent(new Comment("comment"));
+ Element otherchild = new Element("child", Namespace.getNamespace("cns", "childns"));
+ otherchild.addNamespaceDeclaration(Namespace.getNamespace("abc","oddns"));
+ Element grandchild = new Element("leaf", Namespace.getNamespace("abc", "oddns"));
+ otherchild.addContent(grandchild);
+ root.addContent(otherchild);
+ doc.addContent(root);
+ checkTransform(doc);
+
+ }
+
+}

0 comments on commit f026e89

Please sign in to comment.
Something went wrong with that request. Please try again.