You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by sc...@apache.org on 2006/10/18 02:16:41 UTC
svn commit: r465107 - in /webservices/commons/trunk/modules/axiom/modules:
axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/
axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/
Author: scheu
Date: Tue Oct 17 17:16:39 2006
New Revision: 465107
URL: http://svn.apache.org/viewvc?view=rev&rev=465107
Log:
WSCOMMONS-71
Contributor: Rich Scheuerle
Changes and Tests for errors found embedding OMSourcedElementImpl in an OM tree.
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNavigator.java
webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/OMSourcedElementTest.java
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNavigator.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNavigator.java?view=diff&rev=465107&r1=465106&r2=465107
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNavigator.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMNavigator.java Tue Oct 17 17:16:39 2006
@@ -22,7 +22,7 @@
import org.apache.axiom.om.OMNode;
/**
- * Refer to the testClass to find out how to use
+ * Refer to the test, org.apache.axiom.om.OMNavigatorTest, to find out how to use
* features like isNavigable, isComplete and step.
*/
public class OMNavigator {
@@ -123,28 +123,63 @@
* Private method to encapsulate the searching logic.
*/
private void updateNextNode() {
- if ((next instanceof OMElement) && !visited) {
- OMElementImpl e = (OMElementImpl) next;
- if (e.firstChild != null) {
- next = e.firstChild;
- } else if (e.isComplete()) {
- backtracked = true;
- } else {
- next = null;
- }
- } else {
- OMNode nextSibling = ((OMNodeImpl) next).nextSibling;
- //OMNode parent = next.getParent();
- OMContainer parent = next.getParent();
- if (nextSibling != null) {
- next = nextSibling;
- } else if ((parent != null) && parent.isComplete() && !(parent instanceof OMDocument)) {
- next = (OMNodeImpl) parent;
- backtracked = true;
- } else {
- next = null;
- }
- }
+
+ if ((next instanceof OMElement) && !visited) {
+ OMNode firstChild = _getFirstChild((OMElement) next);
+ if (firstChild != null) {
+ next = firstChild;
+ } else if (next.isComplete()) {
+ backtracked = true;
+ } else {
+ next = null;
+ }
+ } else {
+ OMContainer parent = next.getParent();
+ OMNode nextSibling = _getNextSibling(next);
+ if (nextSibling != null) {
+ next = nextSibling;
+ } else if ((parent != null) && parent.isComplete() && !(parent instanceof OMDocument)) {
+ next = (OMNodeImpl) parent;
+ backtracked = true;
+ } else {
+ next = null;
+ }
+ }
+ }
+
+ /**
+ * @param node
+ * @return first child or null
+ */
+ private OMNode _getFirstChild(OMElement node) {
+ if (node instanceof OMSourcedElementImpl) {
+ OMNode first = node.getFirstOMChild();
+ OMNode sibling = first;
+ while (sibling != null) {
+ sibling = sibling.getNextOMSibling();
+ }
+ return first;
+ } else {
+ // Field access is used to prevent advancing the parser.
+ // Some tests fail if the following is used
+ // return node.getFirstOMChild()
+ return ((OMElementImpl)node).firstChild;
+ }
+ }
+
+ /**
+ * @param node
+ * @return next sibling or null
+ */
+ private OMNode _getNextSibling(OMNode node) {
+ if (node instanceof OMSourcedElementImpl) {
+ return node.getNextOMSibling();
+ } else {
+ // Field access is used to prevent advancing the parser.
+ // Some tests fail if the following is used
+ // return node.getNextOMSibling()
+ return ((OMNodeImpl)node).nextSibling;
+ }
}
/**
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java?view=diff&rev=465107&r1=465106&r2=465107
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java Tue Oct 17 17:16:39 2006
@@ -109,7 +109,13 @@
*/
private XMLStreamReader getDirectReader() {
try {
- return dataSource.getReader();
+ // If expansion has occurred, then the reader from the datasource is consumed or stale.
+ // In such cases use the stream reader from the OMElementImpl
+ if (isDataSourceConsumed()) {
+ return super.getXMLStreamReader();
+ } else {
+ return dataSource.getReader();
+ }
} catch (XMLStreamException e) {
log.error("Could not get parser from data source for element " +
getPrintableName(), e);
@@ -150,12 +156,14 @@
throw new RuntimeException("Element name from data source is " +
reader.getLocalName() + ", not the expected " + getLocalName());
}
- if (!reader.getNamespaceURI().equals(getNamespace().getNamespaceURI())) {
- String uri = getNamespace().getNamespaceURI();
+ String readerURI = reader.getNamespaceURI();
+ readerURI = (readerURI == null) ? "" : readerURI;
+ String uri = getNamespace().getNamespaceURI();
+ if (!readerURI.equals(uri)) {
log.error("forceExpand: expected element namespace " +
getLocalName() + ", found " + uri);
throw new RuntimeException("Element namespace from data source is " +
- reader.getNamespaceURI() + ", not the expected " + uri);
+ readerURI + ", not the expected " + uri);
}
// set the builder for this element
@@ -173,6 +181,16 @@
public boolean isExpanded() {
return isParserSet;
}
+
+ /**
+ * Returns whether the datasource is consumed
+ */
+ private boolean isDataSourceConsumed() {
+ // The datasource might be consumed when it is touched/read.
+ // For now I am going to assume that it is since the OMDataSource currently has
+ // no way to convey this information.
+ return isExpanded();
+ }
/* (non-Javadoc)
* @see org.apache.axiom.om.OMElement#getChildElements()
@@ -421,7 +439,7 @@
* @see org.apache.axiom.om.OMElement#getQName()
*/
public QName getQName() {
- if (isParserSet) {
+ if (isExpanded()) {
return super.getQName();
} else if (definedNamespace != null) {
// always ignore prefix on name from sourced element
@@ -436,9 +454,13 @@
* @see org.apache.axiom.om.OMElement#toStringWithConsume()
*/
public String toStringWithConsume() throws XMLStreamException {
- StringWriter writer = new StringWriter();
- dataSource.serialize(writer, null);
- return writer.toString();
+ if (isDataSourceConsumed()) {
+ return super.toStringWithConsume();
+ } else {
+ StringWriter writer = new StringWriter();
+ dataSource.serialize(writer, null);
+ return writer.toString();
+ }
}
/* (non-Javadoc)
@@ -494,14 +516,22 @@
* @see org.apache.axiom.om.OMNode#internalSerialize(javax.xml.stream.XMLStreamWriter)
*/
public void internalSerialize(javax.xml.stream.XMLStreamWriter writer) throws XMLStreamException {
- internalSerializeAndConsume(writer);
+ if (isDataSourceConsumed()) {
+ super.internalSerialize(writer);
+ } else {
+ internalSerializeAndConsume(writer);
+ }
}
/* (non-Javadoc)
* @see org.apache.axiom.om.impl.llom.OMElementImpl#internalSerialize(javax.xml.stream.XMLStreamWriter, boolean)
*/
protected void internalSerialize(XMLStreamWriter writer, boolean cache) throws XMLStreamException {
- internalSerializeAndConsume(writer);
+ if (isDataSourceConsumed()) {
+ super.internalSerialize(writer, cache);
+ } else {
+ internalSerializeAndConsume(writer);
+ }
}
/* (non-Javadoc)
@@ -511,7 +541,11 @@
if (log.isDebugEnabled()) {
log.debug("serialize " + getPrintableName() + " to XMLStreamWriter");
}
- dataSource.serialize(writer);
+ if (isDataSourceConsumed()) {
+ super.internalSerializeAndConsume(writer);
+ } else {
+ dataSource.serialize(writer);
+ }
}
/* (non-Javadoc)
@@ -563,7 +597,11 @@
if (log.isDebugEnabled()) {
log.debug("serialize " + getPrintableName() + " to output stream");
}
- dataSource.serialize(output, null);
+ if (isDataSourceConsumed()) {
+ super.serializeAndConsume(output, null);
+ } else {
+ dataSource.serialize(output, null);
+ }
}
/* (non-Javadoc)
@@ -573,7 +611,11 @@
if (log.isDebugEnabled()) {
log.debug("serialize " + getPrintableName() + " to writer");
}
- dataSource.serialize(writer, null);
+ if (isDataSourceConsumed()) {
+ super.serializeAndConsume(writer);
+ } else {
+ dataSource.serialize(writer, null);
+ }
}
/* (non-Javadoc)
@@ -584,7 +626,11 @@
log.debug("serialize formatted " + getPrintableName() +
" to output stream");
}
- dataSource.serialize(output, format);
+ if (isDataSourceConsumed()) {
+ super.serializeAndConsume(output, format);
+ } else {
+ dataSource.serialize(output, format);
+ }
}
/* (non-Javadoc)
@@ -595,7 +641,11 @@
log.debug("serialize formatted " + getPrintableName() +
" to writer");
}
- dataSource.serialize(writer, format);
+ if (isDataSourceConsumed()) {
+ super.serializeAndConsume(writer, format);
+ } else {
+ dataSource.serialize(writer, format);
+ }
}
/* (non-Javadoc)
Modified: webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/OMSourcedElementTest.java
URL: http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/OMSourcedElementTest.java?view=diff&rev=465107&r1=465106&r2=465107
==============================================================================
--- webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/OMSourcedElementTest.java (original)
+++ webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/impl/llom/OMSourcedElementTest.java Tue Oct 17 17:16:39 2006
@@ -18,10 +18,14 @@
import org.apache.axiom.om.AbstractTestCase;
import org.apache.axiom.om.OMDataSource;
+import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.impl.OMNamespaceImpl;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory;
import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
@@ -31,6 +35,8 @@
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
+
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -42,6 +48,9 @@
import java.util.Arrays;
import java.util.Iterator;
+/**
+ * Tests the characteristics of OMSourcedElementImpl.
+ */
public class OMSourcedElementTest extends AbstractTestCase {
private static String testDocument =
"<library xmlns='http://www.sosnoski.com/uwjws/library' books='1'>" +
@@ -53,6 +62,7 @@
"<price>29.95</price></book></library>";
private OMSourcedElementImpl element;
+ private OMElement root;
/**
* @param testName
@@ -62,11 +72,17 @@
}
protected void setUp() throws Exception {
- element = new OMSourcedElementImpl("library",
- new OMNamespaceImpl("http://www.sosnoski.com/uwjws/library", ""),
- new OMLinkedListImplFactory(), new TestDataSource(testDocument));
+ OMFactory f = new OMLinkedListImplFactory();
+ OMNamespace ns = new OMNamespaceImpl("http://www.sosnoski.com/uwjws/library", "");
+ OMNamespace rootNS = new OMNamespaceImpl("http://sampleroot", "rootPrefix");
+ element = new OMSourcedElementImpl("library", ns, f, new TestDataSource(testDocument));
+ root = f.createOMElement("root", rootNS);
+ root.addChild(element);
}
+ /**
+ * Ensure that each method of OMElementImpl is overridden in OMSourcedElementImpl
+ */
public void testMethodOverrides() {
Method[] submeths = OMSourcedElementImpl.class.getDeclaredMethods();
Method[] supmeths = OMElementImpl.class.getDeclaredMethods();
@@ -97,6 +113,10 @@
return count;
}
+ /**
+ * Test serialization of OMSourcedElementImpl to a Stream
+ * @throws Exception
+ */
public void testSerializeToStream() throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
element.serialize(bos);
@@ -105,13 +125,22 @@
assertFalse("Element expansion when serializing", element.isExpanded());
}
+ /**
+ * Test serialization of OMSourcedElementImpl to a Writer
+ * @throws Exception
+ */
public void testSerializeToWriter() throws Exception {
StringWriter writer = new StringWriter();
element.serialize(writer);
- assertEquals("Serialized text error", testDocument, writer.toString());
+ String result = writer.toString();
+ assertEquals("Serialized text error", testDocument, result);
assertFalse("Element expansion when serializing", element.isExpanded());
}
+ /**
+ * Test serialization of OMSourcedElementImpl to an XMLWriter
+ * @throws Exception
+ */
public void testSerializeToXMLWriter() throws Exception {
StringWriter writer = new StringWriter();
XMLStreamWriter xmlwriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
@@ -120,7 +149,76 @@
assertEquals("Serialized text error", testDocument, writer.toString());
assertFalse("Element expansion when serializing", element.isExpanded());
}
+
+ /**
+ * Tests OMSourcedElement serialization when the root (parent) is serialized.
+ * @throws Exception
+ */
+ public void testSerializeToXMLWriterEmbedded() throws Exception {
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter xmlwriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+ root.serialize(writer);
+ xmlwriter.flush();
+ String result = writer.toString();
+ // We can't test for equivalence because the underlying OMSourceElement is
+ // streamed as it is serialized. So I am testing for an internal value.
+ assertTrue("Serialized text error" + result, result.indexOf("1930110111") > 0);
+ assertFalse("Element expansion when serializing", element.isExpanded());
+ }
+
+ /**
+ * Tests OMSourcedElement getReader support
+ * @throws Exception
+ */
+ public void testSerializeToXMLWriterFromReader() throws Exception {
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter xmlwriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+
+ StAXOMBuilder builder = new StAXOMBuilder(element.getXMLStreamReader());
+ OMDocument omDocument = builder.getDocument();
+ Iterator it = omDocument.getChildren();
+ while(it.hasNext()) {
+ OMNode omNode = (OMNode) it.next();
+ omNode.serializeAndConsume(xmlwriter);
+ }
+
+ xmlwriter.flush();
+ String result = writer.toString();
+ // We can't test for equivalence because the underlying OMSourceElement is
+ // changed as it is serialized. So I am testing for an internal value.
+ assertTrue("Serialized text error" + result, result.indexOf("1930110111") > 0);
+ assertFalse("Element expansion when serializing", element.isExpanded());
+ }
+
+ /**
+ * Tests OMSourcedElement processing when the getReader() of the parent is accessed.
+ * @throws Exception
+ */
+ public void testSerializeToXMLWriterFromReaderEmbedded() throws Exception {
+ StringWriter writer = new StringWriter();
+ XMLStreamWriter xmlwriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
+
+ StAXOMBuilder builder = new StAXOMBuilder(root.getXMLStreamReader());
+ OMDocument omDocument = builder.getDocument();
+ Iterator it = omDocument.getChildren();
+ while(it.hasNext()) {
+ OMNode omNode = (OMNode) it.next();
+ omNode.serializeAndConsume(xmlwriter);
+ }
+ xmlwriter.flush();
+ String result = writer.toString();
+ // We can't test for equivalence because the underlying OMSourceElement is
+ // changed as it is serialized. So I am testing for an internal value.
+ assertTrue("Serialized text error" + result, result.indexOf("1930110111") > 0);
+ // The implementation uses OMNavigator to walk the tree. Currently OMNavigator must
+ // expand the OMSourcedElement to correctly walk the elements. (See OMNavigator._getFirstChild)
+ //assertFalse("Element expansion when serializing", element.isExpanded());
+ }
+ /**
+ * Make sure the expanded OMSourcedElement behaves like a normal OMElement.
+ * @throws Exception
+ */
public void testExpand() throws Exception {
element.getAllDeclaredNamespaces();
assertEquals("Expanded namespace count error", 1,
@@ -146,10 +244,13 @@
}
private static class TestDataSource implements OMDataSource {
- private final String data;
+ // The data source is a ByteArrayInputStream so that we can verify that the datasource
+ // is only accessed once. Currently there is no way to identify a destructive vs. non-destructive OMDataSource.
+ private final ByteArrayInputStream data;
private TestDataSource(String data) {
- this.data = data;
+ this.data = new ByteArrayInputStream(data.getBytes());
+ this.data.mark(0);
}
/* (non-Javadoc)
@@ -157,7 +258,7 @@
*/
public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
try {
- output.write(data.getBytes());
+ output.write(getBytes());
} catch (IOException e) {
throw new XMLStreamException(e);
}
@@ -168,7 +269,7 @@
*/
public void serialize(Writer writer, OMOutputFormat format) throws XMLStreamException {
try {
- writer.write(data);
+ writer.write(getString());
} catch (IOException e) {
throw new XMLStreamException(e);
}
@@ -187,7 +288,24 @@
*/
public XMLStreamReader getReader() throws XMLStreamException {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
- return inputFactory.createXMLStreamReader(new StringReader(data));
+ return inputFactory.createXMLStreamReader(new StringReader(getString()));
+ }
+
+ private byte[] getBytes() throws XMLStreamException {
+ try {
+ // The data from the data source should only be accessed once
+ //data.reset();
+ byte[] rc = new byte[data.available()];
+ data.read(rc);
+ return rc;
+ } catch (IOException io) {
+ throw new XMLStreamException(io);
+ }
+ }
+
+ private String getString() throws XMLStreamException {
+ String text = new String(getBytes());
+ return text;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: commons-dev-help@ws.apache.org