From 7f4602c41b68994b3e9cf1bdb24c82fa20bbc329 Mon Sep 17 00:00:00 2001 From: rfeng Date: Thu, 6 Aug 2009 23:50:19 +0000 Subject: Reorg the package names git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@801844 13f79535-47bb-0310-9956-ffa450edef68 --- java/sca/modules/common-xml/META-INF/MANIFEST.MF | 12 +- .../tuscany/sca/common/xml/SimpleTypeMapper.java | 210 ----- .../sca/common/xml/XSDDataTypeConverter.java | 945 --------------------- .../tuscany/sca/common/xml/dom/DOMHelper.java | 1 + .../tuscany/sca/common/xml/dom/SAX2DOMAdapter.java | 242 ------ .../sca/common/xml/dom/impl/SAX2DOMAdapter.java | 244 ++++++ .../sca/common/xml/stax/DOMXMLStreamReader.java | 36 - .../sca/common/xml/stax/DOMXmlNodeImpl.java | 150 ---- .../xml/stax/DelegatingNamespaceContext.java | 310 ------- .../xml/stax/NameValueArrayStreamReader.java | 404 --------- .../common/xml/stax/NameValuePairStreamReader.java | 348 -------- .../tuscany/sca/common/xml/stax/NamedProperty.java | 59 -- .../common/xml/stax/NilElementStreamReader.java | 279 ------ .../sca/common/xml/stax/SimpleXmlNodeImpl.java | 112 --- .../sca/common/xml/stax/StAX2SAXAdapter.java | 256 ------ .../tuscany/sca/common/xml/stax/StAXHelper.java | 10 + .../common/xml/stax/WrappingXMLStreamReader.java | 100 --- .../common/xml/stax/XMLDocumentStreamReader.java | 482 ----------- .../common/xml/stax/XMLFragmentStreamReader.java | 53 -- .../xml/stax/XMLFragmentStreamReaderImpl.java | 858 ------------------- .../sca/common/xml/stax/XMLStreamSerializer.java | 287 ------- .../tuscany/sca/common/xml/stax/XMLStreamable.java | 37 - .../tuscany/sca/common/xml/stax/XmlNode.java | 69 -- .../sca/common/xml/stax/XmlNodeIterator.java | 355 -------- .../common/xml/stax/XmlTreeStreamReaderImpl.java | 531 ------------ .../sca/common/xml/stax/impl/StAX2SAXAdapter.java | 256 ++++++ .../common/xml/stax/impl/XMLStreamSerializer.java | 287 +++++++ .../common/xml/stax/reader/DOMXMLStreamReader.java | 36 + .../sca/common/xml/stax/reader/DOMXmlNodeImpl.java | 150 ++++ .../stax/reader/DelegatingNamespaceContext.java | 310 +++++++ .../stax/reader/NameValueArrayStreamReader.java | 404 +++++++++ .../xml/stax/reader/NameValuePairStreamReader.java | 348 ++++++++ .../sca/common/xml/stax/reader/NamedProperty.java | 59 ++ .../xml/stax/reader/NilElementStreamReader.java | 279 ++++++ .../common/xml/stax/reader/SimpleXmlNodeImpl.java | 112 +++ .../xml/stax/reader/WrappingXMLStreamReader.java | 100 +++ .../xml/stax/reader/XMLDocumentStreamReader.java | 482 +++++++++++ .../xml/stax/reader/XMLFragmentStreamReader.java | 53 ++ .../stax/reader/XMLFragmentStreamReaderImpl.java | 858 +++++++++++++++++++ .../sca/common/xml/stax/reader/XMLStreamable.java | 37 + .../sca/common/xml/stax/reader/XmlNode.java | 69 ++ .../common/xml/stax/reader/XmlNodeIterator.java | 355 ++++++++ .../xml/stax/reader/XmlTreeStreamReaderImpl.java | 531 ++++++++++++ .../xml/stax/XmlTreeStreamReaderTestCase.java | 14 +- 44 files changed, 5000 insertions(+), 6130 deletions(-) delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/SimpleTypeMapper.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/XSDDataTypeConverter.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/SAX2DOMAdapter.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/impl/SAX2DOMAdapter.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXMLStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXmlNodeImpl.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DelegatingNamespaceContext.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValueArrayStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValuePairStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NamedProperty.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NilElementStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/SimpleXmlNodeImpl.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAX2SAXAdapter.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/WrappingXMLStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLDocumentStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReader.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReaderImpl.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamSerializer.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamable.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNode.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNodeIterator.java delete mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderImpl.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/StAX2SAXAdapter.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/XMLStreamSerializer.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXMLStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXmlNodeImpl.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DelegatingNamespaceContext.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValueArrayStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValuePairStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NamedProperty.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NilElementStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/SimpleXmlNodeImpl.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/WrappingXMLStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLDocumentStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReader.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReaderImpl.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLStreamable.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNode.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNodeIterator.java create mode 100644 java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlTreeStreamReaderImpl.java (limited to 'java') diff --git a/java/sca/modules/common-xml/META-INF/MANIFEST.MF b/java/sca/modules/common-xml/META-INF/MANIFEST.MF index ad4d6bd487..3d6db9d52f 100644 --- a/java/sca/modules/common-xml/META-INF/MANIFEST.MF +++ b/java/sca/modules/common-xml/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Version: 2.0.0 Bnd-LastModified: 1225397108125 Bundle-ManifestVersion: 2 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt -Bundle-Description: Apache Tuscany SCA Core SPI +Bundle-Description: Apache Tuscany SCA Common XML Import-Package: javax.xml.namespace, javax.xml.xpath, javax.xml.datatype, @@ -23,7 +23,15 @@ Import-Package: javax.xml.namespace, org.xml.sax.ext, org.xml.sax.helpers, org.apache.tuscany.sca.core;version="2.0.0", - org.apache.tuscany.sca.extensibility;version="2.0.0" + org.apache.tuscany.sca.extensibility;version="2.0.0", + org.apache.tuscany.sca.common.xml.dom;version="2.0.0", + org.apache.tuscany.sca.common.xml.sax;version="2.0.0", + org.apache.tuscany.sca.common.xml.stax;version="2.0.0", + org.apache.tuscany.sca.common.xml.stax.reader;version="2.0.0" Bundle-SymbolicName: org.apache.tuscany.sca.common.xml Bundle-DocURL: http://www.apache.org/ +Export-Package: org.apache.tuscany.sca.common.xml.dom;version="2.0.0", + org.apache.tuscany.sca.common.xml.sax;version="2.0.0", + org.apache.tuscany.sca.common.xml.stax;version="2.0.0", + org.apache.tuscany.sca.common.xml.stax.reader;version="2.0.0" diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/SimpleTypeMapper.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/SimpleTypeMapper.java deleted file mode 100644 index 8bdb8ae2df..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/SimpleTypeMapper.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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.common.xml; - -import java.util.HashMap; -import java.util.Map; - -import javax.xml.namespace.QName; - -/** - * Simple type mapper that maps from XSD types to Java Classes and Java Classes to XSD types. - * - * @version $Rev$ $Date$ - */ -public class SimpleTypeMapper extends XSDDataTypeConverter { - - public static final Map, String> JAVA2XML = new HashMap, String>(); - - public static final String URI_2001_SCHEMA_XSD = "http://www.w3.org/2001/XMLSchema"; - - public static final Map> XML2JAVA = new HashMap>(); - - public static final QName XSD_ANY = new QName(URI_2001_SCHEMA_XSD, "any"); - - public static final QName XSD_ANYSIMPLETYPE = new QName(URI_2001_SCHEMA_XSD, "anySimpleType"); - - public static final QName XSD_ANYTYPE = new QName(URI_2001_SCHEMA_XSD, "anyType"); - - public static final QName XSD_ANYURI = new QName(URI_2001_SCHEMA_XSD, "anyURI"); - - public static final QName XSD_BASE64 = new QName(URI_2001_SCHEMA_XSD, "base64Binary"); - - public static final QName XSD_BOOLEAN = new QName(URI_2001_SCHEMA_XSD, "boolean"); - - public static final QName XSD_BYTE = new QName(URI_2001_SCHEMA_XSD, "byte"); - - public static final QName XSD_DATE = new QName(URI_2001_SCHEMA_XSD, "date"); - - public static final QName XSD_DATETIME = new QName(URI_2001_SCHEMA_XSD, "dateTime"); - - public static final QName XSD_DAY = new QName(URI_2001_SCHEMA_XSD, "gDay"); - - public static final QName XSD_DECIMAL = new QName(URI_2001_SCHEMA_XSD, "decimal"); - - public static final QName XSD_DOUBLE = new QName(URI_2001_SCHEMA_XSD, "double"); - - public static final QName XSD_DURATION = new QName(URI_2001_SCHEMA_XSD, "duration"); - - public static final QName XSD_ENTITIES = new QName(URI_2001_SCHEMA_XSD, "ENTITIES"); - - public static final QName XSD_ENTITY = new QName(URI_2001_SCHEMA_XSD, "ENTITY"); - - public static final QName XSD_FLOAT = new QName(URI_2001_SCHEMA_XSD, "float"); - - public static final QName XSD_HEXBIN = new QName(URI_2001_SCHEMA_XSD, "hexBinary"); - - public static final QName XSD_IDREF = new QName(URI_2001_SCHEMA_XSD, "IDREF"); - - public static final QName XSD_IDREFS = new QName(URI_2001_SCHEMA_XSD, "IDREFS"); - - public static final QName XSD_INT = new QName(URI_2001_SCHEMA_XSD, "int"); - - public static final QName XSD_INTEGER = new QName(URI_2001_SCHEMA_XSD, "integer"); - - public static final QName XSD_LONG = new QName(URI_2001_SCHEMA_XSD, "long"); - - public static final QName XSD_MONTH = new QName(URI_2001_SCHEMA_XSD, "gMonth"); - - public static final QName XSD_MONTHDAY = new QName(URI_2001_SCHEMA_XSD, "gMonthDay"); - - public static final QName XSD_NAME = new QName(URI_2001_SCHEMA_XSD, "Name"); - - public static final QName XSD_NCNAME = new QName(URI_2001_SCHEMA_XSD, "NCName"); - - public static final QName XSD_NEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "negativeInteger"); - - public static final QName XSD_NMTOKEN = new QName(URI_2001_SCHEMA_XSD, "NMTOKEN"); - - public static final QName XSD_NMTOKENS = new QName(URI_2001_SCHEMA_XSD, "NMTOKENS"); - - public static final QName XSD_NONNEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonNegativeInteger"); - - public static final QName XSD_NONPOSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonPositiveInteger"); - - public static final QName XSD_NORMALIZEDSTRING = new QName(URI_2001_SCHEMA_XSD, "normalizedString"); - - public static final QName XSD_NOTATION = new QName(URI_2001_SCHEMA_XSD, "NOTATION"); - - public static final QName XSD_POSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "positiveInteger"); - - public static final QName XSD_QNAME = new QName(URI_2001_SCHEMA_XSD, "QName"); - - public static final QName XSD_SHORT = new QName(URI_2001_SCHEMA_XSD, "short"); - - public static final QName XSD_STRING = new QName(URI_2001_SCHEMA_XSD, "string"); - - public static final QName XSD_TIME = new QName(URI_2001_SCHEMA_XSD, "time"); - - public static final QName XSD_TOKEN = new QName(URI_2001_SCHEMA_XSD, "token"); - - public static final QName XSD_UNSIGNEDBYTE = new QName(URI_2001_SCHEMA_XSD, "unsignedByte"); - - public static final QName XSD_UNSIGNEDINT = new QName(URI_2001_SCHEMA_XSD, "unsignedInt"); - - public static final QName XSD_UNSIGNEDLONG = new QName(URI_2001_SCHEMA_XSD, "unsignedLong"); - - public static final QName XSD_UNSIGNEDSHORT = new QName(URI_2001_SCHEMA_XSD, "unsignedShort"); - - public static final QName XSD_YEAR = new QName(URI_2001_SCHEMA_XSD, "gYear"); - - public static final QName XSD_YEARMONTH = new QName(URI_2001_SCHEMA_XSD, "gYearMonth"); - - static { - JAVA2XML.put(boolean.class, "boolean"); - JAVA2XML.put(byte.class, "byte"); - JAVA2XML.put(short.class, "short"); - JAVA2XML.put(int.class, "int"); - JAVA2XML.put(long.class, "long"); - JAVA2XML.put(float.class, "float"); - JAVA2XML.put(double.class, "double"); - JAVA2XML.put(Boolean.class, "boolean"); - JAVA2XML.put(Byte.class, "byte"); - JAVA2XML.put(Short.class, "short"); - JAVA2XML.put(Integer.class, "int"); - JAVA2XML.put(Long.class, "long"); - JAVA2XML.put(Float.class, "float"); - JAVA2XML.put(Double.class, "double"); - JAVA2XML.put(java.lang.String.class, "string"); - JAVA2XML.put(java.math.BigInteger.class, "integer"); - JAVA2XML.put(java.math.BigDecimal.class, "decimal"); - JAVA2XML.put(java.util.Calendar.class, "dateTime"); - JAVA2XML.put(java.util.Date.class, "dateTime"); - JAVA2XML.put(javax.xml.namespace.QName.class, "QName"); - JAVA2XML.put(java.net.URI.class, "string"); - JAVA2XML.put(javax.xml.datatype.XMLGregorianCalendar.class, "anySimpleType"); - JAVA2XML.put(javax.xml.datatype.Duration.class, "duration"); - JAVA2XML.put(java.lang.Object.class, "anyType"); - JAVA2XML.put(java.awt.Image.class, "base64Binary"); - JAVA2XML.put(byte[].class, "base64Binary"); - // java2XSD.put(javax.activation.DataHandler.class, "base64Binary"); - JAVA2XML.put(javax.xml.transform.Source.class, "base64Binary"); - JAVA2XML.put(java.util.UUID.class, "string"); - } - - static { - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "string"), java.lang.String.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "integer"), java.math.BigInteger.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "int"), int.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "long"), long.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "short"), short.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "decimal"), java.math.BigDecimal.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "float"), float.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "double"), double.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "boolean"), boolean.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "byte"), byte.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "QName"), javax.xml.namespace.QName.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "dateTime"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "base64Binary"), byte[].class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "hexBinary"), byte[].class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "unsignedInt"), long.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "unsignedShort"), int.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "unsignedByte"), short.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "time"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "date"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "gDay"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "gMonth"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "gYear"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "gYearMonth"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "gMonthDay"), javax.xml.datatype.XMLGregorianCalendar.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "anySimpleType"), java.lang.Object.class); // For elements - // XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "anySimpleType"), java.lang.String.class); // For - // attributes - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "duration"), javax.xml.datatype.Duration.class); - XML2JAVA.put(new QName(URI_2001_SCHEMA_XSD, "NOTATION"), javax.xml.namespace.QName.class); - } - - public SimpleTypeMapper() { - super(); - } - - public static Class getJavaType(QName xmlType) { - if (xmlType != null && URI_2001_SCHEMA_XSD.equals(xmlType.getNamespaceURI())) { - return XML2JAVA.get(xmlType.getLocalPart()); - } else { - return null; - } - } - - public static QName getXMLType(Class javaType) { - return new QName(URI_2001_SCHEMA_XSD, JAVA2XML.get(javaType)); - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/XSDDataTypeConverter.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/XSDDataTypeConverter.java deleted file mode 100644 index 895e4e476c..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/XSDDataTypeConverter.java +++ /dev/null @@ -1,945 +0,0 @@ -/* - * 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.common.xml; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Writer; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.FieldPosition; -import java.text.Format; -import java.text.ParsePosition; -import java.util.Calendar; -import java.util.TimeZone; - -import javax.xml.XMLConstants; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.Duration; -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; - -/** - * Utility class for XSD data type conversions - * - * @version $Rev$ $Date$ - */ -public class XSDDataTypeConverter { - public static final class Base64Binary { - private static final char[] S_BASE64CHAR = - {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', '+', '/'}; - - private static final char S_BASE64PAD = '='; - - private static final byte[] S_DECODETABLE = new byte[128]; - - static { - for (int i = 0; i < S_DECODETABLE.length; i++) { - S_DECODETABLE[i] = Byte.MAX_VALUE; // 127 - } - for (int i = 0; i < S_BASE64CHAR.length; i++) { - // 0 to 63 - S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i; - } - } - - private Base64Binary() { - } - - /** - * - */ - public static byte[] decode(char[] data, int off, int len) { - char[] ibuf = new char[4]; - int ibufcount = 0; - byte[] obuf = new byte[len / 4 * 3 + 3]; - int obufcount = 0; - for (int i = off; i < off + len; i++) { - char ch = data[i]; - if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { - ibuf[ibufcount++] = ch; - if (ibufcount == ibuf.length) { - ibufcount = 0; - obufcount += decode0(ibuf, obuf, obufcount); - } - } - } - if (obufcount == obuf.length) { - return obuf; - } - byte[] ret = new byte[obufcount]; - System.arraycopy(obuf, 0, ret, 0, obufcount); - return ret; - } - - /** - * - */ - public static void decode(char[] data, int off, int len, OutputStream ostream) throws IOException { - char[] ibuf = new char[4]; - int ibufcount = 0; - byte[] obuf = new byte[3]; - for (int i = off; i < off + len; i++) { - char ch = data[i]; - if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { - ibuf[ibufcount++] = ch; - if (ibufcount == ibuf.length) { - ibufcount = 0; - int obufcount = decode0(ibuf, obuf, 0); - ostream.write(obuf, 0, obufcount); - } - } - } - } - - /** - * - */ - public static byte[] decode(String data) { - char[] ibuf = new char[4]; - int ibufcount = 0; - byte[] obuf = new byte[data.length() / 4 * 3 + 3]; - int obufcount = 0; - for (int i = 0; i < data.length(); i++) { - char ch = data.charAt(i); - if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { - ibuf[ibufcount++] = ch; - if (ibufcount == ibuf.length) { - ibufcount = 0; - obufcount += decode0(ibuf, obuf, obufcount); - } - } - } - if (obufcount == obuf.length) { - return obuf; - } - byte[] ret = new byte[obufcount]; - System.arraycopy(obuf, 0, ret, 0, obufcount); - return ret; - } - - /** - * - */ - public static void decode(String data, OutputStream ostream) throws IOException { - char[] ibuf = new char[4]; - int ibufcount = 0; - byte[] obuf = new byte[3]; - for (int i = 0; i < data.length(); i++) { - char ch = data.charAt(i); - if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { - ibuf[ibufcount++] = ch; - if (ibufcount == ibuf.length) { - ibufcount = 0; - int obufcount = decode0(ibuf, obuf, 0); - ostream.write(obuf, 0, obufcount); - } - } - } - } - - private static int decode0(char[] ibuf, byte[] obuf, int index) { - int wp = index; - int outlen = 3; - if (ibuf[3] == S_BASE64PAD) { - outlen = 2; - } - if (ibuf[2] == S_BASE64PAD) { - outlen = 1; - } - int b0 = S_DECODETABLE[ibuf[0]]; - int b1 = S_DECODETABLE[ibuf[1]]; - int b2 = S_DECODETABLE[ibuf[2]]; - int b3 = S_DECODETABLE[ibuf[3]]; - switch (outlen) { - case 1: - obuf[wp] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); - return 1; - case 2: - obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); - obuf[wp] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); - return 2; - case 3: - obuf[wp++] = (byte) (b0 << 2 & 0xfc | b1 >> 4 & 0x3); - obuf[wp++] = (byte) (b1 << 4 & 0xf0 | b2 >> 2 & 0xf); - obuf[wp] = (byte) (b2 << 6 & 0xc0 | b3 & 0x3f); - return 3; - default: - throw new IllegalArgumentException("The character sequence is not base64 encoded."); - } - } - - /** - * Returns base64 representation of specified byte array. - */ - public static String encode(byte[] data) { - return encode(data, 0, data.length); - } - - /** - * Returns base64 representation of specified byte array. - */ - public static String encode(byte[] data, int off, int len) { - if (len <= 0) { - return ""; - } - char[] out = new char[len / 3 * 4 + 4]; - int rindex = off; - int windex = 0; - int rest = len - off; - while (rest >= 3) { - int i = - ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) - + (data[rindex + 2] & 0xff); - out[windex++] = S_BASE64CHAR[i >> 18]; - out[windex++] = S_BASE64CHAR[(i >> 12) & 0x3f]; - out[windex++] = S_BASE64CHAR[(i >> 6) & 0x3f]; - out[windex++] = S_BASE64CHAR[i & 0x3f]; - rindex += 3; - rest -= 3; - } - if (rest == 1) { - int i = data[rindex] & 0xff; - out[windex++] = S_BASE64CHAR[i >> 2]; - out[windex++] = S_BASE64CHAR[(i << 4) & 0x3f]; - out[windex++] = S_BASE64PAD; - out[windex++] = S_BASE64PAD; - } else if (rest == 2) { - int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); - out[windex++] = S_BASE64CHAR[i >> 10]; - out[windex++] = S_BASE64CHAR[(i >> 4) & 0x3f]; - out[windex++] = S_BASE64CHAR[(i << 2) & 0x3f]; - out[windex++] = S_BASE64PAD; - } - return new String(out, 0, windex); - } - - /** - * Outputs base64 representation of the specified byte array to a byte stream. - */ - public static void encode(byte[] data, int off, int len, OutputStream ostream) throws IOException { - if (len <= 0) { - return; - } - byte[] out = new byte[4]; - int rindex = off; - int rest = len - off; - while (rest >= 3) { - int i = - ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) - + (data[rindex + 2] & 0xff); - out[0] = (byte) S_BASE64CHAR[i >> 18]; - out[1] = (byte) S_BASE64CHAR[(i >> 12) & 0x3f]; - out[2] = (byte) S_BASE64CHAR[(i >> 6) & 0x3f]; - out[3] = (byte) S_BASE64CHAR[i & 0x3f]; - ostream.write(out, 0, 4); - rindex += 3; - rest -= 3; - } - if (rest == 1) { - int i = data[rindex] & 0xff; - out[0] = (byte) S_BASE64CHAR[i >> 2]; - out[1] = (byte) S_BASE64CHAR[(i << 4) & 0x3f]; - out[2] = (byte) S_BASE64PAD; - out[3] = (byte) S_BASE64PAD; - ostream.write(out, 0, 4); - } else if (rest == 2) { - int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); - out[0] = (byte) S_BASE64CHAR[i >> 10]; - out[1] = (byte) S_BASE64CHAR[(i >> 4) & 0x3f]; - out[2] = (byte) S_BASE64CHAR[(i << 2) & 0x3f]; - out[3] = (byte) S_BASE64PAD; - ostream.write(out, 0, 4); - } - } - - /** - * Outputs base64 representation of the specified byte array to a character stream. - */ - public static void encode(byte[] data, int off, int len, Writer writer) throws IOException { - if (len <= 0) { - return; - } - char[] out = new char[4]; - int rindex = off; - int rest = len - off; - int output = 0; - while (rest >= 3) { - int i = - ((data[rindex] & 0xff) << 16) + ((data[rindex + 1] & 0xff) << 8) - + (data[rindex + 2] & 0xff); - out[0] = S_BASE64CHAR[i >> 18]; - out[1] = S_BASE64CHAR[(i >> 12) & 0x3f]; - out[2] = S_BASE64CHAR[(i >> 6) & 0x3f]; - out[3] = S_BASE64CHAR[i & 0x3f]; - writer.write(out, 0, 4); - rindex += 3; - rest -= 3; - output += 4; - if (output % 76 == 0) { - writer.write("\n"); - } - } - if (rest == 1) { - int i = data[rindex] & 0xff; - out[0] = S_BASE64CHAR[i >> 2]; - out[1] = S_BASE64CHAR[(i << 4) & 0x3f]; - out[2] = S_BASE64PAD; - out[3] = S_BASE64PAD; - writer.write(out, 0, 4); - } else if (rest == 2) { - int i = ((data[rindex] & 0xff) << 8) + (data[rindex + 1] & 0xff); - out[0] = S_BASE64CHAR[i >> 10]; - out[1] = S_BASE64CHAR[(i >> 4) & 0x3f]; - out[2] = S_BASE64CHAR[(i << 2) & 0x3f]; - out[3] = S_BASE64PAD; - writer.write(out, 0, 4); - } - } - } - - /** - *

- * Utility class for xs:hexbinary.

