blob: f814c7c8e4793e864b522ac358f388736974a71b [file] [log] [blame]
/**
* Copyright (c) 2002-2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.ecore.xmi.impl;
import java.util.Map;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* This class is a SAX handler for creating MOF2 objects from an XMI 2.0 file.
*/
public abstract class XMIHandler extends XMLHandler
{
protected static final String XMI_ELEMENT_TYPE = "xmi";
protected static final String XMI_UUID = "uuid";
protected static final String XMI_EXTENSION = "Extension";
protected final static String XMI_TYPE_ATTRIB = XMIResource.XMI_NS + ":" + XMLResource.TYPE;
protected final static String ID_ATTRIB = XMIResource.XMI_NS + ":" + XMIResource.XMI_ID;
protected final static String VERSION_ATTRIB = XMIResource.XMI_NS + ":" + XMIResource.VERSION_NAME;
protected final static String UUID_ATTRIB = XMIResource.XMI_NS + ":" + XMI_UUID;
protected final static String XMI_ELEMENT_NAME = XMIResource.XMI_NS + ":" + XMIResource.XMI_TAG_NAME;
/**
* Constructor.
*/
public XMIHandler(XMLResource xmiResource, XMLHelper helper, Map<?, ?> options)
{
super(xmiResource, helper, options);
hrefAttribute = XMLResource.HREF;
notFeatures.add(VERSION_ATTRIB);
notFeatures.add(XMI_TYPE_ATTRIB);
notFeatures.add(UUID_ATTRIB);
}
@Override
protected void processElement(String name, String prefix, String localName)
{
if (localName.equals(XMIResource.XMI_TAG_NAME))
{
types.push(XMI_ELEMENT_TYPE);
String namespace = helper.getURI(XMIResource.XMI_NS);
if (namespace != null && namespace.startsWith(XMIResource.XMI_NAMESPACE_PREFIX))
{
((XMIResource)xmlResource).setXMIVersion(namespace.substring(XMIResource.XMI_NAMESPACE_PREFIX.length()));
}
isRoot = false;
}
else if (isRoot)
{
String namespace = helper.getURI(XMIResource.XMI_NS);
if (namespace != null && namespace.startsWith(XMIResource.XMI_NAMESPACE_PREFIX))
{
((XMIResource)xmlResource).setXMIVersion(namespace.substring(XMIResource.XMI_NAMESPACE_PREFIX.length()));
}
super.processElement(name, prefix, localName);
}
else
{
super.processElement(name, prefix, localName);
}
}
@Override
protected boolean isTextFeatureValue(Object type)
{
return super.isTextFeatureValue(type) && type != XMI_ELEMENT_TYPE;
}
@Override
protected EObject createDocumentRoot(String prefix, String uri, String name, EFactory eFactory, boolean top)
{
if (extendedMetaData != null && eFactory != null && extendedMetaData.demandedPackages().contains(eFactory.getEPackage()))
{
EClass eClass = (EClass)extendedMetaData.demandType(uri, name);
@SuppressWarnings("deprecation") EObject newObject = useNewMethods ? createObject(eFactory, eClass, true) : helper.createObject(eFactory, name);
validateCreateObjectFromFactory(eFactory, name, newObject);
handleObjectAttribs(newObject);
if (top)
{
processTopObject(newObject);
}
return newObject;
}
else
{
return super.createDocumentRoot(prefix, uri, name, eFactory, top);
}
}
@Override
protected void createObject(EObject peekObject, EStructuralFeature feature)
{
String id = attribs.getValue("xmi:idref");
if (id != null)
{
EReference eReference = (EReference)feature;
if (!eReference.isContainment())
{
if (eReference.isMany())
{
if (eReference.isResolveProxies() && (!eReference.getEReferenceType().isAbstract() || getXSIType() != null))
{
super.createObject(peekObject, feature);
return;
}
else
{
SingleReference ref = new SingleReference
(peekObject,
eReference,
id,
-1,
getLineNumber(),
getColumnNumber());
forwardSingleReferences.add(ref);
}
}
else
{
setValueFromId(peekObject, eReference, id);
}
objects.push(null);
mixedTargets.push(null);
types.push(OBJECT_TYPE);
return;
}
}
super.createObject(peekObject, feature);
}
@Override
protected void handleUnknownFeature(String prefix, String name, boolean isElement, EObject peekObject, String value)
{
if (XMI_EXTENSION.equals(name) && XMLContentHandlerImpl.isXMINamespace(helper.getURI(prefix)))
{
if (extendedMetaData == null)
{
setExtendedMetaDataOption(Boolean.TRUE);
}
recordUnknownFeature(prefix, name, isElement, peekObject, value);
}
else if ("idref".equals(name) && XMLContentHandlerImpl.isXMINamespace(helper.getURI(prefix)))
{
handleProxy((InternalEObject)peekObject, "#" + value);
}
else
{
super.handleUnknownFeature(prefix, name, isElement, peekObject, value);
}
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException
{
if (documentRoot != null)
{
EObject eObject = objects.peekEObject();
if (eObject == documentRoot && (extendedMetaData == null || extendedMetaData.isDocumentRoot(eObject.eClass())))
{
types.pop();
objects.pop();
mixedTargets.pop();
documentRoot= null;
}
}
super.startElement(uri, localName, name, attributes);
}
} // XMIHandler