You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by fr...@apache.org on 2007/02/05 23:53:35 UTC
svn commit: r503913 [1/2] - in /incubator/tuscany/java/sdo/impl/src:
main/java/org/apache/tuscany/sdo/helper/
main/java/org/apache/tuscany/sdo/impl/ main/java/org/apache/tuscany/sdo/util/
main/java/org/apache/tuscany/sdo/util/resource/ test/java/org/ap...
Author: frankb
Date: Mon Feb 5 14:53:34 2007
New Revision: 503913
URL: http://svn.apache.org/viewvc?view=rev&rev=503913
Log:
Fix for TUSCANY-1082
Added:
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StreamDeserializer.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/ChangeSummaryStreamDeserializer.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/RecordedEventXMLStreamReader.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDODeserializer.java
Modified:
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/impl/ChangeSummaryImpl.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StAX2SAXAdapter.java
incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java
incubator/tuscany/java/sdo/impl/src/test/java/org/apache/tuscany/sdo/test/ChangeSummaryPropertyTestCase.java
incubator/tuscany/java/sdo/impl/src/test/java/org/apache/tuscany/sdo/test/XMLStreamHelperTestCase.java
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java Mon Feb 5 14:53:34 2007
@@ -40,17 +40,17 @@
private XMLHelper xmlHelper;
private XSDHelper xsdHelper;
-
- public HelperContextImpl() {
+ public HelperContextImpl(ExtendedMetaData extendedMetaData) {
+ typeHelper = new TypeHelperImpl(extendedMetaData);
- EPackage.Registry registry = new EPackageRegistryImpl(EPackage.Registry.INSTANCE);
- ExtendedMetaData extendedMetaData = new SDOExtendedMetaDataImpl(registry); //TODO create subclass that makes demand() methods synchronous
- typeHelper = new TypeHelperImpl(extendedMetaData);
-
- dataFactory = new DataFactoryImpl(typeHelper);
- xmlHelper = new XMLHelperImpl(typeHelper);
- xsdHelper = new XSDHelperImpl(typeHelper);
- }
+ dataFactory = new DataFactoryImpl(typeHelper);
+ xmlHelper = new XMLHelperImpl(typeHelper);
+ xsdHelper = new XSDHelperImpl(typeHelper);
+ }
+
+ public HelperContextImpl() {
+ this(new SDOExtendedMetaDataImpl(new EPackageRegistryImpl(EPackage.Registry.INSTANCE))); //TODO create subclass that makes demand() methods synchronous
+ }
public CopyHelper getCopyHelper() {
return CopyHelper.INSTANCE;
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java Mon Feb 5 14:53:34 2007
@@ -222,9 +222,9 @@
load(inputSource, locationURI, options);
}
- protected void load(XMLStreamReader reader) throws IOException
+ protected final void load(XMLStreamReader reader, Map options) throws IOException
{
- ((SDOXMLResourceImpl)resource).load(reader, null);
+ ((SDOXMLResourceImpl)resource).load(reader, options);
initLoadedRoot();
}
@@ -275,6 +275,8 @@
break;
}
} //for
+ if (rootObject == null)
+ rootObject = ((SDOXMLResourceImpl) resource).root;
}
else
{
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java Mon Feb 5 14:53:34 2007
@@ -19,6 +19,7 @@
*/
package org.apache.tuscany.sdo.helper;
+import java.util.Map;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
@@ -71,6 +72,25 @@
* @throws IllegalStateException if the reader is not positioned on a START_ELEMENT event
*/
DataObject loadObject(XMLStreamReader reader) throws XMLStreamException, IllegalStateException;
+
+ /**
+ * Default Type to load DataObject if the element is unqualified/local without xsi:type
+ * or the qualified/global element or xsi:type fail to resolve.
+ * Can be null.
+ */
+ String OPTION_DEFAULT_ROOT_TYPE = "default root type";
+
+ /**
+ * Create a DataObject from an element in a XML stream.
+ * The reader must be positioned on a START_ELEMENT event.
+ *
+ * @param reader the stream to read
+ * @param options {@link OPTION_DEFAULT_ROOT_TYPE}; can be null or empty
+ * @return a DataObject created from the element in the stream
+ * @throws XMLStreamException if there was a problem reading the stream
+ * @throws IllegalStateException if the reader is not positioned on a START_ELEMENT event
+ */
+ DataObject loadObject(XMLStreamReader reader, Map options) throws XMLStreamException, IllegalStateException;
/**
* Save a DataObject to an XML stream.
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java Mon Feb 5 14:53:34 2007
@@ -19,6 +19,7 @@
*/
package org.apache.tuscany.sdo.helper;
+import java.util.Map;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
@@ -51,7 +52,7 @@
if (reader.getEventType() != XMLStreamConstants.START_DOCUMENT)
throw new IllegalStateException();
- return loadDocument(reader);
+ return loadDocument(reader, null);
}
public void save(XMLDocument document, XMLStreamWriter writer) throws XMLStreamException
@@ -68,7 +69,7 @@
}
- public DataObject loadObject(XMLStreamReader reader) throws XMLStreamException, IllegalStateException
+ public final DataObject loadObject(XMLStreamReader reader, Map options) throws XMLStreamException, IllegalStateException
{
if (reader.getEventType() != XMLStreamConstants.START_ELEMENT)
throw new IllegalStateException();
@@ -77,7 +78,12 @@
// Wrap the reader so it represents a document
reader = new XMLDocumentStreamReader(reader);
- return loadDocument(reader).getRootObject();
+ return loadDocument(reader, options).getRootObject();
+ }
+
+ public DataObject loadObject(XMLStreamReader reader) throws XMLStreamException, IllegalStateException
+ {
+ return loadObject(reader, null);
}
public void saveObject(DataObject sdo, XMLStreamWriter writer) throws XMLStreamException
@@ -106,11 +112,11 @@
return new DataObjectXMLStreamReader(dataObject, rootElementURI, rootElementName, typeHelper);
}
- protected XMLDocument loadDocument(XMLStreamReader reader) throws XMLStreamException
+ protected XMLDocument loadDocument(XMLStreamReader reader, Map options) throws XMLStreamException
{
try {
XMLDocumentImpl document = new XMLDocumentImpl(typeHelper.extendedMetaData, null);
- document.load(reader);
+ document.load(reader, options);
return document;
}
catch (Exception e) {
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/impl/ChangeSummaryImpl.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/impl/ChangeSummaryImpl.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/impl/ChangeSummaryImpl.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/impl/ChangeSummaryImpl.java Mon Feb 5 14:53:34 2007
@@ -751,9 +751,11 @@
{
//TODO: Fix this method. Currently, it has the side effect of undoing the unset of contained children references
// of root deleted objects - i.e., when featureChange.apply(oldDataObject) is called.
+ //
+ List changes = (List) getObjectChanges().get(dataObject);
+ if (changes == null)
+ return dataObject;
EObject oldDataObject = EcoreUtil.copy((EObject)dataObject);
-
- List changes = (List)getObjectChanges().get(dataObject);
for (Iterator fIter = changes.iterator(); fIter.hasNext(); )
{
FeatureChange featureChange = (FeatureChange)fIter.next();
Modified: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StAX2SAXAdapter.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StAX2SAXAdapter.java?view=diff&rev=503913&r1=503912&r2=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StAX2SAXAdapter.java (original)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StAX2SAXAdapter.java Mon Feb 5 14:53:34 2007
@@ -119,7 +119,7 @@
case XMLStreamConstants.END_ELEMENT:
handleEndElement(reader, handler);
level--;
- if (level == 0) {
+ if (level == 1) {
return;
}
break;
Added: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StreamDeserializer.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StreamDeserializer.java?view=auto&rev=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StreamDeserializer.java (added)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/StreamDeserializer.java Mon Feb 5 14:53:34 2007
@@ -0,0 +1,74 @@
+/**
+ *
+ * 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.sdo.util;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.*;
+
+import org.apache.tuscany.sdo.util.resource.RecordedEventXMLStreamReader;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.util.*;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xml.type.internal.QName;
+
+/**
+ * StAX Deserializer. The instance isn't thread-safe, however it's safe to use the instance any times on the same thread.
+ */
+public class StreamDeserializer implements XMLStreamConstants {
+ protected XMLStreamReader reader;
+
+ protected final XMLStreamReader play(RecordedEventXMLStreamReader.Tag tag) {
+ return tag.play(reader);
+ }
+
+ protected String nameSpace, name;
+
+ protected final boolean typedXSI() {
+ name = reader.getAttributeValue(ExtendedMetaData.XSI_URI, XMLResource.TYPE);
+ if (name == null)
+ return false;
+ int index = name.indexOf(':');
+ if (index == -1)
+ nameSpace = reader.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX); // may be XMLConstants.NULL_NS_URI
+ else {
+ nameSpace = reader.getNamespaceURI(name.substring(0, index));
+ name = name.substring(++index);
+ }
+ return true;
+ }
+
+ static protected Object value(Object type, String literal, NamespaceContext nameSpaces) {
+ Object value = EcoreUtil.createFromString((EDataType) type, literal);
+ if (!(value instanceof QName))
+ return value;
+ QName qName = (QName) value;
+ qName.setNamespaceURI(nameSpaces.getNamespaceURI(qName.getPrefix()));
+ return value;
+ }
+
+ static public class Attribute {
+ public String name, value;
+ }
+
+ static public final class QualifiedAttribute extends Attribute {
+ public String nameSpace;
+ }
+}
\ No newline at end of file
Added: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/ChangeSummaryStreamDeserializer.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/ChangeSummaryStreamDeserializer.java?view=auto&rev=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/ChangeSummaryStreamDeserializer.java (added)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/ChangeSummaryStreamDeserializer.java Mon Feb 5 14:53:34 2007
@@ -0,0 +1,579 @@
+/**
+ *
+ * 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.sdo.util.resource;
+
+import java.util.*;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.*;
+
+import commonj.sdo.*;
+import commonj.sdo.helper.HelperContext;
+
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.change.*;
+import org.apache.tuscany.sdo.SDOFactory;
+import org.apache.tuscany.sdo.helper.SDOAnnotations;
+import org.apache.tuscany.sdo.impl.*;
+
+/**
+ * ChangeSummary StAX Deserializer whose input conforms to the SDO Java/C++/PHP specifications. The instance isn't thread-safe, however it's safe to
+ * use the instance any times on the same thread.
+ */
+public class ChangeSummaryStreamDeserializer extends SDODeserializer {
+ static final class ForwardReference {
+ String ref, unset;
+
+ Collection attributes/* = null */, qualifiedAttributes/* = null */, tags/* = null */; // may be null, never empty
+
+ NamespaceContext nameSpaces;
+ }
+
+ protected Collection forwardReferences/* = null */;
+
+ static private final class ElementChange {
+ private Object property;
+
+ private String ref;
+ }
+
+ static private class PropertyMapChanges {
+ Map/* Property,List */lists/* = null */;// may be null
+
+ Collection put(Object property) {
+ Collection list = new ArrayList();
+ lists.put(property, list);
+ return list;
+ }
+
+ protected final Collection get(Object property) {
+ Object list = lists.get(property);
+ return list == null ? put(property) : (Collection) list;
+ }
+
+ protected final Collection newList(Object property) {
+ lists = new HashMap();
+ return put(property);
+ }
+ }
+
+ static final class ObjectChanges extends PropertyMapChanges {
+ Collection elementChanges/* = null */,// may be null, never empty
+ featureChanges;
+
+ protected final void newElementChanges() {
+ elementChanges = new ArrayList();
+ }
+ }
+
+ Collection objectChangesCollection/* = null */, objectMapChanges, deletedDataObjects;
+
+ protected final ObjectChanges newObjectChanges(Collection featureChanges) {
+ ObjectChanges objectChanges = new ObjectChanges();
+ objectChanges.featureChanges = featureChanges;
+ if (objectChangesCollection == null)
+ objectChangesCollection = new ArrayList();
+ objectChangesCollection.add(objectChanges);
+ return objectChanges;
+ }
+
+ private ChangeFactory changeFactory;
+
+ private SDOFactory changeSettingFactory;
+
+ private void logPropertyChange(Collection featureChanges, Object property, Object value, boolean set) {
+ EStructuralFeature feature = (EStructuralFeature) property;
+ if (changeSettingFactory == null)
+ featureChanges.add(changeFactory.createFeatureChange(feature, value, set));
+ else
+ featureChanges.add(changeSettingFactory.createChangeSummarySetting(feature, value, set));
+ }
+
+ void unsetProperty(Collection featureChanges, String unset, int begin, int index, Type type) {
+ logPropertyChange(featureChanges, type.getProperty(unset.substring(begin, index)), null, false);
+ }
+
+ static boolean isWhitespace(String unset, int index) {
+ return Character.isWhitespace(unset.charAt(index));
+ }
+
+ protected final Collection unsetProperties(EObject referent, String unset, Type type) {
+ Map.Entry entry = changeFactory.createEObjectToChangesMapEntry(referent);
+ objectMapChanges.add(entry);
+ Collection featureChanges = (Collection) entry.getValue();
+ if (unset == null)
+ return featureChanges;
+ int end = unset.length();
+ if (end != 0)
+ for (int begin = 0, index = 1;/* true */; ++index) {
+ if (index == end) {
+ unsetProperty(featureChanges, unset, begin, index, type);
+ break;
+ }
+ if (isWhitespace(unset, index)) {
+ unsetProperty(featureChanges, unset, begin, index, type);
+ while (true) {
+ if (++index != end)
+ return featureChanges;
+ if (!isWhitespace(unset, index)) {
+ begin = index;
+ break;
+ }
+ }
+ }
+ }
+ return featureChanges;
+ }
+
+ private void logPropertyChange(Collection featureChanges, Object property, Object value) {
+ logPropertyChange(featureChanges, property, value, true);
+ }
+
+ void logAttributeChange(Collection featureChanges, Property property, String literal, NamespaceContext nameSpaces) {
+ if (property != null)
+ logPropertyChange(featureChanges, property, value(property.getType(), literal, nameSpaces));
+ // else report error?
+ }
+
+ protected final void logAttributeChange(Collection featureChanges, String property, Type type, String value, NamespaceContext nameSpaces) {
+ logAttributeChange(featureChanges, type.getProperty(property), value, nameSpaces);
+ }
+
+ protected final void logAttributeChange(Collection featureChanges, String nameSpace, String name, Type type, String value,
+ NamespaceContext nameSpaces) {
+ logAttributeChange(featureChanges, getProperty(type, nameSpace, name), value, nameSpaces);
+ }
+
+ protected final String ref() {
+ return reader.getAttributeValue(SDOAnnotations.COMMONJ_SDO_NS, ChangeSummaryStreamSerializer.REF_ATTRIBUTE);
+ }
+
+ ChangeSummaryImpl changeSummary;
+
+ protected Object load(XMLStreamReader reader, Map options) throws XMLStreamException {
+ Object value = super.load(reader, options);
+ deletedDataObjects.add(value);
+ return value;
+ }
+
+ protected final void getChangeSummary(DataObject rootObject) {
+ changeSummary = (ChangeSummaryImpl) rootObject.getChangeSummary(); // DynamicDataObjectImpl(EClass)
+ }
+
+ static protected final class Tag extends RecordedEventXMLStreamReader.Tag {
+ protected String ref;
+
+ protected Object value;
+
+ protected Tag(XMLStreamReader reader) {
+ super(reader);
+ }
+ }
+
+ protected boolean logging;
+
+ /**
+ * Imports ChangeSummary 2-1. Forward references will be resolved by {@link #end()}.
+ *
+ * @param reader
+ * Never null
+ * @throws XMLStreamException
+ */
+ public final void begin(DataObject rootObject, HelperContext scope, XMLStreamReader reader) throws XMLStreamException {
+ /*
+ * 3-1. Instantiate ChangeSummary input: reader (xsi:type), factory, rootObject output: changeSummary, changeDescription
+ */
+ initialize(reader, scope, rootObject);
+ if (typedXSI()) {
+ changeSummary = (ChangeSummaryImpl) scope.getDataFactory().create(nameSpace, name);
+ if (changeSummary == null)
+ getChangeSummary(rootObject);
+ else {
+ Property csp = ((ClassImpl) rootObject.getType()).getChangeSummaryProperty();
+ rootObject.set(csp, changeSummary);
+ changeSummary.setDataObject(rootObject);
+ }
+ } else
+ getChangeSummary(rootObject);
+ ChangeDescription changeDescription = (ChangeDescription) changeSummary;
+
+ /*
+ * 3-2. "logging" attribute input: reader output: logging
+ */
+ logging = Boolean.valueOf(reader.getAttributeValue(null, "logging")).booleanValue();
+
+ /*
+ * 3-3. Modified DataObjects input: changeDescription
+ */
+ if (forwardReferences != null)
+ forwardReferences.clear();
+ if (objectChangesCollection != null)
+ objectChangesCollection.clear();
+ if (START_ELEMENT == reader.nextTag()) {
+ objectMapChanges = changeDescription.getObjectChanges();
+ deletedDataObjects = changeDescription.getObjectsToAttach();
+ Object factory = changeDescription.eClass().getEPackage().getEFactoryInstance();
+ changeFactory = factory instanceof ChangeFactory ? (ChangeFactory) factory : ChangeFactory.eINSTANCE;
+ changeSettingFactory = factory instanceof SDOFactory ? (SDOFactory) factory : null;
+ do {
+ /*
+ * Modified DataObject
+ */
+ String ref = ref(), unset = reader.getAttributeValue(SDOAnnotations.COMMONJ_SDO_NS, ChangeSummaryStreamSerializer.UNSET);
+ int attributes = reader.getAttributeCount();
+ NamespaceContext nameSpaces = reader.getNamespaceContext();
+ EObject referent = referent(ref);
+ if (referent == null) {
+ /*
+ * Forward-referenced(unresolved) modified DataObject
+ */
+ ForwardReference forwardReference = new ForwardReference();
+ if (forwardReferences == null)
+ forwardReferences = new ArrayList();
+ forwardReferences.add(forwardReference);
+ forwardReference.ref = ref;
+ forwardReference.unset = unset;
+ forwardReference.nameSpaces = nameSpaces;
+ do // what about xmlns="NS1" a1="qName" xmlns="NS2" a2="qName" ?
+ {
+ /*
+ * Record property old value as attribute for end()
+ */
+ String nameSpace = reader.getAttributeNamespace(--attributes), name = reader.getAttributeLocalName(attributes), value = reader
+ .getAttributeValue(attributes);
+ if (nameSpace == null) {
+ /*
+ * Local attribute
+ */
+ Attribute attribute = new Attribute();
+ attribute.name = name;
+ attribute.value = value;
+ if (forwardReference.attributes == null)
+ forwardReference.attributes = new ArrayList();
+ forwardReference.attributes.add(attribute);
+ } else if (!SDOAnnotations.COMMONJ_SDO_NS.equals(nameSpace) || !ChangeSummaryStreamSerializer.REF_ATTRIBUTE.equals(name)
+ && !ChangeSummaryStreamSerializer.UNSET.equals(name)) {
+ /*
+ * Qualified(global) attribute
+ */
+ QualifiedAttribute attribute = new QualifiedAttribute();
+ attribute.name = name;
+ attribute.value = value;
+ attribute.nameSpace = nameSpace;
+ if (forwardReference.qualifiedAttributes == null)
+ forwardReference.qualifiedAttributes = new ArrayList();
+ forwardReference.qualifiedAttributes.add(attribute);
+ }
+ } while (attributes != 0);
+ while (START_ELEMENT == reader.nextTag()) {
+ /*
+ * Record property old value as element for end()
+ */
+ Tag tag = new Tag(reader);
+ if (forwardReference.tags == null)
+ forwardReference.tags = new ArrayList();
+ forwardReference.tags.add(tag);
+ tag.ref = ref();
+ if (tag.ref != null)
+ continue;
+ Type xsi = typeXSI();
+ if (xsi == null) {
+ nameSpace = tag.nameSpace;
+ if (nameSpace != null)
+ tag.value = value(globalElementType(tag.name.getLocalPart())); // TODO substitutionGroup type if null
+ else if (tag.record(reader))
+ break;
+ } else
+ tag.value = value(xsi);
+ }
+ } else {
+ /*
+ * Resolved(back-referenced) modified DataObject
+ */
+ Type type = ((DataObject) referent).getType();
+ Collection featureChanges = unsetProperties(referent, unset, type);
+ do // what about xmlns="NS1" a1="qName" xmlns="NS2" a2="qName" ?
+ {
+ /*
+ * Log property old value as attribute
+ */
+ String nameSpace = reader.getAttributeNamespace(--attributes), name = reader.getAttributeLocalName(attributes), value = reader
+ .getAttributeValue(attributes);
+ if (nameSpace == null)
+ logAttributeChange(featureChanges, name, type, value, nameSpaces);
+ else if (!SDOAnnotations.COMMONJ_SDO_NS.equals(nameSpace) || !ChangeSummaryStreamSerializer.REF_ATTRIBUTE.equals(name)
+ && !ChangeSummaryStreamSerializer.UNSET.equals(name))
+ logAttributeChange(featureChanges, nameSpace, name, type, value, nameSpaces);
+ } while (attributes != 0);
+ if (START_ELEMENT == reader.nextTag()) {
+ ObjectChanges objectChanges = null;
+ do {
+ /*
+ * Log property old value as element
+ */
+ nameSpace = reader.getNamespaceURI();
+ name = reader.getLocalName();
+ Property property = getProperty(nameSpace, name, type);
+ boolean many = property.isMany();
+ Object value;
+ ref = ref();
+ if (ref == null) {
+ /*
+ * Contained property old value
+ */
+ Type xsi = typeXSI();
+ if (xsi != null)
+ value = value(xsi);
+ else if (nameSpace == null)
+ value = value(property, reader);
+ else {
+ xsi = globalElementType(name);
+ value = value(xsi == null ? property.getType() : xsi);
+ }
+ } else {
+ /*
+ * Referenced child DataObject
+ */
+ reader.nextTag()/* END_ELEMENT */;
+ value = referent(ref);
+ if (value == null) {
+ /*
+ * Forward-referenced(unresolved) child DataObject
+ */
+ if (!many) {
+ ElementChange elementChange = new ElementChange();
+ elementChange.property = property;
+ elementChange.ref = ref;
+ if (objectChanges == null) {
+ objectChanges = newObjectChanges(featureChanges);
+ objectChanges.newElementChanges();
+ } else if (objectChanges.elementChanges == null)
+ objectChanges.newElementChanges();
+ objectChanges.elementChanges.add(elementChange);
+ continue;
+ }
+ value = ref;
+ }
+ }
+ if (many) {
+ Collection list;
+ if (objectChanges == null) {
+ objectChanges = newObjectChanges(featureChanges);
+ list = objectChanges.newList(property);
+ } else if (objectChanges.lists == null)
+ list = objectChanges.newList(property);
+ else
+ list = objectChanges.get(property);
+ list.add(value);
+ } else
+ logPropertyChange(featureChanges, property, value);
+ } while (START_ELEMENT == reader.nextTag());
+ }
+ }
+ } while (START_ELEMENT == reader.nextTag());
+ }
+ }
+
+ private Collection changeList(ChangeKind changeKind, int index, Collection listChanges) {
+ ListChange listChange = changeFactory.createListChange();
+ listChange.setKind(changeKind);
+ listChange.setIndex(index);
+ listChanges.add(listChange);
+ return listChange.getValues();
+ }
+
+ Collection add(Collection adds, int change, Collection listChanges, Object value) {
+ if (adds == null)
+ adds = changeList(ChangeKind.ADD_LITERAL, change, listChanges);
+ adds.add(value);
+ return adds;
+ }
+
+ private int remove(int change, Collection listChanges, List list, int begin, int end) {
+ Collection removes = changeList(ChangeKind.REMOVE_LITERAL, change, listChanges);
+ do
+ removes.add(list.get(begin));
+ while (++begin != end);
+ return begin;
+ }
+
+ int remove(int begin, int end, int change, Collection listChanges, List list) {
+ return begin == end ? begin : remove(change, listChanges, list, begin, end);
+ }
+
+ protected final void logManyChanges(PropertyMapChanges propertyMapChanges, Object referent, Collection featureChanges) {
+ for (Iterator lists = propertyMapChanges.lists.entrySet().iterator(); lists.hasNext();) {
+ /*
+ * Compute ListChanges out of comparision of old and new list
+ */
+ Map.Entry entry = (Map.Entry) lists.next();
+ Property property = (Property) entry.getKey();
+ Iterator values = ((Collection) entry.getValue()).iterator(); // old list
+ List list = ((DataObject) referent).getList(property); // new
+ int change = 0;
+ FeatureChange featureChange = changeSettingFactory == null ? changeFactory.createFeatureChange() : (FeatureChange) changeSettingFactory
+ .createChangeSummarySetting();
+ featureChange.setFeature((EStructuralFeature) property);
+ Collection listChanges = featureChange.getListChanges(), adds = null;
+ featureChanges.add(featureChange);
+ Type type = property.getType();
+ if (type.isDataType()) {
+ /*
+ * Log simple value changes
+ */
+ while (values.hasNext()) {
+ Object value = values.next();
+ // values.remove();
+ int index = list.indexOf(value);
+ switch (index) {
+ case -1:
+ adds = add(adds, change, listChanges, value);
+ break;
+ default:
+ remove(change, listChanges, list, 0, index);
+ case 0:
+ list = list.subList(++index, list.size());
+ adds = null;
+ }
+ ++change;
+ }
+ remove(0, list.size(), change, listChanges, list);
+ } else {
+ /*
+ * Log child DataObject changes
+ */
+ int begin = 0, end = list.size();
+ while (values.hasNext()) {
+ Object value = values.next();
+ if (value.getClass() == String.class) // final
+ {
+ value = referent((String) value);
+ if (value == null)
+ continue;// report error?
+ }
+ // values.remove();
+ for (int index = begin;/* true */; ++index)
+ if (index == end) {
+ adds = add(adds, change, listChanges, value);
+ break;
+ } else if (list.get(index) == value) // List#indexOf uses equals
+ {
+ begin = remove(begin, index, change, listChanges, list);
+ ++begin;
+ adds = null;
+ break;
+ }
+ ++change;
+ }
+ remove(begin, end, change, listChanges, list);
+ }
+ }
+ }
+
+ protected PropertyMapChanges propertyMapChanges/* = null */;
+
+ /**
+ * Imports ChangeSummary 2-2. Resolves forward references from {@link #begin} and resumes logging if necessary. If it's invoked from
+ * patching/resolving, try to make it last since logging may be turned on.
+ *
+ * @see #begin
+ */
+ public final ChangeSummary end() throws XMLStreamException {
+ if (forwardReferences != null)
+ for (Iterator iterator = forwardReferences.iterator(); iterator.hasNext();) {
+ /*
+ * Forward-referenced(unresolved) modified DataObject from begin(...)
+ */
+ ForwardReference forwardReference = (ForwardReference) iterator.next();
+ EObject referent = referent(forwardReference.ref);
+ if (referent == null)
+ continue; // report error?
+ // iterator.remove();
+ Type type = ((DataObject) referent).getType();
+ Collection featureChanges = unsetProperties(referent, forwardReference.unset, type);
+ if (forwardReference.attributes != null)
+ for (Iterator attributes = forwardReference.attributes.iterator(); attributes.hasNext();) {
+ /*
+ * Log property old value as local attribute from begin(...)
+ */
+ Attribute attribute = (Attribute) attributes.next();
+ logAttributeChange(featureChanges, attribute.name, type, attribute.value, forwardReference.nameSpaces);
+ }
+ if (forwardReference.qualifiedAttributes != null)
+ for (Iterator attributes = forwardReference.qualifiedAttributes.iterator(); attributes.hasNext();) {
+ /*
+ * Log property old value as qualified/global attribute from begin(...)
+ */
+ QualifiedAttribute attribute = (QualifiedAttribute) attributes.next();
+ logAttributeChange(featureChanges, attribute.nameSpace, attribute.name, type, attribute.value, forwardReference.nameSpaces);
+ }
+ if (forwardReference.tags != null) {
+ if (propertyMapChanges != null)
+ propertyMapChanges.lists.clear();
+ for (Iterator tags = forwardReference.tags.iterator(); tags.hasNext();) {
+ /*
+ * Log property old value as element from begin(...)
+ */
+ Tag tag = (Tag) tags.next();
+ Property property = getProperty(tag.nameSpace, tag.name.getLocalPart(), type);
+ if (tag.ref != null)
+ tag.value = referent(tag.ref);
+ // if (tag.value == null) report error?
+ else if (tag.events != null)
+ tag.value = value(property, play(tag));
+ if (property.isMany()) {
+ Collection list;
+ if (propertyMapChanges == null) {
+ propertyMapChanges = new PropertyMapChanges();
+ list = propertyMapChanges.newList(property);
+ } else
+ list = propertyMapChanges.get(property);
+ list.add(tag.value);
+ } else
+ logPropertyChange(featureChanges, property, tag.value);
+ }
+ if (propertyMapChanges != null)
+ logManyChanges(propertyMapChanges, referent, featureChanges);
+ }
+ }
+ if (objectChangesCollection != null)
+ for (Iterator iterator = objectChangesCollection.iterator(); iterator.hasNext();) {
+ /*
+ * Forward-referenced(unresolved) child DataObject from begin(...)
+ */
+ ObjectChanges objectChanges = (ObjectChanges) iterator.next();
+ if (objectChanges.elementChanges != null)
+ for (Iterator elementChanges = objectChanges.elementChanges.iterator(); elementChanges.hasNext();) {
+ ElementChange elementChange = (ElementChange) elementChanges.next();
+ Object value = referent(elementChange.ref);
+ if (value == null)
+ continue; // report error?
+ // iterator.remove();
+ logPropertyChange(objectChanges.featureChanges, elementChange.property, value);
+ }
+ if (objectChanges.lists != null)
+ logManyChanges(objectChanges, ((Map.Entry) ((EStructuralFeature.Setting) objectChanges.featureChanges).getEObject()).getKey(),
+ objectChanges.featureChanges);
+ }
+ if (logging)
+ changeSummary.resumeLogging();
+ return changeSummary;
+ }
+}
\ No newline at end of file
Added: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/RecordedEventXMLStreamReader.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/RecordedEventXMLStreamReader.java?view=auto&rev=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/RecordedEventXMLStreamReader.java (added)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/RecordedEventXMLStreamReader.java Mon Feb 5 14:53:34 2007
@@ -0,0 +1,854 @@
+/**
+ *
+ * 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.sdo.util.resource;
+
+import java.util.*;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.*;
+import javax.xml.stream.*;
+
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.xml.sax.*;
+
+/**
+ * This special purpose XMLStreamReader is used to produce a StAX event stream corresponding to a list of events
+ * recorded earlier. The recorded events are generated by the inner class RecordedEventXMLStreamReader.Tag,
+ * which records the events in either of 2 ways:
+ *
+ * 1) in conjunction with class SDOXMLLoadImpl, it records events corresponding to the SAX events being
+ * handled by the SDOXMLLoadImpl when loading XML using SDOXMLResourceImpl.
+ * 2) when Tag.record() is called (see class ChangeSummaryStreamDeserializer), it walks through and records
+ * the StAX events produced by another XMLStreamReader.
+ *
+ * This class is used by the SDO StAX-based ChangeSummaryType-property loader, class
+ * ChangeSummaryStreamDeserializer, which is inoked by and uses (for loading deleted object XML fragments)
+ * the SAX-based loader class XMLResourceImpl.
+ */
+public abstract class RecordedEventXMLStreamReader implements XMLStreamReader {
+
+ static private class Event {
+ int type;
+
+ NamespaceContext nameSpaceContext;
+
+ Location location;
+
+ protected final void initialize(XMLStreamReader reader) {
+ nameSpaceContext = reader.getNamespaceContext();
+ location = reader.getLocation();
+ }
+
+ protected final void location(final Locator locator) {
+ location = new Location() {
+ public int getCharacterOffset() {
+ return -1;
+ }
+
+ public int getColumnNumber() {
+ return locator.getColumnNumber();
+ }
+
+ public int getLineNumber() {
+ return locator.getLineNumber();
+ }
+
+ public String getPublicId() {
+ return locator.getPublicId();
+ }
+
+ public String getSystemId() {
+ return locator.getSystemId();
+ }
+ };
+ }
+ }
+
+ static class ValueEvent extends Event {
+ final String value;
+
+ protected ValueEvent(String v) {
+ value = v;
+ }
+ }
+
+ static protected class Reference extends ValueEvent {
+ final String target;
+
+ protected Reference(String name, String data) {
+ super(data);
+ target = name;
+ }
+ }
+
+ static protected final class AttributeEvent extends Reference {
+ final QName name;
+
+ final String nameSpace, prefix;
+
+ int attributes;
+
+ final boolean specified;
+
+ protected AttributeEvent(XMLStreamReader reader) {
+ super(reader.getAttributeType(0), reader.getAttributeValue(0));
+ attributes = reader.getAttributeCount();
+ name = reader.getAttributeName(0);
+ nameSpace = reader.getAttributeNamespace(0);
+ prefix = reader.getAttributePrefix(0);
+ specified = reader.isAttributeSpecified(0);
+ }
+ }
+
+ static protected final class NameSpaceEvent extends Reference {
+ int nameSpaces;
+
+ protected NameSpaceEvent(XMLStreamReader reader) {
+ super(reader.getNamespacePrefix(0), reader.getNamespaceURI(0));
+ nameSpaces = reader.getNamespaceCount();
+ }
+ }
+
+ static protected String prefix(String qName, String nameSpace) {
+ int delimiter = qName.indexOf(':');
+ if (delimiter != -1)
+ return qName.substring(0, delimiter);
+ if (nameSpace.length() != 0)
+ return XMLConstants.DEFAULT_NS_PREFIX;
+ // if (nameSpaceContext.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX) != null || xsdHelper.getGlobalProperty(null, name, element) == null)
+ return null;
+ }
+
+ static class EndElement extends Event {
+ List nameSpaces/* = null */;
+
+ public final QName name;
+
+ public final String nameSpace;
+
+ final String prefix;
+
+ protected EndElement(XMLStreamReader reader) {
+ name = reader.getName();
+ nameSpace = reader.getNamespaceURI();
+ prefix = reader.getPrefix();
+ int count = reader.getNamespaceCount();
+ if (count == 0)
+ return;
+ nameSpaces = new ArrayList(count);
+ int index = 0;
+ do
+ Tag.bind(reader.getNamespacePrefix(index), reader.getNamespaceURI(index), nameSpaces);
+ while (++index != count);
+ }
+
+ protected EndElement(String uri, String local, String p, Locator locator) {
+ if (p == null) {
+ name = new QName(uri, local, XMLConstants.DEFAULT_NS_PREFIX);
+ nameSpace = null;
+ } else {
+ name = new QName(uri, local, p);
+ nameSpace = uri;
+ }
+ prefix = p;
+ location(locator);
+ }
+ }
+
+ static class NameSpace {
+ final String prefix, uri;
+
+ protected NameSpace(String p, String nameSpace) {
+ prefix = p;
+ uri = nameSpace;
+ }
+ }
+
+ static final class Attribute extends NameSpace {
+ final String type, value;
+
+ final QName qName;
+
+ boolean specified/* = false */;
+
+ protected Attribute(String t, String v, QName name, String prefix, String nameSpace) {
+ super(prefix, nameSpace);
+ type = t;
+ value = v;
+ qName = name;
+ }
+ }
+
+ static final class AttributeList /* implements Attributes */{// TODO exclude XMLConstants.XMLNS_ATTRIBUTE
+ final List attributes;
+
+ protected AttributeList(int size) {
+ attributes = new ArrayList(size);
+ }
+
+ /*
+ * @param uri Never null
+ */
+ public final int getIndex(String uri, String localName) {
+ for (int index = getLength(); index != 0;)
+ if (getLocalName(--index).equals(localName) && uri.equals(getURI(index)))
+ return index;
+ return -1;
+ }
+
+ public final int getLength() {
+ return attributes.size();
+ }
+
+ protected final Attribute attribute(int index) {
+ return (Attribute) attributes.get(index);
+ }
+
+ public final String getLocalName(int index) {
+ return attribute(index).qName.getLocalPart();
+ }
+
+ public final String getType(int index) {
+ return attribute(index).type;
+ }
+
+ /*public String getType(String uri, String localName) {
+ int index = getIndex(uri, localName);
+ return index == -1 ? null: getType(index);
+ } */
+
+ public final String getURI(int index) {
+ return attribute(index).uri;
+ }
+
+ public final String getValue(int index) {
+ return attribute(index).value;
+ }
+
+ /*
+ * @param uri Never null
+ */
+ public final String getValue(String uri, String localName) {
+ int index = getIndex(uri, localName);
+ return index == -1 ? null : getValue(index);
+ }
+ }
+
+ static protected class StartElement extends EndElement {
+ final AttributeList attributes;
+
+ protected StartElement(XMLStreamReader reader) {
+ super(reader);
+ int count = reader.getAttributeCount();
+ if (count == 0)
+ attributes = null;
+ else {
+ attributes = new AttributeList(count);
+ int index = 0;
+ do {
+ Attribute attribute = new Attribute(reader.getAttributeType(index), reader.getAttributeValue(index), reader
+ .getAttributeName(index), reader.getAttributePrefix(index), reader.getAttributeNamespace(index));
+ attribute.specified = reader.isAttributeSpecified(index);
+ attributes.attributes.add(attribute);
+ } while (++index != count);
+ }
+ }
+
+ protected StartElement(String nameSpace, String local, String prefix, Attributes attributeArray, Locator locator, List bindings,
+ final NamespaceContext context) {
+ super(nameSpace, local, prefix, locator);
+ nameSpaces = bindings;
+ nameSpaceContext = bindings == null || bindings.isEmpty() ? context : new NamespaceContext() {
+ public String getNamespaceURI(String prefix) {
+ for (int index = nameSpaces.size(); index != 0;) {
+ NameSpace binding = (NameSpace) nameSpaces.get(--index);
+ if (binding.prefix.equals(prefix))
+ return binding.uri;
+ }
+ return context.getNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI) {
+ for (int index = nameSpaces.size(); index != 0;) {
+ NameSpace binding = (NameSpace) nameSpaces.get(--index);
+ if (binding.uri.equals(namespaceURI))
+ return binding.prefix;
+ }
+ return context.getPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(final String namespaceURI) {
+ final Iterator iterator = context.getPrefixes(namespaceURI);
+ return new Iterator() {
+ Iterator bindings = nameSpaces.iterator();
+
+ NameSpace binding/* = null */;
+
+ protected final boolean prefix() {
+ while (bindings.hasNext()) {
+ binding = (NameSpace) bindings.next();
+ if (binding.uri.equals(namespaceURI))
+ return true;
+ }
+ bindings = null;
+ return false;
+ }
+
+ public boolean hasNext() {
+ return bindings != null && prefix() || iterator.hasNext();
+ }
+
+ protected NameSpace nameSpace;
+
+ public Object next() {
+ if (bindings == null || binding == null && !prefix())
+ return iterator.next();
+ nameSpace = binding;
+ binding = null;
+ return nameSpace.prefix;
+ }
+
+ public void remove() {
+ if (bindings == null)
+ iterator.remove();
+ else
+ nameSpaces.remove(nameSpace);
+ }
+ };
+ }
+ };
+ int count = attributeArray.getLength();
+ if (count == 0)
+ attributes = null;
+ else {
+ attributes = new AttributeList(count);
+ int index = 0;
+ do {
+ QName name;
+ nameSpace = attributeArray.getURI(index);
+ local = attributeArray.getLocalName(index);
+ prefix = prefix(attributeArray.getQName(index), nameSpace);
+ if (prefix == null) {
+ name = new QName(nameSpace, local, XMLConstants.DEFAULT_NS_PREFIX);
+ nameSpace = null;
+ } else
+ name = new QName(nameSpace, local, prefix);
+ attributes.attributes.add(new Attribute(attributeArray.getType(index), attributeArray.getValue(index), name, prefix, nameSpace));
+ } while (++index != count);
+ }
+ }
+ }
+
+ static public class Tag extends StartElement {
+ public Tag(XMLStreamReader reader) {
+ super(reader);
+ initialize(reader);
+ }
+
+ public List events/* = null */; // may be empty
+
+ protected final void events() {
+ events = new ArrayList();
+ }
+
+ public Tag(String nameSpace, String local, String prefix, Attributes attributes, Locator locator, NamespaceContext context, List bindings) {
+ super(nameSpace, local, prefix, attributes, locator, bindings, context);
+ events();
+ }
+
+ static public void bind(String prefix, String nameSpace, Collection nameSpaces) {
+ nameSpaces.add(new NameSpace(prefix, nameSpace));
+ }
+
+ protected int nest/* = 0 */;
+
+ public final void start(String nameSpace, String local, String qName, Attributes attributes, Locator locator, List bindings) {
+ Event event;
+ for (int index = events.size();/* true */;) {
+ if (index == 0) {
+ event = this;
+ break;
+ }
+ event = (Event) events.get(--index);
+ if (event.type != END_ELEMENT)
+ break;
+ siblings: for (int nest = 0;/* true */;)
+ switch (((Event) events.get(--index)).type) {
+ case START_ELEMENT:
+ if (nest == 0)
+ break siblings;
+ --nest;
+ break;
+ case END_ELEMENT:
+ ++nest;
+ }
+ }
+ Event start = new StartElement(nameSpace, local, prefix(qName, nameSpace), attributes, locator, bindings, event.nameSpaceContext);
+ start.type = START_ELEMENT;
+ events.add(start);
+ ++nest;
+ }
+
+ public final void text(int type, String value, Locator locator) {
+ Event event = new ValueEvent(value);
+ event.type = type;
+ event.location(locator);
+ int index = events.size();
+ event.nameSpaceContext = index == 0 ? nameSpaceContext : ((Event) events.get(--index)).nameSpaceContext;
+ events.add(event);
+ }
+
+ public final boolean end(String nameSpace, String local, String qName, Locator locator) {
+ Event end = new EndElement(nameSpace, local, prefix(qName, nameSpace), locator);
+ end.type = END_ELEMENT;
+ events.add(end);
+ if (nest == 0)
+ return true;
+ --nest;
+ return false;
+ }
+
+ public final XMLStreamReader play(final XMLResource resource) {
+ return new RecordedEventXMLStreamReader(this) {
+ public void close() {
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null; // TODO
+ }
+
+ public String getEncoding() {
+ return resource.getEncoding();
+ }
+
+ public Object getProperty(String property) {
+ return null; // TODO javax.xml.stream.notations & javax.xml.stream.entities for DTD
+ }
+
+ public String getVersion() {
+ return resource.getXMLVersion();
+ }
+
+ public boolean isStandalone() {
+ return false; // TODO
+ }
+
+ public boolean standaloneSet() {
+ return false; // TODO
+ }
+ };
+ }
+
+ protected final void add(Event event, int type, XMLStreamReader reader) {
+ event.type = type;
+ event.initialize(reader);
+ events.add(event);
+ }
+
+ public final boolean record(XMLStreamReader reader) throws XMLStreamException {
+ events();
+ for (int nest = 0; reader.hasNext();) {
+ Event event;
+ int type = reader.next();
+ switch (type) {
+ case CHARACTERS:
+ case CDATA:
+ case COMMENT:
+ case SPACE:
+ case DTD:
+ event = new ValueEvent(reader.getText());
+ break;
+ case ENTITY_REFERENCE:
+ event = new Reference(reader.getLocalName(), reader.getText());
+ break;
+ case PROCESSING_INSTRUCTION:
+ event = new Reference(reader.getPITarget(), reader.getPIData());
+ break;
+ case ATTRIBUTE:
+ event = new AttributeEvent(reader);
+ break;
+ case NAMESPACE:
+ event = new NameSpaceEvent(reader);
+ break;
+ case START_ELEMENT:
+ ++nest;
+ event = new StartElement(reader);
+ break;
+ case END_ELEMENT:
+ add(new EndElement(reader), type, reader);
+ if (nest == 0)
+ return false;
+ --nest;
+ continue;
+ case END_DOCUMENT:
+ return true; // report error?
+ default: // new type
+ event = new Event();
+ }
+ add(event, type, reader);
+ }
+ return true; // report error?
+ }
+
+ public final XMLStreamReader play(final XMLStreamReader reader) {
+ return new RecordedEventXMLStreamReader(this) {
+ public void close() throws XMLStreamException {
+ reader.close();
+ }
+
+ public String getCharacterEncodingScheme() {
+ return reader.getCharacterEncodingScheme();
+ }
+
+ public String getEncoding() {
+ return reader.getEncoding();
+ }
+
+ public Object getProperty(String property) {
+ return reader.getProperty(property); // TODO javax.xml.stream.notations & javax.xml.stream.entities for DTD
+ }
+
+ public String getVersion() {
+ return reader.getVersion();
+ }
+
+ public boolean isStandalone() {
+ return reader.isStandalone();
+ }
+
+ public boolean standaloneSet() {
+ return reader.standaloneSet();
+ }
+ };
+ }
+ }
+
+ Event event;
+
+ final List events;
+
+ final int size;
+
+ protected RecordedEventXMLStreamReader(Tag tag) {
+ event = tag;
+ tag.type = START_ELEMENT;
+ events = tag.events;
+ size = events.size();
+ }
+
+ public int getAttributeCount() {
+ switch (getEventType()) {
+ case START_ELEMENT:
+ AttributeList attributes = ((StartElement) event).attributes;
+ return attributes == null ? 0 : attributes.getLength();
+ case ATTRIBUTE:
+ return ((AttributeEvent) event).attributes;
+ }
+ throw new IllegalStateException("Neither START_ELEMENT nor ATTRIBUTE");
+ }
+
+ protected final AttributeList attributes() {
+ if (getEventType() == START_ELEMENT)
+ return ((StartElement) event).attributes;
+ throw new IllegalStateException("Neither START_ELEMENT nor ATTRIBUTE");
+ }
+
+ public String getAttributeLocalName(int index) {
+ return attributes().getLocalName(index);
+ }
+
+ static Attribute attribute(AttributeList attributes, int index) {
+ return (Attribute) attributes.attributes.get(index);
+ }
+
+ public QName getAttributeName(int index) {
+ return getEventType() == ATTRIBUTE ? ((AttributeEvent) event).name : attribute(attributes(), index).qName;
+ }
+
+ public String getAttributeNamespace(int index) {
+ return getEventType() == ATTRIBUTE ? ((AttributeEvent) event).nameSpace : attributes().getURI(index);
+ }
+
+ public String getAttributePrefix(int index) {
+ return getEventType() == ATTRIBUTE ? ((AttributeEvent) event).prefix : attribute(attributes(), index).prefix;
+ }
+
+ public String getAttributeType(int index) {
+ return getEventType() == ATTRIBUTE ? ((Reference) event).target : attributes().getType(index);
+ }
+
+ public String getAttributeValue(int index) {
+ return getEventType() == ATTRIBUTE ? ((ValueEvent) event).value : attributes().getValue(index);
+ }
+
+ public boolean isAttributeSpecified(int index) {
+ if (getEventType() == ATTRIBUTE)
+ return ((AttributeEvent) event).specified;
+ AttributeList attributes = attributes();
+ return attribute(attributes, index).specified;
+ }
+
+ public String getAttributeValue(String nameSpace, String name) {
+ if (getEventType() == ATTRIBUTE) {
+ AttributeEvent attribute = (AttributeEvent) event;
+ return !attribute.name.getLocalPart().equals(name) ? null : nameSpace == null ? (attribute.nameSpace == null ? attribute.value : null)
+ : nameSpace.equals(attribute.nameSpace) ? attribute.value : null;
+ }
+ AttributeList attributes = attributes();
+ return attributes == null ? null : attributes.getValue(nameSpace == null ? "" : nameSpace, name);
+ }
+
+ protected StringBuffer buffer/* = null */;
+
+ public String getElementText() {
+ if (buffer != null)
+ buffer.delete(0, buffer.length());
+ for (;;)
+ switch (next()) {
+ case END_ELEMENT:
+ return buffer == null ? null : buffer.toString();
+ default:
+ if (buffer == null)
+ buffer = new StringBuffer();
+ buffer.append(getText());
+ case PROCESSING_INSTRUCTION:
+ case COMMENT:
+ }
+ }
+
+ public final int getEventType() {
+ return event.type;
+ }
+
+ public String getLocalName() {
+ if (getEventType() == ENTITY_REFERENCE)
+ return ((Reference) event).target;
+ if (event instanceof EndElement)
+ return ((EndElement) event).name.getLocalPart();
+ throw new IllegalStateException("Neither START_ELEMENT, END_ELEMENT nor ENTITY_REFERENCE");
+ }
+
+ public final Location getLocation() {
+ return event.location;
+ }
+
+ public QName getName() {
+ if (hasName())
+ return ((EndElement) event).name;
+ throw new IllegalStateException("Neither START_ELEMENT nor END_ELEMENT");
+ }
+
+ public final NamespaceContext getNamespaceContext() {
+ return event.nameSpaceContext;
+ }
+
+ public int getNamespaceCount() {
+ if (getEventType() == NAMESPACE)
+ return ((NameSpaceEvent) event).nameSpaces;
+ if (!(event instanceof EndElement))
+ throw new IllegalStateException("Neither START_ELEMENT, END_ELEMENT nor NAMESPACE");
+ Collection nameSpaces = ((EndElement) event).nameSpaces;
+ return nameSpaces == null ? 0 : nameSpaces.size();
+ }
+
+ protected final NameSpace getNameSpace(int index) {
+ if (event instanceof EndElement)
+ return (NameSpace) ((EndElement) event).nameSpaces.get(index);
+ throw new IllegalStateException("Neither START_ELEMENT, END_ELEMENT nor NAMESPACE");
+ }
+
+ public String getNamespacePrefix(int index) {
+ return getEventType() == NAMESPACE ? ((Reference) event).target : getNameSpace(index).prefix;
+ }
+
+ public final String getNamespaceURI() {
+ switch (getEventType()) {
+ case ATTRIBUTE:
+ return ((AttributeEvent) event).nameSpace;
+ case NAMESPACE:
+ return ((ValueEvent) event).value;
+ }
+ return event instanceof EndElement ? ((EndElement) event).nameSpace : null;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return getNamespaceContext().getNamespaceURI(prefix);
+ }
+
+ public String getNamespaceURI(int index) {
+ return getEventType() == NAMESPACE ? ((ValueEvent) event).value : getNameSpace(index).uri;
+ }
+
+ public String getPIData() {
+ return getEventType() == PROCESSING_INSTRUCTION ? ((ValueEvent) event).value : null;
+ }
+
+ public String getPITarget() {
+ return getEventType() == PROCESSING_INSTRUCTION ? ((Reference) event).target : null;
+ }
+
+ public String getPrefix() {
+ switch (getEventType()) {
+ case ATTRIBUTE:
+ return ((AttributeEvent) event).prefix;
+ case NAMESPACE:
+ return ((Reference) event).target;
+ }
+ return event instanceof EndElement ? ((EndElement) event).prefix : null;
+ }
+
+ public final String getText() {
+ if (hasText())
+ return ((ValueEvent) event).value;
+ throw new IllegalStateException("Neither CHARACTERS, CDATA, COMMENT, SPACE, ENTITY_REFERENCE nor DTD");
+ }
+
+ public final char[] getTextCharacters() {
+ switch (getEventType()) {
+ case CHARACTERS:
+ case CDATA:
+ case COMMENT:
+ case SPACE:
+ return ((ValueEvent) event).value.toCharArray();
+ }
+ throw new IllegalStateException("Neither CHARACTERS, CDATA, COMMENT nor SPACE");
+ }
+
+ public int getTextCharacters(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 getTextLength() {
+ return getTextCharacters().length;
+ }
+
+ public int getTextStart() {
+ return 0;
+ }
+
+ public final boolean hasName() {
+ return event instanceof EndElement;
+ }
+
+ protected int next/* = 0 */;
+
+ public final boolean hasNext() {
+ return next != size;
+ }
+
+ public final boolean hasText() {
+ switch (getEventType()) {
+ case CHARACTERS:
+ case CDATA:
+ case COMMENT:
+ case SPACE:
+ case ENTITY_REFERENCE:
+ case DTD:
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isCharacters() {
+ switch (getEventType()) {
+ case CHARACTERS:
+ case CDATA:
+ case SPACE:
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isEndElement() {
+ return getEventType() == END_ELEMENT;
+ }
+
+ public boolean isStartElement() {
+ return getEventType() == START_ELEMENT;
+ }
+
+ protected final boolean areWhiteSpace() {
+ String text = getText();
+ for (int index = text.length(); index != 0;)
+ if (!Character.isWhitespace(text.charAt(--index)))
+ return false;
+ return true;
+ }
+
+ public boolean isWhiteSpace() {
+ switch (getEventType()) {
+ case CHARACTERS:
+ case CDATA:
+ return areWhiteSpace();
+ case SPACE:
+ return true;
+ }
+ return false;
+ }
+
+ public final int next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+ event = (Event) events.get(next++);
+ return event.type;
+ }
+
+ protected final void throwXMLStreamException(String message) throws XMLStreamException {
+ throw new XMLStreamException(message, getLocation());
+ }
+
+ public int nextTag() throws XMLStreamException {
+ for (;;) {
+ int type = next();
+ switch (type) {
+ case CHARACTERS:
+ case CDATA:
+ if (!areWhiteSpace())
+ break;
+ case SPACE:
+ case PROCESSING_INSTRUCTION:
+ case COMMENT:
+ continue;
+ case START_ELEMENT:
+ case END_ELEMENT:
+ return type;
+ }
+ throwXMLStreamException("expected start or end tag");
+ }
+ }
+
+ public void require(int type, String nameSpace, String name) throws XMLStreamException {
+ if (getEventType() != type)
+ throwXMLStreamException("type not matched");
+ if (nameSpace != null && !nameSpace.equals(getNamespaceURI()))
+ throwXMLStreamException("Name Space not matched");
+ if (name != null
+ && !(getEventType() == ATTRIBUTE ? name.equals(((AttributeEvent) event).name.getLocalPart()) : event instanceof EndElement
+ && name.equals(((EndElement) event).name.getLocalPart())))
+ throwXMLStreamException("name not matched");
+ }
+}
\ No newline at end of file
Added: incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDODeserializer.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDODeserializer.java?view=auto&rev=503913
==============================================================================
--- incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDODeserializer.java (added)
+++ incubator/tuscany/java/sdo/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDODeserializer.java Mon Feb 5 14:53:34 2007
@@ -0,0 +1,193 @@
+/**
+ *
+ * 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.sdo.util.resource;
+
+import java.util.*;
+
+import javax.xml.stream.*;
+
+import commonj.sdo.*;
+import commonj.sdo.helper.*;
+
+import org.apache.tuscany.sdo.helper.*;
+import org.apache.tuscany.sdo.util.StreamDeserializer;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.util.*;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+
+/**
+ * SDO StAX Deserializer. The instance isn't thread-safe, however it's safe to use the instance any times on the same thread.
+ */
+public class SDODeserializer extends StreamDeserializer {
+ protected final void initialize(XMLStreamReader stream, HelperContext scope, Object rootObject) {
+ reader = stream;
+ xsdHelper = scope.getXSDHelper();
+ typeHelper = scope.getTypeHelper();
+ deserializer = null;
+ root = (EObject) rootObject;
+ }
+
+ XSDHelper xsdHelper;
+
+ protected final Property getProperty(Type type, String nameSpace, String name) {
+ for (Iterator iterator = type.getProperties().iterator(); iterator.hasNext();) {
+ Property property = (Property) iterator.next();
+ if (nameSpace.equals(xsdHelper.getNamespaceURI(property)) && name.equals(xsdHelper.getLocalName(property)))
+ return property;
+ }
+ return null; // TODO substitutionGroup & any
+ }
+
+ protected final Property getProperty(String nameSpace, String name, Type type) {
+ return nameSpace == null ? type.getProperty(name) : getProperty(type, nameSpace, name);
+ // if (property == null) report error?
+ }
+
+ XMLStreamHelperImpl deserializer;
+
+ TypeHelper typeHelper;
+
+ protected Object load(XMLStreamReader reader, Map options) throws XMLStreamException {
+ if (deserializer == null)
+ deserializer = new XMLStreamHelperImpl(typeHelper);
+ return deserializer.loadObject(reader, options);
+ }
+
+ static Object value(Type type, XMLStreamReader reader) throws XMLStreamException {
+ return value(type, reader.getElementText(), reader.getNamespaceContext());
+ }
+
+ protected final Object value(Type type) throws XMLStreamException {
+ return "true".equals(reader.getAttributeValue(ExtendedMetaData.XSI_URI, XMLResource.NIL)) ? null : type.isDataType() ? value(type, reader)
+ : load(reader, null);
+ }
+
+ Map options/* = null */;
+
+ protected final Object value(Property property, XMLStreamReader reader) throws XMLStreamException {
+ Type propertyType = property.getType();
+ if (propertyType.isDataType())
+ return value(propertyType, reader);
+ if (options == null)
+ options = new HashMap();
+ options.put(XMLStreamHelper.OPTION_DEFAULT_ROOT_TYPE, propertyType);
+ return load(reader, options);
+ }
+
+ EObject root;
+
+ static EObject step(String ref, int step, int index, EObject container, ExtendedMetaData extendedMetaData) {
+ String name = ref.substring(step, index);
+ for (Iterator iterator = container.eContents().iterator(); iterator.hasNext();) {
+ container = (EObject) iterator.next();
+ // if( container == null )continue;
+ if (name.equals(extendedMetaData.getName(container.eContainmentFeature())))
+ return container;
+ }
+ return null;
+ }
+
+ protected EObject referent(String ref) {
+ int length = ref.length();
+ switch (length) {
+ case 0:
+ return null;
+ case 1: // #
+ return root;
+ }
+ EObject container;
+ int step;
+ if (ref.charAt(1) == '/') {
+ container = EcoreUtil.getRootContainer(root);
+ if (length == 2)
+ return container;
+ if (ref.charAt(2) == '/') {
+ for (Iterator iterator = container.eContents().iterator();/* true */;) {
+ if (!iterator.hasNext())
+ return null;
+ container = (EObject) iterator.next();
+ // if( container != null )
+ break;
+ }
+ /*#// is invalid
+ if (length == 3)
+ return container; */
+ step = 3;
+ } else
+ step = 2;
+ } else {
+ container = root;
+ step = 1;
+ }
+ ExtendedMetaData extendedMetaData = ((TypeHelperImpl) typeHelper).getExtendedMetaData();
+ for (int index = step; ++index != length;) {
+ switch (ref.charAt(index)) {
+ case '/':
+ container = step(ref, step, index, container, extendedMetaData);
+ if (container == null)
+ return null;
+ break;
+ default:
+ continue;
+ case '[':
+ name = ref.substring(step, index);
+ step = ref.indexOf(']', index + 2);
+ if (step == -1)
+ return null;
+ index = Integer.parseInt(ref.substring(++index, step));
+ EStructuralFeature feature;
+ for (Iterator iterator = container.eContents().iterator();/* true */;) {
+ if (!iterator.hasNext())
+ return null;
+ EObject content = (EObject) iterator.next();
+ // if( content == null )continue;
+ feature = content.eContainmentFeature();
+ if (name.equals(extendedMetaData.getName(feature)))
+ break;
+ }
+ Object value = container.eGet(feature);
+ if (value instanceof List) {
+ List values = (List) value;
+ if (index > values.size())
+ return null;
+ container = (EObject) values.get(--index);
+ } else if (index == 1)
+ container = (EObject) value;
+ else
+ return null;
+ index = ref.indexOf('/', ++step);
+ if (index == -1)
+ return container;
+ }
+ if (++index == length)
+ return container;
+ step = index;
+ }
+ return step(ref, step, length, container, extendedMetaData);
+ }
+
+ protected final Type typeXSI() {
+ return typedXSI() ? typeHelper.getType(nameSpace, name) : null;
+ }
+
+ protected final Type globalElementType(String name) {
+ return xsdHelper.getGlobalProperty(nameSpace, name, true).getType();
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org