- */ - public static final class HexBinary { - private HexBinary() { - } - - /** - * Converts the string pValue into an array of hex bytes. - */ - public static byte[] decode(String pValue) { - if ((pValue.length() % 2) != 0) { - throw new IllegalArgumentException("A HexBinary string must have even length."); - } - byte[] result = new byte[pValue.length() / 2]; - int j = 0; - int i = 0; - while (i < pValue.length()) { - byte b; - char c = pValue.charAt(i++); - char d = pValue.charAt(i++); - if (c >= '0' && c <= '9') { - b = (byte) ((c - '0') << 4); - } else if (c >= 'A' && c <= 'F') { - b = (byte) ((c - 'A' + 10) << 4); - } else if (c >= 'a' && c <= 'f') { - b = (byte) ((c - 'a' + 10) << 4); - } else { - throw new IllegalArgumentException("Invalid hex digit: " + c); - } - if (d >= '0' && d <= '9') { - b += (byte) (d - '0'); - } else if (d >= 'A' && d <= 'F') { - b += (byte) (d - 'A' + 10); - } else if (d >= 'a' && d <= 'f') { - b += (byte) (d - 'a' + 10); - } else { - throw new IllegalArgumentException("Invalid hex digit: " + d); - } - result[j++] = b; - } - return result; - } - - /** - * Converts the byte array pHexBinary into a string. - */ - public static String encode(byte[] pHexBinary) { - StringBuffer result = new StringBuffer(); - for (int i = 0; i < pHexBinary.length; i++) { - byte b = pHexBinary[i]; - byte c = (byte) ((b & 0xf0) >> 4); - if (c <= 9) { - result.append((char) ('0' + c)); - } else { - result.append((char) ('A' + c - 10)); - } - c = (byte) (b & 0x0f); - if (c <= 9) { - result.append((char) ('0' + c)); - } else { - result.append((char) ('A' + c - 10)); - } - } - return result.toString(); - } - - /** - * Creates a clone of the given byte array. - */ - public static byte[] getClone(byte[] pHexBinary) { - byte[] result = new byte[pHexBinary.length]; - System.arraycopy(pHexBinary, 0, result, 0, pHexBinary.length); - return result; - } - } - - public class XSDDateFormat extends XSDDateTimeFormat { - private static final long serialVersionUID = -1629412916827246627L; - - /** - * Creates a new instance. - */ - public XSDDateFormat() { - super(true, false); - } - } - - /** - *

- * An instance of {@link java.text.Format}, which may be used to parse and format xs:dateTime values. - *

- */ - public static class XSDDateTimeFormat extends Format { - private static final long serialVersionUID = -1148332471737068969L; - - final boolean parseDate; - - final boolean parseTime; - - /** - * Creates a new instance. - */ - public XSDDateTimeFormat() { - this(true, true); - } - - XSDDateTimeFormat(boolean pParseDate, boolean pParseTime) { - parseDate = pParseDate; - parseTime = pParseTime; - } - - private void append(StringBuffer pBuffer, int pNum, int pMinLen) { - String s = Integer.toString(pNum); - for (int i = s.length(); i < pMinLen; i++) { - pBuffer.append('0'); - } - pBuffer.append(s); - } - - @Override - public StringBuffer format(Object pCalendar, StringBuffer pBuffer, FieldPosition pPos) { - assert pCalendar != null : "The Calendar argument must not be null."; - assert pBuffer != null : "The StringBuffer argument must not be null."; - assert pPos != null : "The FieldPosition argument must not be null."; - - Calendar cal = (Calendar) pCalendar; - if (parseDate) { - int year = cal.get(Calendar.YEAR); - if (year < 0) { - pBuffer.append('-'); - year = -year; - } - append(pBuffer, year, 4); - pBuffer.append('-'); - append(pBuffer, cal.get(Calendar.MONTH) + 1, 2); - pBuffer.append('-'); - append(pBuffer, cal.get(Calendar.DAY_OF_MONTH), 2); - if (parseTime) { - pBuffer.append('T'); - } - } - if (parseTime) { - append(pBuffer, cal.get(Calendar.HOUR_OF_DAY), 2); - pBuffer.append(':'); - append(pBuffer, cal.get(Calendar.MINUTE), 2); - pBuffer.append(':'); - append(pBuffer, cal.get(Calendar.SECOND), 2); - int millis = cal.get(Calendar.MILLISECOND); - if (millis > 0) { - pBuffer.append('.'); - append(pBuffer, millis, 3); - } - } - TimeZone tz = cal.getTimeZone(); - // JDK 1.4: int offset = tz.getOffset(cal.getTimeInMillis()); - int offset = cal.get(Calendar.ZONE_OFFSET); - if (tz.inDaylightTime(cal.getTime())) { - offset += cal.get(Calendar.DST_OFFSET); - } - if (offset == 0) { - pBuffer.append('Z'); - } else { - if (offset < 0) { - pBuffer.append('-'); - offset = -offset; - } else { - pBuffer.append('+'); - } - int minutes = offset / (60 * 1000); - int hours = minutes / 60; - minutes -= hours * 60; - append(pBuffer, hours, 2); - pBuffer.append(':'); - append(pBuffer, minutes, 2); - } - return pBuffer; - } - - private int parseInt(String pString, int offset, StringBuffer pDigits) { - int length = pString.length(); - int pOffset = offset; - pDigits.setLength(0); - while (pOffset < length) { - char c = pString.charAt(pOffset); - if (Character.isDigit(c)) { - pDigits.append(c); - ++pOffset; - } else { - break; - } - } - return pOffset; - } - - @Override - public Object parseObject(String pString, ParsePosition pParsePosition) { - assert pString != null : "The String argument must not be null."; - assert pParsePosition != null : "The ParsePosition argument must not be null."; - int offset = pParsePosition.getIndex(); - int length = pString.length(); - - boolean isMinus = false; - StringBuffer digits = new StringBuffer(); - int year = 0; - int month = 0; - int mday = 0; - if (parseDate) { - // Sign - if (offset < length) { - char c = pString.charAt(offset); - if (c == '+') { - ++offset; - } else if (c == '-') { - ++offset; - isMinus = true; - } - } - - offset = parseInt(pString, offset, digits); - if (digits.length() < 4) { - pParsePosition.setErrorIndex(offset); - return null; - } - year = Integer.parseInt(digits.toString()); - - if (offset < length && pString.charAt(offset) == '-') { - ++offset; - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - - offset = parseInt(pString, offset, digits); - if (digits.length() != 2) { - pParsePosition.setErrorIndex(offset); - return null; - } - month = Integer.parseInt(digits.toString()); - - if (offset < length && pString.charAt(offset) == '-') { - ++offset; - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - - offset = parseInt(pString, offset, digits); - if (digits.length() != 2) { - pParsePosition.setErrorIndex(offset); - return null; - } - mday = Integer.parseInt(digits.toString()); - - if (parseTime) { - if (offset < length && pString.charAt(offset) == 'T') { - ++offset; - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - } - } else { - year = month = mday = 0; - } - - int hour = 0; - int minute = 0; - int second = 0; - int millis = 0; - if (parseTime) { - offset = parseInt(pString, offset, digits); - if (digits.length() != 2) { - pParsePosition.setErrorIndex(offset); - return null; - } - hour = Integer.parseInt(digits.toString()); - - if (offset < length && pString.charAt(offset) == ':') { - ++offset; - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - - offset = parseInt(pString, offset, digits); - if (digits.length() != 2) { - pParsePosition.setErrorIndex(offset); - return null; - } - minute = Integer.parseInt(digits.toString()); - - if (offset < length && pString.charAt(offset) == ':') { - ++offset; - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - - offset = parseInt(pString, offset, digits); - if (digits.length() != 2) { - pParsePosition.setErrorIndex(offset); - return null; - } - second = Integer.parseInt(digits.toString()); - - if (offset < length && pString.charAt(offset) == '.') { - ++offset; - offset = parseInt(pString, offset, digits); - if (digits.length() > 0) { - millis = Integer.parseInt(digits.toString()); - } else { - millis = 0; - } - } else { - millis = 0; - } - } else { - hour = minute = second = millis = 0; - } - - digits.setLength(0); - digits.append("GMT"); - if (offset < length) { - char c = pString.charAt(offset); - if (c == 'Z') { - // Ignore UTC, it is the default - ++offset; - } else if (c == '+' || c == '-') { - digits.append(c); - ++offset; - for (int i = 0; i < 5; i++) { - if (offset >= length) { - pParsePosition.setErrorIndex(offset); - return null; - } - c = pString.charAt(offset); - if ((i != 2 && Character.isDigit(c)) || (i == 2 && c == ':')) { - digits.append(c); - } else { - pParsePosition.setErrorIndex(offset); - return null; - } - ++offset; - } - } - } - - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(digits.toString())); - cal.set(isMinus ? -year : year, parseDate ? month - 1 : month, mday, hour, minute, second); - cal.set(Calendar.MILLISECOND, millis); - pParsePosition.setIndex(offset); - return cal; - } - } - - public static class XSDTimeFormat extends XSDDateTimeFormat { - private static final long serialVersionUID = 1346506860724640517L; - - /** - * Creates a new instance. - */ - public XSDTimeFormat() { - super(false, true); - } - } - - private static final long MAX_UNSIGNED_INT = (((long) Integer.MAX_VALUE) * 2) + 1; - - private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1; - - public String parseAnySimpleType(String value) { - return value; - } - - public byte[] parseBase64Binary(String value) { - return Base64Binary.decode(value); - } - - public boolean parseBoolean(String value) { - return Boolean.valueOf(value).booleanValue(); - } - - public byte parseByte(String value) { - return Byte.parseByte(value); - } - - public Calendar parseDate(String value) { - XSDDateFormat format = new XSDDateFormat(); - ParsePosition pos = new ParsePosition(0); - Calendar cal = (Calendar) format.parseObject(value, pos); - if (cal == null) { - throw new IllegalArgumentException("Failed to parse date " + value + " at:" - + value.substring(pos.getErrorIndex())); - } - return cal; - } - - public Calendar parseDateTime(String value) { - XSDDateTimeFormat format = new XSDDateTimeFormat(); - ParsePosition pos = new ParsePosition(0); - Calendar cal = (Calendar) format.parseObject(value, pos); - if (cal == null) { - throw new IllegalArgumentException("Failed to parse dateTime " + value + " at:" - + value.substring(pos.getErrorIndex())); - } - return cal; - } - - public BigDecimal parseDecimal(String value) { - return new BigDecimal(value); - } - - public double parseDouble(String value) { - if ("INF".equals(value)) { - return Double.POSITIVE_INFINITY; - } else if ("-INF".equals(value)) { - return Double.NEGATIVE_INFINITY; - } else if ("NaN".equals(value)) { - return Double.NaN; - } else { - return Double.parseDouble(value); - } - } - - public Duration parseDuration(String pDuration) { - try { - return DatatypeFactory.newInstance().newDuration(pDuration); - } catch (DatatypeConfigurationException e) { - throw new IllegalArgumentException(e); - } - } - - public float parseFloat(String value) { - if ("INF".equals(value)) { - return Float.POSITIVE_INFINITY; - } else if ("-INF".equals(value)) { - return Float.NEGATIVE_INFINITY; - } else if ("NaN".equals(value)) { - return Float.NaN; - } else { - return Float.parseFloat(value); - } - } - - public byte[] parseHexBinary(String value) { - return HexBinary.decode(value); - } - - public int parseInt(String value) { - return Integer.parseInt(value); - } - - public BigInteger parseInteger(String value) { - return new BigInteger(value); - } - - public long parseLong(String value) { - return Long.parseLong(value); - } - - public QName parseQName(String value, NamespaceContext context) { - int offset = value.indexOf(':'); - String uri; - String localName; - switch (offset) { - case -1: - localName = value; - uri = context.getNamespaceURI(""); - if (uri == null) { - // Should not happen, indicates an error in the - // NamespaceContext - // implementation - throw new IllegalArgumentException("The default prefix is not bound."); - } - break; - case 0: - throw new IllegalArgumentException("Default prefix must be indicated by not using a colon: " - + value); - default: - String prefix = value.substring(0, offset); - localName = value.substring(offset + 1); - uri = context.getNamespaceURI(prefix); - if (uri == null) { - throw new IllegalArgumentException("The prefix " + prefix + " is not bound."); - } - } - return new QName(uri, localName); - } - - public short parseShort(String value) { - return Short.parseShort(value); - } - - public String parseString(String value) { - return value; - } - - public Calendar parseTime(String value) { - XSDTimeFormat format = new XSDTimeFormat(); - ParsePosition pos = new ParsePosition(0); - Calendar cal = (Calendar) format.parseObject(value, pos); - if (cal == null) { - throw new IllegalArgumentException("Failed to parse time " + value + " at:" - + value.substring(pos.getErrorIndex())); - } - return cal; - } - - public long parseUnsignedInt(String value) { - long l = Long.parseLong(value); - if (l < 0) { - throw new IllegalArgumentException("Failed to parse UnsignedInt " + value - + ": result is negative"); - } - if (l > MAX_UNSIGNED_INT) { - throw new IllegalArgumentException("Failed to parse UnsignedInt " + value - + ": result exceeds maximum value " + MAX_UNSIGNED_INT); - } - return l; - } - - public int parseUnsignedShort(String value) { - int i = Integer.parseInt(value); - if (i < 0) { - throw new IllegalArgumentException("Failed to parse UnsignedShort " + value - + ": result is negative"); - } - if (i > MAX_UNSIGNED_SHORT) { - throw new IllegalArgumentException("Failed to parse UnsignedShort " + value - + ": result exceeds maximum value " + MAX_UNSIGNED_SHORT); - } - return i; - } - - public String printAnySimpleType(String value) { - return value; - } - - public String printBase64Binary(byte[] value) { - return Base64Binary.encode(value); - } - - public String printBoolean(boolean value) { - return (value ? Boolean.TRUE : Boolean.FALSE).toString(); - } - - public String printByte(byte value) { - return Byte.toString(value); - } - - public String printDate(Calendar value) { - return new XSDDateFormat().format(value); - } - - public String printDateTime(Calendar value) { - return new XSDDateTimeFormat().format(value); - } - - public String printDecimal(BigDecimal value) { - return value.toString(); - } - - public String printDouble(double value) { - return Double.toString(value); - } - - public String printDuration(Duration pDuration) { - return pDuration.toString(); - } - - public String printFloat(float value) { - return Float.toString(value); - } - - public String printHexBinary(byte[] value) { - return HexBinary.encode(value); - } - - public String printInt(int value) { - return Integer.toString(value); - } - - public String printInteger(BigInteger value) { - return value.toString(); - } - - public String printLong(long value) { - return Long.toString(value); - } - - public String printQName(QName value, NamespaceContext context) { - String prefix = context.getPrefix(value.getNamespaceURI()); - if (prefix == null) { - throw new IllegalArgumentException("The namespace URI " + value.getNamespaceURI() - + " is not bound."); - } else if (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) { - return value.getLocalPart(); - } else { - return prefix + ":" + value.getLocalPart(); - } - } - - public String printShort(short value) { - return Short.toString(value); - } - - public String printString(String value) { - return value; - } - - public String printTime(Calendar value) { - return new XSDTimeFormat().format(value); - } - - public String printUnsignedInt(long value) { - return Long.toString(value); - } - - public String printUnsignedShort(int value) { - return Integer.toString(value); - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java index 923d290f36..cc2460b8f9 100644 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/DOMHelper.java @@ -34,6 +34,7 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.stream.StreamResult; +import org.apache.tuscany.sca.common.xml.dom.impl.SAX2DOMAdapter; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.w3c.dom.Attr; diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/SAX2DOMAdapter.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/SAX2DOMAdapter.java deleted file mode 100644 index 861107e6a4..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/SAX2DOMAdapter.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2001-2004 The Apache Software Foundation. - * - * Licensed 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.common.xml.dom; - -import java.util.ArrayList; -import java.util.List; -import java.util.Stack; - -import org.apache.tuscany.sca.core.ExtensionPointRegistry; -import org.apache.tuscany.sca.core.UtilityExtensionPoint; -import org.w3c.dom.Comment; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.ProcessingInstruction; -import org.w3c.dom.Text; -import org.xml.sax.Attributes; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; - -/** - * SAX2DOM adapter - * - * @version $Rev$ $Date$ - */ -public class SAX2DOMAdapter implements DOMHelper.NodeContentHandler { - public static final String EMPTYSTRING = ""; - public static final String XML_PREFIX = "xml"; - public static final String XMLNS_PREFIX = "xmlns"; - public static final String XMLNS_STRING = "xmlns:"; - public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; - - private Node root; - - private Document document; - - private Node nextSibling; - - private Stack nodeStk = new Stack(); - - private List namespaceDecls; - - private Node lastSibling; - - public SAX2DOMAdapter(ExtensionPointRegistry registry) { - UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); - DOMHelper domHelper = utilities.getUtility(DOMHelper.class); - this.document = domHelper.newDocument(); - this.root = document; - } - - public SAX2DOMAdapter(Node root, Node nextSibling) { - this.root = root; - if (root instanceof Document) { - this.document = (Document)root; - } else if (root != null) { - this.document = root.getOwnerDocument(); - } - - this.nextSibling = nextSibling; - } - - public SAX2DOMAdapter(Node root) { - this(root, null); - } - - public Node getNode() { - return root; - } - - public void characters(char[] ch, int start, int length) { - final Node last = nodeStk.peek(); - - // No text nodes can be children of root (DOM006 exception) - if (last != document) { - final String text = new String(ch, start, length); - if (lastSibling != null && lastSibling.getNodeType() == Node.TEXT_NODE) { - ((Text)lastSibling).appendData(text); - } else if (last == root && nextSibling != null) { - lastSibling = last.insertBefore(document.createTextNode(text), nextSibling); - } else { - lastSibling = last.appendChild(document.createTextNode(text)); - } - - } - } - - public void startDocument() { - nodeStk.push(root); - } - - public void endDocument() { - nodeStk.pop(); - } - - public void startElement(String namespace, String localName, String qName, Attributes attrs) { - final Element tmp = document.createElementNS(namespace, qName); - - // Add namespace declarations first - if (namespaceDecls != null) { - final int nDecls = namespaceDecls.size(); - for (int i = 0; i < nDecls; i++) { - final String prefix = namespaceDecls.get(i++); - - if (prefix == null || prefix.equals(EMPTYSTRING)) { - tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceDecls.get(i)); - } else { - tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, namespaceDecls.get(i)); - } - } - namespaceDecls.clear(); - } - - // Add attributes to element - final int nattrs = attrs.getLength(); - for (int i = 0; i < nattrs; i++) { - if (attrs.getLocalName(i) == null) { - tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); - } else { - tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i)); - } - } - - // Append this new node onto current stack node - Node last = nodeStk.peek(); - - // If the SAX2DOM is created with a non-null next sibling node, - // insert the result nodes before the next sibling under the root. - if (last == root && nextSibling != null) { - last.insertBefore(tmp, nextSibling); - } else { - last.appendChild(tmp); - } - - // Push this node onto stack - nodeStk.push(tmp); - lastSibling = null; - } - - public void endElement(String namespace, String localName, String qName) { - nodeStk.pop(); - lastSibling = null; - } - - public void startPrefixMapping(String prefix, String uri) { - if (namespaceDecls == null) { - namespaceDecls = new ArrayList(2); - } - namespaceDecls.add(prefix); - namespaceDecls.add(uri); - } - - public void endPrefixMapping(String prefix) { - // do nothing - } - - /** - * This class is only used internally so this method should never be called. - */ - public void ignorableWhitespace(char[] ch, int start, int length) { - } - - /** - * adds processing instruction node to DOM. - */ - public void processingInstruction(String target, String data) { - final Node last = nodeStk.peek(); - ProcessingInstruction pi = document.createProcessingInstruction(target, data); - if (pi != null) { - if (last == root && nextSibling != null) { - last.insertBefore(pi, nextSibling); - } else { - last.appendChild(pi); - } - - lastSibling = pi; - } - } - - /** - * This class is only used internally so this method should never be called. - */ - public void setDocumentLocator(Locator locator) { - } - - /** - * This class is only used internally so this method should never be called. - */ - public void skippedEntity(String name) { - } - - /** - * Lexical Handler method to create comment node in DOM tree. - */ - public void comment(char[] ch, int start, int length) { - final Node last = nodeStk.peek(); - Comment comment = document.createComment(new String(ch, start, length)); - if (comment != null) { - if (last == root && nextSibling != null) { - last.insertBefore(comment, nextSibling); - } else { - last.appendChild(comment); - } - - lastSibling = comment; - } - } - - // Lexical Handler methods- not implemented - public void startCDATA() { - } - - public void endCDATA() { - } - - public void startEntity(java.lang.String name) { - } - - public void endDTD() { - } - - public void endEntity(String name) { - } - - public void startDTD(String name, String publicId, String systemId) throws SAXException { - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/impl/SAX2DOMAdapter.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/impl/SAX2DOMAdapter.java new file mode 100644 index 0000000000..11d692c81e --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/dom/impl/SAX2DOMAdapter.java @@ -0,0 +1,244 @@ +/* + * Copyright 2001-2004 The Apache Software Foundation. + * + * Licensed 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.common.xml.dom.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.apache.tuscany.sca.common.xml.dom.DOMHelper.NodeContentHandler; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.w3c.dom.Comment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.ProcessingInstruction; +import org.w3c.dom.Text; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +/** + * SAX2DOM adapter + * + * @version $Rev$ $Date$ + */ +public class SAX2DOMAdapter implements DOMHelper.NodeContentHandler { + public static final String EMPTYSTRING = ""; + public static final String XML_PREFIX = "xml"; + public static final String XMLNS_PREFIX = "xmlns"; + public static final String XMLNS_STRING = "xmlns:"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + + private Node root; + + private Document document; + + private Node nextSibling; + + private Stack nodeStk = new Stack(); + + private List namespaceDecls; + + private Node lastSibling; + + public SAX2DOMAdapter(ExtensionPointRegistry registry) { + UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); + DOMHelper domHelper = utilities.getUtility(DOMHelper.class); + this.document = domHelper.newDocument(); + this.root = document; + } + + public SAX2DOMAdapter(Node root, Node nextSibling) { + this.root = root; + if (root instanceof Document) { + this.document = (Document)root; + } else if (root != null) { + this.document = root.getOwnerDocument(); + } + + this.nextSibling = nextSibling; + } + + public SAX2DOMAdapter(Node root) { + this(root, null); + } + + public Node getNode() { + return root; + } + + public void characters(char[] ch, int start, int length) { + final Node last = nodeStk.peek(); + + // No text nodes can be children of root (DOM006 exception) + if (last != document) { + final String text = new String(ch, start, length); + if (lastSibling != null && lastSibling.getNodeType() == Node.TEXT_NODE) { + ((Text)lastSibling).appendData(text); + } else if (last == root && nextSibling != null) { + lastSibling = last.insertBefore(document.createTextNode(text), nextSibling); + } else { + lastSibling = last.appendChild(document.createTextNode(text)); + } + + } + } + + public void startDocument() { + nodeStk.push(root); + } + + public void endDocument() { + nodeStk.pop(); + } + + public void startElement(String namespace, String localName, String qName, Attributes attrs) { + final Element tmp = document.createElementNS(namespace, qName); + + // Add namespace declarations first + if (namespaceDecls != null) { + final int nDecls = namespaceDecls.size(); + for (int i = 0; i < nDecls; i++) { + final String prefix = namespaceDecls.get(i++); + + if (prefix == null || prefix.equals(EMPTYSTRING)) { + tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, namespaceDecls.get(i)); + } else { + tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, namespaceDecls.get(i)); + } + } + namespaceDecls.clear(); + } + + // Add attributes to element + final int nattrs = attrs.getLength(); + for (int i = 0; i < nattrs; i++) { + if (attrs.getLocalName(i) == null) { + tmp.setAttribute(attrs.getQName(i), attrs.getValue(i)); + } else { + tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i)); + } + } + + // Append this new node onto current stack node + Node last = nodeStk.peek(); + + // If the SAX2DOM is created with a non-null next sibling node, + // insert the result nodes before the next sibling under the root. + if (last == root && nextSibling != null) { + last.insertBefore(tmp, nextSibling); + } else { + last.appendChild(tmp); + } + + // Push this node onto stack + nodeStk.push(tmp); + lastSibling = null; + } + + public void endElement(String namespace, String localName, String qName) { + nodeStk.pop(); + lastSibling = null; + } + + public void startPrefixMapping(String prefix, String uri) { + if (namespaceDecls == null) { + namespaceDecls = new ArrayList(2); + } + namespaceDecls.add(prefix); + namespaceDecls.add(uri); + } + + public void endPrefixMapping(String prefix) { + // do nothing + } + + /** + * This class is only used internally so this method should never be called. + */ + public void ignorableWhitespace(char[] ch, int start, int length) { + } + + /** + * adds processing instruction node to DOM. + */ + public void processingInstruction(String target, String data) { + final Node last = nodeStk.peek(); + ProcessingInstruction pi = document.createProcessingInstruction(target, data); + if (pi != null) { + if (last == root && nextSibling != null) { + last.insertBefore(pi, nextSibling); + } else { + last.appendChild(pi); + } + + lastSibling = pi; + } + } + + /** + * This class is only used internally so this method should never be called. + */ + public void setDocumentLocator(Locator locator) { + } + + /** + * This class is only used internally so this method should never be called. + */ + public void skippedEntity(String name) { + } + + /** + * Lexical Handler method to create comment node in DOM tree. + */ + public void comment(char[] ch, int start, int length) { + final Node last = nodeStk.peek(); + Comment comment = document.createComment(new String(ch, start, length)); + if (comment != null) { + if (last == root && nextSibling != null) { + last.insertBefore(comment, nextSibling); + } else { + last.appendChild(comment); + } + + lastSibling = comment; + } + } + + // Lexical Handler methods- not implemented + public void startCDATA() { + } + + public void endCDATA() { + } + + public void startEntity(java.lang.String name) { + } + + public void endDTD() { + } + + public void endEntity(String name) { + } + + public void startDTD(String name, String publicId, String systemId) throws SAXException { + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXMLStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXMLStreamReader.java deleted file mode 100644 index 4a5d4aaa6a..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXMLStreamReader.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.common.xml.stax; - -import org.w3c.dom.Node; - -public class DOMXMLStreamReader extends XmlTreeStreamReaderImpl { - - public DOMXMLStreamReader(Node node) { - super(new DOMXmlNodeImpl(node)); - switch (node.getNodeType()) { - case Node.DOCUMENT_NODE: - break; - case Node.ELEMENT_NODE: - break; - default: - throw new IllegalArgumentException("Illegal node type: " + node); - } - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXmlNodeImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXmlNodeImpl.java deleted file mode 100644 index 95b10358b8..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DOMXmlNodeImpl.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; - -import org.apache.tuscany.sca.common.xml.dom.DOMHelper; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * @version $Rev$ $Date$ - */ -public class DOMXmlNodeImpl implements XmlNode { - private Node node; - private Map namespaces; - private Type type; - - /** - * @param element - */ - public DOMXmlNodeImpl(Node element) { - super(); - if (element.getNodeType() == Node.DOCUMENT_NODE) { - this.node = ((Document)element).getDocumentElement(); - } else { - this.node = element; - } - switch (node.getNodeType()) { - case Node.CDATA_SECTION_NODE: - this.type = Type.CHARACTERS; - break; - case Node.ELEMENT_NODE: - this.type = Type.ELEMENT; - break; - case Node.TEXT_NODE: - this.type = Type.CHARACTERS; - break; - } - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#attributes() - */ - public List attributes() { - if (type != Type.ELEMENT) { - return null; - } - NamedNodeMap attrs = node.getAttributes(); - List xmlAttrs = new ArrayList(); - for (int i = 0; i < attrs.getLength(); i++) { - Attr attr = (Attr)attrs.item(i); - if (!attr.getName().equals("xmlns") && !attr.getName().startsWith("xmlns:")) { - xmlAttrs.add(new SimpleXmlNodeImpl(getQName(attr), attr.getValue(), XmlNode.Type.ATTRIBUTE)); - } - } - return xmlAttrs; - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#children() - */ - public Iterator children() { - if (type != Type.ELEMENT) { - return null; - } - NodeList nodes = node.getChildNodes(); - List xmlNodes = new ArrayList(); - for (int i = 0; i < nodes.getLength(); i++) { - Node child = (Node)nodes.item(i); - int nodeType = child.getNodeType(); - if (nodeType == Node.ELEMENT_NODE || nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { - xmlNodes.add(new DOMXmlNodeImpl(child)); - } - } - return xmlNodes.iterator(); - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#getName() - */ - public QName getName() { - return getQName(node); - } - - private static QName getQName(Node node) { - return DOMHelper.getQName(node); - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#getValue() - */ - public String getValue() { - return node.getNodeValue(); - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#namespaces() - */ - public Map namespaces() { - if (type != Type.ELEMENT) { - return null; - } - if (namespaces == null) { - namespaces = new HashMap(); - NamedNodeMap attrs = node.getAttributes(); - for (int i = 0; i < attrs.getLength(); i++) { - Attr attr = (Attr)attrs.item(i); - if ("xmlns".equals(attr.getPrefix())) { - namespaces.put(attr.getLocalName(), attr.getValue()); - } - if ("xmlns".equals(attr.getName())) { - namespaces.put("", attr.getValue()); - } - } - } - return namespaces; - } - - public Type getType() { - return type; - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DelegatingNamespaceContext.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DelegatingNamespaceContext.java deleted file mode 100644 index 21a857491b..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/DelegatingNamespaceContext.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.ArrayList; -import java.util.EmptyStackException; -import java.util.Iterator; -import java.util.List; - -import javax.xml.namespace.NamespaceContext; - -public class DelegatingNamespaceContext implements NamespaceContext { - private static int count; - - private class WrappingIterator implements Iterator { - - private Iterator containedIterator; - - public WrappingIterator(Iterator containedIterator) { - this.containedIterator = containedIterator; - } - - public Iterator getContainedIterator() { - return containedIterator; - } - - public boolean hasNext() { - return containedIterator.hasNext(); - } - - public Object next() { - return containedIterator.next(); - } - - /** - * As per the contract on the API of Namespace context the returned iterator should be immutable - */ - public void remove() { - throw new UnsupportedOperationException(); - } - - public void setContainedIterator(Iterator containedIterator) { - this.containedIterator = containedIterator; - } - } - - private NamespaceContext parentNsContext; - - private FastStack prefixStack = new FastStack(); - - // Keep two ArrayLists for the prefixes and namespaces. They should be in - // sync - // since the index of the entry will be used to relate them - // use the minimum initial capacity to let things handle memory better - - private FastStack uriStack = new FastStack(); - - /** - * Generates a unique namespace prefix that is not in the scope of the NamespaceContext - * - * @return string - */ - public String generateUniquePrefix() { - String prefix = "p" + count++; - // null should be returned if the prefix is not bound! - while (getNamespaceURI(prefix) != null) { - prefix = "p" + count++; - } - - return prefix; - } - - public String getNamespaceURI(String prefix) { - // do the corrections as per the Javadoc - int index = prefixStack.search(prefix); - if (index != -1) { - return uriStack.get(index); - } - if (parentNsContext != null) { - return parentNsContext.getPrefix(prefix); - } - return null; - } - - public NamespaceContext getParentNsContext() { - return parentNsContext; - } - - public String getPrefix(String uri) { - // do the corrections as per the Javadoc - int index = uriStack.search(uri); - if (index != -1) { - return prefixStack.get(index); - } - - if (parentNsContext != null) { - return parentNsContext.getPrefix(uri); - } - return null; - } - - public Iterator getPrefixes(String uri) { - // create an ArrayList that contains the relevant prefixes - String[] uris = uriStack.toArray(new String[uriStack.size()]); - List tempList = new ArrayList(); - for (int i = uris.length - 1; i >= 0; i--) { - if (uris[i].equals(uri)) { - tempList.add(prefixStack.get(i)); - // we assume that array conversion preserves the order - } - } - // by now all the relevant prefixes are collected - // make a new iterator and provide a wrapper iterator to - // obey the contract on the API - return new WrappingIterator(tempList.iterator()); - } - - /** - * Pop a namespace - */ - public void popNamespace() { - prefixStack.pop(); - uriStack.pop(); - } - - /** - * Register a namespace in this context - * - * @param prefix - * @param uri - */ - public void pushNamespace(String prefix, String uri) { - prefixStack.push(prefix); - uriStack.push(uri); - - } - - public void setParentNsContext(NamespaceContext parentNsContext) { - this.parentNsContext = parentNsContext; - } - - /** - * An implementation of the {@link java.util.Stack} API that is based on an ArrayList instead of a - * Vector, so it is not synchronized to protect against multi-threaded access. The implementation is - * therefore operates faster in environments where you do not need to worry about multiple thread contention. - *

- * The removal order of an ArrayStack is based on insertion order: The most recently added element is - * removed first. The iteration order is not the same as the removal order. The iterator returns elements - * from the bottom up, whereas the {@link #remove()} method removes them from the top down. - *

- * Unlike Stack, ArrayStack accepts null entries. - */ - public static class FastStack extends ArrayList { - - /** Ensure Serialization compatibility */ - private static final long serialVersionUID = 2130079159931574599L; - - /** - * Constructs a new empty ArrayStack. The initial size is controlled by ArrayList - * and is currently 10. - */ - public FastStack() { - super(); - } - - /** - * Constructs a new empty ArrayStack with an initial size. - * - * @param initialSize the initial size to use - * @throws IllegalArgumentException if the specified initial size is negative - */ - public FastStack(int initialSize) { - super(initialSize); - } - - /** - * Return true if this stack is currently empty. - *

- * This method exists for compatibility with java.util.Stack. New users of this class should use - * isEmpty instead. - * - * @return true if the stack is currently empty - */ - public boolean empty() { - return isEmpty(); - } - - /** - * Returns the top item off of this stack without removing it. - * - * @return the top item on the stack - * @throws EmptyStackException if the stack is empty - */ - public T peek() throws EmptyStackException { - int n = size(); - if (n <= 0) { - throw new EmptyStackException(); - } else { - return get(n - 1); - } - } - - /** - * Returns the n'th item down (zero-relative) from the top of this stack without removing it. - * - * @param n the number of items down to go - * @return the n'th item on the stack, zero relative - * @throws EmptyStackException if there are not enough items on the stack to satisfy this request - */ - public T peek(int n) throws EmptyStackException { - int m = (size() - n) - 1; - if (m < 0) { - throw new EmptyStackException(); - } else { - return get(m); - } - } - - /** - * Pops the top item off of this stack and return it. - * - * @return the top item on the stack - * @throws EmptyStackException if the stack is empty - */ - public T pop() throws EmptyStackException { - int n = size(); - if (n <= 0) { - throw new EmptyStackException(); - } else { - return remove(n - 1); - } - } - - /** - * Pushes a new item onto the top of this stack. The pushed item is also returned. This is equivalent to calling - * add. - * - * @param item the item to be added - * @return the item just pushed - */ - public Object push(T item) { - add(item); - return item; - } - - /** - * Returns the top-most index for the object in the stack - * - * @param object the object to be searched for - * @return top-most index, or -1 if not found - */ - public int search(T object) { - int i = size() - 1; // Current index - while (i >= 0) { - T current = get(i); - if ((object == null && current == null) || (object != null && object.equals(current))) { - return i; - } - i--; - } - return -1; - } - - /** - * Returns the element on the top of the stack. - * - * @return the element on the top of the stack - * @throws EmptyStackException if the stack is empty - */ - public T get() { - int size = size(); - if (size == 0) { - throw new EmptyStackException(); - } - return get(size - 1); - } - - /** - * Removes the element on the top of the stack. - * - * @return the removed element - * @throws EmptyStackException if the stack is empty - */ - public T remove() { - int size = size(); - if (size == 0) { - throw new EmptyStackException(); - } - return remove(size - 1); - } - - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValueArrayStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValueArrayStreamReader.java deleted file mode 100644 index 5942f23d20..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValueArrayStreamReader.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; -import javax.xml.stream.Location; -import javax.xml.stream.XMLStreamException; - - -public class NameValueArrayStreamReader implements XMLFragmentStreamReader { - - private static final int START_ELEMENT_STATE = 0; - private static final int TEXT_STATE = 1; - private static final int END_ELEMENT_STATE = 2; - private static final int FINAL_END_ELEMENT_STATE = 3; - private static final int START_ELEMENT_STATE_WITH_NULL = 4; - - private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); - // the index of the array - private int arrayIndex; - - private QName name; - private String[] values; - - // start element is the default state - private int state = START_ELEMENT_STATE; - - public NameValueArrayStreamReader(QName name, String[] values) { - this.name = name; - this.values = values; - } - - public void setParentNamespaceContext(NamespaceContext nsContext) { - this.namespaceContext.setParentNsContext(nsContext); - } - - public void init() { - // TODO what if the QName namespace has not been declared - } - - public Object getProperty(String string) throws IllegalArgumentException { - return null; - } - - /** - * @throws XMLStreamException - */ - public int next() throws XMLStreamException { - switch (state) { - case START_ELEMENT_STATE: - if (values.length > 0) { - state = TEXT_STATE; - return CHARACTERS; - } else { - state = FINAL_END_ELEMENT_STATE; - return END_ELEMENT; - } - - case START_ELEMENT_STATE_WITH_NULL: - if (arrayIndex == (values.length - 1)) { - state = FINAL_END_ELEMENT_STATE; - } else { - state = END_ELEMENT_STATE; - } - return END_ELEMENT; - case FINAL_END_ELEMENT_STATE: - // oops, not supposed to happen! - throw new XMLStreamException("end already reached!"); - case END_ELEMENT_STATE: - // we've to have more values since this is not the - // last value - // increment the counter - arrayIndex++; - if (values[arrayIndex] == null) { - state = START_ELEMENT_STATE_WITH_NULL; - } else { - state = START_ELEMENT_STATE; - } - return START_ELEMENT; - case TEXT_STATE: - if (arrayIndex == (values.length - 1)) { - state = FINAL_END_ELEMENT_STATE; - return END_ELEMENT; - } else { - state = END_ELEMENT_STATE; - return END_ELEMENT; - } - - default: - throw new XMLStreamException("unknown event type!"); - } - } - - public void require(int i, String string, String string1) throws XMLStreamException { - // nothing done here - } - - public String getElementText() throws XMLStreamException { - return null; // not implemented - } - - public int nextTag() throws XMLStreamException { - return 0; // not implemented - } - - public String getAttributeValue(String string, String string1) { - if (state == TEXT_STATE) { - // TODO something - return null; - } else { - return null; - } - - } - - public int getAttributeCount() { - if (state == START_ELEMENT_STATE_WITH_NULL) { - return 1; - } - if (state == START_ELEMENT_STATE) { - return 0; - } else { - throw new IllegalStateException(); - } - - } - - public QName getAttributeName(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { - return NIL_QNAME; - } - if (state == START_ELEMENT_STATE) { - return null; - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeNamespace(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { - return NIL_QNAME.getNamespaceURI(); - } - if (state == START_ELEMENT_STATE) { - return null; - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeLocalName(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { - return NIL_QNAME.getLocalPart(); - } - if (state == START_ELEMENT_STATE) { - return null; - } else { - throw new IllegalStateException(); - } - } - - public String getAttributePrefix(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { - return NIL_QNAME.getPrefix(); - } - if (state == START_ELEMENT_STATE) { - return null; - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeType(int i) { - return null; // not implemented - } - - public String getAttributeValue(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { - return NIL_VALUE_TRUE; - } - if (state == START_ELEMENT_STATE) { - return null; - } else { - throw new IllegalStateException(); - } - } - - public boolean isAttributeSpecified(int i) { - return false; // not supported - } - - public int getNamespaceCount() { - if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent()) { - return 1; - } else { - return 0; - } - - } - - public String getNamespacePrefix(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { - return NIL_QNAME.getPrefix(); - } else { - return null; - } - } - - public String getNamespaceURI(int i) { - if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { - return NIL_QNAME.getNamespaceURI(); - } else { - return null; - } - } - - public NamespaceContext getNamespaceContext() { - return this.namespaceContext; - } - - public boolean isDone() { - return state == FINAL_END_ELEMENT_STATE; - } - - public int getEventType() { - switch (state) { - case START_ELEMENT_STATE: - return START_ELEMENT; - case END_ELEMENT_STATE: - return END_ELEMENT; - case TEXT_STATE: - return CHARACTERS; - case FINAL_END_ELEMENT_STATE: - return END_ELEMENT; - default: - throw new UnsupportedOperationException(); - // we've no idea what this is!!!!! - } - - } - - public String getText() { - if (state == TEXT_STATE) { - return values[arrayIndex]; - } else { - throw new IllegalStateException(); - } - } - - public char[] getTextCharacters() { - if (state == TEXT_STATE) { - return values[arrayIndex].toCharArray(); - } else { - throw new IllegalStateException(); - } - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - // not implemented - throw new UnsupportedOperationException(); - } - - public int getTextStart() { - if (state == TEXT_STATE) { - return 0; - } else { - throw new IllegalStateException(); - } - } - - public int getTextLength() { - if (state == TEXT_STATE) { - return values[arrayIndex].length(); - } else { - throw new IllegalStateException(); - } - - } - - public String getEncoding() { - return null; - } - - public boolean hasText() { - return state == TEXT_STATE; - } - - public Location getLocation() { - return null; // not supported - } - - public QName getName() { - if (state != TEXT_STATE) { - return name; - } else { - return null; - } - } - - public String getLocalName() { - if (state != TEXT_STATE) { - return name.getLocalPart(); - } else { - return null; - } - } - - public boolean hasName() { - return state != TEXT_STATE; - - } - - public String getNamespaceURI() { - if (state != TEXT_STATE) { - return name.getNamespaceURI(); - } else { - return null; - } - - } - - public String getPrefix() { - if (state != TEXT_STATE) { - return name.getPrefix(); - } else { - return null; - } - } - - public String getVersion() { - return null; // TODO 1.0 ? - } - - public boolean isStandalone() { - return false; - } - - public boolean standaloneSet() { - return false; - } - - public String getCharacterEncodingScheme() { - return null; - } - - public String getPITarget() { - return null; - } - - public String getPIData() { - return null; - } - - public boolean hasNext() throws XMLStreamException { - return state != FINAL_END_ELEMENT_STATE; - } - - public void close() throws XMLStreamException { - // Do nothing - we've nothing to free here - } - - public String getNamespaceURI(String prefix) { - return namespaceContext.getNamespaceURI(prefix); - } - - public boolean isStartElement() { - return state == START_ELEMENT_STATE; - } - - public boolean isEndElement() { - return state == END_ELEMENT_STATE; - } - - public boolean isCharacters() { - return state == TEXT_STATE; - } - - public boolean isWhiteSpace() { - return false; // no whitespaces here - } - - /** - * Test whether the xsi namespace is present - */ - private boolean isXsiNamespacePresent() { - return namespaceContext.getNamespaceURI(NIL_QNAME.getPrefix()) != null; - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValuePairStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValuePairStreamReader.java deleted file mode 100644 index b4b655d541..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NameValuePairStreamReader.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; -import javax.xml.stream.Location; -import javax.xml.stream.XMLStreamException; - - - -public class NameValuePairStreamReader implements XMLFragmentStreamReader { - - private static final int START_ELEMENT_STATE = 0; - private static final int TEXT_STATE = 1; - private static final int END_ELEMENT_STATE = 2; - - private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); - - private QName name; - private String value; - - private int state = START_ELEMENT_STATE; - // initiate at the start element state - - // keeps track whether the namespace is declared - // false by default - private boolean nsDeclared; - - public NameValuePairStreamReader(QName name, String value) { - this.name = name; - this.value = value; - } - - public Object getProperty(String key) throws IllegalArgumentException { - return null; - } - - public int next() throws XMLStreamException { - // no need to handle null here. it should have been handled - // already - switch (state) { - case START_ELEMENT_STATE: - state = TEXT_STATE; - return CHARACTERS; - case END_ELEMENT_STATE: - // oops, not supposed to happen! - throw new XMLStreamException("end already reached!"); - case TEXT_STATE: - state = END_ELEMENT_STATE; - return END_ELEMENT; - default: - throw new XMLStreamException("unknown event type!"); - } - } - - public void require(int i, String string, String string1) throws XMLStreamException { - // not implemented - } - - public String getElementText() throws XMLStreamException { - if (state == START_ELEMENT) { - // move to the end state and return the value - state = END_ELEMENT_STATE; - return value; - } else { - throw new XMLStreamException(); - } - - } - - public int nextTag() throws XMLStreamException { - return 0; // TODO - } - - public boolean hasNext() throws XMLStreamException { - return state != END_ELEMENT_STATE; - } - - public void close() throws XMLStreamException { - // Do nothing - we've nothing to free here - } - - public String getNamespaceURI(String prefix) { - return namespaceContext.getNamespaceURI(prefix); - } - - public boolean isStartElement() { - return state == START_ELEMENT_STATE; - } - - public boolean isEndElement() { - return state == END_ELEMENT_STATE; - } - - public boolean isCharacters() { - return state == TEXT_STATE; - } - - public boolean isWhiteSpace() { - return false; // no whitespaces here - } - - public String getAttributeValue(String string, String string1) { - return null; - } - - public int getAttributeCount() { - return 0; - } - - public QName getAttributeName(int i) { - return null; - } - - public String getAttributeNamespace(int i) { - return null; - } - - public String getAttributeLocalName(int i) { - return null; - } - - public String getAttributePrefix(int i) { - return null; - } - - public String getAttributeType(int i) { - return null; - } - - public String getAttributeValue(int i) { - return null; - } - - public boolean isAttributeSpecified(int i) { - return false; // no attributes here - } - - public int getNamespaceCount() { - return nsDeclared ? 1 : 0; - } - - public String getNamespacePrefix(int i) { - return (nsDeclared && i == 0) ? name.getPrefix() : null; - } - - public String getNamespaceURI(int i) { - return (nsDeclared && i == 0) ? name.getNamespaceURI() : null; - } - - public NamespaceContext getNamespaceContext() { - return this.namespaceContext; - } - - public int getEventType() { - switch (state) { - case START_ELEMENT_STATE: - return START_ELEMENT; - case END_ELEMENT_STATE: - return END_ELEMENT; - case TEXT_STATE: - return CHARACTERS; - default: - throw new UnsupportedOperationException(); - // we've no idea what this is!!!!! - } - - } - - public String getText() { - if (state == TEXT_STATE) { - return value; - } else { - throw new IllegalStateException(); - } - } - - public char[] getTextCharacters() { - if (state == TEXT_STATE) { - return value.toCharArray(); - } else { - throw new IllegalStateException(); - } - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - // not implemented - throw new UnsupportedOperationException(); - } - - public int getTextStart() { - if (state == TEXT_STATE) { - return 0; - } else { - throw new IllegalStateException(); - } - } - - public int getTextLength() { - if (state == TEXT_STATE) { - return value.length(); - } else { - throw new IllegalStateException(); - } - - } - - public String getEncoding() { - return null; - } - - public boolean hasText() { - return state == TEXT_STATE; - } - - public Location getLocation() { - return new Location() { - public int getLineNumber() { - return 0; - } - - public int getColumnNumber() { - return 0; - } - - public int getCharacterOffset() { - return 0; - } - - public String getPublicId() { - return null; - } - - public String getSystemId() { - return null; - } - }; - } - - public QName getName() { - if (state != TEXT_STATE) { - return name; - } else { - return null; - } - } - - public String getLocalName() { - if (state != TEXT_STATE) { - return name.getLocalPart(); - } else { - return null; - } - } - - public boolean hasName() { - return state != TEXT_STATE; - - } - - public String getNamespaceURI() { - if (state != TEXT_STATE) { - return name.getNamespaceURI(); - } else { - return null; - } - - } - - public String getPrefix() { - if (state != TEXT_STATE) { - return name.getPrefix(); - } else { - return null; - } - } - - public String getVersion() { - return null; // TODO 1.0 ? - } - - public boolean isStandalone() { - return false; - } - - public boolean standaloneSet() { - return false; - } - - public String getCharacterEncodingScheme() { - return null; - } - - public String getPITarget() { - return null; - } - - public String getPIData() { - return null; - } - - public boolean isDone() { - return state == END_ELEMENT_STATE; - } - - public void setParentNamespaceContext(NamespaceContext nsContext) { - this.namespaceContext.setParentNsContext(nsContext); - } - - public void init() { - // just add the current elements namespace and prefix to the this - // elements nscontext - addToNsMap(name.getPrefix(), name.getNamespaceURI()); - - } - - /** - * @param prefix - * @param uri - */ - private void addToNsMap(String prefix, String uri) { - // TODO - need to fix this up to cater for cases where - // namespaces are having no prefixes - if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { - // this namespace is not there. Need to declare it - namespaceContext.pushNamespace(prefix, uri); - nsDeclared = true; - } - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NamedProperty.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NamedProperty.java deleted file mode 100644 index 2ddcd4baa5..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NamedProperty.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.Map; - -import javax.xml.namespace.QName; - -/** - * A named property - * - * @version $Rev$ $Date$ - */ -public class NamedProperty implements Map.Entry { - private QName key; - - private Object value; - - public NamedProperty(QName key, Object value) { - this.key = key; - this.value = value; - } - - public NamedProperty(String key, Object value) { - this.key = new QName(key); - this.value = value; - } - - public QName getKey() { - return key; - } - - public Object getValue() { - return value; - } - - public Object setValue(Object value) { - Object v = this.value; - this.value = value; - return v; - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NilElementStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NilElementStreamReader.java deleted file mode 100644 index fc78807cdb..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/NilElementStreamReader.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; -import javax.xml.stream.Location; -import javax.xml.stream.XMLStreamException; - -public class NilElementStreamReader implements XMLFragmentStreamReader { - - private static final int END_ELEMENT_STATE = 2; - - private static final int START_ELEMENT_STATE = 1; - private int currentState = START_ELEMENT; - - private QName elementQName; - - public NilElementStreamReader(QName elementQName) { - this.elementQName = elementQName; - } - - public void setParentNamespaceContext(NamespaceContext nsContext) { - // NOOP - } - - public void close() throws XMLStreamException { - // do nothing - } - - public int getAttributeCount() { - return 1; - } - - public String getAttributeLocalName(int i) { - return (i == 0) ? NIL_QNAME.getLocalPart() : null; - } - - public QName getAttributeName(int i) { - return (i == 0) ? NIL_QNAME : null; - } - - public String getAttributeNamespace(int i) { - return (i == 0) ? NIL_QNAME.getNamespaceURI() : null; - } - - public String getAttributePrefix(int i) { - return (i == 0) ? NIL_QNAME.getPrefix() : null; - } - - public String getAttributeType(int i) { - throw new UnsupportedOperationException(); - } - - public String getAttributeValue(int i) { - return (i == 0) ? NIL_VALUE_TRUE : null; - } - - public String getAttributeValue(String string, String string1) { - if (string == null && NIL_QNAME.getLocalPart().equals(string1)) { - return NIL_VALUE_TRUE; - } - return null; - } - - public String getCharacterEncodingScheme() { - throw new UnsupportedOperationException(); - } - - public String getElementText() throws XMLStreamException { - return null; - } - - public String getEncoding() { - return null; - } - - public int getEventType() { - int returnEvent = START_DOCUMENT; - switch (currentState) { - case START_ELEMENT_STATE: - returnEvent = START_ELEMENT; - break; - case END_ELEMENT_STATE: - returnEvent = END_ELEMENT; - break; - } - return returnEvent; - } - - public String getLocalName() { - return elementQName.getLocalPart(); - } - - public Location getLocation() { - return new Location() { - public int getCharacterOffset() { - return 0; - } - - public int getColumnNumber() { - return 0; - } - - public int getLineNumber() { - return 0; - } - - public String getPublicId() { - return null; - } - - public String getSystemId() { - return null; - } - }; - } - - public QName getName() { - return elementQName; - } - - public NamespaceContext getNamespaceContext() { - throw new UnsupportedOperationException(); - } - - public int getNamespaceCount() { - return 0; - } - - public String getNamespacePrefix(int i) { - return null; - } - - public String getNamespaceURI() { - return elementQName.getNamespaceURI(); - } - - public String getNamespaceURI(int i) { - return null; - } - - public String getNamespaceURI(String string) { - if (elementQName.getPrefix() != null && elementQName.getPrefix().equals(string)) { - return elementQName.getNamespaceURI(); - } else { - return null; - } - } - - public String getPIData() { - throw new UnsupportedOperationException(); - } - - public String getPITarget() { - throw new UnsupportedOperationException(); - } - - public String getPrefix() { - return elementQName.getPrefix(); - } - - public Object getProperty(String key) throws IllegalArgumentException { - // since optimization is a global property - // we've to implement it everywhere - return null; - } - - public String getText() { - return null; - } - - public char[] getTextCharacters() { - return new char[0]; - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - return 0; - } - - public int getTextLength() { - return 0; - } - - public int getTextStart() { - return 0; - } - - public String getVersion() { - throw new UnsupportedOperationException(); - } - - public boolean hasName() { - return true; - } - - public boolean hasNext() throws XMLStreamException { - return currentState != END_ELEMENT_STATE; - - } - - public boolean hasText() { - return false; - } - - public void init() { - // NOOP - } - - public boolean isAttributeSpecified(int i) { - return i == 0; - } - - public boolean isCharacters() { - return false; - } - - public boolean isDone() { - return currentState == END_ELEMENT_STATE; - } - - public boolean isEndElement() { - return currentState == END_ELEMENT_STATE; - } - - public boolean isStandalone() { - throw new UnsupportedOperationException(); - } - - public boolean isStartElement() { - return currentState == START_ELEMENT_STATE; - } - - public boolean isWhiteSpace() { - return false; - } - - public int next() throws XMLStreamException { - int returnEvent = START_DOCUMENT; - switch (currentState) { - case START_ELEMENT_STATE: - currentState = END_ELEMENT_STATE; - returnEvent = END_ELEMENT; - break; - case END_ELEMENT_STATE: - throw new XMLStreamException("parser completed!"); - - } - return returnEvent; - } - - public int nextTag() throws XMLStreamException { - throw new UnsupportedOperationException(); - } - - public void require(int i, String string, String string1) throws XMLStreamException { - // nothing - } - - public boolean standaloneSet() { - throw new UnsupportedOperationException(); - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/SimpleXmlNodeImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/SimpleXmlNodeImpl.java deleted file mode 100644 index a28705cff2..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/SimpleXmlNodeImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; - -/** - * @version $Rev$ $Date$ - */ -public class SimpleXmlNodeImpl implements XmlNode { - private static final String XSI_PREFIX = "xsi"; - private static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance"; - private static final QName XSI_NIL = new QName(XSI_NS, "nil", XSI_PREFIX); - private static final Map NS_MAP = new HashMap(); - static { - NS_MAP.put(XSI_PREFIX, XSI_NS); - } - - protected Type type; - protected QName name; - protected Object value; - - public SimpleXmlNodeImpl(QName name, Object value) { - this(name, value, name != null ? Type.ELEMENT : Type.CHARACTERS); - } - - public SimpleXmlNodeImpl(QName name, Object value, Type type) { - super(); - this.type = type; - this.name = name; - this.value = value; - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#attributes() - */ - public List attributes() { - if (type == Type.ELEMENT && value == null) { - // Nil element - XmlNode attr = new SimpleXmlNodeImpl(XSI_NIL, "true"); - return Arrays.asList(attr); - } - return null; - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#children() - */ - public Iterator children() { - if (type == Type.ELEMENT && value != null) { - // Nil element - XmlNode node = new SimpleXmlNodeImpl(null, value); - return Arrays.asList(node).iterator(); - } - return null; - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#getName() - */ - public QName getName() { - return name; - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#getValue() - */ - public String getValue() { - return value == null ? null : String.valueOf(value); - } - - /** - * @see org.apache.tuscany.sca.common.xml.stax.databinding.xml.XmlNode#namespaces() - */ - public Map namespaces() { - if (type == Type.ELEMENT && value == null) { - return NS_MAP; - } - return null; - } - - public Type getType() { - return type; - } - - public void setType(Type type) { - this.type = type; - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAX2SAXAdapter.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAX2SAXAdapter.java deleted file mode 100644 index 12550781d3..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAX2SAXAdapter.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.QName; -import javax.xml.stream.Location; -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.Locator; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.AttributesImpl; - -/** - * Adapter that converts from StAX to SAX event streams. Currently the following - * SAX events are not generated: - *

    - *
  • ignorableWhitespace
  • - *
  • skippedEntity
  • - *
      - * Also the following StAX events are not mapped: - *
        - *
      • CDATA
      • - *
      • COMMENT
      • - *
      • DTD
      • - *
      • ENTITY_DECLARATION
      • - *
      • ENTITY_REFERENCE
      • - *
      • NOTATION_DECLARATION
      • - *
      • SPACE
      • - *
      - * StAX ATTRIBUTE events are ignored but the equivalent attributes (derived from - * the START_ELEMENT event) are supplied in the SAX startElement event's - * Attributes parameter. If the adaptor is configured to pass namespace prefixes - * then namespace information will also be included in the Attributes; StAX - * NAMESPACE events are ignored.

      Another issue is namespace processing. If - * the reader is positioned at a sub-node, we cannot capture all the in-scope - * namespace bindings. Therefore we cannot re-create a proper SAX event stream - * from a StAX parser.

      For example

      <a:root xmlns:a="foo" - * xmlns:b="bar"><b:sub>a:foo</b:sub></a:root>

      And if - * you are handed a parser at <b:sub>, then your SAX events should look - * like:

      <b:sub xmlns:a="foo" xmlns:b="bar">a:foo</b:sub>

      - * not:

      <b:sub>a:foo</b:sub>

      Proposal: we change the - * receiver of SAX events (SDOXMLResourceImpl) so that it uses NamespaceContext - * to resolve prefix (as opposed to record start/endPrefixMappings and use it - * for resolution.) - * - * @version $Rev$ $Date$ - */ -public class StAX2SAXAdapter { - private final boolean namespacePrefixes; - - /** - * Construct a new StAX to SAX adapter that will convert a StAX event stream - * into a SAX event stream. - * - * @param namespacePrefixes whether xmlns attributes should be included in - * startElement events; - */ - public StAX2SAXAdapter(boolean namespacePrefixes) { - this.namespacePrefixes = namespacePrefixes; - } - - /** - * Pull events from the StAX stream and dispatch to the SAX ContentHandler. - * The StAX stream would typically be located on a START_DOCUMENT or - * START_ELEMENT event and when this method returns it will be located on - * the associated END_DOCUMENT or END_ELEMENT event. Behaviour with other - * start events is undefined. - * - * @param reader StAX event source to read - * @param handler SAX ContentHandler for processing events - * @throws XMLStreamException if there was a problem reading the stream - * @throws SAXException passed through from the ContentHandler - */ - public void parse(XMLStreamReader reader, ContentHandler handler) throws XMLStreamException, SAXException { - handler.setDocumentLocator(new LocatorAdaptor(reader.getLocation())); - - // remembers the nest level of elements to know when we are done - int level = 0; - int event = reader.getEventType(); - while (true) { - switch (event) { - case XMLStreamConstants.START_DOCUMENT: - level++; - handler.startDocument(); - break; - case XMLStreamConstants.START_ELEMENT: - level++; - handleStartElement(reader, handler); - break; - case XMLStreamConstants.PROCESSING_INSTRUCTION: - handler.processingInstruction(reader.getPITarget(), reader.getPIData()); - break; - case XMLStreamConstants.CHARACTERS: - handler.characters(reader.getTextCharacters(), reader.getTextStart(), reader - .getTextLength()); - break; - case XMLStreamConstants.END_ELEMENT: - handleEndElement(reader, handler); - level--; - if (level == 0) { - return; - } - break; - case XMLStreamConstants.END_DOCUMENT: - handler.endDocument(); - return; - /* - * uncomment to handle all events rather than just mapped - * ones // StAX events that are not mapped to SAX case - * XMLStreamConstants.COMMENT: case - * XMLStreamConstants.SPACE: case - * XMLStreamConstants.ENTITY_REFERENCE: case - * XMLStreamConstants.DTD: case XMLStreamConstants.CDATA: - * case XMLStreamConstants.NOTATION_DECLARATION: case - * XMLStreamConstants.ENTITY_DECLARATION: break; // StAX - * events handled in START_ELEMENT case - * XMLStreamConstants.ATTRIBUTE: case - * XMLStreamConstants.NAMESPACE: break; default: throw new - * AssertionError("Unknown StAX event: " + event); - */ - } - event = reader.next(); - } - } - - private void handleStartElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { - // send startPrefixMapping events immediately before startElement event - int nsCount = reader.getNamespaceCount(); - for (int i = 0; i < nsCount; i++) { - String prefix = reader.getNamespacePrefix(i); - if (prefix == null) { // true for default namespace - prefix = ""; - } - handler.startPrefixMapping(prefix, reader.getNamespaceURI(i)); - } - - // fire startElement - QName qname = reader.getName(); - String prefix = qname.getPrefix(); - String rawname; - if (prefix == null || prefix.length() == 0) { - rawname = qname.getLocalPart(); - } else { - rawname = prefix + ':' + qname.getLocalPart(); - } - Attributes attrs = getAttributes(reader); - handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs); - } - - private static void handleEndElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { - // fire endElement - QName qname = reader.getName(); - handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString()); - - // send endPrefixMapping events immediately after endElement event - // we send them in the opposite order to that returned but this is not - // actually required by SAX - int nsCount = reader.getNamespaceCount(); - for (int i = nsCount - 1; i >= 0; i--) { - String prefix = reader.getNamespacePrefix(i); - if (prefix == null) { // true for default namespace - prefix = ""; - } - handler.endPrefixMapping(prefix); - } - } - - /** - * Get the attributes associated with the current START_ELEMENT event. - * - * @return the StAX attributes converted to org.xml.sax.Attributes - */ - private Attributes getAttributes(XMLStreamReader reader) { - assert reader.getEventType() == XMLStreamConstants.START_ELEMENT; - - AttributesImpl attrs = new AttributesImpl(); - - // add namespace declarations if required - if (namespacePrefixes) { - for (int i = 0; i < reader.getNamespaceCount(); i++) { - String prefix = reader.getNamespacePrefix(i); - String uri = reader.getNamespaceURI(i); - attrs.addAttribute(null, prefix, "xmlns:" + prefix, "CDATA", uri); - } - } - - // Regular attributes - for (int i = 0; i < reader.getAttributeCount(); i++) { - String uri = reader.getAttributeNamespace(i); - if (uri == null) { - uri = ""; - } - String localName = reader.getAttributeLocalName(i); - String prefix = reader.getAttributePrefix(i); - String qname; - if (prefix == null || prefix.length() == 0) { - qname = localName; - } else { - qname = prefix + ':' + localName; - } - String type = reader.getAttributeType(i); - String value = reader.getAttributeValue(i); - - attrs.addAttribute(uri, localName, qname, type, value); - } - - return attrs; - } - - /** - * Adaptor for mapping Locator information. - */ - private static final class LocatorAdaptor implements Locator { - private final Location location; - - private LocatorAdaptor(Location location) { - this.location = location; - } - - public int getColumnNumber() { - return location == null ? 0 : location.getColumnNumber(); - } - - public int getLineNumber() { - return location == null ? 0 : location.getLineNumber(); - } - - public String getPublicId() { - return location == null ? "" : location.getPublicId(); - } - - public String getSystemId() { - return location == null ? "" : location.getSystemId(); - } - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAXHelper.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAXHelper.java index e78e8558e7..5283de272d 100644 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAXHelper.java +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/StAXHelper.java @@ -35,11 +35,16 @@ import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.apache.tuscany.sca.common.xml.stax.impl.StAX2SAXAdapter; +import org.apache.tuscany.sca.common.xml.stax.impl.XMLStreamSerializer; +import org.apache.tuscany.sca.common.xml.stax.reader.DOMXMLStreamReader; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.w3c.dom.Document; import org.w3c.dom.Node; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; public final class StAXHelper { private final XMLInputFactory inputFactory; @@ -129,4 +134,9 @@ public final class StAXHelper { writer.flush(); } + public void saveAsSAX(XMLStreamReader reader, ContentHandler contentHandler) throws XMLStreamException, + SAXException { + new StAX2SAXAdapter(false).parse(reader, contentHandler); + } + } diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/WrappingXMLStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/WrappingXMLStreamReader.java deleted file mode 100644 index a237bb457e..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/WrappingXMLStreamReader.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.util.StreamReaderDelegate; - -public class WrappingXMLStreamReader extends StreamReaderDelegate implements XMLFragmentStreamReader { - - private boolean done; - private int level; - - public WrappingXMLStreamReader(XMLStreamReader realReader) throws XMLStreamException { - super(realReader); - if (realReader == null) { - throw new UnsupportedOperationException("Reader cannot be null"); - } - - if (realReader instanceof XMLFragmentStreamReader) { - ((XMLFragmentStreamReader)realReader).init(); - } - - if (realReader.getEventType() == START_DOCUMENT) { - // Position to the 1st element - realReader.nextTag(); - } - if (realReader.getEventType() != START_ELEMENT) { - throw new IllegalStateException("The reader is not positioned at START_DOCUMENT or START_ELEMENT"); - } - this.done = false; - this.level = 1; - } - - @Override - public boolean hasNext() throws XMLStreamException { - return !done && super.hasNext(); - } - - @Override - public int next() throws XMLStreamException { - if (!hasNext()) { - throw new IllegalStateException("No more events"); - } - int event = super.next(); - if (!super.hasNext()) { - done = true; - } - if (event == START_ELEMENT) { - level++; - } else if (event == END_ELEMENT) { - level--; - if (level == 0) { - done = true; - } - } - return event; - } - - @Override - public int nextTag() throws XMLStreamException { - int event = 0; - while (true) { - event = next(); - if (event == START_ELEMENT || event == END_ELEMENT) { - return event; - } - } - } - - public void setParentNamespaceContext(NamespaceContext nsContext) { - // nothing to do here - } - - public void init() { - // Nothing to do here - } - - public boolean isDone() { - return done; - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLDocumentStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLDocumentStreamReader.java deleted file mode 100644 index 8ee9ea2242..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLDocumentStreamReader.java +++ /dev/null @@ -1,482 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.NoSuchElementException; - -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; - -/** - * This class is derived from Apache Axis2 class - * org.apache.axis2.util.StreamWrapper. It's used wrap a XMLStreamReader to - * create a XMLStreamReader representing a document and it will produce - * START_DOCUMENT, END_DOCUMENT events. - * - * @version $Rev$ $Date$ - */ -public class XMLDocumentStreamReader implements XMLStreamReader { - private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper - // will produce - // END_DOCUMENT - - private static final int STATE_COMPLETED = 3; // Done - - private static final int STATE_INIT = 0; // The wrapper will produce - // START_DOCUMENT - - private static final int STATE_SWITCHED = 1; // The real reader will - // produce events - - private XMLStreamReader realReader; - private boolean fragment; - private int level = 1; - - private int state = STATE_INIT; - - public XMLDocumentStreamReader(XMLStreamReader realReader) { - if (realReader == null) { - throw new UnsupportedOperationException("Reader cannot be null"); - } - - this.realReader = realReader; - - if (realReader instanceof XMLFragmentStreamReader) { - ((XMLFragmentStreamReader)realReader).init(); - } - - // If the real reader is positioned at START_DOCUMENT, always use - // the real reader - if (realReader.getEventType() == START_DOCUMENT) { - fragment = false; - state = STATE_SWITCHED; - } - } - - public void close() throws XMLStreamException { - realReader.close(); - } - - public int getAttributeCount() { - if (isDelegating()) { - return realReader.getAttributeCount(); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeLocalName(int i) { - if (isDelegating()) { - return realReader.getAttributeLocalName(i); - } else { - throw new IllegalStateException(); - } - } - - public QName getAttributeName(int i) { - if (isDelegating()) { - return realReader.getAttributeName(i); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeNamespace(int i) { - if (isDelegating()) { - return realReader.getAttributeNamespace(i); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributePrefix(int i) { - if (isDelegating()) { - return realReader.getAttributePrefix(i); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeType(int i) { - if (isDelegating()) { - return realReader.getAttributeType(i); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeValue(int i) { - if (isDelegating()) { - return realReader.getAttributeValue(i); - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeValue(String s, String s1) { - if (isDelegating()) { - return realReader.getAttributeValue(s, s1); - } else { - throw new IllegalStateException(); - } - } - - public String getCharacterEncodingScheme() { - return realReader.getCharacterEncodingScheme(); - } - - public String getElementText() throws XMLStreamException { - if (isDelegating()) { - return realReader.getElementText(); - } else { - throw new XMLStreamException(); - } - } - - public String getEncoding() { - return realReader.getEncoding(); - } - - public int getEventType() { - int event = -1; - switch (state) { - case STATE_SWITCHED: - case STATE_COMPLETE_AT_NEXT: - event = realReader.getEventType(); - break; - case STATE_INIT: - event = START_DOCUMENT; - break; - case STATE_COMPLETED: - event = END_DOCUMENT; - break; - } - return event; - } - - public String getLocalName() { - if (isDelegating()) { - return realReader.getLocalName(); - } else { - throw new IllegalStateException(); - } - } - - public Location getLocation() { - if (isDelegating()) { - return realReader.getLocation(); - } else { - return null; - } - } - - public QName getName() { - if (isDelegating()) { - return realReader.getName(); - } else { - throw new IllegalStateException(); - } - } - - public NamespaceContext getNamespaceContext() { - return realReader.getNamespaceContext(); - } - - public int getNamespaceCount() { - if (isDelegating()) { - return realReader.getNamespaceCount(); - } else { - throw new IllegalStateException(); - } - } - - public String getNamespacePrefix(int i) { - if (isDelegating()) { - return realReader.getNamespacePrefix(i); - } else { - throw new IllegalStateException(); - } - } - - public String getNamespaceURI() { - if (isDelegating()) { - return realReader.getNamespaceURI(); - } else { - throw new IllegalStateException(); - } - } - - public String getNamespaceURI(int i) { - if (isDelegating()) { - return realReader.getNamespaceURI(i); - } else { - throw new IllegalStateException(); - } - } - - public String getNamespaceURI(String s) { - if (isDelegating()) { - return realReader.getNamespaceURI(s); - } else { - throw new IllegalStateException(); - } - } - - public String getPIData() { - if (isDelegating()) { - return realReader.getPIData(); - } else { - throw new IllegalStateException(); - } - } - - public String getPITarget() { - if (isDelegating()) { - return realReader.getPITarget(); - } else { - throw new IllegalStateException(); - } - } - - public String getPrefix() { - if (isDelegating()) { - return realReader.getPrefix(); - } else { - throw new IllegalStateException(); - } - } - - public Object getProperty(String s) throws IllegalArgumentException { - if (isDelegating()) { - return realReader.getProperty(s); - } else { - throw new IllegalArgumentException(); - } - } - - public String getText() { - if (isDelegating()) { - return realReader.getText(); - } else { - throw new IllegalStateException(); - } - } - - public char[] getTextCharacters() { - if (isDelegating()) { - return realReader.getTextCharacters(); - } else { - throw new IllegalStateException(); - } - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - if (isDelegating()) { - return realReader.getTextCharacters(i, chars, i1, i2); - } else { - throw new IllegalStateException(); - } - } - - public int getTextLength() { - if (isDelegating()) { - return realReader.getTextLength(); - } else { - throw new IllegalStateException(); - } - } - - public int getTextStart() { - if (isDelegating()) { - return realReader.getTextStart(); - } else { - throw new IllegalStateException(); - } - } - - public String getVersion() { - if (isDelegating()) { - return realReader.getVersion(); - } else { - return null; - } - } - - public boolean hasName() { - if (isDelegating()) { - return realReader.hasName(); - } else { - return false; - } - } - - public boolean hasNext() throws XMLStreamException { - if (state == STATE_COMPLETE_AT_NEXT) { - return true; - } else if (state == STATE_COMPLETED) { - return false; - } else if (state == STATE_SWITCHED) { - return realReader.hasNext(); - } else { - return true; - } - } - - public boolean hasText() { - if (isDelegating()) { - return realReader.hasText(); - } else { - return false; - } - } - - public boolean isAttributeSpecified(int i) { - if (isDelegating()) { - return realReader.isAttributeSpecified(i); - } else { - return false; - } - } - - public boolean isCharacters() { - if (isDelegating()) { - return realReader.isCharacters(); - } else { - return false; - } - } - - private boolean isDelegating() { - return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT; - } - - public boolean isEndElement() { - if (isDelegating()) { - return realReader.isEndElement(); - } else { - return false; - } - } - - public boolean isStandalone() { - if (isDelegating()) { - return realReader.isStandalone(); - } else { - return false; - } - } - - public boolean isStartElement() { - if (isDelegating()) { - return realReader.isStartElement(); - } else { - return false; - } - } - - public boolean isWhiteSpace() { - if (isDelegating()) { - return realReader.isWhiteSpace(); - } else { - return false; - } - } - - public int next() throws XMLStreamException { - int returnEvent; - - switch (state) { - case STATE_SWITCHED: - returnEvent = realReader.next(); - if (returnEvent == END_DOCUMENT) { - state = STATE_COMPLETED; - } else if (!realReader.hasNext()) { - state = STATE_COMPLETE_AT_NEXT; - } - if (fragment && returnEvent == END_ELEMENT) { - level--; - if (level == 0) { - // We are now at the end of the top-level element in the fragment - state = STATE_COMPLETE_AT_NEXT; - } - } - if (fragment && returnEvent == START_ELEMENT) { - level++; - } - break; - case STATE_INIT: - state = STATE_SWITCHED; - returnEvent = realReader.getEventType(); - if (returnEvent == START_ELEMENT) { - // The real reader is positioned at the top-level element in the fragment - level = 0; - fragment = true; - } - break; - case STATE_COMPLETE_AT_NEXT: - state = STATE_COMPLETED; - returnEvent = END_DOCUMENT; - break; - case STATE_COMPLETED: - // oops - no way we can go beyond this - throw new NoSuchElementException("End of stream has reached."); - default: - throw new UnsupportedOperationException(); - } - - return returnEvent; - } - - public int nextTag() throws XMLStreamException { - if (isDelegating()) { - int returnEvent = realReader.nextTag(); - if (fragment && returnEvent == END_ELEMENT) { - level--; - if (level == 0) { - // We are now at the end of the top-level element in the fragment - state = STATE_COMPLETE_AT_NEXT; - } - } - if (fragment && returnEvent == START_ELEMENT) { - level++; - } - return returnEvent; - } else { - throw new XMLStreamException(); - } - } - - public void require(int i, String s, String s1) throws XMLStreamException { - if (isDelegating()) { - realReader.require(i, s, s1); - } - } - - public boolean standaloneSet() { - if (isDelegating()) { - return realReader.standaloneSet(); - } else { - return false; - } - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReader.java deleted file mode 100644 index defe3595be..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReader.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.namespace.QName; -import javax.xml.stream.XMLStreamReader; - -public interface XMLFragmentStreamReader extends XMLStreamReader { - QName NIL_QNAME = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi"); - String NIL_VALUE_TRUE = "true"; - - /** - * this will help to handle Text within the current element. user should - * pass the element text to the property list as this ELEMENT_TEXT as the - * key. This key deliberately has a space in it so that it is not a valid - * XML name - */ - String ELEMENT_TEXT = "Element Text"; - - /** - * Extra method to query the state of the pullparser - */ - boolean isDone(); - - /** - * add the parent namespace context to this parser - */ - void setParentNamespaceContext(NamespaceContext nsContext); - - /** - * Initiate the parser - this will do whatever the needed tasks to initiate - * the parser and must be called before attempting any specific parsing - * using this parser - */ - void init(); -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReaderImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReaderImpl.java deleted file mode 100644 index 2e42ac868f..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLFragmentStreamReaderImpl.java +++ /dev/null @@ -1,858 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -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; - - -/** - * This is the new implementation of the XMLFramentStreamReader. The approach - * here is simple When the pull parser needs to generate events for a particular - * name-value(s) pair it always hands over (delegates) the task to another pull - * parser which knows how to deal with it The common types of name value pairs - * we'll come across are - *

        - *
      • String name/QName name - String value - *
      • String name/QName name - String[] value - *
      • QName name/String name - XMLStreamReader value - *
      • QName name/String name - XMLStreamable value - *
      • QName name/String name - Java bean - *
      • QName name/String name - Datahandler - * - *
      - *

      As for the attributes, these are the possible combinations in the array - *

        - *
      • String name/QName name - String value - *
      - * Note that certain array methods have been deliberately removed to avoid - * complications. The generated code will take the trouble to lay the elements - * of the array in the correct order

      Hence there will be a parser impl - * that knows how to handle these types, and this parent parser will always - * delegate these tasks to the child pullparasers in effect this is one huge - * state machine that has only a few states and delegates things down to the - * child parsers whenever possible

      - * - * @version $Rev$ $Date$ - */ -public class XMLFragmentStreamReaderImpl implements XMLFragmentStreamReader { - - private static final int DELEGATED_STATE = 2; - private static final int END_ELEMENT_STATE = 1; - // states for this pullparser - it can only have four states - private static final int START_ELEMENT_STATE = 0; - private static final int TEXT_STATE = 3; - - protected NamedProperty[] attributes; - - // reference to the child reader - protected XMLFragmentStreamReader childReader; - // current property index - // initialized at zero - protected int index; - protected Map declaredNamespaceMap = new HashMap(); - protected QName elementQName; - - // we always create a new namespace context - protected DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); - - protected NamedProperty[] elements; - - // integer field that keeps the state of this - // parser. - protected int state = START_ELEMENT_STATE; - - /* - * we need to pass in a namespace context since when delegated, we've no - * idea of the current namespace context. So it needs to be passed on here! - */ - public XMLFragmentStreamReaderImpl(QName elementQName, NamedProperty[] elements, NamedProperty[] attributes) { - // validate the lengths, since both the arrays are supposed - // to have - this.elements = elements == null ? new NamedProperty[0] : elements; - this.elementQName = elementQName; - this.attributes = attributes == null ? new NamedProperty[0] : attributes; - } - - protected XMLFragmentStreamReaderImpl(QName elementQName) { - this.elementQName = elementQName; - } - - /** - * add the namespace context - */ - - public void setParentNamespaceContext(NamespaceContext nsContext) { - // register the namespace context passed in to this - this.namespaceContext.setParentNsContext(nsContext); - - } - - protected NamedProperty[] getElements() { - return elements; - } - - protected NamedProperty[] getAttributes() { - return attributes; - } - - protected QName[] getNamespaces() { - return new QName[0]; - } - - /** - * @param prefix - * @param uri - */ - protected void addToNsMap(String prefix, String uri) { - if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { - namespaceContext.pushNamespace(prefix, uri); - declaredNamespaceMap.put(prefix, uri); - } - } - - public void close() throws XMLStreamException { - // do nothing here - we have no resources to free - } - - public int getAttributeCount() { - return (state == DELEGATED_STATE) ? childReader.getAttributeCount() : (state == START_ELEMENT_STATE - ? getAttributes().length : 0); - } - - public String getAttributeLocalName(int i) { - if (state == DELEGATED_STATE) { - return childReader.getAttributeLocalName(i); - } else if (state == START_ELEMENT_STATE) { - QName name = getAttributeName(i); - if (name == null) { - return null; - } else { - return name.getLocalPart(); - } - } else { - throw new IllegalStateException(); - } - } - - /** - * @param i - */ - public QName getAttributeName(int i) { - if (state == DELEGATED_STATE) { - return childReader.getAttributeName(i); - } else if (state == START_ELEMENT_STATE) { - if ((i >= (getAttributes().length)) || i < 0) { // out of range - return null; - } else { - // get the attribute pointer - QName attribPointer = getAttributes()[i].getKey(); - // case one - attrib name is null - // this should be the pointer to the OMAttribute then - if (attribPointer == null) { - throw new UnsupportedOperationException(); - } else if (attribPointer instanceof QName) { - return attribPointer; - } else { - return null; - } - } - } else { - throw new IllegalStateException(); // as per the API contract - } - - } - - public String getAttributeNamespace(int i) { - if (state == DELEGATED_STATE) { - return childReader.getAttributeNamespace(i); - } else if (state == START_ELEMENT_STATE) { - QName name = getAttributeName(i); - if (name == null) { - return null; - } else { - return name.getNamespaceURI(); - } - } else { - throw new IllegalStateException(); - } - } - - public String getAttributePrefix(int i) { - if (state == DELEGATED_STATE) { - return childReader.getAttributePrefix(i); - } else if (state == START_ELEMENT_STATE) { - QName name = getAttributeName(i); - if (name == null) { - return null; - } else { - return name.getPrefix(); - } - } else { - throw new IllegalStateException(); - } - } - - public String getAttributeType(int i) { - return null; // not supported - } - - public String getAttributeValue(int i) { - if (state == DELEGATED_STATE) { - return childReader.getAttributeValue(i); - } else if (state == START_ELEMENT_STATE) { - if ((i >= (getAttributes().length)) || i < 0) { // out of range - return null; - } else { - // get the attribute pointer - QName attribPointer = getAttributes()[i].getKey(); - Object omAttribObj = getAttributes()[i].getValue(); - // case one - attrib name is null - // this should be the pointer to the OMAttribute then - if (attribPointer == null) { - throw new UnsupportedOperationException(); - } else if (attribPointer instanceof QName) { - return (String)omAttribObj; - } else { - return null; - } - } - } else { - throw new IllegalStateException(); - } - - } - - public String getAttributeValue(String nsUri, String localName) { - - int attribCount = getAttributeCount(); - String returnValue = null; - QName attribQualifiedName; - for (int i = 0; i < attribCount; i++) { - attribQualifiedName = getAttributeName(i); - if (nsUri == null) { - if (localName.equals(attribQualifiedName.getLocalPart())) { - returnValue = getAttributeValue(i); - break; - } - } else { - if (localName.equals(attribQualifiedName.getLocalPart()) && nsUri.equals(attribQualifiedName - .getNamespaceURI())) { - returnValue = getAttributeValue(i); - break; - } - } - - } - - return returnValue; - } - - public String getCharacterEncodingScheme() { - return null; // TODO - should we return something for this ? - } - - /** - * TODO implement the right contract for this - * - * @throws XMLStreamException - */ - public String getElementText() throws XMLStreamException { - if (state == DELEGATED_STATE) { - return childReader.getElementText(); - } else { - return null; - } - - } - - // ///////////////////////////////////////////////////////////////////////// - // / attribute handling - // ///////////////////////////////////////////////////////////////////////// - - public String getEncoding() { - if (state == DELEGATED_STATE) { - return childReader.getEncoding(); - } else { - // we've no idea what the encoding is going to be in this case - // perhaps we ought to return some constant here, which the user - // might - // have access to change! - return null; - } - } - - public int getEventType() { - if (state == START_ELEMENT_STATE) { - return START_ELEMENT; - } else if (state == END_ELEMENT_STATE) { - return END_ELEMENT; - } else if (state == TEXT_STATE) { - return CHARACTERS; - } else { // this is the delegated state - return childReader.getEventType(); - } - } - - public String getLocalName() { - if (state == DELEGATED_STATE) { - return childReader.getLocalName(); - } else if (state != TEXT_STATE) { - return elementQName.getLocalPart(); - } else { - throw new IllegalStateException(); - } - } - - /** - */ - public Location getLocation() { - // return a default location - return new Location() { - public int getCharacterOffset() { - return 0; - } - - public int getColumnNumber() { - return 0; - } - - public int getLineNumber() { - return 0; - } - - public String getPublicId() { - return null; - } - - public String getSystemId() { - return null; - } - }; - } - - public QName getName() { - if (state == DELEGATED_STATE) { - return childReader.getName(); - } else if (state != TEXT_STATE) { - return elementQName; - } else { - throw new IllegalStateException(); - } - - } - - public NamespaceContext getNamespaceContext() { - if (state == DELEGATED_STATE) { - return childReader.getNamespaceContext(); - } else { - return namespaceContext; - } - - } - - public int getNamespaceCount() { - if (state == DELEGATED_STATE) { - return childReader.getNamespaceCount(); - } else { - return declaredNamespaceMap.size(); - } - } - - /** - * @param i - */ - public String getNamespacePrefix(int i) { - if (state == DELEGATED_STATE) { - return childReader.getNamespacePrefix(i); - } else if (state != TEXT_STATE) { - // order the prefixes - String[] prefixes = makePrefixArray(); - if ((i >= prefixes.length) || (i < 0)) { - return null; - } else { - return prefixes[i]; - } - - } else { - throw new IllegalStateException(); - } - - } - - public String getNamespaceURI() { - if (state == DELEGATED_STATE) { - return childReader.getNamespaceURI(); - } else if (state == TEXT_STATE) { - return null; - } else { - return elementQName.getNamespaceURI(); - } - } - - // ///////////////////////////////////////////////////////////////////////// - // //////////// end of attribute handling - // ///////////////////////////////////////////////////////////////////////// - - // ////////////////////////////////////////////////////////////////////////// - // //////////// namespace handling - // ////////////////////////////////////////////////////////////////////////// - - public String getNamespaceURI(int i) { - if (state == DELEGATED_STATE) { - return childReader.getNamespaceURI(i); - } else if (state != TEXT_STATE) { - String namespacePrefix = getNamespacePrefix(i); - return namespacePrefix == null ? null : (String)declaredNamespaceMap.get(namespacePrefix); - } else { - throw new IllegalStateException(); - } - - } - - public String getNamespaceURI(String prefix) { - return namespaceContext.getNamespaceURI(prefix); - } - - public String getPIData() { - throw new UnsupportedOperationException("Yet to be implemented !!"); - } - - public String getPITarget() { - throw new UnsupportedOperationException("Yet to be implemented !!"); - } - - public String getPrefix() { - if (state == DELEGATED_STATE) { - return childReader.getPrefix(); - } else if (state == TEXT_STATE) { - return null; - } else { - String prefix = elementQName.getPrefix(); - return "".equals(prefix) ? null : prefix; - } - } - - // ///////////////////////////////////////////////////////////////////////// - // /////// end of namespace handling - // ///////////////////////////////////////////////////////////////////////// - - /** - * @param key - * @throws IllegalArgumentException - */ - public Object getProperty(String key) throws IllegalArgumentException { - if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { - return null; - } else if (state == TEXT_STATE) { - return null; - } else if (state == DELEGATED_STATE) { - return childReader.getProperty(key); - } else { - return null; - } - - } - - public String getText() { - if (state == DELEGATED_STATE) { - return childReader.getText(); - } else if (state == TEXT_STATE) { - return (String)getElements()[index - 1].getValue(); - } else { - throw new IllegalStateException(); - } - } - - public char[] getTextCharacters() { - if (state == DELEGATED_STATE) { - return childReader.getTextCharacters(); - } else if (state == TEXT_STATE) { - return getElements()[index - 1].getValue() == null ? new char[0] : ((String)getElements()[index - 1] - .getValue()).toCharArray(); - } else { - throw new IllegalStateException(); - } - } - - private int copy(int sourceStart, char[] target, int targetStart, int length) { - char[] source = getTextCharacters(); - if (sourceStart > source.length) { - throw new IndexOutOfBoundsException("source start > source length"); - } - int sourceLen = source.length - sourceStart; - if (length > sourceLen) { - length = sourceLen; - } - System.arraycopy(source, sourceStart, target, targetStart, length); - return sourceLen; - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - if (state == DELEGATED_STATE) { - return childReader.getTextCharacters(i, chars, i1, i2); - } else if (state == TEXT_STATE) { - return copy(i, chars, i1, i2); - } else { - throw new IllegalStateException(); - } - } - - public int getTextLength() { - if (state == DELEGATED_STATE) { - return childReader.getTextLength(); - } else if (state == TEXT_STATE) { - return getTextCharacters().length; - } else { - throw new IllegalStateException(); - } - } - - public int getTextStart() { - if (state == DELEGATED_STATE) { - return childReader.getTextStart(); - } else if (state == TEXT_STATE) { - return 0; // assume text always starts at 0 - } else { - throw new IllegalStateException(); - } - } - - public String getVersion() { - return null; - } - - public boolean hasName() { - // since this parser always has a name, the hasName - // has to return true if we are still navigating this element - // if not we should ask the child reader for it. - if (state == DELEGATED_STATE) { - return childReader.hasName(); - } else { - return state != TEXT_STATE; - } - } - - /** - * @throws XMLStreamException - */ - public boolean hasNext() throws XMLStreamException { - if (state == DELEGATED_STATE) { - if (childReader.isDone()) { - // the child reader is done. We shouldn't be getting the - // hasNext result from the child pullparser then - return true; - } else { - return childReader.hasNext(); - } - } else { - return state == START_ELEMENT_STATE || state == TEXT_STATE; - - } - } - - /** - * check the validity of this implementation - */ - public boolean hasText() { - if (state == DELEGATED_STATE) { - return childReader.hasText(); - } else { - return state == TEXT_STATE; - } - - } - - /** - * we need to split out the calling to the populate namespaces separately - * since this needs to be done *after* setting the parent namespace context. - * We cannot assume it will happen at construction! - */ - public void init() { - // here we have an extra issue to attend to. we need to look at the - // prefixes and URIs (the combination) and populate a HashMap of - // namespaces. The HashMap of namespaces will be used to serve the - // namespace context - - populateNamespaceContext(); - } - - public boolean isAttributeSpecified(int i) { - return false; // not supported - } - - public boolean isCharacters() { - if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { - return false; - } - return childReader.isCharacters(); - } - - /** - * are we done ? - */ - public boolean isDone() { - return state == END_ELEMENT_STATE; - } - - public boolean isEndElement() { - if (state == START_ELEMENT_STATE) { - return false; - } else if (state == END_ELEMENT_STATE) { - return true; - } - return childReader.isEndElement(); - } - - public boolean isStandalone() { - return true; - } - - public boolean isStartElement() { - if (state == START_ELEMENT_STATE) { - return true; - } else if (state == END_ELEMENT_STATE) { - return false; - } - return childReader.isStartElement(); - } - - public boolean isWhiteSpace() { - if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { - return false; - } - return childReader.isWhiteSpace(); - } - - /** - * Get the prefix list from the HashTable and take that into an array - */ - private String[] makePrefixArray() { - String[] prefixes = declaredNamespaceMap.keySet().toArray(new String[declaredNamespaceMap.size()]); - Arrays.sort(prefixes); - return prefixes; - } - - /** - * By far this should be the most important method in this class this method - * changes the state of the parser - */ - public int next() throws XMLStreamException { - int returnEvent = -1; // invalid state is the default state - switch (state) { - case START_ELEMENT_STATE: - // current element is start element. We should be looking at the - // property list and making a pullparser for the property value - if (getElements() == null || getElements().length == 0) { - // no properties - move to the end element state - // straight away - state = END_ELEMENT_STATE; - returnEvent = END_ELEMENT; - } else { - // there are properties. now we should delegate this task to - // a - // child reader depending on the property type - returnEvent = processProperties(); - - } - break; - case END_ELEMENT_STATE: - // we've reached the end element already. If the user tries to - // push - // further ahead then it is an exception - throw new XMLStreamException("Trying to go beyond the end of the pullparser"); - - case DELEGATED_STATE: - if (childReader.isDone()) { - // we've reached the end! - if (index > (getElements().length - 1)) { - state = END_ELEMENT_STATE; - returnEvent = END_ELEMENT; - } else { - returnEvent = processProperties(); - } - } else { - returnEvent = childReader.next(); - } - break; - - case TEXT_STATE: - // if there are any more event we should be delegating to - // processProperties. if not we just return an end element - if (index > (getElements().length - 1)) { - state = END_ELEMENT_STATE; - returnEvent = END_ELEMENT; - } else { - returnEvent = processProperties(); - } - break; - } - return returnEvent; - } - - // ///////////////////////////////////////////////////////////////////////// - // / Other utility methods - // //////////////////////////////////////////////////////////////////////// - - /** - * TODO implement this - * - * @throws XMLStreamException - */ - public int nextTag() throws XMLStreamException { - return 0; - } - - /** - * Populates a namespace context - */ - private void populateNamespaceContext() { - - // first add the current element namespace to the namespace context - // declare it if not found - addToNsMap(elementQName.getPrefix(), elementQName.getNamespaceURI()); - - for (QName n : getNamespaces()) { - addToNsMap(n.getPrefix(), n.getNamespaceURI()); - } - - // traverse through the attributes and populate the namespace context - // the attrib list can be of many combinations - // the valid combinations are - // String - String - // QName - QName - // null - OMAttribute - - for (int i = 0; i < getAttributes().length; i++) { // jump in two - QName attrQName = getAttributes()[i].getKey(); - if (!"".equals(attrQName.getNamespaceURI())) { - addToNsMap(attrQName.getPrefix(), attrQName.getNamespaceURI()); - } - } - } - - /** - * A convenient method to reuse the properties - * - * @return event to be thrown - * @throws XMLStreamException - */ - private int processProperties() throws XMLStreamException { - // move to the next property depending on the current property - // index - QName propertyQName = getElements()[index].getKey(); - boolean textFound = false; - if (propertyQName == null) { - throw new XMLStreamException("property key cannot be null!"); - } else if (ELEMENT_TEXT.equals(propertyQName.getLocalPart())) { - // propPointer being a String has a special case - // that is it can be a the special constant ELEMENT_TEXT that - // says this text event - textFound = true; - } - - // OK! we got the key. Now look at the value - Object propertyValue = getElements()[index].getValue(); - // cater for the special case now - if (textFound) { - // no delegation here - make the parser null and immediately - // return with the event characters - childReader = null; - state = TEXT_STATE; - ++index; - return CHARACTERS; - } else if (propertyValue == null) { - // if the value is null we delegate the work to a nullable - // parser - childReader = new NilElementStreamReader(propertyQName); - childReader.setParentNamespaceContext(this.namespaceContext); - childReader.init(); - } else if (propertyValue instanceof String) { - // strings are handled by the NameValuePairStreamReader - childReader = new NameValuePairStreamReader(propertyQName, (String)propertyValue); - childReader.setParentNamespaceContext(this.namespaceContext); - childReader.init(); - } else if (propertyValue instanceof String[]) { - // string[] are handled by the NameValueArrayStreamReader - // if the array is empty - skip it - if (((String[])propertyValue).length == 0) { - // advance the index - ++index; - return processProperties(); - } else { - childReader = new NameValueArrayStreamReader(propertyQName, (String[])propertyValue); - childReader.setParentNamespaceContext(this.namespaceContext); - childReader.init(); - } - - } else if (propertyValue instanceof XMLStreamable) { - // ADBbean has it's own method to get a reader - XMLStreamReader reader = ((XMLStreamable)propertyValue).getXMLStreamReader(propertyQName); - // we know for sure that this is an ADB XMLStreamreader. - // However we need to make sure that it is compatible - if (reader instanceof XMLFragmentStreamReader) { - childReader = (XMLFragmentStreamReader)reader; - childReader.setParentNamespaceContext(this.namespaceContext); - childReader.init(); - } else { - // wrap it to make compatible - childReader = new WrappingXMLStreamReader(reader); - } - } else if (propertyValue instanceof XMLStreamReader) { - XMLStreamReader reader = (XMLStreamReader)propertyValue; - if (reader instanceof XMLFragmentStreamReader) { - childReader = (XMLFragmentStreamReader)reader; - childReader.setParentNamespaceContext(this.namespaceContext); - childReader.init(); - } else { - // wrap it to make compatible - childReader = new WrappingXMLStreamReader(reader); - } - - } else { - // all special possibilities has been tried! Let's treat - // the thing as a bean and try generating events from it - throw new UnsupportedOperationException("Property type is not supported"); - // we cannot register the namespace context here - } - - // set the state here - state = DELEGATED_STATE; - // we are done with the delegation - // increment the property index - ++index; - return childReader.getEventType(); - } - - public void require(int i, String string, String string1) throws XMLStreamException { - throw new UnsupportedOperationException(); - } - - public boolean standaloneSet() { - return true; - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamSerializer.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamSerializer.java deleted file mode 100644 index 2a86611fcb..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamSerializer.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.NamespaceContext; -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.stream.XMLStreamWriter; - -/** - * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps into the XMLStreamWriter - * - * @version $Rev$ $Date$ - */ -public class XMLStreamSerializer implements XMLStreamConstants { - public static final String NAMESPACE_PREFIX = "ns"; - private static int namespaceSuffix; - - /* - * The behavior of the Serializer is such that it returns when it encounters the starting element for the second - * time. The depth variable tracks the depth of the Serializer and tells it when to return. Note that it is assumed - * that this Serialization starts on an Element. - */ - - /** - * Field depth - */ - private int depth; - - /** - * Generates a unique namespace prefix that is not in the scope of the NamespaceContext - * - * @param nsCtxt - * @return string - */ - private String generateUniquePrefix(NamespaceContext nsCtxt) { - String prefix = NAMESPACE_PREFIX + namespaceSuffix++; - // null should be returned if the prefix is not bound! - while (nsCtxt.getNamespaceURI(prefix) != null) { - prefix = NAMESPACE_PREFIX + namespaceSuffix++; - } - - return prefix; - } - - /** - * Method serialize. - * - * @param node - * @param writer - * @throws XMLStreamException - */ - public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws XMLStreamException { - serializeNode(node, writer); - } - - /** - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - int count = reader.getAttributeCount(); - String prefix; - String namespaceName; - String writerPrefix; - for (int i = 0; i < count; i++) { - prefix = reader.getAttributePrefix(i); - namespaceName = reader.getAttributeNamespace(i); - /* - * Due to parser implementations returning null as the namespace URI (for the empty namespace) we need to - * make sure that we deal with a namespace name that is not null. The best way to work around this issue is - * to set the namespace URI to "" if it is null - */ - if (namespaceName == null) { - namespaceName = ""; - } - - writerPrefix = writer.getPrefix(namespaceName); - - if (!"".equals(namespaceName)) { - // prefix has already being declared but this particular - // attrib has a - // no prefix attached. So use the prefix provided by the - // writer - if (writerPrefix != null && (prefix == null || prefix.equals(""))) { - writer.writeAttribute(writerPrefix, namespaceName, reader.getAttributeLocalName(i), reader - .getAttributeValue(i)); - - // writer prefix is available but different from the - // current - // prefix of the attrib. We should be declaring the new - // prefix - // as a namespace declaration - } else if (prefix != null && !"".equals(prefix) && !prefix.equals(writerPrefix)) { - writer.writeNamespace(prefix, namespaceName); - writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader - .getAttributeValue(i)); - - // prefix is null (or empty), but the namespace name is - // valid! it has not - // being written previously also. So we need to generate - // a prefix - // here - } else if (prefix == null || prefix.equals("")) { - prefix = generateUniquePrefix(writer.getNamespaceContext()); - writer.writeNamespace(prefix, namespaceName); - writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader - .getAttributeValue(i)); - } else { - writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader - .getAttributeValue(i)); - } - } else { - // empty namespace is equal to no namespace! - writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i)); - } - - } - } - - /** - * Method serializeCData. - * - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeCData(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - writer.writeCData(reader.getText()); - } - - /** - * Method serializeComment. - * - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeComment(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - writer.writeComment(reader.getText()); - } - - /** - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - String prefix = reader.getPrefix(); - String nameSpaceName = reader.getNamespaceURI(); - if (nameSpaceName != null) { - String writerPrefix = writer.getPrefix(nameSpaceName); - if (writerPrefix != null) { - writer.writeStartElement(nameSpaceName, reader.getLocalName()); - } else { - if (prefix != null) { - writer.writeStartElement(prefix, reader.getLocalName(), nameSpaceName); - writer.writeNamespace(prefix, nameSpaceName); - // writer.setPrefix(prefix, nameSpaceName); - } else { - // [rfeng] We need to set default NS 1st before calling writeStateElement - writer.setDefaultNamespace(nameSpaceName); - writer.writeStartElement(nameSpaceName, reader.getLocalName()); - writer.writeDefaultNamespace(nameSpaceName); - } - } - } else { - writer.writeStartElement(reader.getLocalName()); - } - - // add the namespaces - int count = reader.getNamespaceCount(); - String namespacePrefix; - for (int i = 0; i < count; i++) { - namespacePrefix = reader.getNamespacePrefix(i); - // [rfeng] The following is commented out to allow to default ns - // if (namespacePrefix != null && namespacePrefix.length() == 0) { - // continue; - // } - - serializeNamespace(namespacePrefix, reader.getNamespaceURI(i), writer); - } - - // add attributes - serializeAttributes(reader, writer); - - } - - /** - * Method serializeEndElement. - * - * @param writer - * @throws XMLStreamException - */ - protected void serializeEndElement(XMLStreamWriter writer) throws XMLStreamException { - writer.writeEndElement(); - } - - /** - * Method serializeNamespace. - * - * @param prefix - * @param uri - * @param writer - * @throws XMLStreamException - */ - private void serializeNamespace(String prefix, String uri, XMLStreamWriter writer) throws XMLStreamException { - String prefix1 = writer.getPrefix(uri); - if (prefix1 == null) { - writer.writeNamespace(prefix, uri); - // writer.setPrefix(prefix, uri); - } - } - - /** - * Method serializeNode. - * - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - while (true) { - int event = reader.getEventType(); - if (event == START_ELEMENT) { - serializeElement(reader, writer); - depth++; - } else if (event == ATTRIBUTE) { - serializeAttributes(reader, writer); - } else if (event == CHARACTERS) { - serializeText(reader, writer); - } else if (event == COMMENT) { - serializeComment(reader, writer); - } else if (event == CDATA) { - serializeCData(reader, writer); - } else if (event == END_ELEMENT) { - serializeEndElement(writer); - depth--; - } else if (event == START_DOCUMENT) { - depth++; // if a start document is found then increment - writer.writeStartDocument(); - // the depth - } else if (event == END_DOCUMENT) { - if (depth != 0) { - depth--; // for the end document - reduce the depth - } - writer.writeEndDocument(); - } - if (depth == 0) { - break; - } - if (reader.hasNext()) { - reader.next(); - } else { - break; - } - } - } - - /** - * @param reader - * @param writer - * @throws XMLStreamException - */ - protected void serializeText(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { - writer.writeCharacters(reader.getText()); - } -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamable.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamable.java deleted file mode 100644 index b4b1a24f9d..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XMLStreamable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.common.xml.stax; - -import javax.xml.namespace.QName; -import javax.xml.stream.XMLStreamReader; - -/** - * An interface represents data that can be read using StAX streaming - * - * @version $Rev$ $Date$ - */ -public interface XMLStreamable { - /** - * Get the XMLStreamReader for StAX processing - * - * @param rootElementName the name of the element to be generated - * @return Returns a pull parser. - */ - XMLStreamReader getXMLStreamReader(QName rootElementName); -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNode.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNode.java deleted file mode 100644 index 75a820a620..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNode.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.QName; - -/** - * @version $Rev$ $Date$ - */ -public interface XmlNode { - enum Type {ELEMENT, ATTRIBUTE, CHARACTERS, READER}; - /** - * Returns the children of the receiver as an Iterator. - */ - Iterator children(); - - /** - * Returns the attributes of the element as an List. Namespace declarations - * should be excluded. - * - * @return - */ - List attributes(); - - /** - * Returns a map of prefix to namespace URI - * @return - */ - Map namespaces(); - - /** - * Return the QName of the element. If it's for a text node, the name is null. - * @return - */ - QName getName(); - - /** - * Return the text value of the leaf element - * @return - */ - T getValue(); - - /** - * Return the type of the XML node - * @return - */ - Type getType(); -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNodeIterator.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNodeIterator.java deleted file mode 100644 index 080f9c21e0..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlNodeIterator.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.ArrayList; -import java.util.EmptyStackException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.namespace.NamespaceContext; - -/** - * @version $Rev$ $Date$ - */ -public class XmlNodeIterator implements Iterator { - public static final int START = 0; - public static final int END = 1; - - protected FastStack stack; - protected int state; - protected NamespaceContextImpl nsContext; - - public XmlNodeIterator(XmlNode rootNode) { - super(); - List v = new ArrayList(1); - v.add(rootNode); - stack = new FastStack(); - Iterator i = v.iterator(); - stack.push(new ElementHolder(null, i)); - this.state = START; - this.nsContext = new NamespaceContextImpl(null); - } - - public boolean hasNext() { - return !(stack.empty() || (state == END && stack.peek().parent == null)); - } - - public XmlNode next() { - this.state = START; - ElementHolder element = stack.peek(); - Iterator it = element.children; - if (it == null || (!it.hasNext())) { - // End of the children, return END event of parent - stack.pop(); - this.state = END; - this.nsContext = (NamespaceContextImpl)nsContext.getParent(); - return element.parent; - } - XmlNode node = it.next(); - stack.push(new ElementHolder(node, node.children())); - this.nsContext = new NamespaceContextImpl(this.nsContext); - populateNamespaces(node); - return node; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public int getState() { - return state; - } - - public NamespaceContext getNamespaceContext() { - return nsContext; - } - - private void populateNamespaces(XmlNode element) { - if (element.getName() != null) { - if (element.namespaces() != null) { - for (Map.Entry e : element.namespaces().entrySet()) { - nsContext.register(e.getKey(), e.getValue()); - } - } - } - } - - private static class ElementHolder { - private XmlNode parent; - private Iterator children; - - public ElementHolder(XmlNode parent, Iterator children) { - this.parent = parent; - this.children = children; - } - } - - private static class NamespaceContextImpl implements NamespaceContext { - private NamespaceContext parent; - private Map map = new HashMap(); - - /** - * @param parent - */ - public NamespaceContextImpl(NamespaceContext parent) { - super(); - this.parent = parent; - if (parent == null) { - map.put("xml", "http://www.w3.org/XML/1998/namespace"); - map.put("xmlns", "http://www.w3.org/2000/xmlns/"); - } - } - - public String getNamespaceURI(String prefix) { - if (prefix == null) { - throw new IllegalArgumentException("Prefix is null"); - } - - String ns = (String)map.get(prefix); - if (ns != null) { - return ns; - } - if (parent != null) { - return parent.getNamespaceURI(prefix); - } - return null; - } - - public String getPrefix(String nsURI) { - if (nsURI == null) - throw new IllegalArgumentException("Namespace is null"); - for (Iterator> i = map.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = i.next(); - if (entry.getValue().equals(nsURI)) { - return entry.getKey(); - } - } - if (parent != null) { - return parent.getPrefix(nsURI); - } - return null; - } - - public Iterator getPrefixes(String nsURI) { - List prefixList = new ArrayList(); - for (Iterator> i = map.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = i.next(); - if (entry.getValue().equals(nsURI)) { - prefixList.add(entry.getKey()); - } - } - final Iterator currentIterator = prefixList.iterator(); - final Iterator parentIterator = parent != null ? null : parent.getPrefixes(nsURI); - return new Iterator() { - - public boolean hasNext() { - return currentIterator.hasNext() || (parentIterator != null && parentIterator.hasNext()); - } - - public Object next() { - if (!hasNext()) { - throw new IllegalStateException("End of iterator has reached"); - } - return currentIterator.hasNext() ? currentIterator.next() : parentIterator.next(); - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - }; - - } - - public void register(String prefix, String ns) { - map.put(prefix, ns); - } - - public NamespaceContext getParent() { - return parent; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(map.toString()); - if (parent != null) { - sb.append("\nParent: "); - sb.append(parent); - } - return sb.toString(); - } - } - - /** - * An implementation of the {@link java.util.Stack} API that is based on an ArrayList instead of a - * Vector, so it is not synchronized to protect against multi-threaded access. The implementation is - * therefore operates faster in environments where you do not need to worry about multiple thread contention. - *

      - * The removal order of an ArrayStack is based on insertion order: The most recently added element is - * removed first. The iteration order is not the same as the removal order. The iterator returns elements - * from the bottom up, whereas the {@link #remove()} method removes them from the top down. - *

      - * Unlike Stack, ArrayStack accepts null entries. - */ - public static class FastStack extends ArrayList { - - /** Ensure Serialization compatibility */ - private static final long serialVersionUID = 2130079159931574599L; - - /** - * Constructs a new empty ArrayStack. The initial size is controlled by ArrayList - * and is currently 10. - */ - public FastStack() { - super(); - } - - /** - * Constructs a new empty ArrayStack with an initial size. - * - * @param initialSize the initial size to use - * @throws IllegalArgumentException if the specified initial size is negative - */ - public FastStack(int initialSize) { - super(initialSize); - } - - /** - * Return true if this stack is currently empty. - *

      - * This method exists for compatibility with java.util.Stack. New users of this class should use - * isEmpty instead. - * - * @return true if the stack is currently empty - */ - public boolean empty() { - return isEmpty(); - } - - /** - * Returns the top item off of this stack without removing it. - * - * @return the top item on the stack - * @throws EmptyStackException if the stack is empty - */ - public T peek() throws EmptyStackException { - int n = size(); - if (n <= 0) { - throw new EmptyStackException(); - } else { - return get(n - 1); - } - } - - /** - * Returns the n'th item down (zero-relative) from the top of this stack without removing it. - * - * @param n the number of items down to go - * @return the n'th item on the stack, zero relative - * @throws EmptyStackException if there are not enough items on the stack to satisfy this request - */ - public T peek(int n) throws EmptyStackException { - int m = (size() - n) - 1; - if (m < 0) { - throw new EmptyStackException(); - } else { - return get(m); - } - } - - /** - * Pops the top item off of this stack and return it. - * - * @return the top item on the stack - * @throws EmptyStackException if the stack is empty - */ - public T pop() throws EmptyStackException { - int n = size(); - if (n <= 0) { - throw new EmptyStackException(); - } else { - return remove(n - 1); - } - } - - /** - * Pushes a new item onto the top of this stack. The pushed item is also returned. This is equivalent to calling - * add. - * - * @param item the item to be added - * @return the item just pushed - */ - public Object push(T item) { - add(item); - return item; - } - - /** - * Returns the top-most index for the object in the stack - * - * @param object the object to be searched for - * @return top-most index, or -1 if not found - */ - public int search(T object) { - int i = size() - 1; // Current index - while (i >= 0) { - T current = get(i); - if ((object == null && current == null) || (object != null && object.equals(current))) { - return i; - } - i--; - } - return -1; - } - - /** - * Returns the element on the top of the stack. - * - * @return the element on the top of the stack - * @throws EmptyStackException if the stack is empty - */ - public T get() { - int size = size(); - if (size == 0) { - throw new EmptyStackException(); - } - return get(size - 1); - } - - /** - * Removes the element on the top of the stack. - * - * @return the removed element - * @throws EmptyStackException if the stack is empty - */ - public T remove() { - int size = size(); - if (size == 0) { - throw new EmptyStackException(); - } - return remove(size - 1); - } - - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderImpl.java deleted file mode 100644 index 93295b3d43..0000000000 --- a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderImpl.java +++ /dev/null @@ -1,531 +0,0 @@ -/* - * 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.common.xml.stax; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -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; - -/** - * - * @version $Rev$ $Date$ - */ -public class XmlTreeStreamReaderImpl implements XMLStreamReader { - - protected int state; - protected XmlNodeIterator iterator; - protected XmlNode current; - - protected XMLStreamReader reader; - - /* - * we need to pass in a namespace context since when delegated, we've no - * idea of the current namespace context. So it needs to be passed on here! - */ - public XmlTreeStreamReaderImpl(XmlNode root) { - this.iterator = new XmlNodeIterator(root); - this.current = null; - this.state = START_DOCUMENT; - this.reader = null; - } - - public void close() throws XMLStreamException { - if (reader != null) { - reader.close(); - } - } - - private void checkElementState() { - if (getEventType() != START_ELEMENT && getEventType() != END_ELEMENT) { - throw new IllegalStateException(); - } - } - - private List getAttributes() { - if (current != null && current.attributes() != null) { - return current.attributes(); - } else { - return Collections.emptyList(); - } - } - - public int getAttributeCount() { - checkElementState(); - if (reader != null) { - return reader.getAttributeCount(); - } - return getAttributes().size(); - } - - public String getAttributeLocalName(int i) { - checkElementState(); - if (reader != null) { - return reader.getAttributeLocalName(i); - } - return getAttributes().get(i).getName().getLocalPart(); - } - - /** - * @param i - */ - public QName getAttributeName(int i) { - checkElementState(); - if (reader != null) { - return reader.getAttributeName(i); - } - return getAttributes().get(i).getName(); - } - - public String getAttributeNamespace(int i) { - checkElementState(); - if (reader != null) { - return reader.getAttributeNamespace(i); - } - return getAttributes().get(i).getName().getNamespaceURI(); - } - - public String getAttributePrefix(int i) { - checkElementState(); - if (reader != null) { - return reader.getAttributePrefix(i); - } - return getAttributes().get(i).getName().getPrefix(); - } - - public String getAttributeType(int i) { - if (reader != null) { - return reader.getAttributeType(i); - } - return null; // not supported - } - - public String getAttributeValue(int i) { - checkElementState(); - if (reader != null) { - return reader.getAttributeValue(i); - } - return getAttributes().get(i).getValue(); - } - - public String getAttributeValue(String nsUri, String localName) { - checkElementState(); - if (reader != null) { - return reader.getAttributeValue(nsUri, localName); - } - int count = getAttributeCount(); - String value = null; - QName attrQName; - for (int i = 0; i < count; i++) { - attrQName = getAttributeName(i); - if (nsUri == null) { - if (localName.equals(attrQName.getLocalPart())) { - value = getAttributeValue(i); - break; - } - } else { - if (localName.equals(attrQName.getLocalPart()) && nsUri.equals(attrQName.getNamespaceURI())) { - value = getAttributeValue(i); - break; - } - } - - } - - return value; - } - - public String getCharacterEncodingScheme() { - if (reader != null) { - return reader.getCharacterEncodingScheme(); - } - return "UTF-8"; - } - - public String getElementText() throws XMLStreamException { - checkElementState(); - if (reader != null) { - return reader.getElementText(); - } - return current.getValue(); - } - - public String getEncoding() { - if (reader != null) { - return reader.getEncoding(); - } - return "UTF-8"; - } - - public int getEventType() { - return state; - } - - public String getLocalName() { - checkElementState(); - if (reader != null) { - return reader.getLocalName(); - } - return current.getName().getLocalPart(); - } - - /** - */ - public Location getLocation() { - if (reader != null) { - return reader.getLocation(); - } - // return a default location - return new Location() { - public int getCharacterOffset() { - return 0; - } - - public int getColumnNumber() { - return 0; - } - - public int getLineNumber() { - return 0; - } - - public String getPublicId() { - return null; - } - - public String getSystemId() { - return null; - } - }; - } - - public QName getName() { - checkElementState(); - if (reader != null) { - return reader.getName(); - } - return current.getName(); - } - - public NamespaceContext getNamespaceContext() { - if (reader != null) { - return reader.getNamespaceContext(); - } - return iterator.getNamespaceContext(); - } - - private Map getNamespaces() { - if (current != null && current.namespaces() != null) { - return current.namespaces(); - } else { - return Collections.emptyMap(); - } - } - - public int getNamespaceCount() { - checkElementState(); - if (reader != null) { - return reader.getNamespaceCount(); - } - return getNamespaces().size(); - } - - /** - * @param i - */ - public String getNamespacePrefix(int i) { - checkElementState(); - if (reader != null) { - return reader.getNamespacePrefix(i); - } - return new ArrayList>(getNamespaces().entrySet()).get(i).getKey(); - } - - public String getNamespaceURI() { - checkElementState(); - if (reader != null) { - return reader.getNamespaceURI(); - } - return current.getName().getNamespaceURI(); - } - - public String getNamespaceURI(int i) { - checkElementState(); - if (reader != null) { - return reader.getNamespaceURI(i); - } - return new ArrayList>(getNamespaces().entrySet()).get(i).getValue(); - } - - public String getNamespaceURI(String prefix) { - if (reader != null) { - return reader.getNamespaceURI(prefix); - } - return getNamespaceContext().getNamespaceURI(prefix); - } - - public String getPIData() { - if (reader != null) { - return reader.getPIData(); - } - throw new UnsupportedOperationException("Yet to be implemented !!"); - } - - public String getPITarget() { - if (reader != null) { - return reader.getPITarget(); - } - throw new UnsupportedOperationException("Yet to be implemented !!"); - } - - public String getPrefix() { - if (reader != null) { - return reader.getPrefix(); - } - if (state == START_ELEMENT || state == END_ELEMENT) { - String prefix = current.getName().getPrefix(); - return "".equals(prefix) ? null : prefix; - } else if (state == START_DOCUMENT) { - return null; - } else { - throw new IllegalStateException("State==" + state); - } - } - - /** - * @param key - * @throws IllegalArgumentException - */ - public Object getProperty(String key) throws IllegalArgumentException { - if (reader != null) { - return reader.getProperty(key); - } - return null; - } - - public String getText() { - if (reader != null) { - return reader.getText(); - } - return current.getValue(); - } - - public char[] getTextCharacters() { - if (reader != null) { - return reader.getTextCharacters(); - } - String value = current.getValue(); - return value == null ? new char[0] : value.toCharArray(); - } - - private int copy(int sourceStart, char[] target, int targetStart, int length) { - char[] source = getTextCharacters(); - if (sourceStart > source.length) { - throw new IndexOutOfBoundsException("source start > source length"); - } - int sourceLen = source.length - sourceStart; - if (length > sourceLen) { - length = sourceLen; - } - System.arraycopy(source, sourceStart, target, targetStart, length); - return sourceLen; - } - - public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { - if (reader != null) { - return reader.getTextCharacters(i, chars, i1, i2); - } - return copy(i, chars, i1, i2); - } - - public int getTextLength() { - if (reader != null) { - return reader.getTextLength(); - } - return getTextCharacters().length; - } - - public int getTextStart() { - if (reader != null) { - return reader.getTextStart(); - } - return 0; - } - - public String getVersion() { - return "1.0"; - } - - public boolean hasName() { - if (reader != null) { - return reader.hasName(); - } - return current.getName() != null; - } - - /** - * @throws XMLStreamException - */ - public boolean hasNext() throws XMLStreamException { - return iterator.hasNext() || state != END_DOCUMENT || (reader != null && reader.hasNext()); - } - - public boolean hasText() { - if (reader != null) { - return reader.hasText(); - } - return current.getType() == XmlNode.Type.CHARACTERS; - } - - public boolean isAttributeSpecified(int i) { - if (reader != null) { - return reader.isAttributeSpecified(i); - } - return false; // not supported - } - - public boolean isCharacters() { - if (reader != null) { - return reader.isCharacters(); - } - return current.getType() == XmlNode.Type.CHARACTERS; - } - - public boolean isEndElement() { - if (reader != null) { - return reader.isEndElement(); - } - return getEventType() == END_ELEMENT; - } - - public boolean isStandalone() { - return true; - } - - public boolean isStartElement() { - if (reader != null) { - return reader.isStartElement(); - } - return getEventType() == START_ELEMENT; - } - - public boolean isWhiteSpace() { - if (reader != null) { - return reader.isWhiteSpace(); - } - return false; - } - - /** - * By far this should be the most important method in this class this method - * changes the state of the parser - */ - public int next() throws XMLStreamException { - if (!hasNext()) { - throw new IllegalStateException("No more events"); - } - if (reader != null) { - if (!reader.hasNext()) { - this.reader = null; - } else { - // Go to the delegation mode - state = reader.next(); - return state; - } - } - if (!iterator.hasNext()) { - state = END_DOCUMENT; - current = null; - return state; - } - current = iterator.next(); - XmlNode.Type type = current.getType(); - - int itState = iterator.getState(); - if (itState == XmlNodeIterator.END) { - if (type == XmlNode.Type.ELEMENT) { - state = END_ELEMENT; - } else { - // Ignore the pop - state = next(); - } - } - if (itState == XmlNodeIterator.START) { - if (type == XmlNode.Type.ELEMENT) { - state = START_ELEMENT; - } else if (type == XmlNode.Type.CHARACTERS) { - state = CHARACTERS; - } else if (type == XmlNode.Type.READER) { - XMLStreamReader value = current.getValue(); - this.reader = new WrappingXMLStreamReader(value); - state = reader.getEventType(); - return state; - } - } - return state; - } - - /** - * TODO implement this - * - * @throws XMLStreamException - */ - public int nextTag() throws XMLStreamException { - while (true) { - int event = next(); - if (event == START_ELEMENT || event == END_ELEMENT) { - return event; - } - } - } - - public void require(int i, String ns, String localPart) throws XMLStreamException { - if (reader != null) { - reader.require(i, ns, localPart); - return; - } - int event = getEventType(); - if (event != i) { - throw new IllegalStateException("Event type is " + event + " (!=" + i + ")"); - } - QName name = getName(); - String ns1 = name.getNamespaceURI(); - String localName1 = name.getLocalPart(); - - if (ns != null && !ns.equals(ns1)) { - throw new IllegalStateException("Namespace URI is " + ns1 + " (!=" + ns + ")"); - } - - if (localPart != null && !localPart.equals(localName1)) { - throw new IllegalStateException("Local name is " + localName1 + " (!=" + localPart + ")"); - } - - } - - public boolean standaloneSet() { - return true; - } - -} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/StAX2SAXAdapter.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/StAX2SAXAdapter.java new file mode 100644 index 0000000000..df0fc069b6 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/StAX2SAXAdapter.java @@ -0,0 +1,256 @@ +/* + * 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.common.xml.stax.impl; + +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +/** + * Adapter that converts from StAX to SAX event streams. Currently the following + * SAX events are not generated: + *

        + *
      • ignorableWhitespace
      • + *
      • skippedEntity
      • + *
          + * Also the following StAX events are not mapped: + *
            + *
          • CDATA
          • + *
          • COMMENT
          • + *
          • DTD
          • + *
          • ENTITY_DECLARATION
          • + *
          • ENTITY_REFERENCE
          • + *
          • NOTATION_DECLARATION
          • + *
          • SPACE
          • + *
          + * StAX ATTRIBUTE events are ignored but the equivalent attributes (derived from + * the START_ELEMENT event) are supplied in the SAX startElement event's + * Attributes parameter. If the adaptor is configured to pass namespace prefixes + * then namespace information will also be included in the Attributes; StAX + * NAMESPACE events are ignored.

          Another issue is namespace processing. If + * the reader is positioned at a sub-node, we cannot capture all the in-scope + * namespace bindings. Therefore we cannot re-create a proper SAX event stream + * from a StAX parser.

          For example

          <a:root xmlns:a="foo" + * xmlns:b="bar"><b:sub>a:foo</b:sub></a:root>

          And if + * you are handed a parser at <b:sub>, then your SAX events should look + * like:

          <b:sub xmlns:a="foo" xmlns:b="bar">a:foo</b:sub>

          + * not:

          <b:sub>a:foo</b:sub>

          Proposal: we change the + * receiver of SAX events (SDOXMLResourceImpl) so that it uses NamespaceContext + * to resolve prefix (as opposed to record start/endPrefixMappings and use it + * for resolution.) + * + * @version $Rev$ $Date$ + */ +public class StAX2SAXAdapter { + private final boolean namespacePrefixes; + + /** + * Construct a new StAX to SAX adapter that will convert a StAX event stream + * into a SAX event stream. + * + * @param namespacePrefixes whether xmlns attributes should be included in + * startElement events; + */ + public StAX2SAXAdapter(boolean namespacePrefixes) { + this.namespacePrefixes = namespacePrefixes; + } + + /** + * Pull events from the StAX stream and dispatch to the SAX ContentHandler. + * The StAX stream would typically be located on a START_DOCUMENT or + * START_ELEMENT event and when this method returns it will be located on + * the associated END_DOCUMENT or END_ELEMENT event. Behaviour with other + * start events is undefined. + * + * @param reader StAX event source to read + * @param handler SAX ContentHandler for processing events + * @throws XMLStreamException if there was a problem reading the stream + * @throws SAXException passed through from the ContentHandler + */ + public void parse(XMLStreamReader reader, ContentHandler handler) throws XMLStreamException, SAXException { + handler.setDocumentLocator(new LocatorAdaptor(reader.getLocation())); + + // remembers the nest level of elements to know when we are done + int level = 0; + int event = reader.getEventType(); + while (true) { + switch (event) { + case XMLStreamConstants.START_DOCUMENT: + level++; + handler.startDocument(); + break; + case XMLStreamConstants.START_ELEMENT: + level++; + handleStartElement(reader, handler); + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + handler.processingInstruction(reader.getPITarget(), reader.getPIData()); + break; + case XMLStreamConstants.CHARACTERS: + handler.characters(reader.getTextCharacters(), reader.getTextStart(), reader + .getTextLength()); + break; + case XMLStreamConstants.END_ELEMENT: + handleEndElement(reader, handler); + level--; + if (level == 0) { + return; + } + break; + case XMLStreamConstants.END_DOCUMENT: + handler.endDocument(); + return; + /* + * uncomment to handle all events rather than just mapped + * ones // StAX events that are not mapped to SAX case + * XMLStreamConstants.COMMENT: case + * XMLStreamConstants.SPACE: case + * XMLStreamConstants.ENTITY_REFERENCE: case + * XMLStreamConstants.DTD: case XMLStreamConstants.CDATA: + * case XMLStreamConstants.NOTATION_DECLARATION: case + * XMLStreamConstants.ENTITY_DECLARATION: break; // StAX + * events handled in START_ELEMENT case + * XMLStreamConstants.ATTRIBUTE: case + * XMLStreamConstants.NAMESPACE: break; default: throw new + * AssertionError("Unknown StAX event: " + event); + */ + } + event = reader.next(); + } + } + + private void handleStartElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { + // send startPrefixMapping events immediately before startElement event + int nsCount = reader.getNamespaceCount(); + for (int i = 0; i < nsCount; i++) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.startPrefixMapping(prefix, reader.getNamespaceURI(i)); + } + + // fire startElement + QName qname = reader.getName(); + String prefix = qname.getPrefix(); + String rawname; + if (prefix == null || prefix.length() == 0) { + rawname = qname.getLocalPart(); + } else { + rawname = prefix + ':' + qname.getLocalPart(); + } + Attributes attrs = getAttributes(reader); + handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs); + } + + private static void handleEndElement(XMLStreamReader reader, ContentHandler handler) throws SAXException { + // fire endElement + QName qname = reader.getName(); + handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString()); + + // send endPrefixMapping events immediately after endElement event + // we send them in the opposite order to that returned but this is not + // actually required by SAX + int nsCount = reader.getNamespaceCount(); + for (int i = nsCount - 1; i >= 0; i--) { + String prefix = reader.getNamespacePrefix(i); + if (prefix == null) { // true for default namespace + prefix = ""; + } + handler.endPrefixMapping(prefix); + } + } + + /** + * Get the attributes associated with the current START_ELEMENT event. + * + * @return the StAX attributes converted to org.xml.sax.Attributes + */ + private Attributes getAttributes(XMLStreamReader reader) { + assert reader.getEventType() == XMLStreamConstants.START_ELEMENT; + + AttributesImpl attrs = new AttributesImpl(); + + // add namespace declarations if required + if (namespacePrefixes) { + for (int i = 0; i < reader.getNamespaceCount(); i++) { + String prefix = reader.getNamespacePrefix(i); + String uri = reader.getNamespaceURI(i); + attrs.addAttribute(null, prefix, "xmlns:" + prefix, "CDATA", uri); + } + } + + // Regular attributes + for (int i = 0; i < reader.getAttributeCount(); i++) { + String uri = reader.getAttributeNamespace(i); + if (uri == null) { + uri = ""; + } + String localName = reader.getAttributeLocalName(i); + String prefix = reader.getAttributePrefix(i); + String qname; + if (prefix == null || prefix.length() == 0) { + qname = localName; + } else { + qname = prefix + ':' + localName; + } + String type = reader.getAttributeType(i); + String value = reader.getAttributeValue(i); + + attrs.addAttribute(uri, localName, qname, type, value); + } + + return attrs; + } + + /** + * Adaptor for mapping Locator information. + */ + private static final class LocatorAdaptor implements Locator { + private final Location location; + + private LocatorAdaptor(Location location) { + this.location = location; + } + + public int getColumnNumber() { + return location == null ? 0 : location.getColumnNumber(); + } + + public int getLineNumber() { + return location == null ? 0 : location.getLineNumber(); + } + + public String getPublicId() { + return location == null ? "" : location.getPublicId(); + } + + public String getSystemId() { + return location == null ? "" : location.getSystemId(); + } + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/XMLStreamSerializer.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/XMLStreamSerializer.java new file mode 100644 index 0000000000..64ac0a40e5 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/impl/XMLStreamSerializer.java @@ -0,0 +1,287 @@ +/* + * 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.common.xml.stax.impl; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +/** + * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps into the XMLStreamWriter + * + * @version $Rev$ $Date$ + */ +public class XMLStreamSerializer implements XMLStreamConstants { + public static final String NAMESPACE_PREFIX = "ns"; + private static int namespaceSuffix; + + /* + * The behavior of the Serializer is such that it returns when it encounters the starting element for the second + * time. The depth variable tracks the depth of the Serializer and tells it when to return. Note that it is assumed + * that this Serialization starts on an Element. + */ + + /** + * Field depth + */ + private int depth; + + /** + * Generates a unique namespace prefix that is not in the scope of the NamespaceContext + * + * @param nsCtxt + * @return string + */ + private String generateUniquePrefix(NamespaceContext nsCtxt) { + String prefix = NAMESPACE_PREFIX + namespaceSuffix++; + // null should be returned if the prefix is not bound! + while (nsCtxt.getNamespaceURI(prefix) != null) { + prefix = NAMESPACE_PREFIX + namespaceSuffix++; + } + + return prefix; + } + + /** + * Method serialize. + * + * @param node + * @param writer + * @throws XMLStreamException + */ + public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws XMLStreamException { + serializeNode(node, writer); + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + int count = reader.getAttributeCount(); + String prefix; + String namespaceName; + String writerPrefix; + for (int i = 0; i < count; i++) { + prefix = reader.getAttributePrefix(i); + namespaceName = reader.getAttributeNamespace(i); + /* + * Due to parser implementations returning null as the namespace URI (for the empty namespace) we need to + * make sure that we deal with a namespace name that is not null. The best way to work around this issue is + * to set the namespace URI to "" if it is null + */ + if (namespaceName == null) { + namespaceName = ""; + } + + writerPrefix = writer.getPrefix(namespaceName); + + if (!"".equals(namespaceName)) { + // prefix has already being declared but this particular + // attrib has a + // no prefix attached. So use the prefix provided by the + // writer + if (writerPrefix != null && (prefix == null || prefix.equals(""))) { + writer.writeAttribute(writerPrefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + + // writer prefix is available but different from the + // current + // prefix of the attrib. We should be declaring the new + // prefix + // as a namespace declaration + } else if (prefix != null && !"".equals(prefix) && !prefix.equals(writerPrefix)) { + writer.writeNamespace(prefix, namespaceName); + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + + // prefix is null (or empty), but the namespace name is + // valid! it has not + // being written previously also. So we need to generate + // a prefix + // here + } else if (prefix == null || prefix.equals("")) { + prefix = generateUniquePrefix(writer.getNamespaceContext()); + writer.writeNamespace(prefix, namespaceName); + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + } else { + writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader + .getAttributeValue(i)); + } + } else { + // empty namespace is equal to no namespace! + writer.writeAttribute(reader.getAttributeLocalName(i), reader.getAttributeValue(i)); + } + + } + } + + /** + * Method serializeCData. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeCData(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + writer.writeCData(reader.getText()); + } + + /** + * Method serializeComment. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeComment(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + writer.writeComment(reader.getText()); + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + String prefix = reader.getPrefix(); + String nameSpaceName = reader.getNamespaceURI(); + if (nameSpaceName != null) { + String writerPrefix = writer.getPrefix(nameSpaceName); + if (writerPrefix != null) { + writer.writeStartElement(nameSpaceName, reader.getLocalName()); + } else { + if (prefix != null) { + writer.writeStartElement(prefix, reader.getLocalName(), nameSpaceName); + writer.writeNamespace(prefix, nameSpaceName); + // writer.setPrefix(prefix, nameSpaceName); + } else { + // [rfeng] We need to set default NS 1st before calling writeStateElement + writer.setDefaultNamespace(nameSpaceName); + writer.writeStartElement(nameSpaceName, reader.getLocalName()); + writer.writeDefaultNamespace(nameSpaceName); + } + } + } else { + writer.writeStartElement(reader.getLocalName()); + } + + // add the namespaces + int count = reader.getNamespaceCount(); + String namespacePrefix; + for (int i = 0; i < count; i++) { + namespacePrefix = reader.getNamespacePrefix(i); + // [rfeng] The following is commented out to allow to default ns + // if (namespacePrefix != null && namespacePrefix.length() == 0) { + // continue; + // } + + serializeNamespace(namespacePrefix, reader.getNamespaceURI(i), writer); + } + + // add attributes + serializeAttributes(reader, writer); + + } + + /** + * Method serializeEndElement. + * + * @param writer + * @throws XMLStreamException + */ + protected void serializeEndElement(XMLStreamWriter writer) throws XMLStreamException { + writer.writeEndElement(); + } + + /** + * Method serializeNamespace. + * + * @param prefix + * @param uri + * @param writer + * @throws XMLStreamException + */ + private void serializeNamespace(String prefix, String uri, XMLStreamWriter writer) throws XMLStreamException { + String prefix1 = writer.getPrefix(uri); + if (prefix1 == null) { + writer.writeNamespace(prefix, uri); + // writer.setPrefix(prefix, uri); + } + } + + /** + * Method serializeNode. + * + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + while (true) { + int event = reader.getEventType(); + if (event == START_ELEMENT) { + serializeElement(reader, writer); + depth++; + } else if (event == ATTRIBUTE) { + serializeAttributes(reader, writer); + } else if (event == CHARACTERS) { + serializeText(reader, writer); + } else if (event == COMMENT) { + serializeComment(reader, writer); + } else if (event == CDATA) { + serializeCData(reader, writer); + } else if (event == END_ELEMENT) { + serializeEndElement(writer); + depth--; + } else if (event == START_DOCUMENT) { + depth++; // if a start document is found then increment + writer.writeStartDocument(); + // the depth + } else if (event == END_DOCUMENT) { + if (depth != 0) { + depth--; // for the end document - reduce the depth + } + writer.writeEndDocument(); + } + if (depth == 0) { + break; + } + if (reader.hasNext()) { + reader.next(); + } else { + break; + } + } + } + + /** + * @param reader + * @param writer + * @throws XMLStreamException + */ + protected void serializeText(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException { + writer.writeCharacters(reader.getText()); + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXMLStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXMLStreamReader.java new file mode 100644 index 0000000000..b0224b6ca5 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXMLStreamReader.java @@ -0,0 +1,36 @@ +/* + * 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.common.xml.stax.reader; + +import org.w3c.dom.Node; + +public class DOMXMLStreamReader extends XmlTreeStreamReaderImpl { + + public DOMXMLStreamReader(Node node) { + super(new DOMXmlNodeImpl(node)); + switch (node.getNodeType()) { + case Node.DOCUMENT_NODE: + break; + case Node.ELEMENT_NODE: + break; + default: + throw new IllegalArgumentException("Illegal node type: " + node); + } + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXmlNodeImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXmlNodeImpl.java new file mode 100644 index 0000000000..faa56701ad --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DOMXmlNodeImpl.java @@ -0,0 +1,150 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * @version $Rev$ $Date$ + */ +public class DOMXmlNodeImpl implements XmlNode { + private Node node; + private Map namespaces; + private Type type; + + /** + * @param element + */ + public DOMXmlNodeImpl(Node element) { + super(); + if (element.getNodeType() == Node.DOCUMENT_NODE) { + this.node = ((Document)element).getDocumentElement(); + } else { + this.node = element; + } + switch (node.getNodeType()) { + case Node.CDATA_SECTION_NODE: + this.type = Type.CHARACTERS; + break; + case Node.ELEMENT_NODE: + this.type = Type.ELEMENT; + break; + case Node.TEXT_NODE: + this.type = Type.CHARACTERS; + break; + } + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#attributes() + */ + public List attributes() { + if (type != Type.ELEMENT) { + return null; + } + NamedNodeMap attrs = node.getAttributes(); + List xmlAttrs = new ArrayList(); + for (int i = 0; i < attrs.getLength(); i++) { + Attr attr = (Attr)attrs.item(i); + if (!attr.getName().equals("xmlns") && !attr.getName().startsWith("xmlns:")) { + xmlAttrs.add(new SimpleXmlNodeImpl(getQName(attr), attr.getValue(), XmlNode.Type.ATTRIBUTE)); + } + } + return xmlAttrs; + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#children() + */ + public Iterator children() { + if (type != Type.ELEMENT) { + return null; + } + NodeList nodes = node.getChildNodes(); + List xmlNodes = new ArrayList(); + for (int i = 0; i < nodes.getLength(); i++) { + Node child = (Node)nodes.item(i); + int nodeType = child.getNodeType(); + if (nodeType == Node.ELEMENT_NODE || nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + xmlNodes.add(new DOMXmlNodeImpl(child)); + } + } + return xmlNodes.iterator(); + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getName() + */ + public QName getName() { + return getQName(node); + } + + private static QName getQName(Node node) { + return DOMHelper.getQName(node); + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getValue() + */ + public String getValue() { + return node.getNodeValue(); + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#namespaces() + */ + public Map namespaces() { + if (type != Type.ELEMENT) { + return null; + } + if (namespaces == null) { + namespaces = new HashMap(); + NamedNodeMap attrs = node.getAttributes(); + for (int i = 0; i < attrs.getLength(); i++) { + Attr attr = (Attr)attrs.item(i); + if ("xmlns".equals(attr.getPrefix())) { + namespaces.put(attr.getLocalName(), attr.getValue()); + } + if ("xmlns".equals(attr.getName())) { + namespaces.put("", attr.getValue()); + } + } + } + return namespaces; + } + + public Type getType() { + return type; + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DelegatingNamespaceContext.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DelegatingNamespaceContext.java new file mode 100644 index 0000000000..8f136df7df --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/DelegatingNamespaceContext.java @@ -0,0 +1,310 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.Iterator; +import java.util.List; + +import javax.xml.namespace.NamespaceContext; + +public class DelegatingNamespaceContext implements NamespaceContext { + private static int count; + + private class WrappingIterator implements Iterator { + + private Iterator containedIterator; + + public WrappingIterator(Iterator containedIterator) { + this.containedIterator = containedIterator; + } + + public Iterator getContainedIterator() { + return containedIterator; + } + + public boolean hasNext() { + return containedIterator.hasNext(); + } + + public Object next() { + return containedIterator.next(); + } + + /** + * As per the contract on the API of Namespace context the returned iterator should be immutable + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + public void setContainedIterator(Iterator containedIterator) { + this.containedIterator = containedIterator; + } + } + + private NamespaceContext parentNsContext; + + private FastStack prefixStack = new FastStack(); + + // Keep two ArrayLists for the prefixes and namespaces. They should be in + // sync + // since the index of the entry will be used to relate them + // use the minimum initial capacity to let things handle memory better + + private FastStack uriStack = new FastStack(); + + /** + * Generates a unique namespace prefix that is not in the scope of the NamespaceContext + * + * @return string + */ + public String generateUniquePrefix() { + String prefix = "p" + count++; + // null should be returned if the prefix is not bound! + while (getNamespaceURI(prefix) != null) { + prefix = "p" + count++; + } + + return prefix; + } + + public String getNamespaceURI(String prefix) { + // do the corrections as per the Javadoc + int index = prefixStack.search(prefix); + if (index != -1) { + return uriStack.get(index); + } + if (parentNsContext != null) { + return parentNsContext.getPrefix(prefix); + } + return null; + } + + public NamespaceContext getParentNsContext() { + return parentNsContext; + } + + public String getPrefix(String uri) { + // do the corrections as per the Javadoc + int index = uriStack.search(uri); + if (index != -1) { + return prefixStack.get(index); + } + + if (parentNsContext != null) { + return parentNsContext.getPrefix(uri); + } + return null; + } + + public Iterator getPrefixes(String uri) { + // create an ArrayList that contains the relevant prefixes + String[] uris = uriStack.toArray(new String[uriStack.size()]); + List tempList = new ArrayList(); + for (int i = uris.length - 1; i >= 0; i--) { + if (uris[i].equals(uri)) { + tempList.add(prefixStack.get(i)); + // we assume that array conversion preserves the order + } + } + // by now all the relevant prefixes are collected + // make a new iterator and provide a wrapper iterator to + // obey the contract on the API + return new WrappingIterator(tempList.iterator()); + } + + /** + * Pop a namespace + */ + public void popNamespace() { + prefixStack.pop(); + uriStack.pop(); + } + + /** + * Register a namespace in this context + * + * @param prefix + * @param uri + */ + public void pushNamespace(String prefix, String uri) { + prefixStack.push(prefix); + uriStack.push(uri); + + } + + public void setParentNsContext(NamespaceContext parentNsContext) { + this.parentNsContext = parentNsContext; + } + + /** + * An implementation of the {@link java.util.Stack} API that is based on an ArrayList instead of a + * Vector, so it is not synchronized to protect against multi-threaded access. The implementation is + * therefore operates faster in environments where you do not need to worry about multiple thread contention. + *

          + * The removal order of an ArrayStack is based on insertion order: The most recently added element is + * removed first. The iteration order is not the same as the removal order. The iterator returns elements + * from the bottom up, whereas the {@link #remove()} method removes them from the top down. + *

          + * Unlike Stack, ArrayStack accepts null entries. + */ + public static class FastStack extends ArrayList { + + /** Ensure Serialization compatibility */ + private static final long serialVersionUID = 2130079159931574599L; + + /** + * Constructs a new empty ArrayStack. The initial size is controlled by ArrayList + * and is currently 10. + */ + public FastStack() { + super(); + } + + /** + * Constructs a new empty ArrayStack with an initial size. + * + * @param initialSize the initial size to use + * @throws IllegalArgumentException if the specified initial size is negative + */ + public FastStack(int initialSize) { + super(initialSize); + } + + /** + * Return true if this stack is currently empty. + *

          + * This method exists for compatibility with java.util.Stack. New users of this class should use + * isEmpty instead. + * + * @return true if the stack is currently empty + */ + public boolean empty() { + return isEmpty(); + } + + /** + * Returns the top item off of this stack without removing it. + * + * @return the top item on the stack + * @throws EmptyStackException if the stack is empty + */ + public T peek() throws EmptyStackException { + int n = size(); + if (n <= 0) { + throw new EmptyStackException(); + } else { + return get(n - 1); + } + } + + /** + * Returns the n'th item down (zero-relative) from the top of this stack without removing it. + * + * @param n the number of items down to go + * @return the n'th item on the stack, zero relative + * @throws EmptyStackException if there are not enough items on the stack to satisfy this request + */ + public T peek(int n) throws EmptyStackException { + int m = (size() - n) - 1; + if (m < 0) { + throw new EmptyStackException(); + } else { + return get(m); + } + } + + /** + * Pops the top item off of this stack and return it. + * + * @return the top item on the stack + * @throws EmptyStackException if the stack is empty + */ + public T pop() throws EmptyStackException { + int n = size(); + if (n <= 0) { + throw new EmptyStackException(); + } else { + return remove(n - 1); + } + } + + /** + * Pushes a new item onto the top of this stack. The pushed item is also returned. This is equivalent to calling + * add. + * + * @param item the item to be added + * @return the item just pushed + */ + public Object push(T item) { + add(item); + return item; + } + + /** + * Returns the top-most index for the object in the stack + * + * @param object the object to be searched for + * @return top-most index, or -1 if not found + */ + public int search(T object) { + int i = size() - 1; // Current index + while (i >= 0) { + T current = get(i); + if ((object == null && current == null) || (object != null && object.equals(current))) { + return i; + } + i--; + } + return -1; + } + + /** + * Returns the element on the top of the stack. + * + * @return the element on the top of the stack + * @throws EmptyStackException if the stack is empty + */ + public T get() { + int size = size(); + if (size == 0) { + throw new EmptyStackException(); + } + return get(size - 1); + } + + /** + * Removes the element on the top of the stack. + * + * @return the removed element + * @throws EmptyStackException if the stack is empty + */ + public T remove() { + int size = size(); + if (size == 0) { + throw new EmptyStackException(); + } + return remove(size - 1); + } + + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValueArrayStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValueArrayStreamReader.java new file mode 100644 index 0000000000..ec3b6e083b --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValueArrayStreamReader.java @@ -0,0 +1,404 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + + +public class NameValueArrayStreamReader implements XMLFragmentStreamReader { + + private static final int START_ELEMENT_STATE = 0; + private static final int TEXT_STATE = 1; + private static final int END_ELEMENT_STATE = 2; + private static final int FINAL_END_ELEMENT_STATE = 3; + private static final int START_ELEMENT_STATE_WITH_NULL = 4; + + private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); + // the index of the array + private int arrayIndex; + + private QName name; + private String[] values; + + // start element is the default state + private int state = START_ELEMENT_STATE; + + public NameValueArrayStreamReader(QName name, String[] values) { + this.name = name; + this.values = values; + } + + public void setParentNamespaceContext(NamespaceContext nsContext) { + this.namespaceContext.setParentNsContext(nsContext); + } + + public void init() { + // TODO what if the QName namespace has not been declared + } + + public Object getProperty(String string) throws IllegalArgumentException { + return null; + } + + /** + * @throws XMLStreamException + */ + public int next() throws XMLStreamException { + switch (state) { + case START_ELEMENT_STATE: + if (values.length > 0) { + state = TEXT_STATE; + return CHARACTERS; + } else { + state = FINAL_END_ELEMENT_STATE; + return END_ELEMENT; + } + + case START_ELEMENT_STATE_WITH_NULL: + if (arrayIndex == (values.length - 1)) { + state = FINAL_END_ELEMENT_STATE; + } else { + state = END_ELEMENT_STATE; + } + return END_ELEMENT; + case FINAL_END_ELEMENT_STATE: + // oops, not supposed to happen! + throw new XMLStreamException("end already reached!"); + case END_ELEMENT_STATE: + // we've to have more values since this is not the + // last value + // increment the counter + arrayIndex++; + if (values[arrayIndex] == null) { + state = START_ELEMENT_STATE_WITH_NULL; + } else { + state = START_ELEMENT_STATE; + } + return START_ELEMENT; + case TEXT_STATE: + if (arrayIndex == (values.length - 1)) { + state = FINAL_END_ELEMENT_STATE; + return END_ELEMENT; + } else { + state = END_ELEMENT_STATE; + return END_ELEMENT; + } + + default: + throw new XMLStreamException("unknown event type!"); + } + } + + public void require(int i, String string, String string1) throws XMLStreamException { + // nothing done here + } + + public String getElementText() throws XMLStreamException { + return null; // not implemented + } + + public int nextTag() throws XMLStreamException { + return 0; // not implemented + } + + public String getAttributeValue(String string, String string1) { + if (state == TEXT_STATE) { + // TODO something + return null; + } else { + return null; + } + + } + + public int getAttributeCount() { + if (state == START_ELEMENT_STATE_WITH_NULL) { + return 1; + } + if (state == START_ELEMENT_STATE) { + return 0; + } else { + throw new IllegalStateException(); + } + + } + + public QName getAttributeName(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return NIL_QNAME; + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeNamespace(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return NIL_QNAME.getNamespaceURI(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeLocalName(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return NIL_QNAME.getLocalPart(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return NIL_QNAME.getPrefix(); + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + return null; // not implemented + } + + public String getAttributeValue(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) { + return NIL_VALUE_TRUE; + } + if (state == START_ELEMENT_STATE) { + return null; + } else { + throw new IllegalStateException(); + } + } + + public boolean isAttributeSpecified(int i) { + return false; // not supported + } + + public int getNamespaceCount() { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent()) { + return 1; + } else { + return 0; + } + + } + + public String getNamespacePrefix(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { + return NIL_QNAME.getPrefix(); + } else { + return null; + } + } + + public String getNamespaceURI(int i) { + if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) { + return NIL_QNAME.getNamespaceURI(); + } else { + return null; + } + } + + public NamespaceContext getNamespaceContext() { + return this.namespaceContext; + } + + public boolean isDone() { + return state == FINAL_END_ELEMENT_STATE; + } + + public int getEventType() { + switch (state) { + case START_ELEMENT_STATE: + return START_ELEMENT; + case END_ELEMENT_STATE: + return END_ELEMENT; + case TEXT_STATE: + return CHARACTERS; + case FINAL_END_ELEMENT_STATE: + return END_ELEMENT; + default: + throw new UnsupportedOperationException(); + // we've no idea what this is!!!!! + } + + } + + public String getText() { + if (state == TEXT_STATE) { + return values[arrayIndex]; + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (state == TEXT_STATE) { + return values[arrayIndex].toCharArray(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + // not implemented + throw new UnsupportedOperationException(); + } + + public int getTextStart() { + if (state == TEXT_STATE) { + return 0; + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (state == TEXT_STATE) { + return values[arrayIndex].length(); + } else { + throw new IllegalStateException(); + } + + } + + public String getEncoding() { + return null; + } + + public boolean hasText() { + return state == TEXT_STATE; + } + + public Location getLocation() { + return null; // not supported + } + + public QName getName() { + if (state != TEXT_STATE) { + return name; + } else { + return null; + } + } + + public String getLocalName() { + if (state != TEXT_STATE) { + return name.getLocalPart(); + } else { + return null; + } + } + + public boolean hasName() { + return state != TEXT_STATE; + + } + + public String getNamespaceURI() { + if (state != TEXT_STATE) { + return name.getNamespaceURI(); + } else { + return null; + } + + } + + public String getPrefix() { + if (state != TEXT_STATE) { + return name.getPrefix(); + } else { + return null; + } + } + + public String getVersion() { + return null; // TODO 1.0 ? + } + + public boolean isStandalone() { + return false; + } + + public boolean standaloneSet() { + return false; + } + + public String getCharacterEncodingScheme() { + return null; + } + + public String getPITarget() { + return null; + } + + public String getPIData() { + return null; + } + + public boolean hasNext() throws XMLStreamException { + return state != FINAL_END_ELEMENT_STATE; + } + + public void close() throws XMLStreamException { + // Do nothing - we've nothing to free here + } + + public String getNamespaceURI(String prefix) { + return namespaceContext.getNamespaceURI(prefix); + } + + public boolean isStartElement() { + return state == START_ELEMENT_STATE; + } + + public boolean isEndElement() { + return state == END_ELEMENT_STATE; + } + + public boolean isCharacters() { + return state == TEXT_STATE; + } + + public boolean isWhiteSpace() { + return false; // no whitespaces here + } + + /** + * Test whether the xsi namespace is present + */ + private boolean isXsiNamespacePresent() { + return namespaceContext.getNamespaceURI(NIL_QNAME.getPrefix()) != null; + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValuePairStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValuePairStreamReader.java new file mode 100644 index 0000000000..4abf9b3dcf --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NameValuePairStreamReader.java @@ -0,0 +1,348 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + + + +public class NameValuePairStreamReader implements XMLFragmentStreamReader { + + private static final int START_ELEMENT_STATE = 0; + private static final int TEXT_STATE = 1; + private static final int END_ELEMENT_STATE = 2; + + private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); + + private QName name; + private String value; + + private int state = START_ELEMENT_STATE; + // initiate at the start element state + + // keeps track whether the namespace is declared + // false by default + private boolean nsDeclared; + + public NameValuePairStreamReader(QName name, String value) { + this.name = name; + this.value = value; + } + + public Object getProperty(String key) throws IllegalArgumentException { + return null; + } + + public int next() throws XMLStreamException { + // no need to handle null here. it should have been handled + // already + switch (state) { + case START_ELEMENT_STATE: + state = TEXT_STATE; + return CHARACTERS; + case END_ELEMENT_STATE: + // oops, not supposed to happen! + throw new XMLStreamException("end already reached!"); + case TEXT_STATE: + state = END_ELEMENT_STATE; + return END_ELEMENT; + default: + throw new XMLStreamException("unknown event type!"); + } + } + + public void require(int i, String string, String string1) throws XMLStreamException { + // not implemented + } + + public String getElementText() throws XMLStreamException { + if (state == START_ELEMENT) { + // move to the end state and return the value + state = END_ELEMENT_STATE; + return value; + } else { + throw new XMLStreamException(); + } + + } + + public int nextTag() throws XMLStreamException { + return 0; // TODO + } + + public boolean hasNext() throws XMLStreamException { + return state != END_ELEMENT_STATE; + } + + public void close() throws XMLStreamException { + // Do nothing - we've nothing to free here + } + + public String getNamespaceURI(String prefix) { + return namespaceContext.getNamespaceURI(prefix); + } + + public boolean isStartElement() { + return state == START_ELEMENT_STATE; + } + + public boolean isEndElement() { + return state == END_ELEMENT_STATE; + } + + public boolean isCharacters() { + return state == TEXT_STATE; + } + + public boolean isWhiteSpace() { + return false; // no whitespaces here + } + + public String getAttributeValue(String string, String string1) { + return null; + } + + public int getAttributeCount() { + return 0; + } + + public QName getAttributeName(int i) { + return null; + } + + public String getAttributeNamespace(int i) { + return null; + } + + public String getAttributeLocalName(int i) { + return null; + } + + public String getAttributePrefix(int i) { + return null; + } + + public String getAttributeType(int i) { + return null; + } + + public String getAttributeValue(int i) { + return null; + } + + public boolean isAttributeSpecified(int i) { + return false; // no attributes here + } + + public int getNamespaceCount() { + return nsDeclared ? 1 : 0; + } + + public String getNamespacePrefix(int i) { + return (nsDeclared && i == 0) ? name.getPrefix() : null; + } + + public String getNamespaceURI(int i) { + return (nsDeclared && i == 0) ? name.getNamespaceURI() : null; + } + + public NamespaceContext getNamespaceContext() { + return this.namespaceContext; + } + + public int getEventType() { + switch (state) { + case START_ELEMENT_STATE: + return START_ELEMENT; + case END_ELEMENT_STATE: + return END_ELEMENT; + case TEXT_STATE: + return CHARACTERS; + default: + throw new UnsupportedOperationException(); + // we've no idea what this is!!!!! + } + + } + + public String getText() { + if (state == TEXT_STATE) { + return value; + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (state == TEXT_STATE) { + return value.toCharArray(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + // not implemented + throw new UnsupportedOperationException(); + } + + public int getTextStart() { + if (state == TEXT_STATE) { + return 0; + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (state == TEXT_STATE) { + return value.length(); + } else { + throw new IllegalStateException(); + } + + } + + public String getEncoding() { + return null; + } + + public boolean hasText() { + return state == TEXT_STATE; + } + + public Location getLocation() { + return new Location() { + public int getLineNumber() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getCharacterOffset() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + if (state != TEXT_STATE) { + return name; + } else { + return null; + } + } + + public String getLocalName() { + if (state != TEXT_STATE) { + return name.getLocalPart(); + } else { + return null; + } + } + + public boolean hasName() { + return state != TEXT_STATE; + + } + + public String getNamespaceURI() { + if (state != TEXT_STATE) { + return name.getNamespaceURI(); + } else { + return null; + } + + } + + public String getPrefix() { + if (state != TEXT_STATE) { + return name.getPrefix(); + } else { + return null; + } + } + + public String getVersion() { + return null; // TODO 1.0 ? + } + + public boolean isStandalone() { + return false; + } + + public boolean standaloneSet() { + return false; + } + + public String getCharacterEncodingScheme() { + return null; + } + + public String getPITarget() { + return null; + } + + public String getPIData() { + return null; + } + + public boolean isDone() { + return state == END_ELEMENT_STATE; + } + + public void setParentNamespaceContext(NamespaceContext nsContext) { + this.namespaceContext.setParentNsContext(nsContext); + } + + public void init() { + // just add the current elements namespace and prefix to the this + // elements nscontext + addToNsMap(name.getPrefix(), name.getNamespaceURI()); + + } + + /** + * @param prefix + * @param uri + */ + private void addToNsMap(String prefix, String uri) { + // TODO - need to fix this up to cater for cases where + // namespaces are having no prefixes + if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { + // this namespace is not there. Need to declare it + namespaceContext.pushNamespace(prefix, uri); + nsDeclared = true; + } + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NamedProperty.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NamedProperty.java new file mode 100644 index 0000000000..dc5954f541 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NamedProperty.java @@ -0,0 +1,59 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.Map; + +import javax.xml.namespace.QName; + +/** + * A named property + * + * @version $Rev$ $Date$ + */ +public class NamedProperty implements Map.Entry { + private QName key; + + private Object value; + + public NamedProperty(QName key, Object value) { + this.key = key; + this.value = value; + } + + public NamedProperty(String key, Object value) { + this.key = new QName(key); + this.value = value; + } + + public QName getKey() { + return key; + } + + public Object getValue() { + return value; + } + + public Object setValue(Object value) { + Object v = this.value; + this.value = value; + return v; + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NilElementStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NilElementStreamReader.java new file mode 100644 index 0000000000..cee70f64df --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/NilElementStreamReader.java @@ -0,0 +1,279 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +public class NilElementStreamReader implements XMLFragmentStreamReader { + + private static final int END_ELEMENT_STATE = 2; + + private static final int START_ELEMENT_STATE = 1; + private int currentState = START_ELEMENT; + + private QName elementQName; + + public NilElementStreamReader(QName elementQName) { + this.elementQName = elementQName; + } + + public void setParentNamespaceContext(NamespaceContext nsContext) { + // NOOP + } + + public void close() throws XMLStreamException { + // do nothing + } + + public int getAttributeCount() { + return 1; + } + + public String getAttributeLocalName(int i) { + return (i == 0) ? NIL_QNAME.getLocalPart() : null; + } + + public QName getAttributeName(int i) { + return (i == 0) ? NIL_QNAME : null; + } + + public String getAttributeNamespace(int i) { + return (i == 0) ? NIL_QNAME.getNamespaceURI() : null; + } + + public String getAttributePrefix(int i) { + return (i == 0) ? NIL_QNAME.getPrefix() : null; + } + + public String getAttributeType(int i) { + throw new UnsupportedOperationException(); + } + + public String getAttributeValue(int i) { + return (i == 0) ? NIL_VALUE_TRUE : null; + } + + public String getAttributeValue(String string, String string1) { + if (string == null && NIL_QNAME.getLocalPart().equals(string1)) { + return NIL_VALUE_TRUE; + } + return null; + } + + public String getCharacterEncodingScheme() { + throw new UnsupportedOperationException(); + } + + public String getElementText() throws XMLStreamException { + return null; + } + + public String getEncoding() { + return null; + } + + public int getEventType() { + int returnEvent = START_DOCUMENT; + switch (currentState) { + case START_ELEMENT_STATE: + returnEvent = START_ELEMENT; + break; + case END_ELEMENT_STATE: + returnEvent = END_ELEMENT; + break; + } + return returnEvent; + } + + public String getLocalName() { + return elementQName.getLocalPart(); + } + + public Location getLocation() { + return new Location() { + public int getCharacterOffset() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getLineNumber() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + return elementQName; + } + + public NamespaceContext getNamespaceContext() { + throw new UnsupportedOperationException(); + } + + public int getNamespaceCount() { + return 0; + } + + public String getNamespacePrefix(int i) { + return null; + } + + public String getNamespaceURI() { + return elementQName.getNamespaceURI(); + } + + public String getNamespaceURI(int i) { + return null; + } + + public String getNamespaceURI(String string) { + if (elementQName.getPrefix() != null && elementQName.getPrefix().equals(string)) { + return elementQName.getNamespaceURI(); + } else { + return null; + } + } + + public String getPIData() { + throw new UnsupportedOperationException(); + } + + public String getPITarget() { + throw new UnsupportedOperationException(); + } + + public String getPrefix() { + return elementQName.getPrefix(); + } + + public Object getProperty(String key) throws IllegalArgumentException { + // since optimization is a global property + // we've to implement it everywhere + return null; + } + + public String getText() { + return null; + } + + public char[] getTextCharacters() { + return new char[0]; + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + return 0; + } + + public int getTextLength() { + return 0; + } + + public int getTextStart() { + return 0; + } + + public String getVersion() { + throw new UnsupportedOperationException(); + } + + public boolean hasName() { + return true; + } + + public boolean hasNext() throws XMLStreamException { + return currentState != END_ELEMENT_STATE; + + } + + public boolean hasText() { + return false; + } + + public void init() { + // NOOP + } + + public boolean isAttributeSpecified(int i) { + return i == 0; + } + + public boolean isCharacters() { + return false; + } + + public boolean isDone() { + return currentState == END_ELEMENT_STATE; + } + + public boolean isEndElement() { + return currentState == END_ELEMENT_STATE; + } + + public boolean isStandalone() { + throw new UnsupportedOperationException(); + } + + public boolean isStartElement() { + return currentState == START_ELEMENT_STATE; + } + + public boolean isWhiteSpace() { + return false; + } + + public int next() throws XMLStreamException { + int returnEvent = START_DOCUMENT; + switch (currentState) { + case START_ELEMENT_STATE: + currentState = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + break; + case END_ELEMENT_STATE: + throw new XMLStreamException("parser completed!"); + + } + return returnEvent; + } + + public int nextTag() throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public void require(int i, String string, String string1) throws XMLStreamException { + // nothing + } + + public boolean standaloneSet() { + throw new UnsupportedOperationException(); + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/SimpleXmlNodeImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/SimpleXmlNodeImpl.java new file mode 100644 index 0000000000..30f388543c --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/SimpleXmlNodeImpl.java @@ -0,0 +1,112 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +/** + * @version $Rev$ $Date$ + */ +public class SimpleXmlNodeImpl implements XmlNode { + private static final String XSI_PREFIX = "xsi"; + private static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance"; + private static final QName XSI_NIL = new QName(XSI_NS, "nil", XSI_PREFIX); + private static final Map NS_MAP = new HashMap(); + static { + NS_MAP.put(XSI_PREFIX, XSI_NS); + } + + protected Type type; + protected QName name; + protected Object value; + + public SimpleXmlNodeImpl(QName name, Object value) { + this(name, value, name != null ? Type.ELEMENT : Type.CHARACTERS); + } + + public SimpleXmlNodeImpl(QName name, Object value, Type type) { + super(); + this.type = type; + this.name = name; + this.value = value; + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#attributes() + */ + public List attributes() { + if (type == Type.ELEMENT && value == null) { + // Nil element + XmlNode attr = new SimpleXmlNodeImpl(XSI_NIL, "true"); + return Arrays.asList(attr); + } + return null; + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#children() + */ + public Iterator children() { + if (type == Type.ELEMENT && value != null) { + // Nil element + XmlNode node = new SimpleXmlNodeImpl(null, value); + return Arrays.asList(node).iterator(); + } + return null; + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getName() + */ + public QName getName() { + return name; + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getValue() + */ + public String getValue() { + return value == null ? null : String.valueOf(value); + } + + /** + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#namespaces() + */ + public Map namespaces() { + if (type == Type.ELEMENT && value == null) { + return NS_MAP; + } + return null; + } + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/WrappingXMLStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/WrappingXMLStreamReader.java new file mode 100644 index 0000000000..896f4b5b71 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/WrappingXMLStreamReader.java @@ -0,0 +1,100 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.util.StreamReaderDelegate; + +public class WrappingXMLStreamReader extends StreamReaderDelegate implements XMLFragmentStreamReader { + + private boolean done; + private int level; + + public WrappingXMLStreamReader(XMLStreamReader realReader) throws XMLStreamException { + super(realReader); + if (realReader == null) { + throw new UnsupportedOperationException("Reader cannot be null"); + } + + if (realReader instanceof XMLFragmentStreamReader) { + ((XMLFragmentStreamReader)realReader).init(); + } + + if (realReader.getEventType() == START_DOCUMENT) { + // Position to the 1st element + realReader.nextTag(); + } + if (realReader.getEventType() != START_ELEMENT) { + throw new IllegalStateException("The reader is not positioned at START_DOCUMENT or START_ELEMENT"); + } + this.done = false; + this.level = 1; + } + + @Override + public boolean hasNext() throws XMLStreamException { + return !done && super.hasNext(); + } + + @Override + public int next() throws XMLStreamException { + if (!hasNext()) { + throw new IllegalStateException("No more events"); + } + int event = super.next(); + if (!super.hasNext()) { + done = true; + } + if (event == START_ELEMENT) { + level++; + } else if (event == END_ELEMENT) { + level--; + if (level == 0) { + done = true; + } + } + return event; + } + + @Override + public int nextTag() throws XMLStreamException { + int event = 0; + while (true) { + event = next(); + if (event == START_ELEMENT || event == END_ELEMENT) { + return event; + } + } + } + + public void setParentNamespaceContext(NamespaceContext nsContext) { + // nothing to do here + } + + public void init() { + // Nothing to do here + } + + public boolean isDone() { + return done; + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLDocumentStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLDocumentStreamReader.java new file mode 100644 index 0000000000..a020a8a61e --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLDocumentStreamReader.java @@ -0,0 +1,482 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.NoSuchElementException; + +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; + +/** + * This class is derived from Apache Axis2 class + * org.apache.axis2.util.StreamWrapper. It's used wrap a XMLStreamReader to + * create a XMLStreamReader representing a document and it will produce + * START_DOCUMENT, END_DOCUMENT events. + * + * @version $Rev$ $Date$ + */ +public class XMLDocumentStreamReader implements XMLStreamReader { + private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper + // will produce + // END_DOCUMENT + + private static final int STATE_COMPLETED = 3; // Done + + private static final int STATE_INIT = 0; // The wrapper will produce + // START_DOCUMENT + + private static final int STATE_SWITCHED = 1; // The real reader will + // produce events + + private XMLStreamReader realReader; + private boolean fragment; + private int level = 1; + + private int state = STATE_INIT; + + public XMLDocumentStreamReader(XMLStreamReader realReader) { + if (realReader == null) { + throw new UnsupportedOperationException("Reader cannot be null"); + } + + this.realReader = realReader; + + if (realReader instanceof XMLFragmentStreamReader) { + ((XMLFragmentStreamReader)realReader).init(); + } + + // If the real reader is positioned at START_DOCUMENT, always use + // the real reader + if (realReader.getEventType() == START_DOCUMENT) { + fragment = false; + state = STATE_SWITCHED; + } + } + + public void close() throws XMLStreamException { + realReader.close(); + } + + public int getAttributeCount() { + if (isDelegating()) { + return realReader.getAttributeCount(); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeLocalName(int i) { + if (isDelegating()) { + return realReader.getAttributeLocalName(i); + } else { + throw new IllegalStateException(); + } + } + + public QName getAttributeName(int i) { + if (isDelegating()) { + return realReader.getAttributeName(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeNamespace(int i) { + if (isDelegating()) { + return realReader.getAttributeNamespace(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (isDelegating()) { + return realReader.getAttributePrefix(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + if (isDelegating()) { + return realReader.getAttributeType(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeValue(int i) { + if (isDelegating()) { + return realReader.getAttributeValue(i); + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeValue(String s, String s1) { + if (isDelegating()) { + return realReader.getAttributeValue(s, s1); + } else { + throw new IllegalStateException(); + } + } + + public String getCharacterEncodingScheme() { + return realReader.getCharacterEncodingScheme(); + } + + public String getElementText() throws XMLStreamException { + if (isDelegating()) { + return realReader.getElementText(); + } else { + throw new XMLStreamException(); + } + } + + public String getEncoding() { + return realReader.getEncoding(); + } + + public int getEventType() { + int event = -1; + switch (state) { + case STATE_SWITCHED: + case STATE_COMPLETE_AT_NEXT: + event = realReader.getEventType(); + break; + case STATE_INIT: + event = START_DOCUMENT; + break; + case STATE_COMPLETED: + event = END_DOCUMENT; + break; + } + return event; + } + + public String getLocalName() { + if (isDelegating()) { + return realReader.getLocalName(); + } else { + throw new IllegalStateException(); + } + } + + public Location getLocation() { + if (isDelegating()) { + return realReader.getLocation(); + } else { + return null; + } + } + + public QName getName() { + if (isDelegating()) { + return realReader.getName(); + } else { + throw new IllegalStateException(); + } + } + + public NamespaceContext getNamespaceContext() { + return realReader.getNamespaceContext(); + } + + public int getNamespaceCount() { + if (isDelegating()) { + return realReader.getNamespaceCount(); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespacePrefix(int i) { + if (isDelegating()) { + return realReader.getNamespacePrefix(i); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI() { + if (isDelegating()) { + return realReader.getNamespaceURI(); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI(int i) { + if (isDelegating()) { + return realReader.getNamespaceURI(i); + } else { + throw new IllegalStateException(); + } + } + + public String getNamespaceURI(String s) { + if (isDelegating()) { + return realReader.getNamespaceURI(s); + } else { + throw new IllegalStateException(); + } + } + + public String getPIData() { + if (isDelegating()) { + return realReader.getPIData(); + } else { + throw new IllegalStateException(); + } + } + + public String getPITarget() { + if (isDelegating()) { + return realReader.getPITarget(); + } else { + throw new IllegalStateException(); + } + } + + public String getPrefix() { + if (isDelegating()) { + return realReader.getPrefix(); + } else { + throw new IllegalStateException(); + } + } + + public Object getProperty(String s) throws IllegalArgumentException { + if (isDelegating()) { + return realReader.getProperty(s); + } else { + throw new IllegalArgumentException(); + } + } + + public String getText() { + if (isDelegating()) { + return realReader.getText(); + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (isDelegating()) { + return realReader.getTextCharacters(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + if (isDelegating()) { + return realReader.getTextCharacters(i, chars, i1, i2); + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (isDelegating()) { + return realReader.getTextLength(); + } else { + throw new IllegalStateException(); + } + } + + public int getTextStart() { + if (isDelegating()) { + return realReader.getTextStart(); + } else { + throw new IllegalStateException(); + } + } + + public String getVersion() { + if (isDelegating()) { + return realReader.getVersion(); + } else { + return null; + } + } + + public boolean hasName() { + if (isDelegating()) { + return realReader.hasName(); + } else { + return false; + } + } + + public boolean hasNext() throws XMLStreamException { + if (state == STATE_COMPLETE_AT_NEXT) { + return true; + } else if (state == STATE_COMPLETED) { + return false; + } else if (state == STATE_SWITCHED) { + return realReader.hasNext(); + } else { + return true; + } + } + + public boolean hasText() { + if (isDelegating()) { + return realReader.hasText(); + } else { + return false; + } + } + + public boolean isAttributeSpecified(int i) { + if (isDelegating()) { + return realReader.isAttributeSpecified(i); + } else { + return false; + } + } + + public boolean isCharacters() { + if (isDelegating()) { + return realReader.isCharacters(); + } else { + return false; + } + } + + private boolean isDelegating() { + return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT; + } + + public boolean isEndElement() { + if (isDelegating()) { + return realReader.isEndElement(); + } else { + return false; + } + } + + public boolean isStandalone() { + if (isDelegating()) { + return realReader.isStandalone(); + } else { + return false; + } + } + + public boolean isStartElement() { + if (isDelegating()) { + return realReader.isStartElement(); + } else { + return false; + } + } + + public boolean isWhiteSpace() { + if (isDelegating()) { + return realReader.isWhiteSpace(); + } else { + return false; + } + } + + public int next() throws XMLStreamException { + int returnEvent; + + switch (state) { + case STATE_SWITCHED: + returnEvent = realReader.next(); + if (returnEvent == END_DOCUMENT) { + state = STATE_COMPLETED; + } else if (!realReader.hasNext()) { + state = STATE_COMPLETE_AT_NEXT; + } + if (fragment && returnEvent == END_ELEMENT) { + level--; + if (level == 0) { + // We are now at the end of the top-level element in the fragment + state = STATE_COMPLETE_AT_NEXT; + } + } + if (fragment && returnEvent == START_ELEMENT) { + level++; + } + break; + case STATE_INIT: + state = STATE_SWITCHED; + returnEvent = realReader.getEventType(); + if (returnEvent == START_ELEMENT) { + // The real reader is positioned at the top-level element in the fragment + level = 0; + fragment = true; + } + break; + case STATE_COMPLETE_AT_NEXT: + state = STATE_COMPLETED; + returnEvent = END_DOCUMENT; + break; + case STATE_COMPLETED: + // oops - no way we can go beyond this + throw new NoSuchElementException("End of stream has reached."); + default: + throw new UnsupportedOperationException(); + } + + return returnEvent; + } + + public int nextTag() throws XMLStreamException { + if (isDelegating()) { + int returnEvent = realReader.nextTag(); + if (fragment && returnEvent == END_ELEMENT) { + level--; + if (level == 0) { + // We are now at the end of the top-level element in the fragment + state = STATE_COMPLETE_AT_NEXT; + } + } + if (fragment && returnEvent == START_ELEMENT) { + level++; + } + return returnEvent; + } else { + throw new XMLStreamException(); + } + } + + public void require(int i, String s, String s1) throws XMLStreamException { + if (isDelegating()) { + realReader.require(i, s, s1); + } + } + + public boolean standaloneSet() { + if (isDelegating()) { + return realReader.standaloneSet(); + } else { + return false; + } + } +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReader.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReader.java new file mode 100644 index 0000000000..95ede0a840 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReader.java @@ -0,0 +1,53 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +public interface XMLFragmentStreamReader extends XMLStreamReader { + QName NIL_QNAME = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi"); + String NIL_VALUE_TRUE = "true"; + + /** + * this will help to handle Text within the current element. user should + * pass the element text to the property list as this ELEMENT_TEXT as the + * key. This key deliberately has a space in it so that it is not a valid + * XML name + */ + String ELEMENT_TEXT = "Element Text"; + + /** + * Extra method to query the state of the pullparser + */ + boolean isDone(); + + /** + * add the parent namespace context to this parser + */ + void setParentNamespaceContext(NamespaceContext nsContext); + + /** + * Initiate the parser - this will do whatever the needed tasks to initiate + * the parser and must be called before attempting any specific parsing + * using this parser + */ + void init(); +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReaderImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReaderImpl.java new file mode 100644 index 0000000000..4fd70bea67 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLFragmentStreamReaderImpl.java @@ -0,0 +1,858 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +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; + + +/** + * This is the new implementation of the XMLFramentStreamReader. The approach + * here is simple When the pull parser needs to generate events for a particular + * name-value(s) pair it always hands over (delegates) the task to another pull + * parser which knows how to deal with it The common types of name value pairs + * we'll come across are + *

            + *
          • String name/QName name - String value + *
          • String name/QName name - String[] value + *
          • QName name/String name - XMLStreamReader value + *
          • QName name/String name - XMLStreamable value + *
          • QName name/String name - Java bean + *
          • QName name/String name - Datahandler + * + *
          + *

          As for the attributes, these are the possible combinations in the array + *

            + *
          • String name/QName name - String value + *
          + * Note that certain array methods have been deliberately removed to avoid + * complications. The generated code will take the trouble to lay the elements + * of the array in the correct order

          Hence there will be a parser impl + * that knows how to handle these types, and this parent parser will always + * delegate these tasks to the child pullparasers in effect this is one huge + * state machine that has only a few states and delegates things down to the + * child parsers whenever possible

          + * + * @version $Rev$ $Date$ + */ +public class XMLFragmentStreamReaderImpl implements XMLFragmentStreamReader { + + private static final int DELEGATED_STATE = 2; + private static final int END_ELEMENT_STATE = 1; + // states for this pullparser - it can only have four states + private static final int START_ELEMENT_STATE = 0; + private static final int TEXT_STATE = 3; + + protected NamedProperty[] attributes; + + // reference to the child reader + protected XMLFragmentStreamReader childReader; + // current property index + // initialized at zero + protected int index; + protected Map declaredNamespaceMap = new HashMap(); + protected QName elementQName; + + // we always create a new namespace context + protected DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(); + + protected NamedProperty[] elements; + + // integer field that keeps the state of this + // parser. + protected int state = START_ELEMENT_STATE; + + /* + * we need to pass in a namespace context since when delegated, we've no + * idea of the current namespace context. So it needs to be passed on here! + */ + public XMLFragmentStreamReaderImpl(QName elementQName, NamedProperty[] elements, NamedProperty[] attributes) { + // validate the lengths, since both the arrays are supposed + // to have + this.elements = elements == null ? new NamedProperty[0] : elements; + this.elementQName = elementQName; + this.attributes = attributes == null ? new NamedProperty[0] : attributes; + } + + protected XMLFragmentStreamReaderImpl(QName elementQName) { + this.elementQName = elementQName; + } + + /** + * add the namespace context + */ + + public void setParentNamespaceContext(NamespaceContext nsContext) { + // register the namespace context passed in to this + this.namespaceContext.setParentNsContext(nsContext); + + } + + protected NamedProperty[] getElements() { + return elements; + } + + protected NamedProperty[] getAttributes() { + return attributes; + } + + protected QName[] getNamespaces() { + return new QName[0]; + } + + /** + * @param prefix + * @param uri + */ + protected void addToNsMap(String prefix, String uri) { + if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) { + namespaceContext.pushNamespace(prefix, uri); + declaredNamespaceMap.put(prefix, uri); + } + } + + public void close() throws XMLStreamException { + // do nothing here - we have no resources to free + } + + public int getAttributeCount() { + return (state == DELEGATED_STATE) ? childReader.getAttributeCount() : (state == START_ELEMENT_STATE + ? getAttributes().length : 0); + } + + public String getAttributeLocalName(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeLocalName(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getLocalPart(); + } + } else { + throw new IllegalStateException(); + } + } + + /** + * @param i + */ + public QName getAttributeName(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeName(i); + } else if (state == START_ELEMENT_STATE) { + if ((i >= (getAttributes().length)) || i < 0) { // out of range + return null; + } else { + // get the attribute pointer + QName attribPointer = getAttributes()[i].getKey(); + // case one - attrib name is null + // this should be the pointer to the OMAttribute then + if (attribPointer == null) { + throw new UnsupportedOperationException(); + } else if (attribPointer instanceof QName) { + return attribPointer; + } else { + return null; + } + } + } else { + throw new IllegalStateException(); // as per the API contract + } + + } + + public String getAttributeNamespace(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeNamespace(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getNamespaceURI(); + } + } else { + throw new IllegalStateException(); + } + } + + public String getAttributePrefix(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributePrefix(i); + } else if (state == START_ELEMENT_STATE) { + QName name = getAttributeName(i); + if (name == null) { + return null; + } else { + return name.getPrefix(); + } + } else { + throw new IllegalStateException(); + } + } + + public String getAttributeType(int i) { + return null; // not supported + } + + public String getAttributeValue(int i) { + if (state == DELEGATED_STATE) { + return childReader.getAttributeValue(i); + } else if (state == START_ELEMENT_STATE) { + if ((i >= (getAttributes().length)) || i < 0) { // out of range + return null; + } else { + // get the attribute pointer + QName attribPointer = getAttributes()[i].getKey(); + Object omAttribObj = getAttributes()[i].getValue(); + // case one - attrib name is null + // this should be the pointer to the OMAttribute then + if (attribPointer == null) { + throw new UnsupportedOperationException(); + } else if (attribPointer instanceof QName) { + return (String)omAttribObj; + } else { + return null; + } + } + } else { + throw new IllegalStateException(); + } + + } + + public String getAttributeValue(String nsUri, String localName) { + + int attribCount = getAttributeCount(); + String returnValue = null; + QName attribQualifiedName; + for (int i = 0; i < attribCount; i++) { + attribQualifiedName = getAttributeName(i); + if (nsUri == null) { + if (localName.equals(attribQualifiedName.getLocalPart())) { + returnValue = getAttributeValue(i); + break; + } + } else { + if (localName.equals(attribQualifiedName.getLocalPart()) && nsUri.equals(attribQualifiedName + .getNamespaceURI())) { + returnValue = getAttributeValue(i); + break; + } + } + + } + + return returnValue; + } + + public String getCharacterEncodingScheme() { + return null; // TODO - should we return something for this ? + } + + /** + * TODO implement the right contract for this + * + * @throws XMLStreamException + */ + public String getElementText() throws XMLStreamException { + if (state == DELEGATED_STATE) { + return childReader.getElementText(); + } else { + return null; + } + + } + + // ///////////////////////////////////////////////////////////////////////// + // / attribute handling + // ///////////////////////////////////////////////////////////////////////// + + public String getEncoding() { + if (state == DELEGATED_STATE) { + return childReader.getEncoding(); + } else { + // we've no idea what the encoding is going to be in this case + // perhaps we ought to return some constant here, which the user + // might + // have access to change! + return null; + } + } + + public int getEventType() { + if (state == START_ELEMENT_STATE) { + return START_ELEMENT; + } else if (state == END_ELEMENT_STATE) { + return END_ELEMENT; + } else if (state == TEXT_STATE) { + return CHARACTERS; + } else { // this is the delegated state + return childReader.getEventType(); + } + } + + public String getLocalName() { + if (state == DELEGATED_STATE) { + return childReader.getLocalName(); + } else if (state != TEXT_STATE) { + return elementQName.getLocalPart(); + } else { + throw new IllegalStateException(); + } + } + + /** + */ + public Location getLocation() { + // return a default location + return new Location() { + public int getCharacterOffset() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getLineNumber() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + if (state == DELEGATED_STATE) { + return childReader.getName(); + } else if (state != TEXT_STATE) { + return elementQName; + } else { + throw new IllegalStateException(); + } + + } + + public NamespaceContext getNamespaceContext() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceContext(); + } else { + return namespaceContext; + } + + } + + public int getNamespaceCount() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceCount(); + } else { + return declaredNamespaceMap.size(); + } + } + + /** + * @param i + */ + public String getNamespacePrefix(int i) { + if (state == DELEGATED_STATE) { + return childReader.getNamespacePrefix(i); + } else if (state != TEXT_STATE) { + // order the prefixes + String[] prefixes = makePrefixArray(); + if ((i >= prefixes.length) || (i < 0)) { + return null; + } else { + return prefixes[i]; + } + + } else { + throw new IllegalStateException(); + } + + } + + public String getNamespaceURI() { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceURI(); + } else if (state == TEXT_STATE) { + return null; + } else { + return elementQName.getNamespaceURI(); + } + } + + // ///////////////////////////////////////////////////////////////////////// + // //////////// end of attribute handling + // ///////////////////////////////////////////////////////////////////////// + + // ////////////////////////////////////////////////////////////////////////// + // //////////// namespace handling + // ////////////////////////////////////////////////////////////////////////// + + public String getNamespaceURI(int i) { + if (state == DELEGATED_STATE) { + return childReader.getNamespaceURI(i); + } else if (state != TEXT_STATE) { + String namespacePrefix = getNamespacePrefix(i); + return namespacePrefix == null ? null : (String)declaredNamespaceMap.get(namespacePrefix); + } else { + throw new IllegalStateException(); + } + + } + + public String getNamespaceURI(String prefix) { + return namespaceContext.getNamespaceURI(prefix); + } + + public String getPIData() { + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPITarget() { + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPrefix() { + if (state == DELEGATED_STATE) { + return childReader.getPrefix(); + } else if (state == TEXT_STATE) { + return null; + } else { + String prefix = elementQName.getPrefix(); + return "".equals(prefix) ? null : prefix; + } + } + + // ///////////////////////////////////////////////////////////////////////// + // /////// end of namespace handling + // ///////////////////////////////////////////////////////////////////////// + + /** + * @param key + * @throws IllegalArgumentException + */ + public Object getProperty(String key) throws IllegalArgumentException { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return null; + } else if (state == TEXT_STATE) { + return null; + } else if (state == DELEGATED_STATE) { + return childReader.getProperty(key); + } else { + return null; + } + + } + + public String getText() { + if (state == DELEGATED_STATE) { + return childReader.getText(); + } else if (state == TEXT_STATE) { + return (String)getElements()[index - 1].getValue(); + } else { + throw new IllegalStateException(); + } + } + + public char[] getTextCharacters() { + if (state == DELEGATED_STATE) { + return childReader.getTextCharacters(); + } else if (state == TEXT_STATE) { + return getElements()[index - 1].getValue() == null ? new char[0] : ((String)getElements()[index - 1] + .getValue()).toCharArray(); + } else { + throw new IllegalStateException(); + } + } + + private int copy(int sourceStart, char[] target, int targetStart, int length) { + char[] source = getTextCharacters(); + if (sourceStart > source.length) { + throw new IndexOutOfBoundsException("source start > source length"); + } + int sourceLen = source.length - sourceStart; + if (length > sourceLen) { + length = sourceLen; + } + System.arraycopy(source, sourceStart, target, targetStart, length); + return sourceLen; + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + if (state == DELEGATED_STATE) { + return childReader.getTextCharacters(i, chars, i1, i2); + } else if (state == TEXT_STATE) { + return copy(i, chars, i1, i2); + } else { + throw new IllegalStateException(); + } + } + + public int getTextLength() { + if (state == DELEGATED_STATE) { + return childReader.getTextLength(); + } else if (state == TEXT_STATE) { + return getTextCharacters().length; + } else { + throw new IllegalStateException(); + } + } + + public int getTextStart() { + if (state == DELEGATED_STATE) { + return childReader.getTextStart(); + } else if (state == TEXT_STATE) { + return 0; // assume text always starts at 0 + } else { + throw new IllegalStateException(); + } + } + + public String getVersion() { + return null; + } + + public boolean hasName() { + // since this parser always has a name, the hasName + // has to return true if we are still navigating this element + // if not we should ask the child reader for it. + if (state == DELEGATED_STATE) { + return childReader.hasName(); + } else { + return state != TEXT_STATE; + } + } + + /** + * @throws XMLStreamException + */ + public boolean hasNext() throws XMLStreamException { + if (state == DELEGATED_STATE) { + if (childReader.isDone()) { + // the child reader is done. We shouldn't be getting the + // hasNext result from the child pullparser then + return true; + } else { + return childReader.hasNext(); + } + } else { + return state == START_ELEMENT_STATE || state == TEXT_STATE; + + } + } + + /** + * check the validity of this implementation + */ + public boolean hasText() { + if (state == DELEGATED_STATE) { + return childReader.hasText(); + } else { + return state == TEXT_STATE; + } + + } + + /** + * we need to split out the calling to the populate namespaces separately + * since this needs to be done *after* setting the parent namespace context. + * We cannot assume it will happen at construction! + */ + public void init() { + // here we have an extra issue to attend to. we need to look at the + // prefixes and URIs (the combination) and populate a HashMap of + // namespaces. The HashMap of namespaces will be used to serve the + // namespace context + + populateNamespaceContext(); + } + + public boolean isAttributeSpecified(int i) { + return false; // not supported + } + + public boolean isCharacters() { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return false; + } + return childReader.isCharacters(); + } + + /** + * are we done ? + */ + public boolean isDone() { + return state == END_ELEMENT_STATE; + } + + public boolean isEndElement() { + if (state == START_ELEMENT_STATE) { + return false; + } else if (state == END_ELEMENT_STATE) { + return true; + } + return childReader.isEndElement(); + } + + public boolean isStandalone() { + return true; + } + + public boolean isStartElement() { + if (state == START_ELEMENT_STATE) { + return true; + } else if (state == END_ELEMENT_STATE) { + return false; + } + return childReader.isStartElement(); + } + + public boolean isWhiteSpace() { + if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) { + return false; + } + return childReader.isWhiteSpace(); + } + + /** + * Get the prefix list from the HashTable and take that into an array + */ + private String[] makePrefixArray() { + String[] prefixes = declaredNamespaceMap.keySet().toArray(new String[declaredNamespaceMap.size()]); + Arrays.sort(prefixes); + return prefixes; + } + + /** + * By far this should be the most important method in this class this method + * changes the state of the parser + */ + public int next() throws XMLStreamException { + int returnEvent = -1; // invalid state is the default state + switch (state) { + case START_ELEMENT_STATE: + // current element is start element. We should be looking at the + // property list and making a pullparser for the property value + if (getElements() == null || getElements().length == 0) { + // no properties - move to the end element state + // straight away + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + // there are properties. now we should delegate this task to + // a + // child reader depending on the property type + returnEvent = processProperties(); + + } + break; + case END_ELEMENT_STATE: + // we've reached the end element already. If the user tries to + // push + // further ahead then it is an exception + throw new XMLStreamException("Trying to go beyond the end of the pullparser"); + + case DELEGATED_STATE: + if (childReader.isDone()) { + // we've reached the end! + if (index > (getElements().length - 1)) { + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + returnEvent = processProperties(); + } + } else { + returnEvent = childReader.next(); + } + break; + + case TEXT_STATE: + // if there are any more event we should be delegating to + // processProperties. if not we just return an end element + if (index > (getElements().length - 1)) { + state = END_ELEMENT_STATE; + returnEvent = END_ELEMENT; + } else { + returnEvent = processProperties(); + } + break; + } + return returnEvent; + } + + // ///////////////////////////////////////////////////////////////////////// + // / Other utility methods + // //////////////////////////////////////////////////////////////////////// + + /** + * TODO implement this + * + * @throws XMLStreamException + */ + public int nextTag() throws XMLStreamException { + return 0; + } + + /** + * Populates a namespace context + */ + private void populateNamespaceContext() { + + // first add the current element namespace to the namespace context + // declare it if not found + addToNsMap(elementQName.getPrefix(), elementQName.getNamespaceURI()); + + for (QName n : getNamespaces()) { + addToNsMap(n.getPrefix(), n.getNamespaceURI()); + } + + // traverse through the attributes and populate the namespace context + // the attrib list can be of many combinations + // the valid combinations are + // String - String + // QName - QName + // null - OMAttribute + + for (int i = 0; i < getAttributes().length; i++) { // jump in two + QName attrQName = getAttributes()[i].getKey(); + if (!"".equals(attrQName.getNamespaceURI())) { + addToNsMap(attrQName.getPrefix(), attrQName.getNamespaceURI()); + } + } + } + + /** + * A convenient method to reuse the properties + * + * @return event to be thrown + * @throws XMLStreamException + */ + private int processProperties() throws XMLStreamException { + // move to the next property depending on the current property + // index + QName propertyQName = getElements()[index].getKey(); + boolean textFound = false; + if (propertyQName == null) { + throw new XMLStreamException("property key cannot be null!"); + } else if (ELEMENT_TEXT.equals(propertyQName.getLocalPart())) { + // propPointer being a String has a special case + // that is it can be a the special constant ELEMENT_TEXT that + // says this text event + textFound = true; + } + + // OK! we got the key. Now look at the value + Object propertyValue = getElements()[index].getValue(); + // cater for the special case now + if (textFound) { + // no delegation here - make the parser null and immediately + // return with the event characters + childReader = null; + state = TEXT_STATE; + ++index; + return CHARACTERS; + } else if (propertyValue == null) { + // if the value is null we delegate the work to a nullable + // parser + childReader = new NilElementStreamReader(propertyQName); + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else if (propertyValue instanceof String) { + // strings are handled by the NameValuePairStreamReader + childReader = new NameValuePairStreamReader(propertyQName, (String)propertyValue); + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else if (propertyValue instanceof String[]) { + // string[] are handled by the NameValueArrayStreamReader + // if the array is empty - skip it + if (((String[])propertyValue).length == 0) { + // advance the index + ++index; + return processProperties(); + } else { + childReader = new NameValueArrayStreamReader(propertyQName, (String[])propertyValue); + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } + + } else if (propertyValue instanceof XMLStreamable) { + // ADBbean has it's own method to get a reader + XMLStreamReader reader = ((XMLStreamable)propertyValue).getXMLStreamReader(propertyQName); + // we know for sure that this is an ADB XMLStreamreader. + // However we need to make sure that it is compatible + if (reader instanceof XMLFragmentStreamReader) { + childReader = (XMLFragmentStreamReader)reader; + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else { + // wrap it to make compatible + childReader = new WrappingXMLStreamReader(reader); + } + } else if (propertyValue instanceof XMLStreamReader) { + XMLStreamReader reader = (XMLStreamReader)propertyValue; + if (reader instanceof XMLFragmentStreamReader) { + childReader = (XMLFragmentStreamReader)reader; + childReader.setParentNamespaceContext(this.namespaceContext); + childReader.init(); + } else { + // wrap it to make compatible + childReader = new WrappingXMLStreamReader(reader); + } + + } else { + // all special possibilities has been tried! Let's treat + // the thing as a bean and try generating events from it + throw new UnsupportedOperationException("Property type is not supported"); + // we cannot register the namespace context here + } + + // set the state here + state = DELEGATED_STATE; + // we are done with the delegation + // increment the property index + ++index; + return childReader.getEventType(); + } + + public void require(int i, String string, String string1) throws XMLStreamException { + throw new UnsupportedOperationException(); + } + + public boolean standaloneSet() { + return true; + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLStreamable.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLStreamable.java new file mode 100644 index 0000000000..f433753f96 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XMLStreamable.java @@ -0,0 +1,37 @@ +/* + * 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.common.xml.stax.reader; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; + +/** + * An interface represents data that can be read using StAX streaming + * + * @version $Rev$ $Date$ + */ +public interface XMLStreamable { + /** + * Get the XMLStreamReader for StAX processing + * + * @param rootElementName the name of the element to be generated + * @return Returns a pull parser. + */ + XMLStreamReader getXMLStreamReader(QName rootElementName); +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNode.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNode.java new file mode 100644 index 0000000000..9e39f58b31 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNode.java @@ -0,0 +1,69 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +/** + * @version $Rev$ $Date$ + */ +public interface XmlNode { + enum Type {ELEMENT, ATTRIBUTE, CHARACTERS, READER}; + /** + * Returns the children of the receiver as an Iterator. + */ + Iterator children(); + + /** + * Returns the attributes of the element as an List. Namespace declarations + * should be excluded. + * + * @return + */ + List attributes(); + + /** + * Returns a map of prefix to namespace URI + * @return + */ + Map namespaces(); + + /** + * Return the QName of the element. If it's for a text node, the name is null. + * @return + */ + QName getName(); + + /** + * Return the text value of the leaf element + * @return + */ + T getValue(); + + /** + * Return the type of the XML node + * @return + */ + Type getType(); +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNodeIterator.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNodeIterator.java new file mode 100644 index 0000000000..295fdb3de9 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlNodeIterator.java @@ -0,0 +1,355 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.ArrayList; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.NamespaceContext; + +/** + * @version $Rev$ $Date$ + */ +public class XmlNodeIterator implements Iterator { + public static final int START = 0; + public static final int END = 1; + + protected FastStack stack; + protected int state; + protected NamespaceContextImpl nsContext; + + public XmlNodeIterator(XmlNode rootNode) { + super(); + List v = new ArrayList(1); + v.add(rootNode); + stack = new FastStack(); + Iterator i = v.iterator(); + stack.push(new ElementHolder(null, i)); + this.state = START; + this.nsContext = new NamespaceContextImpl(null); + } + + public boolean hasNext() { + return !(stack.empty() || (state == END && stack.peek().parent == null)); + } + + public XmlNode next() { + this.state = START; + ElementHolder element = stack.peek(); + Iterator it = element.children; + if (it == null || (!it.hasNext())) { + // End of the children, return END event of parent + stack.pop(); + this.state = END; + this.nsContext = (NamespaceContextImpl)nsContext.getParent(); + return element.parent; + } + XmlNode node = it.next(); + stack.push(new ElementHolder(node, node.children())); + this.nsContext = new NamespaceContextImpl(this.nsContext); + populateNamespaces(node); + return node; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public int getState() { + return state; + } + + public NamespaceContext getNamespaceContext() { + return nsContext; + } + + private void populateNamespaces(XmlNode element) { + if (element.getName() != null) { + if (element.namespaces() != null) { + for (Map.Entry e : element.namespaces().entrySet()) { + nsContext.register(e.getKey(), e.getValue()); + } + } + } + } + + private static class ElementHolder { + private XmlNode parent; + private Iterator children; + + public ElementHolder(XmlNode parent, Iterator children) { + this.parent = parent; + this.children = children; + } + } + + private static class NamespaceContextImpl implements NamespaceContext { + private NamespaceContext parent; + private Map map = new HashMap(); + + /** + * @param parent + */ + public NamespaceContextImpl(NamespaceContext parent) { + super(); + this.parent = parent; + if (parent == null) { + map.put("xml", "http://www.w3.org/XML/1998/namespace"); + map.put("xmlns", "http://www.w3.org/2000/xmlns/"); + } + } + + public String getNamespaceURI(String prefix) { + if (prefix == null) { + throw new IllegalArgumentException("Prefix is null"); + } + + String ns = (String)map.get(prefix); + if (ns != null) { + return ns; + } + if (parent != null) { + return parent.getNamespaceURI(prefix); + } + return null; + } + + public String getPrefix(String nsURI) { + if (nsURI == null) + throw new IllegalArgumentException("Namespace is null"); + for (Iterator> i = map.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = i.next(); + if (entry.getValue().equals(nsURI)) { + return entry.getKey(); + } + } + if (parent != null) { + return parent.getPrefix(nsURI); + } + return null; + } + + public Iterator getPrefixes(String nsURI) { + List prefixList = new ArrayList(); + for (Iterator> i = map.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = i.next(); + if (entry.getValue().equals(nsURI)) { + prefixList.add(entry.getKey()); + } + } + final Iterator currentIterator = prefixList.iterator(); + final Iterator parentIterator = parent != null ? null : parent.getPrefixes(nsURI); + return new Iterator() { + + public boolean hasNext() { + return currentIterator.hasNext() || (parentIterator != null && parentIterator.hasNext()); + } + + public Object next() { + if (!hasNext()) { + throw new IllegalStateException("End of iterator has reached"); + } + return currentIterator.hasNext() ? currentIterator.next() : parentIterator.next(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + + } + + public void register(String prefix, String ns) { + map.put(prefix, ns); + } + + public NamespaceContext getParent() { + return parent; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(map.toString()); + if (parent != null) { + sb.append("\nParent: "); + sb.append(parent); + } + return sb.toString(); + } + } + + /** + * An implementation of the {@link java.util.Stack} API that is based on an ArrayList instead of a + * Vector, so it is not synchronized to protect against multi-threaded access. The implementation is + * therefore operates faster in environments where you do not need to worry about multiple thread contention. + *

          + * The removal order of an ArrayStack is based on insertion order: The most recently added element is + * removed first. The iteration order is not the same as the removal order. The iterator returns elements + * from the bottom up, whereas the {@link #remove()} method removes them from the top down. + *

          + * Unlike Stack, ArrayStack accepts null entries. + */ + public static class FastStack extends ArrayList { + + /** Ensure Serialization compatibility */ + private static final long serialVersionUID = 2130079159931574599L; + + /** + * Constructs a new empty ArrayStack. The initial size is controlled by ArrayList + * and is currently 10. + */ + public FastStack() { + super(); + } + + /** + * Constructs a new empty ArrayStack with an initial size. + * + * @param initialSize the initial size to use + * @throws IllegalArgumentException if the specified initial size is negative + */ + public FastStack(int initialSize) { + super(initialSize); + } + + /** + * Return true if this stack is currently empty. + *

          + * This method exists for compatibility with java.util.Stack. New users of this class should use + * isEmpty instead. + * + * @return true if the stack is currently empty + */ + public boolean empty() { + return isEmpty(); + } + + /** + * Returns the top item off of this stack without removing it. + * + * @return the top item on the stack + * @throws EmptyStackException if the stack is empty + */ + public T peek() throws EmptyStackException { + int n = size(); + if (n <= 0) { + throw new EmptyStackException(); + } else { + return get(n - 1); + } + } + + /** + * Returns the n'th item down (zero-relative) from the top of this stack without removing it. + * + * @param n the number of items down to go + * @return the n'th item on the stack, zero relative + * @throws EmptyStackException if there are not enough items on the stack to satisfy this request + */ + public T peek(int n) throws EmptyStackException { + int m = (size() - n) - 1; + if (m < 0) { + throw new EmptyStackException(); + } else { + return get(m); + } + } + + /** + * Pops the top item off of this stack and return it. + * + * @return the top item on the stack + * @throws EmptyStackException if the stack is empty + */ + public T pop() throws EmptyStackException { + int n = size(); + if (n <= 0) { + throw new EmptyStackException(); + } else { + return remove(n - 1); + } + } + + /** + * Pushes a new item onto the top of this stack. The pushed item is also returned. This is equivalent to calling + * add. + * + * @param item the item to be added + * @return the item just pushed + */ + public Object push(T item) { + add(item); + return item; + } + + /** + * Returns the top-most index for the object in the stack + * + * @param object the object to be searched for + * @return top-most index, or -1 if not found + */ + public int search(T object) { + int i = size() - 1; // Current index + while (i >= 0) { + T current = get(i); + if ((object == null && current == null) || (object != null && object.equals(current))) { + return i; + } + i--; + } + return -1; + } + + /** + * Returns the element on the top of the stack. + * + * @return the element on the top of the stack + * @throws EmptyStackException if the stack is empty + */ + public T get() { + int size = size(); + if (size == 0) { + throw new EmptyStackException(); + } + return get(size - 1); + } + + /** + * Removes the element on the top of the stack. + * + * @return the removed element + * @throws EmptyStackException if the stack is empty + */ + public T remove() { + int size = size(); + if (size == 0) { + throw new EmptyStackException(); + } + return remove(size - 1); + } + + } + +} diff --git a/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlTreeStreamReaderImpl.java b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlTreeStreamReaderImpl.java new file mode 100644 index 0000000000..3c4c1bdb06 --- /dev/null +++ b/java/sca/modules/common-xml/src/main/java/org/apache/tuscany/sca/common/xml/stax/reader/XmlTreeStreamReaderImpl.java @@ -0,0 +1,531 @@ +/* + * 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.common.xml.stax.reader; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +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; + +/** + * + * @version $Rev$ $Date$ + */ +public class XmlTreeStreamReaderImpl implements XMLStreamReader { + + protected int state; + protected XmlNodeIterator iterator; + protected XmlNode current; + + protected XMLStreamReader reader; + + /* + * we need to pass in a namespace context since when delegated, we've no + * idea of the current namespace context. So it needs to be passed on here! + */ + public XmlTreeStreamReaderImpl(XmlNode root) { + this.iterator = new XmlNodeIterator(root); + this.current = null; + this.state = START_DOCUMENT; + this.reader = null; + } + + public void close() throws XMLStreamException { + if (reader != null) { + reader.close(); + } + } + + private void checkElementState() { + if (getEventType() != START_ELEMENT && getEventType() != END_ELEMENT) { + throw new IllegalStateException(); + } + } + + private List getAttributes() { + if (current != null && current.attributes() != null) { + return current.attributes(); + } else { + return Collections.emptyList(); + } + } + + public int getAttributeCount() { + checkElementState(); + if (reader != null) { + return reader.getAttributeCount(); + } + return getAttributes().size(); + } + + public String getAttributeLocalName(int i) { + checkElementState(); + if (reader != null) { + return reader.getAttributeLocalName(i); + } + return getAttributes().get(i).getName().getLocalPart(); + } + + /** + * @param i + */ + public QName getAttributeName(int i) { + checkElementState(); + if (reader != null) { + return reader.getAttributeName(i); + } + return getAttributes().get(i).getName(); + } + + public String getAttributeNamespace(int i) { + checkElementState(); + if (reader != null) { + return reader.getAttributeNamespace(i); + } + return getAttributes().get(i).getName().getNamespaceURI(); + } + + public String getAttributePrefix(int i) { + checkElementState(); + if (reader != null) { + return reader.getAttributePrefix(i); + } + return getAttributes().get(i).getName().getPrefix(); + } + + public String getAttributeType(int i) { + if (reader != null) { + return reader.getAttributeType(i); + } + return null; // not supported + } + + public String getAttributeValue(int i) { + checkElementState(); + if (reader != null) { + return reader.getAttributeValue(i); + } + return getAttributes().get(i).getValue(); + } + + public String getAttributeValue(String nsUri, String localName) { + checkElementState(); + if (reader != null) { + return reader.getAttributeValue(nsUri, localName); + } + int count = getAttributeCount(); + String value = null; + QName attrQName; + for (int i = 0; i < count; i++) { + attrQName = getAttributeName(i); + if (nsUri == null) { + if (localName.equals(attrQName.getLocalPart())) { + value = getAttributeValue(i); + break; + } + } else { + if (localName.equals(attrQName.getLocalPart()) && nsUri.equals(attrQName.getNamespaceURI())) { + value = getAttributeValue(i); + break; + } + } + + } + + return value; + } + + public String getCharacterEncodingScheme() { + if (reader != null) { + return reader.getCharacterEncodingScheme(); + } + return "UTF-8"; + } + + public String getElementText() throws XMLStreamException { + checkElementState(); + if (reader != null) { + return reader.getElementText(); + } + return current.getValue(); + } + + public String getEncoding() { + if (reader != null) { + return reader.getEncoding(); + } + return "UTF-8"; + } + + public int getEventType() { + return state; + } + + public String getLocalName() { + checkElementState(); + if (reader != null) { + return reader.getLocalName(); + } + return current.getName().getLocalPart(); + } + + /** + */ + public Location getLocation() { + if (reader != null) { + return reader.getLocation(); + } + // return a default location + return new Location() { + public int getCharacterOffset() { + return 0; + } + + public int getColumnNumber() { + return 0; + } + + public int getLineNumber() { + return 0; + } + + public String getPublicId() { + return null; + } + + public String getSystemId() { + return null; + } + }; + } + + public QName getName() { + checkElementState(); + if (reader != null) { + return reader.getName(); + } + return current.getName(); + } + + public NamespaceContext getNamespaceContext() { + if (reader != null) { + return reader.getNamespaceContext(); + } + return iterator.getNamespaceContext(); + } + + private Map getNamespaces() { + if (current != null && current.namespaces() != null) { + return current.namespaces(); + } else { + return Collections.emptyMap(); + } + } + + public int getNamespaceCount() { + checkElementState(); + if (reader != null) { + return reader.getNamespaceCount(); + } + return getNamespaces().size(); + } + + /** + * @param i + */ + public String getNamespacePrefix(int i) { + checkElementState(); + if (reader != null) { + return reader.getNamespacePrefix(i); + } + return new ArrayList>(getNamespaces().entrySet()).get(i).getKey(); + } + + public String getNamespaceURI() { + checkElementState(); + if (reader != null) { + return reader.getNamespaceURI(); + } + return current.getName().getNamespaceURI(); + } + + public String getNamespaceURI(int i) { + checkElementState(); + if (reader != null) { + return reader.getNamespaceURI(i); + } + return new ArrayList>(getNamespaces().entrySet()).get(i).getValue(); + } + + public String getNamespaceURI(String prefix) { + if (reader != null) { + return reader.getNamespaceURI(prefix); + } + return getNamespaceContext().getNamespaceURI(prefix); + } + + public String getPIData() { + if (reader != null) { + return reader.getPIData(); + } + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPITarget() { + if (reader != null) { + return reader.getPITarget(); + } + throw new UnsupportedOperationException("Yet to be implemented !!"); + } + + public String getPrefix() { + if (reader != null) { + return reader.getPrefix(); + } + if (state == START_ELEMENT || state == END_ELEMENT) { + String prefix = current.getName().getPrefix(); + return "".equals(prefix) ? null : prefix; + } else if (state == START_DOCUMENT) { + return null; + } else { + throw new IllegalStateException("State==" + state); + } + } + + /** + * @param key + * @throws IllegalArgumentException + */ + public Object getProperty(String key) throws IllegalArgumentException { + if (reader != null) { + return reader.getProperty(key); + } + return null; + } + + public String getText() { + if (reader != null) { + return reader.getText(); + } + return current.getValue(); + } + + public char[] getTextCharacters() { + if (reader != null) { + return reader.getTextCharacters(); + } + String value = current.getValue(); + return value == null ? new char[0] : value.toCharArray(); + } + + private int copy(int sourceStart, char[] target, int targetStart, int length) { + char[] source = getTextCharacters(); + if (sourceStart > source.length) { + throw new IndexOutOfBoundsException("source start > source length"); + } + int sourceLen = source.length - sourceStart; + if (length > sourceLen) { + length = sourceLen; + } + System.arraycopy(source, sourceStart, target, targetStart, length); + return sourceLen; + } + + public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException { + if (reader != null) { + return reader.getTextCharacters(i, chars, i1, i2); + } + return copy(i, chars, i1, i2); + } + + public int getTextLength() { + if (reader != null) { + return reader.getTextLength(); + } + return getTextCharacters().length; + } + + public int getTextStart() { + if (reader != null) { + return reader.getTextStart(); + } + return 0; + } + + public String getVersion() { + return "1.0"; + } + + public boolean hasName() { + if (reader != null) { + return reader.hasName(); + } + return current.getName() != null; + } + + /** + * @throws XMLStreamException + */ + public boolean hasNext() throws XMLStreamException { + return iterator.hasNext() || state != END_DOCUMENT || (reader != null && reader.hasNext()); + } + + public boolean hasText() { + if (reader != null) { + return reader.hasText(); + } + return current.getType() == XmlNode.Type.CHARACTERS; + } + + public boolean isAttributeSpecified(int i) { + if (reader != null) { + return reader.isAttributeSpecified(i); + } + return false; // not supported + } + + public boolean isCharacters() { + if (reader != null) { + return reader.isCharacters(); + } + return current.getType() == XmlNode.Type.CHARACTERS; + } + + public boolean isEndElement() { + if (reader != null) { + return reader.isEndElement(); + } + return getEventType() == END_ELEMENT; + } + + public boolean isStandalone() { + return true; + } + + public boolean isStartElement() { + if (reader != null) { + return reader.isStartElement(); + } + return getEventType() == START_ELEMENT; + } + + public boolean isWhiteSpace() { + if (reader != null) { + return reader.isWhiteSpace(); + } + return false; + } + + /** + * By far this should be the most important method in this class this method + * changes the state of the parser + */ + public int next() throws XMLStreamException { + if (!hasNext()) { + throw new IllegalStateException("No more events"); + } + if (reader != null) { + if (!reader.hasNext()) { + this.reader = null; + } else { + // Go to the delegation mode + state = reader.next(); + return state; + } + } + if (!iterator.hasNext()) { + state = END_DOCUMENT; + current = null; + return state; + } + current = iterator.next(); + XmlNode.Type type = current.getType(); + + int itState = iterator.getState(); + if (itState == XmlNodeIterator.END) { + if (type == XmlNode.Type.ELEMENT) { + state = END_ELEMENT; + } else { + // Ignore the pop + state = next(); + } + } + if (itState == XmlNodeIterator.START) { + if (type == XmlNode.Type.ELEMENT) { + state = START_ELEMENT; + } else if (type == XmlNode.Type.CHARACTERS) { + state = CHARACTERS; + } else if (type == XmlNode.Type.READER) { + XMLStreamReader value = current.getValue(); + this.reader = new WrappingXMLStreamReader(value); + state = reader.getEventType(); + return state; + } + } + return state; + } + + /** + * TODO implement this + * + * @throws XMLStreamException + */ + public int nextTag() throws XMLStreamException { + while (true) { + int event = next(); + if (event == START_ELEMENT || event == END_ELEMENT) { + return event; + } + } + } + + public void require(int i, String ns, String localPart) throws XMLStreamException { + if (reader != null) { + reader.require(i, ns, localPart); + return; + } + int event = getEventType(); + if (event != i) { + throw new IllegalStateException("Event type is " + event + " (!=" + i + ")"); + } + QName name = getName(); + String ns1 = name.getNamespaceURI(); + String localName1 = name.getLocalPart(); + + if (ns != null && !ns.equals(ns1)) { + throw new IllegalStateException("Namespace URI is " + ns1 + " (!=" + ns + ")"); + } + + if (localPart != null && !localPart.equals(localName1)) { + throw new IllegalStateException("Local name is " + localName1 + " (!=" + localPart + ")"); + } + + } + + public boolean standaloneSet() { + return true; + } + +} diff --git a/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderTestCase.java b/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderTestCase.java index 4063314f3e..494e053e98 100644 --- a/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderTestCase.java +++ b/java/sca/modules/common-xml/src/test/java/org/apache/tuscany/sca/common/xml/stax/XmlTreeStreamReaderTestCase.java @@ -34,6 +34,10 @@ import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; +import org.apache.tuscany.sca.common.xml.stax.impl.XMLStreamSerializer; +import org.apache.tuscany.sca.common.xml.stax.reader.XmlNode; +import org.apache.tuscany.sca.common.xml.stax.reader.XmlNodeIterator; +import org.apache.tuscany.sca.common.xml.stax.reader.XmlTreeStreamReaderImpl; import org.custommonkey.xmlunit.XMLAssert; import org.junit.Assert; import org.junit.Before; @@ -154,35 +158,35 @@ public class XmlTreeStreamReaderTestCase { private Object value = "123"; /** - * @see org.apache.tuscany.sca.databinding.xml.XmlNode#attributes() + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#attributes() */ public List attributes() { return attrs; } /** - * @see org.apache.tuscany.sca.databinding.xml.XmlNode#children() + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#children() */ public Iterator children() { return children.iterator(); } /** - * @see org.apache.tuscany.sca.databinding.xml.XmlNode#getName() + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getName() */ public QName getName() { return name; } /** - * @see org.apache.tuscany.sca.databinding.xml.XmlNode#getValue() + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#getValue() */ public T getValue() { return (T)value; } /** - * @see org.apache.tuscany.sca.databinding.xml.XmlNode#namespaces() + * @see org.apache.tuscany.sca.common.xml.stax.reader.databinding.xml.XmlNode#namespaces() */ public Map namespaces() { return namespaces; -- cgit v1.2.3