| /** |
| * |
| * 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.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.xml.namespace.NamespaceContext; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamReader; |
| |
| import org.apache.tuscany.sdo.helper.HelperContextImpl; |
| import org.apache.tuscany.sdo.helper.TypeHelperImpl; |
| import org.apache.tuscany.sdo.helper.XMLStreamHelper; |
| import org.apache.tuscany.sdo.helper.XMLStreamHelperImpl; |
| import org.apache.tuscany.sdo.util.StreamDeserializer; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.ExtendedMetaData; |
| import org.eclipse.emf.ecore.xmi.XMLResource; |
| |
| import commonj.sdo.Property; |
| import commonj.sdo.Type; |
| import commonj.sdo.helper.HelperContext; |
| import commonj.sdo.helper.TypeHelper; |
| import commonj.sdo.helper.XSDHelper; |
| |
| /** |
| * 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 { |
| private HelperContext hc; |
| protected final void initialize(XMLStreamReader stream, HelperContext scope, Object rootObject) { |
| hc = scope; |
| reader = stream; |
| xsdHelper = scope.getXSDHelper(); |
| typeHelper = scope.getTypeHelper(); |
| extendedMetaData = ((TypeHelperImpl) typeHelper).getExtendedMetaData(); |
| deserializer = (XMLStreamHelperImpl)((HelperContextImpl)scope).getXMLStreamHelper();; |
| root = (EObject) rootObject; |
| } |
| |
| XSDHelper xsdHelper; |
| |
| protected Property propertyInSequence; |
| |
| Property getProperty(Object type) { |
| EClass c = (EClass) type; |
| EStructuralFeature containment = (EStructuralFeature) propertyInSequence; |
| Object containing = extendedMetaData.getAffiliation(c, containment); |
| // if (containing == null) report error? |
| if (containment == containing && containment.isDerived()) { |
| containing = extendedMetaData.getMixedFeature(c); |
| if (containing == null) { |
| containing = extendedMetaData.getGroup(containment); |
| if (containing == null) |
| return propertyInSequence; |
| } |
| } |
| return (Property) containing; |
| } |
| |
| protected final Property getProperty(Type type, String nameSpace, String name, boolean element) { |
| for (Iterator iterator = type.getProperties().iterator(); iterator.hasNext();) { |
| propertyInSequence = (Property) iterator.next(); |
| if (name.equals(xsdHelper.getLocalName(propertyInSequence)) |
| && nameSpace.equals(xsdHelper.getNamespaceURI(propertyInSequence))) |
| return getProperty(type); |
| } |
| propertyInSequence = xsdHelper.getGlobalProperty(nameSpace, name, element); |
| // if (propertyInSequence == null) report error? |
| return getProperty(type); |
| } |
| |
| protected final Property getProperty(Type type, String name) { |
| propertyInSequence = type.getProperty(name); |
| // if (propertyInSequence == null) report error? |
| return getProperty(type); |
| } |
| |
| protected final Property getProperty(String nameSpace, String name, Type type) { |
| return null == nameSpace ? getProperty(type, name) : getProperty(type, nameSpace, name, true); |
| } |
| |
| XMLStreamHelperImpl deserializer; |
| |
| TypeHelper typeHelper; |
| |
| protected Object load(XMLStreamReader reader, Map options) throws XMLStreamException { |
| 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(XMLStreamReader reader) throws XMLStreamException { |
| Type propertyType = propertyInSequence.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); |
| } |
| |
| private boolean match(String name, String space, EStructuralFeature feature) { |
| return name.equals(extendedMetaData.getName(feature)) && space.equals(extendedMetaData.getNamespace(feature)); |
| } |
| |
| EObject step(String ref, int step, int index, EObject container, String prefix, NamespaceContext nameSpaces) { |
| String name = ref.substring(step, index); |
| Iterator iterator = container.eContents().iterator(); |
| if (iterator.hasNext()) |
| if (prefix == null) |
| do { |
| container = (EObject) iterator.next(); |
| // if( container == null )continue; |
| if (name.equals(extendedMetaData.getName(container.eContainmentFeature()))) |
| return container; |
| } while (iterator.hasNext()); |
| else { |
| prefix = nameSpaces.getNamespaceURI(prefix); |
| do { |
| container = (EObject) iterator.next(); |
| // if( container == null )continue; |
| if (match(name, prefix, container.eContainmentFeature())) |
| return container; |
| } while (iterator.hasNext()); |
| } |
| return null; |
| } |
| |
| EObject root; |
| |
| ExtendedMetaData extendedMetaData; |
| |
| protected final EObject referent(String ref, NamespaceContext nameSpaces) { |
| 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; |
| } |
| String prefix = null; |
| for (int index = step; ++index != length;) { |
| switch (ref.charAt(index)) { |
| case '/': |
| container = step(ref, step, index, container, prefix, nameSpaces); |
| if (container == null) |
| return null; |
| break; |
| case ':': |
| prefix = ref.substring(step, index); |
| if (++index == length) |
| return container; // report error? |
| step = index; |
| default: |
| continue; |
| case '[': |
| name = ref.substring(step, index); |
| step = ref.indexOf(']', index + 2); |
| if (step == -1) |
| return container; // report error? |
| index = Integer.parseInt(ref.substring(++index, step)); |
| EStructuralFeature feature; |
| Iterator iterator = container.eContents().iterator(); |
| if (prefix == null) |
| do { |
| if (!iterator.hasNext()) |
| return null; |
| EObject content = (EObject) iterator.next(); |
| // if( content == null )continue; |
| feature = content.eContainmentFeature(); |
| } while (!name.equals(extendedMetaData.getName(feature))); |
| else { |
| prefix = nameSpaces.getNamespaceURI(prefix); |
| do { |
| if (!iterator.hasNext()) |
| return null; |
| EObject content = (EObject) iterator.next(); |
| // if( content == null )continue; |
| feature = content.eContainmentFeature(); |
| } while (!match(name, prefix, feature)); |
| } |
| 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; |
| prefix = null; |
| } |
| return step(ref, step, length, container, prefix, nameSpaces); |
| } |
| |
| static protected class Ref implements EObject // FeatureMapEntry value |
| { |
| protected Ref(String path, NamespaceContext context) { |
| ref = path; |
| nameSpaces = context; |
| } |
| |
| final String ref; |
| |
| final NamespaceContext nameSpaces; |
| |
| public TreeIterator eAllContents() { |
| return null; |
| } |
| public EClass eClass() { |
| return null; |
| } |
| public EObject eContainer() { |
| return null; |
| } |
| public EStructuralFeature eContainingFeature() { |
| return null; |
| } |
| public EReference eContainmentFeature() { |
| return null; |
| } |
| public EList eContents() { |
| return null; |
| } |
| public EList eCrossReferences() { |
| return null; |
| } |
| public Object eGet(EStructuralFeature feature) { |
| return null; |
| } |
| public Object eGet(EStructuralFeature feature, boolean resolve) { |
| return null; |
| } |
| public boolean eIsProxy() { |
| return false; |
| } |
| public boolean eIsSet(EStructuralFeature feature) { |
| return false; |
| } |
| public Resource eResource() { |
| return null; |
| } |
| public void eSet(EStructuralFeature feature, Object newValue) { |
| } |
| public void eUnset(EStructuralFeature feature) { |
| } |
| public EList eAdapters() { |
| return null; |
| } |
| public boolean eDeliver() { |
| return false; |
| } |
| public void eNotify(Notification notification) { |
| } |
| public void eSetDeliver(boolean deliver) { |
| } |
| } |
| |
| protected final EObject referent(Ref path) { |
| return referent(path.ref, path.nameSpaces); |
| } |
| |
| protected final Type typeXSI() { |
| return typedXSI() ? typeHelper.getType(nameSpace, name) : null; |
| } |
| |
| protected final Type globalElementType(String nameSpace, String name) { |
| return xsdHelper.getGlobalProperty(nameSpace, name, true).getType(); |
| } |
| } |