summaryrefslogtreecommitdiffstats
path: root/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java')
-rw-r--r--sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java1254
1 files changed, 1254 insertions, 0 deletions
diff --git a/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java b/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java
new file mode 100644
index 0000000000..55d365d043
--- /dev/null
+++ b/sdo-java/branches/emf-2.5/impl/src/main/java/org/apache/tuscany/sdo/util/resource/SDOXMLResourceImpl.java
@@ -0,0 +1,1254 @@
+/**
+ *
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sdo.AnyTypeDataObject;
+import org.apache.tuscany.sdo.SDOExtendedMetaData;
+import org.apache.tuscany.sdo.SDOPackage;
+import org.apache.tuscany.sdo.helper.HelperContextImpl;
+import org.apache.tuscany.sdo.helper.SDOExtendedMetaDataImpl;
+import org.apache.tuscany.sdo.helper.XMLStreamHelper;
+import org.apache.tuscany.sdo.helper.XSDHelperImpl;
+import org.apache.tuscany.sdo.impl.AnyTypeDataObjectImpl;
+import org.apache.tuscany.sdo.impl.SDOPackageImpl;
+import org.apache.tuscany.sdo.api.SDOHelper;
+import org.apache.tuscany.sdo.api.SDOUtil;
+import org.apache.tuscany.sdo.util.StAX2SAXAdapter;
+import org.apache.tuscany.sdo.model.internal.InternalFactory;
+import org.apache.tuscany.sdo.model.internal.impl.InternalFactoryImpl;
+import org.eclipse.emf.common.util.EMap;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EFactory;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.InternalEObject;
+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.util.FeatureMap;
+import org.eclipse.emf.ecore.xmi.XMIException;
+import org.eclipse.emf.ecore.xmi.XMLHelper;
+import org.eclipse.emf.ecore.xmi.XMLLoad;
+import org.eclipse.emf.ecore.xmi.XMLOptions;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.XMLSave;
+import org.eclipse.emf.ecore.xmi.impl.SAXXMLHandler;
+import org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLOptionsImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLString;
+import org.eclipse.emf.ecore.xmi.util.DefaultEcoreBuilder;
+import org.eclipse.emf.ecore.xml.type.AnyType;
+import org.eclipse.emf.ecore.xml.type.SimpleAnyType;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import commonj.sdo.ChangeSummary;
+import commonj.sdo.DataObject;
+import commonj.sdo.helper.XSDHelper;
+
+public class SDOXMLResourceImpl extends XMLResourceImpl {
+ private XMLStreamReader reader;
+
+ /**
+ * [rfeng] Override the XMLHelperImpl to replace the NamespaceSupport so
+ * that it's aware of the NamespaceContext from the XMLStreamReader
+ */
+ public static class SDOXMLHelperImpl extends XMLHelperImpl {
+
+ public EObject createObject(EFactory eFactory, EClassifier type) {
+ // this fix does not work!
+ /*
+ * if ("DataObject".equals(type.getName())) { AnyTypeDataObjectImpl
+ * result = (AnyTypeDataObjectImpl)
+ * EcoreUtil.create(SDOPackage.eINSTANCE.getAnyTypeDataObject());
+ * return result; }
+ */
+
+ // this is the createObject from EMF 2.2 note: it creates the object
+ // ALSO for abstract classes....
+ EObject newObject = null;
+ if (eFactory != null) {
+ if (extendedMetaData != null) {
+ if (type == null) {
+ return null;
+ } else if (type instanceof EClass) {
+ newObject = eFactory.create((EClass) type);
+ } else {
+ SimpleAnyType result = (SimpleAnyType) EcoreUtil
+ .create(anySimpleType);
+ result.setInstanceType((EDataType) type);
+ newObject = result;
+ }
+ } else {
+ if (type != null) {
+ newObject = eFactory.create((EClass) type);
+ }
+ }
+ }
+ return newObject;
+ // return super.createObject(eFactory, type);
+ }
+
+ /**
+ * EMF XMLResource (SAX) may be used to load from only a *portion* of a
+ * StAX stream which may reference (global) namespaces bound outside the
+ * (local) portion. This class extends EMF's NamespaceSupport to make
+ * {@link #getPrefix} and {@link #getURI} query these global binding(s)
+ * after first checking the local context(s).
+ */
+ private static class StreamNamespaceSupport extends
+ XMLHelperImpl.NamespaceSupport {
+ protected NamespaceContext nameSpaceContext;
+
+ public String getPrefix(String uri) {
+ String prefix = super.getPrefix(uri);
+ if (prefix == null)
+ try {
+ prefix = nameSpaceContext.getPrefix(uri);
+ } catch (Exception e) {
+ // HACK:
+ // java.lang.UnsupportedOperationException
+ // at
+ // org.apache.axiom.om.impl.llom.OMStAXWrapper.getNamespaceContext(OMStAXWrapper.java:984)
+ }
+ return prefix;
+ }
+
+ public String getURI(String prefix) {
+ String uri = super.getURI(prefix);
+ if (uri == null)
+ try {
+ uri = nameSpaceContext.getNamespaceURI(prefix);
+ } catch (Exception e) {
+ // HACK:
+ // java.lang.UnsupportedOperationException
+ // at
+ // org.apache.axiom.om.impl.llom.OMStAXWrapper.getNamespaceContext(OMStAXWrapper.java:984)
+ }
+ return uri;
+ }
+
+ public StreamNamespaceSupport(XMLStreamReader reader) {
+ super();
+ nameSpaceContext = reader.getNamespaceContext();
+ }
+
+ }
+
+ public SDOXMLHelperImpl(XMLResource resource, XMLStreamReader reader) {
+ this(reader);
+ setResource(resource);
+ }
+
+ public SDOXMLHelperImpl(XMLStreamReader reader) {
+ super();
+ if (reader instanceof XMLDocumentStreamReader) // Only use
+ // StreamNamespaceSupport
+ // when loading from
+ // a *portion* of a
+ // StAX stream
+ namespaceSupport = new StreamNamespaceSupport(reader);
+ }
+
+ private class NameSpaceContext implements NamespaceContext { // TODO
+ // Helper#
+ // pushContext()
+ // &
+ // popContext
+ public String getNamespaceURI(String prefix) {
+ return SDOXMLHelperImpl.this.getNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI) {
+ return SDOXMLHelperImpl.this.getPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ return ((Collection) urisToPrefixes.get(namespaceURI))
+ .iterator();
+ }
+ }
+
+ NameSpaceContext nameSpaceContext/* = null */;
+
+ protected final NameSpaceContext nameSpaceContext() {
+ if (nameSpaceContext == null)
+ nameSpaceContext = new NameSpaceContext();
+ return nameSpaceContext;
+ }
+
+ private String xsdQName2SDOURI(String xsdQName) {
+ org.eclipse.emf.ecore.xml.type.internal.QName qname = new org.eclipse.emf.ecore.xml.type.internal.QName(
+ xsdQName);
+ try {
+ updateQNameURI(qname);
+ } catch (IllegalArgumentException e) {
+ return xsdQName;
+ }
+ String uri = qname.getNamespaceURI();
+ if (uri != "")
+ return uri + "#" + qname.getLocalPart();
+ else
+ return qname.getLocalPart();
+ }
+
+ private String getPrefixFromNamespaceURI(String nsURI) {
+ String nsPrefix = null;
+
+ List prefixes = (List) urisToPrefixes.get(nsURI);
+ if (prefixes != null) {
+ for (Iterator i = prefixes.iterator(); i.hasNext();) {
+ nsPrefix = (String) i.next();
+ if (nsPrefix.length() >= 0) {
+ // When the length is 0, it's the default namespace
+ return nsPrefix;
+ }
+ }
+ }
+
+ nsPrefix = namespaceSupport.getPrefix(nsURI);
+ if (nsPrefix != null) {
+ return nsPrefix;
+ }
+
+ // Demand create a new package
+ EPackage ePackage = extendedMetaData.demandPackage(nsURI);
+
+ if (ExtendedMetaData.XSI_URI.equals(nsURI)) {
+ ePackage.setNsPrefix(ExtendedMetaData.XSI_PREFIX);
+ }
+
+ // getPrefix() will make sure all mapping tables are configured
+ // correctly
+ nsPrefix = getPrefix(ePackage, true);
+
+ return nsPrefix;
+ }
+
+ private String SDOURI2XsdQName(String sdoURI) {
+ String namespace = null;
+ String localPart = sdoURI;
+
+ int index = sdoURI.indexOf('#');
+ if (index == -1) {
+ return localPart;
+ } else {
+ namespace = sdoURI.substring(0, index);
+ localPart = sdoURI.substring(index + 1);
+
+ String prefix = getPrefixFromNamespaceURI(namespace);
+
+ if (prefix.length() == 0)
+ return localPart;
+
+ return prefix + ":" + localPart;
+ }
+ }
+
+ // / TODO?!?!?!
+ /*
+ * public EObject createObject(EFactory eFactory, EClassifier type) { if
+ * (type instanceof AnyTypeDataObject) { AnyTypeDataObjectImpl result =
+ * (AnyTypeDataObjectImpl)
+ * EcoreUtil.create(SDOPackage.eINSTANCE.getAnyTypeDataObject()); return
+ * result; } return super.createObject(eFactory, type); }
+ */
+
+ protected Object createFromString(EFactory eFactory,
+ EDataType eDataType, String value) {
+ Object obj = super.createFromString(eFactory, eDataType, value);
+ if (eDataType == ((InternalFactoryImpl) InternalFactory.INSTANCE)
+ .getQName()) {
+ if (extendedMetaData != null) {
+ if (obj instanceof List) {
+ List list = (List) obj;
+ for (int i = 0; i < list.size(); i++) {
+ String xsdQName = (String) list.get(i);
+ list.set(i, xsdQName2SDOURI(xsdQName));
+ }
+ } else {
+ obj = xsdQName2SDOURI((String) obj);
+ }
+ }
+ }
+ return obj;
+ }
+
+ public String convertToString(EFactory factory, EDataType eDataType,
+ Object value) {
+ if (eDataType == ((InternalFactoryImpl) InternalFactory.INSTANCE)
+ .getQName()) {
+ if (extendedMetaData != null) {
+ if (value instanceof List) {
+ List list = (List) value;
+ for (int i = 0; i < list.size(); i++) {
+ String sdoURI = (String) list.get(i);
+ list.set(i, SDOURI2XsdQName(sdoURI));
+ }
+ } else {
+ value = SDOURI2XsdQName((String) value);
+ }
+ }
+ }
+
+ return super.convertToString(factory, eDataType, value);
+ }
+ }
+
+ public EObject root;
+
+ /**
+ * An EMF XMLLoad that loads a model from a StAX stream
+ */
+ public class SDOXMLLoadImpl extends XMLLoadImpl {
+ public SDOXMLLoadImpl(XMLHelper helper) {
+ super(helper);
+ }
+
+ final class XmlHandler extends SAXXMLHandler {
+ XmlHandler() {
+ super(resource, SDOXMLLoadImpl.this.helper, options);
+ }
+
+ protected void handleTopLocations(String prefix, String name) {
+ processSchemaLocations(prefix, name);
+ if (!processAnyXML)
+ return;
+ String nameSpace = helper.getURI(prefix);
+ if (extendedMetaData.getPackage(nameSpace) == null)
+ if (options.get(XMLStreamHelper.OPTION_DEFAULT_ROOT_TYPE) == null)
+ extendedMetaData.demandFeature(nameSpace, name, true);
+ else
+ extendedMetaData.demandPackage(nameSpace);
+ }
+
+ EClassifier defaultRootType(String prefix, String name,
+ boolean isElement, EObject peekObject, String value) {
+ Object type = options
+ .get(XMLStreamHelper.OPTION_DEFAULT_ROOT_TYPE);
+ if (type != null)
+ return (EClassifier) type;
+ super.handleUnknownFeature(prefix, name, isElement, peekObject,
+ value);
+ return null;
+ }
+
+ protected void handleUnknownFeature(String prefix, String name,
+ boolean isElement, EObject peekObject, String value) {
+
+ if (objects.size() == 1) {
+ EFactory eFactory;
+ EClassifier type;
+ String typeQName = getXSIType();
+ if (typeQName == null) {
+ type = defaultRootType(prefix, name, isElement,
+ peekObject, value);
+ if (type == null)
+ return;
+ eFactory = type.getEPackage().getEFactoryInstance();
+ } else {// createObjectFromTypeName
+ String typeName = null;
+ String xsiPrefix = XMLConstants.DEFAULT_NS_PREFIX;
+ int index = typeQName.indexOf(":");
+ if (index > 0) {
+ xsiPrefix = typeQName.substring(0, index);
+ typeName = typeQName.substring(index + 1);
+ } else
+ typeName = typeQName;
+ eFactory = getFactoryForPrefix(xsiPrefix);
+ if (eFactory != null)
+ type = helper.getType(eFactory, typeName);
+ else if (XMLConstants.DEFAULT_NS_PREFIX
+ .equals(xsiPrefix)
+ && helper.getURI(xsiPrefix) == null) {
+ EPackage ePackage = handleMissingPackage(null);
+ if (ePackage == null) {
+ type = defaultRootType(prefix, name, isElement,
+ peekObject, value);
+ if (type == null)
+ return;
+ eFactory = type.getEPackage()
+ .getEFactoryInstance();
+ } else
+ type = helper.getType(eFactory = ePackage
+ .getEFactoryInstance(), typeName);
+ } else {
+ type = defaultRootType(prefix, name, isElement,
+ peekObject, value);
+ if (type == null)
+ return;
+ eFactory = type.getEPackage().getEFactoryInstance();
+ }
+ }
+ root = helper.createObject(eFactory, type);
+ if (root != null) {
+ if (disableNotify)
+ root.eSetDeliver(false);
+ handleObjectAttribs(root);
+ processObject(root);
+ return;
+ }
+ }
+ super.handleUnknownFeature(prefix, name, isElement, peekObject,
+ value);
+ }
+
+ protected RecordedEventXMLStreamReader.Tag tag/* =null */;
+
+ protected List nameSpaces/* = null */;
+
+ public void startPrefixMapping(String prefix, String uri) {
+ if (nameSpaces == null)
+ nameSpaces = new ArrayList();
+ RecordedEventXMLStreamReader.Tag.bind(prefix, uri, nameSpaces);
+ if (tag == null)
+ super.startPrefixMapping(prefix, uri);
+ }
+
+ public void startElement(String uri, String localName,
+ String qName, Attributes attributes) throws SAXException {
+ if (tag != null) {
+ tag.start(uri, localName, qName, attributes, locator,
+ nameSpaces);
+ nameSpaces = null;
+ return;
+ }
+ EObject peekObject = objects.peekEObject();
+ if (peekObject != null) {
+ String prefix = helper.getPrefix(uri.length() == 0 ? null
+ : uri);
+ EStructuralFeature feature = getFeature(peekObject,
+ prefix == null ? XMLConstants.DEFAULT_NS_PREFIX
+ : prefix, localName, true);
+ if (feature != null
+ && feature.getEType() == ChangeSummaryStreamSerializer.ChangeSummary_TYPE) {
+ tag = new RecordedEventXMLStreamReader.Tag(uri,
+ localName, prefix, attributes, locator,
+ ((SDOXMLHelperImpl) helper).nameSpaceContext(),
+ nameSpaces);
+ nameSpaces = null;
+ return;
+ }
+ }
+ if (nameSpaces != null)
+ nameSpaces.clear();
+ super.startElement(uri, localName, qName, attributes);
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ if (tag == null)
+ super.characters(ch, start, length);
+ else
+ tag.text(XMLStreamConstants.CHARACTERS, new String(ch,
+ start, length), locator);
+ }
+
+ protected Collection changeSummaryDeserializers/* = null */;
+
+ public void endElement(String uri, String localName, String qName) {
+ if (tag == null)
+ super.endElement(uri, localName, qName);
+ else if (tag.end(uri, localName, qName, locator)) {
+ if (changeSummaryDeserializers == null)
+ changeSummaryDeserializers = new ArrayList();
+ ChangeSummaryStreamDeserializer changeSummaryDeserializer = new ChangeSummaryStreamDeserializer();
+ try {
+ changeSummaryDeserializer
+ .begin((DataObject) objects.peekEObject(),
+ new HelperContextImpl(extendedMetaData,
+ false), tag.play(xmlResource));
+ changeSummaryDeserializers
+ .add(changeSummaryDeserializer);
+ } catch (XMLStreamException e) {
+ xmlResource.getErrors().add(new XMIException(e));
+ }
+ tag = null;
+ }
+ }
+
+ public void endDocument() {
+ super.endDocument();
+ if (changeSummaryDeserializers != null)
+ for (Iterator iterator = changeSummaryDeserializers
+ .iterator(); iterator.hasNext();)
+ try {
+ ((ChangeSummaryStreamDeserializer) iterator.next())
+ .end();
+ // iterator.remove();
+ } catch (XMLStreamException e) {
+ xmlResource.getErrors().add(new XMIException(e));
+ }
+ }
+ }
+
+ protected DefaultHandler makeDefaultHandler() {
+ return new XmlHandler();
+ }
+
+ /**
+ * Start parsing an XMLReader with the default handler.
+ */
+ public void load(XMLResource resource, final XMLStreamReader reader,
+ Map options) throws IOException {
+ this.resource = resource;
+ Map mergedOptions = new HashMap(defaultLoadOptions);
+ if (options != null)
+ mergedOptions.putAll(options);
+
+ this.options = mergedOptions;
+
+ final ContentHandler handler = makeDefaultHandler();
+
+ if (errors != null) {
+ errors.clear();
+ }
+
+ final StAX2SAXAdapter adapter = new StAX2SAXAdapter(true);
+ // Parse the XMLReader and generate SAX events
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Object run() throws XMLStreamException, SAXException {
+ adapter.parse(reader, handler);
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw new Resource.IOWrappedException(e.getException());
+ }
+
+ helper = null;
+ if (!resource.getErrors().isEmpty()) {
+ Exception error = (Exception) resource.getErrors().get(0);
+ if (error instanceof XMIException) {
+ XMIException exception = (XMIException) error;
+ if (exception.getWrappedException() != null) {
+ throw new Resource.IOWrappedException(exception
+ .getWrappedException());
+ }
+ }
+ throw new Resource.IOWrappedException(error);
+ }
+ }
+ }
+
+ public SDOXMLResourceImpl(URI uri) {
+ super(uri);
+ }
+
+ protected XMLHelper createXMLHelper() {
+ return new SDOXMLHelperImpl(this, reader);
+ }
+
+ /**
+ * @see org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl#createXMLLoad()
+ */
+ protected XMLLoad createXMLLoad() {
+ return new SDOXMLLoadImpl(createXMLHelper());
+ }
+
+ static protected int loadLaxForm;
+ static {
+ int defaultLaxForm = 0x4242;
+ String property = System.getProperty("XML.load.form.lax");
+ if (property == null)
+ loadLaxForm = defaultLaxForm;
+ else
+ try {
+ loadLaxForm = Integer.decode(property).intValue();
+ } catch (NumberFormatException eNumberFormat) {
+ loadLaxForm = defaultLaxForm;
+ }
+ }
+
+ public void doLoad(InputSource inputSource, Map options) throws IOException {
+ if (options != null) {
+ /*
+ * Tolerates element/attribute malform unless indicated not to
+ */
+ Object option = options.get(SDOHelper.XMLOptions.XML_LOAD_LAX_FORM);
+ int tolerance = option == null ? loadLaxForm : ((Number) option)
+ .intValue();
+ option = options.get(OPTION_EXTENDED_META_DATA);
+ if (tolerance == 0) {
+ if (option instanceof SDOExtendedMetaData)
+ ((SDOExtendedMetaData) option)
+ .setFeatureNamespaceMatchingLax(false);
+ } else if (option instanceof SDOExtendedMetaData) {
+ ((SDOExtendedMetaData) option)
+ .setFeatureNamespaceMatchingLax(true);
+ } else {
+ options.put(OPTION_EXTENDED_META_DATA,
+ option = new SDOExtendedMetaDataImpl()); // TODO copy
+ // (BasicExtendedMetaData)option
+ }
+ /*
+ * Loads schema if necessary
+ */
+ if (Boolean.TRUE.equals(options
+ .get(SDOHelper.XMLOptions.XML_LOAD_SCHEMA))) {
+ XMLOptions xmlOptions = (XMLOptions) options
+ .get(OPTION_XML_OPTIONS);
+ if (xmlOptions == null) {
+ xmlOptions = new XMLOptionsImpl();
+ options.put(OPTION_XML_OPTIONS, xmlOptions);
+ }
+ xmlOptions.setProcessSchemaLocations(true);
+ if (option == null) {
+ option = getDefaultLoadOptions().get(
+ OPTION_EXTENDED_META_DATA);
+ }
+ ExtendedMetaData extendedMetaData;
+ final XSDHelper xsdHelper;
+ if (option == null) {
+ extendedMetaData = ExtendedMetaData.INSTANCE;
+ xsdHelper = XSDHelper.INSTANCE;
+ } else {
+ extendedMetaData = (ExtendedMetaData) option;
+ xsdHelper = (new HelperContextImpl(extendedMetaData, false))
+ .getXSDHelper();
+ }
+ xmlOptions.setEcoreBuilder(new DefaultEcoreBuilder(
+ extendedMetaData) {
+ public Collection generate(Map targetNamespaceToURI)
+ throws IOException {
+ for (Iterator iterator = targetNamespaceToURI.values()
+ .iterator(); iterator.hasNext();) {
+ String uri = iterator.next().toString();
+ xsdHelper.define(uri.indexOf(":/") == -1 ? Thread
+ .currentThread().getContextClassLoader()
+ .getResourceAsStream(uri) : new URL(uri)
+ .openStream(), uri);
+ }
+ return null; // XMLHandler#processSchemaLocations
+ // doesn't take the result
+ }
+ });
+ }
+
+ if (Boolean.TRUE.equals(options
+ .get(SDOHelper.XMLOptions.XML_LOAD_UNKNOWN_PROPERTIES))) {
+ options.put(OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
+ }
+ } else if (loadLaxForm != 0) {
+ /*
+ * Tolerates element/attribute malform
+ */
+ options = new HashMap();
+ options.put(OPTION_EXTENDED_META_DATA,
+ new SDOExtendedMetaDataImpl());
+ }
+ super.doLoad(inputSource, options);
+ // TODO there is some thinking to be done about the restoration of
+ // options
+ }
+
+ /**
+ * Loads the resource from a StAX XMLStreamReader.
+ */
+ public void load(XMLStreamReader reader, Map options) throws IOException {
+ this.reader = reader;
+ SDOXMLLoadImpl xmlLoad = (SDOXMLLoadImpl) createXMLLoad();
+ Map mergedOptions = new HashMap(defaultLoadOptions);
+ if (options != null)
+ mergedOptions.putAll(options);
+ xmlLoad.load(this, reader, mergedOptions);
+ }
+
+ ChangeSummaryStreamSerializer changeSummarySerializer/* = null */;
+
+ static private final class LocalName extends QName {
+ private LocalName(String name) {
+ super(name);
+ }
+
+ public String getNamespaceURI() {
+ return null;
+ }
+ }
+
+ static final String INDENT = " ", LINE_SEPARATOR = System
+ .getProperty("line.separator");
+
+ static final class XmlString extends XMLString {
+ XmlString(int lineWidth, String temporaryFileName) {
+ super(lineWidth, temporaryFileName); // setLineWidth &
+ // setTemporaryFileName
+ }
+
+ XmlString(int lineWidth, String publicId, String systemId,
+ String temporaryFileName) {
+ super(lineWidth, publicId, systemId, temporaryFileName);
+ }
+
+ void setLineBreak(String lineBreak) {
+ lineSeparator = lineBreak;
+ }
+
+ void margin(String margin) {
+ indents.set(0, margin);
+ }
+
+ String indent = INDENT;
+
+ protected String getElementIndent(int extra) {
+ int nesting = depth + extra - 1;
+ for (int i = indents.size() - 1; i < nesting; ++i) {
+ indents.add(indents.get(i) + indent);
+ }
+ return (String) indents.get(nesting);
+ }
+
+ protected String getAttributeIndent() {
+ return getElementIndent();
+ }
+
+ public final boolean mixed() {
+ return isMixed;
+ }
+
+ public void reset(String publicId, String systemId, int lineWidth,
+ String temporaryFileName) {
+ super.reset(publicId, systemId, lineWidth, temporaryFileName);
+ setLineBreak(LINE_SEPARATOR);
+ indent = INDENT;
+ }
+ }
+
+ static final char MARK = '\n';
+
+ static final String LINE_BREAK = new String(new char[] { MARK });
+
+ final class SDOXMLSaveImpl extends XMLSaveImpl {
+ SDOXMLSaveImpl(XMLHelper helper) {
+ super(helper);
+ }
+
+ XmlString doc(XMLResource resource, Map options) {
+ if (doc instanceof XmlString)
+ return (XmlString) doc;
+ Object lineWidth = options.get(OPTION_LINE_WIDTH);
+ int width = lineWidth == null ? Integer.MAX_VALUE
+ : ((Number) lineWidth).intValue();
+ XmlString d = resource != null
+ && Boolean.TRUE.equals(options.get(OPTION_SAVE_DOCTYPE)) ? new XmlString(
+ width, resource.getPublicId(), resource.getSystemId(), doc
+ .getTemporaryFileName())
+ : new XmlString(width, doc.getTemporaryFileName());
+ doc = d;
+ return d;
+ }
+
+ Map changeSummaryOptions = new HashMap();
+ String indent = INDENT, margin;
+
+ protected void init(XMLResource resource, Map options) {
+ super.init(resource, options);
+ int unformat = 0;
+ String lineBreak = (String) options
+ .get(SDOHelper.XMLOptions.XML_SAVE_LINE_BREAK);
+ if (lineBreak == null)
+ changeSummaryOptions.put(
+ SDOHelper.XMLOptions.XML_SAVE_LINE_BREAK, LINE_BREAK);
+ else if (lineBreak.length() == 0)
+ ++unformat;
+ else {
+ changeSummaryOptions.put(
+ SDOHelper.XMLOptions.XML_SAVE_LINE_BREAK, LINE_BREAK);
+ if (lineBreak.equals(LINE_SEPARATOR))
+ lineBreak = null;
+ }
+ String indent = (String) options
+ .get(SDOHelper.XMLOptions.XML_SAVE_INDENT);
+ if (indent == null)
+ changeSummaryOptions.put(SDOHelper.XMLOptions.XML_SAVE_INDENT,
+ INDENT);
+ else if (indent.length() == 0)
+ ++unformat;
+ else {
+ changeSummaryOptions.put(SDOHelper.XMLOptions.XML_SAVE_INDENT,
+ this.indent = indent);
+ if (indent.equals(INDENT))
+ indent = null;
+ }
+ String margin = (String) options
+ .get(SDOHelper.XMLOptions.XML_SAVE_MARGIN);
+ if (margin == null || margin.length() == 0) {
+ if (unformat == 2)
+ doc.setUnformatted(true);
+ else if (lineBreak != null) {
+ XmlString d = doc(resource, options);
+ d.setLineBreak(lineBreak);
+ if (indent != null)
+ d.indent = indent;
+ } else if (indent != null)
+ doc(resource, options).indent = indent;
+ this.margin = this.indent;
+ } else {
+ XmlString d = doc(resource, options);
+ d.margin(margin);
+ if (lineBreak != null)
+ d.setLineBreak(lineBreak);
+ if (indent != null)
+ d.indent = indent;
+ this.margin = margin + this.indent;
+ if (!toDOM && declareXML)
+ d.add(margin);
+ }
+ // changeSummaryOptions.put(ChangeSummaryStreamSerializer.OPTION_RootObject_PATH,
+ // "#");
+ // changeSummaryOptions.put(ChangeSummaryStreamSerializer.OPTION_OPTIMIZE_LIST,
+ // Boolean.TRUE);
+ changeSummaryOptions.put(OPTION_EXTENDED_META_DATA,
+ extendedMetaData);
+ }
+
+ QName qName(EStructuralFeature f) {
+ if (extendedMetaData == null)
+ return new LocalName(f.getName());
+ String nameSpace = extendedMetaData.getNamespace(f), name = extendedMetaData
+ .getName(f);
+ return nameSpace == null ? new LocalName(name) : new QName(
+ nameSpace, name);
+ }
+
+ XMLStreamWriter xmlStreamWriter/* = null */;
+
+ void saveChangeSummary(EObject o, EStructuralFeature f,
+ Object changeSummary) {
+ boolean notMixed;
+ if (doc instanceof XmlString)
+ notMixed = !((XmlString) doc).mixed();
+ else if (extendedMetaData == null)
+ notMixed = true;
+ else
+ switch (extendedMetaData.getContentKind(o.eClass())) {
+ case ExtendedMetaData.MIXED_CONTENT:
+ case ExtendedMetaData.SIMPLE_CONTENT:
+ notMixed = false;
+ break;
+ default:
+ notMixed = true;
+ }
+ if (notMixed) {
+ StringBuffer margin = new StringBuffer(this.margin);
+ for (EObject container = o.eContainer(), grandContainer; (grandContainer = container
+ .eContainer()) != null; container = grandContainer)
+ margin.append(indent);
+ changeSummaryOptions.put(SDOHelper.XMLOptions.XML_SAVE_MARGIN,
+ margin.toString());
+ }
+ try {
+ if (xmlStreamWriter == null) {
+ xmlStreamWriter = XMLOutputFactory.newInstance()
+ .createXMLStreamWriter(new Writer() {
+ public void close() {
+ }
+
+ public void flush() {
+ }
+
+ protected final void add(char[] cbuf,
+ int index, int off) {
+ doc.addText(new String(cbuf, index, off
+ - index));
+ }
+
+ public void write(char[] cbuf, int off, int len) {
+ if (len != 0)
+ for (;;) {
+ while (cbuf[off] == MARK) {
+ doc.addLine();
+ if (--len == 0)
+ return;
+ ++off;
+ }
+ for (int index = off;/* true */;) {
+ ++off;
+ if (--len == 0)
+ add(cbuf, index, off);
+ else {
+ if (cbuf[off] != MARK)
+ continue;
+ add(cbuf, index, off);
+ doc.addLine();
+ if (--len != 0)
+ break;
+ }
+ return;
+ }
+ ++off;
+ }
+ }
+ });
+ xmlStreamWriter
+ .setNamespaceContext(((SDOXMLHelperImpl) helper).new NameSpaceContext() {
+ public String getNamespaceURI(String prefix) {
+ return declareXSI
+ && ExtendedMetaData.XSI_PREFIX
+ .equals(prefix) ? ExtendedMetaData.XSI_URI
+ : super.getNamespaceURI(prefix);
+ }
+
+ public String getPrefix(String namespaceURI) {
+ return declareXSI
+ && ExtendedMetaData.XSI_URI
+ .equals(namespaceURI) ? ExtendedMetaData.XSI_PREFIX
+ : super.getPrefix(namespaceURI);
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ final Iterator iterator = super
+ .getPrefixes(namespaceURI);
+ return ExtendedMetaData.XSI_URI
+ .equals(namespaceURI) ? new Iterator() {
+ boolean first = true;
+
+ public boolean hasNext() {
+ if (first)
+ if (declareXSI) // never from
+ // true to false
+ return true;
+ else
+ first = false;
+ return iterator.hasNext();
+ }
+
+ public Object next() {
+ if (first) {
+ first = false;
+ if (declareXSI)
+ return ExtendedMetaData.XSI_PREFIX;
+ }
+ return iterator.next();
+ }
+
+ public void remove() {
+ if (first)
+ declareXSI = false;
+ else
+ iterator.remove();
+ }
+ }
+ : iterator;
+ }
+ });
+ for (Iterator iterator = helper.getPrefixToNamespaceMap()
+ .iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ xmlStreamWriter.setPrefix((String) entry.getKey(),
+ (String) entry.getValue());
+ }
+ if (declareXSI)
+ xmlStreamWriter.setPrefix(ExtendedMetaData.XSI_PREFIX,
+ ExtendedMetaData.XSI_URI);
+ if (changeSummarySerializer == null)
+ changeSummarySerializer = new ChangeSummaryStreamSerializer();
+ }
+ changeSummarySerializer.saveChangeSummary(
+ (ChangeSummary) changeSummary, qName(f),
+ xmlStreamWriter, changeSummaryOptions);
+ if (notMixed)
+ doc.addLine();
+ } catch (XMLStreamException e) {
+ xmlResource.getErrors().add(new XMIException(e));
+ }
+ }
+
+ protected void saveDataTypeElementSingle(EObject o, EStructuralFeature f) {
+ if (f.getEType() == ChangeSummaryStreamSerializer.ChangeSummary_TYPE)
+ saveChangeSummary(o, f, helper.getValue(o, f));
+ else
+ super.saveDataTypeElementSingle(o, f);
+ }
+
+ // copied from base class because the shouldSaveType did not consider
+ // the DataObject case...
+ protected void saveElement(EObject o, EStructuralFeature f) {
+ EClass eClass = o.eClass();
+ EClassifier eType = f.getEType();
+
+ if (extendedMetaData != null && eClass != eType) {
+ // Check if it's an anonymous type.
+ //
+ String name = extendedMetaData.getName(eClass);
+ if (name.endsWith("_._type")) {
+ String elementName = name.substring(0, name.indexOf("_._"));
+ String prefix = helper.getPrefix(eClass.getEPackage());
+ if (!"".equals(prefix)) {
+ elementName = prefix + ":" + elementName;
+ }
+ if (!toDOM) {
+ doc.startElement(elementName);
+ } else {
+ currentNode = currentNode.appendChild(document
+ .createElementNS(
+ helper.getNamespaceURI(prefix),
+ elementName));
+ handler.recordValues(currentNode, o.eContainer(), f, o);
+ }
+ saveElementID(o);
+ return;
+ }
+ }
+
+ if (map != null) {
+ XMLResource.XMLInfo info = map.getInfo(eClass);
+ if (info != null
+ && info.getXMLRepresentation() == XMLResource.XMLInfo.ELEMENT) {
+ if (!toDOM) {
+ String elementName = helper.getQName(eClass);
+ doc.startElement(elementName);
+ } else {
+ helper.populateNameInfo(nameInfo, eClass);
+ if (currentNode == null) {
+ currentNode = document.createElementNS(nameInfo
+ .getNamespaceURI(), nameInfo
+ .getQualifiedName());
+ document.appendChild(currentNode);
+ handler.recordValues(currentNode, o.eContainer(),
+ f, o);
+ } else {
+ currentNode = currentNode.appendChild(document
+ .createElementNS(
+ nameInfo.getNamespaceURI(),
+ nameInfo.getQualifiedName()));
+ handler.recordValues(currentNode, o.eContainer(),
+ f, o);
+ }
+ }
+ saveElementID(o);
+ return;
+ }
+ }
+ boolean isAnyType = false;
+ if (o instanceof AnyType) {
+ isAnyType = true;
+ helper.pushContext();
+ for (FeatureMap.Entry entry : ((AnyType) o).getAnyAttribute()) {
+ if (ExtendedMetaData.XMLNS_URI.equals(extendedMetaData
+ .getNamespace(entry.getEStructuralFeature()))) {
+ String uri = (String) entry.getValue();
+ helper.addPrefix(extendedMetaData.getName(entry
+ .getEStructuralFeature()), uri == null ? ""
+ : uri);
+ }
+ }
+ }
+ boolean shouldSaveType = saveTypeInfo ?
+ xmlTypeInfo.shouldSaveType(eClass, eType, f) : eClass != eType
+ && ((eClass != anyType && eClass != SDOPackage.Literals.ANY_TYPE_DATA_OBJECT)
+ || extendedMetaData == null
+ || (eType != EcorePackage.Literals.EOBJECT && eClass != SDOPackage.Literals.ANY_TYPE_DATA_OBJECT) || extendedMetaData
+ .getFeatureKind(f) == ExtendedMetaData.UNSPECIFIED_FEATURE);
+ EDataType eDataType = null;
+ if (shouldSaveType) {
+ EClassifier eClassifier = eClass == anySimpleType ? eDataType = ((SimpleAnyType) o)
+ .getInstanceType()
+ : eClass;
+ if (elementHandler != null) {
+ EStructuralFeature substitutionGroup = featureTable
+ .getSubstitutionGroup(f, eClassifier);
+ if (substitutionGroup != null) {
+ f = substitutionGroup;
+ shouldSaveType = substitutionGroup.getEType() != eClassifier;
+ }
+ }
+ }
+
+ if (!toDOM) {
+ String featureName = helper.getQName(f);
+ doc.startElement(featureName);
+ } else {
+ helper.populateNameInfo(nameInfo, f);
+ if (currentNode == null) {
+ // this is a root element
+ currentNode = document.createElementNS(nameInfo
+ .getNamespaceURI(), nameInfo.getQualifiedName());
+ document.appendChild(currentNode);
+ handler.recordValues(currentNode, o.eContainer(), f, o);
+ } else {
+ currentNode = currentNode.appendChild(document
+ .createElementNS(nameInfo.getNamespaceURI(),
+ nameInfo.getQualifiedName()));
+ handler.recordValues(currentNode, o.eContainer(), f, o);
+ }
+ }
+
+ if (shouldSaveType) {
+ if (eDataType != null) {
+ saveTypeAttribute(eDataType);
+ } else {
+ saveTypeAttribute(eClass);
+ }
+ }
+
+ saveElementID(o);
+ if (isAnyType) {
+ helper.popContext();
+ }
+ }
+
+ /*
+ * TEMPORARILY COPIED FROM BASE CLASS - DO NOT EDIT - WILL BE REMOVED
+ * WHEN WE MOVE TO EMF 2.3
+ */
+ protected boolean saveElementFeatureMap(EObject o, EStructuralFeature f) {
+ List values = (List) helper.getValue(o, f);
+ int size = values.size();
+ for (int i = 0; i < size; i++) {
+ FeatureMap.Entry entry = (FeatureMap.Entry) values.get(i);
+ EStructuralFeature entryFeature = entry.getEStructuralFeature();
+ Object value = entry.getValue();
+ if (entryFeature instanceof EReference) {
+ if (value == null) {
+ saveNil(o, entryFeature);
+ } else {
+ EReference referenceEntryFeature = (EReference) entryFeature;
+ if (referenceEntryFeature.isContainment()) {
+ saveElement((InternalEObject) value, entryFeature);
+ } else if (referenceEntryFeature.isResolveProxies()) {
+ saveFeatureMapElementReference((EObject) value,
+ referenceEntryFeature);
+ } else {
+ saveElementIDRef(o, (EObject) value, entryFeature);
+ }
+ }
+ } else {
+ if (entryFeature == XMLTypePackage.eINSTANCE
+ .getXMLTypeDocumentRoot_Text()) {
+ String svalue = value.toString();
+ if (escape != null) {
+ svalue = escape.convertText(svalue);
+ }
+ if (!toDOM) {
+ doc.addText(svalue);
+ } else {
+ Node text = document.createTextNode(svalue);
+ currentNode.appendChild(text);
+ handler.recordValues(text, o, f, entry);
+ }
+ } else if (entryFeature == XMLTypePackage.eINSTANCE
+ .getXMLTypeDocumentRoot_CDATA()) {
+ String stringValue = value.toString();
+ if (escape != null) {
+ stringValue = escape.convertLines(stringValue);
+ }
+ if (!toDOM) {
+ doc.addCDATA(stringValue);
+ } else {
+ Node cdata = document
+ .createCDATASection(stringValue);
+ currentNode.appendChild(cdata);
+ handler.recordValues(cdata, o, f, entry);
+ }
+ } else if (entryFeature == XMLTypePackage.eINSTANCE
+ .getXMLTypeDocumentRoot_Comment()) {
+ String stringValue = value.toString();
+ if (escape != null) {
+ stringValue = escape.convertLines(stringValue);
+ }
+ if (!toDOM) {
+ doc.addComment(stringValue);
+ } else {
+ // TODO comments are not sent to recordValues
+ currentNode.appendChild(document
+ .createComment(stringValue));
+ }
+ } else {
+ saveElement(o, value, entryFeature);
+ }
+ }
+ }
+ return size > 0;
+ }
+
+ protected final void saveElement(EObject o, Object value,
+ EStructuralFeature f) {
+ if (f.getEType() == ChangeSummaryStreamSerializer.ChangeSummary_TYPE) {
+ saveChangeSummary(o, f, value);
+ return;
+ }
+ /*
+ * super.saveElement(o, value, f); TEMPORARILY COPIED FROM BASE
+ * CLASS - DO NOT EDIT - WILL BE REMOVED WHEN WE MOVE TO EMF 2.3
+ */
+ if (value == null) {
+ saveNil(o, f);
+ } else {
+ String svalue = getDatatypeValue(value, f, false);
+ if (!toDOM) {
+ doc.saveDataValueElement(helper.getQName(f), svalue);
+ } else {
+ helper.populateNameInfo(nameInfo, f);
+ Element elem = document.createElementNS(nameInfo
+ .getNamespaceURI(), nameInfo.getQualifiedName());
+ Node text = document.createTextNode(svalue);
+ elem.appendChild(text);
+ currentNode.appendChild(elem);
+ handler.recordValues(elem, o, f, value);
+ handler.recordValues(text, o, f, value);
+ }
+ }
+ }
+ }
+
+ protected XMLSave createXMLSave() {
+ return new SDOXMLSaveImpl(createXMLHelper());
+ }
+}