summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-05-11 07:45:29 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-05-11 07:45:29 +0000
commita3cbf8e5ffabac239cd965d8c0f9c680a83246f7 (patch)
tree03eede7de9657506784538ce0e3786a808e4ab22 /branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java
parenta7a97f2875dc162750736b9611e3e8bc8c13f145 (diff)
Add a new soap/jms transport module copied from the Apache WS Commons transports but with the code backported to work with Axis2 1.4.1
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@773489 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to '')
-rw-r--r--branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java437
1 files changed, 437 insertions, 0 deletions
diff --git a/branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java b/branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java
new file mode 100644
index 0000000000..c656949b1f
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-ws-axis2-jms/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/format/WrappedTextNodeStreamReader.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.binding.ws.axis2.format;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Collections;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.axiom.om.impl.EmptyOMLocation;
+import org.apache.axiom.om.impl.llom.util.NamespaceContextImpl;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * {@link XMLInputStreamReader} implementation that
+ * represents a text node wrapped inside an element. The text data is provided by a
+ * {@link java.io.Reader Reader}.
+ * <p>
+ * It will produce the following sequence of XML events:
+ * <ul>
+ * <li>START_DOCUMENT</li>
+ * <li>START_ELEMENT</li>
+ * <li>(CHARACTER)*</li>
+ * <li>END_ELEMENT</li>
+ * <li>END_DOCMENT</li>
+ * </ul>
+ * The class is implemented as a simple state machine, where the state is identified
+ * by the current event type. The initial state is <tt>START_DOCUMENT</tt> and the
+ * following transitions are triggered by {@link #next()}:
+ * <ul>
+ * <li>START_DOCUMENT &rarr; START_ELEMENT</li>
+ * <li>START_ELEMENT &rarr; END_ELEMENT (if character stream is empty)</li>
+ * <li>START_ELEMENT &rarr; CHARACTERS (if character stream is not empty)</li>
+ * <li>CHARACTERS &rarr; CHARACTERS (if data available in stream)</li>
+ * <li>CHARACTERS &rarr; END_ELEMENT (if end of stream reached)</li>
+ * <li>END_ELEMENT &rarr; END_DOCUMENT</li>
+ * </ul>
+ * Additionally, {@link #getElementText()} triggers the following transition:
+ * <ul>
+ * <li>START_ELEMENT &rarr; END_ELEMENT</li>
+ * </ul>
+ * Note that since multiple consecutive CHARACTERS events may be returned, this
+ * "parser" is not coalescing.
+ *
+ */
+// TODO: This class has been copied from Synapse (package org.apache.synapse.util).
+// Once it has been moved to Axis2 or Axiom, remove the duplicate from Synapse.
+public class WrappedTextNodeStreamReader implements XMLStreamReader {
+ /**
+ * Location object returned by {@link #getLocation()}.
+ * It always returns -1 for the location and null for the publicId and systemId.
+ */
+ private final static Location EMPTY_LOCATION = new EmptyOMLocation();
+
+ /**
+ * The qualified name of the wrapper element.
+ */
+ private final QName wrapperElementName;
+
+ /**
+ * The Reader object that represents the text data.
+ */
+ private final Reader reader;
+
+ /**
+ * The maximum number of characters to return for each CHARACTER event.
+ */
+ private final int chunkSize;
+
+ /**
+ * The type of the current XML event.
+ */
+ private int eventType = START_DOCUMENT;
+
+ /**
+ * The character data for the current event. This is only set if the current
+ * event is a CHARACTER event. The size of the array is determined by
+ * {@link #chunkSize}
+ */
+ private char[] charData;
+
+ /**
+ * The length of the character data in {@link #charData}.
+ */
+ private int charDataLength;
+
+ /**
+ * The namespace context applicable in the scope of the wrapper element.
+ * Beside the default mappings for xml and xmlns, it only contains the
+ * mapping for the namespace of the wrapper element.
+ * This attribute is initialized lazily by {@link #getNamespaceContext()}.
+ */
+ private NamespaceContext namespaceContext;
+
+ /**
+ * Create a new instance.
+ *
+ * @param wrapperElementName the qualified name of the wrapper element
+ * @param reader the Reader object holding the character data to be wrapped
+ * @param chunkSize the maximum number of characters that are returned for each CHARACTER event
+ */
+ public WrappedTextNodeStreamReader(QName wrapperElementName, Reader reader, int chunkSize) {
+ this.wrapperElementName = wrapperElementName;
+ this.reader = reader;
+ this.chunkSize = chunkSize;
+ }
+
+ /**
+ * Create a new instance with chunk size 4096.
+ *
+ * @param wrapperElementName the qualified name of the wrapper element
+ * @param reader the Reader object holding the character data to be wrapped
+ */
+ public WrappedTextNodeStreamReader(QName wrapperElementName, Reader reader) {
+ this(wrapperElementName, reader, 4096);
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ // We don't define any properties
+ return null;
+ }
+
+ //
+ // Methods to manipulate the parser state
+ //
+
+ public boolean hasNext() throws XMLStreamException {
+ return eventType != END_DOCUMENT;
+ }
+
+ public int next() throws XMLStreamException {
+ // Determine next event type based on current event type. If current event type
+ // is START_ELEMENT or CHARACTERS, pull new data from the reader.
+ switch (eventType) {
+ case START_DOCUMENT:
+ eventType = START_ELEMENT;
+ break;
+ case START_ELEMENT:
+ charData = new char[chunkSize];
+ // No break here!
+ case CHARACTERS:
+ try {
+ charDataLength = reader.read(charData);
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ if (charDataLength == -1) {
+ charData = null;
+ eventType = END_ELEMENT;
+ } else {
+ eventType = CHARACTERS;
+ }
+ break;
+ case END_ELEMENT:
+ eventType = END_DOCUMENT;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return eventType;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ // We don't have white space, comments or processing instructions
+ throw new XMLStreamException("Current event is not white space");
+ }
+
+ public int getEventType() {
+ return eventType;
+ }
+
+ public boolean isStartElement() { return eventType == START_ELEMENT; }
+ public boolean isEndElement() { return eventType == END_ELEMENT; }
+ public boolean isCharacters() { return eventType == CHARACTERS; }
+ public boolean isWhiteSpace() { return false; }
+ public boolean hasText() { return eventType == CHARACTERS; }
+ public boolean hasName() { return eventType == START_ELEMENT || eventType == END_ELEMENT; }
+
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ if (type != eventType
+ || (namespaceURI != null && !namespaceURI.equals(getNamespaceURI()))
+ || (localName != null && !namespaceURI.equals(getLocalName()))) {
+ throw new XMLStreamException("Unexpected event type");
+ }
+ }
+
+ public Location getLocation() {
+ // We do not support location information
+ return EMPTY_LOCATION;
+ }
+
+ public void close() throws XMLStreamException {
+ // Javadoc says that this method should not close the underlying input source,
+ // but we need to close the reader somewhere.
+ try {
+ reader.close();
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ }
+
+ //
+ // Methods related to the xml declaration.
+ //
+
+ public String getEncoding() {
+ // Encoding is not known (not relevant?)
+ return null;
+ }
+
+ public String getCharacterEncodingScheme() {
+ // Encoding is not known (not relevant?)
+ return null;
+ }
+
+ public String getVersion() {
+ // Version is not relevant
+ return null;
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+ public boolean isStandalone() {
+ return true;
+ }
+
+ //
+ // Methods related to the namespace context
+ //
+
+ public NamespaceContext getNamespaceContext() {
+ if (namespaceContext == null) {
+ namespaceContext = new NamespaceContextImpl(Collections.singletonMap(wrapperElementName.getPrefix(), wrapperElementName.getNamespaceURI()));
+ }
+ return namespaceContext;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ String namespaceURI = getNamespaceContext().getNamespaceURI(prefix);
+ // NamespaceContext#getNamespaceURI and XMLStreamReader#getNamespaceURI have slightly
+ // different semantics for unbound prefixes.
+ return namespaceURI.equals(XMLConstants.NULL_NS_URI) ? null : prefix;
+ }
+
+ //
+ // Methods related to elements
+ //
+
+ private void checkStartElement() {
+ if (eventType != START_ELEMENT) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String namespaceURI, String localName) {
+ checkStartElement();
+ return null;
+ }
+
+ public int getAttributeCount() {
+ checkStartElement();
+ return 0;
+ }
+
+ public QName getAttributeName(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeLocalName(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributePrefix(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeNamespace(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeType(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public String getAttributeValue(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ public boolean isAttributeSpecified(int index) {
+ checkStartElement();
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private void checkElement() {
+ if (eventType != START_ELEMENT && eventType != END_ELEMENT) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getName() {
+ return null;
+ }
+
+ public String getLocalName() {
+ checkElement();
+ return wrapperElementName.getLocalPart();
+ }
+
+ public String getPrefix() {
+ return wrapperElementName.getPrefix();
+ }
+
+ public String getNamespaceURI() {
+ checkElement();
+ return wrapperElementName.getNamespaceURI();
+ }
+
+ public int getNamespaceCount() {
+ checkElement();
+ // There is one namespace declared on the wrapper element
+ return 1;
+ }
+
+ public String getNamespacePrefix(int index) {
+ checkElement();
+ if (index == 0) {
+ return wrapperElementName.getPrefix();
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public String getNamespaceURI(int index) {
+ checkElement();
+ if (index == 0) {
+ return wrapperElementName.getNamespaceURI();
+ } else {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (eventType == START_ELEMENT) {
+ // Actually the purpose of this class is to avoid storing
+ // the character data entirely in memory, but if the caller
+ // wants a String, we don't have the choice...
+ try {
+ String result = IOUtils.toString(reader);
+ eventType = END_ELEMENT;
+ return result;
+ }
+ catch (IOException ex) {
+ throw new XMLStreamException(ex);
+ }
+ } else {
+ throw new XMLStreamException("Current event is not a START_ELEMENT");
+ }
+ }
+
+ private void checkCharacters() {
+ if (eventType != CHARACTERS) {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getText() {
+ checkCharacters();
+ return new String(charData, 0, charDataLength);
+ }
+
+ public char[] getTextCharacters() {
+ checkCharacters();
+ return charData;
+ }
+
+ public int getTextStart() {
+ checkCharacters();
+ return 0;
+ }
+
+ public int getTextLength() {
+ checkCharacters();
+ return charDataLength;
+ }
+
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+ checkCharacters();
+ int c = Math.min(charDataLength-sourceStart, length);
+ System.arraycopy(charData, sourceStart, target, targetStart, c);
+ return c;
+ }
+
+ //
+ // Methods related to processing instructions
+ //
+
+ public String getPIData() {
+ throw new IllegalStateException();
+ }
+
+ public String getPITarget() {
+ throw new IllegalStateException();
+ }
+}