blob: 4acc9f84808eaa8771269b6e2d45df2b159fec1b [file] [log] [blame]
/*
* Copyright (c) 2006, 2016 IBM Corporation, CEA, 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
* Kenn Hussey (CEA) - 327039, 351774, 464702
*
*/
package org.eclipse.uml2.uml.internal.resource;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.EMOFExtendedMetaData;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.Behavior;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.ProtocolTransition;
import org.eclipse.uml2.uml.State;
import org.eclipse.uml2.uml.Transition;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.CMOF2UMLExtendedMetaData;
import org.eclipse.uml2.uml.resource.CMOF2UMLResource;
import org.eclipse.uml2.uml.util.UMLUtil;
public class XMI2UMLSaveImpl
extends UMLSaveImpl {
protected static class Lookup
extends UMLSaveImpl.Lookup {
public Lookup(XMLResource.XMLMap map, ExtendedMetaData extendedMetaData) {
super(map, extendedMetaData);
}
@Override
protected int featureKind(EStructuralFeature f) {
if (f == UMLPackage.Literals.BEHAVIOR__POSTCONDITION
|| f == UMLPackage.Literals.BEHAVIOR__PRECONDITION
|| f == UMLPackage.Literals.CONSTRAINT__CONTEXT
|| f == UMLPackage.Literals.ELEMENT_IMPORT__IMPORTING_NAMESPACE
|| f == UMLPackage.Literals.OPERATION__BODY_CONDITION
|| f == UMLPackage.Literals.OPERATION__POSTCONDITION
|| f == UMLPackage.Literals.OPERATION__PRECONDITION
|| f == UMLPackage.Literals.PACKAGE_IMPORT__IMPORTING_NAMESPACE
|| f == UMLPackage.Literals.PROFILE__METACLASS_REFERENCE
|| f == UMLPackage.Literals.PROFILE__METAMODEL_REFERENCE
|| f == UMLPackage.Literals.PROTOCOL_TRANSITION__POST_CONDITION
|| f == UMLPackage.Literals.PROTOCOL_TRANSITION__PRE_CONDITION
|| f == UMLPackage.Literals.STATE__STATE_INVARIANT
|| f == UMLPackage.Literals.TRANSITION__GUARD) {
return TRANSIENT;
}
return !f.isTransient()
&& ((EStructuralFeature.Internal) f).isContainer()
? (f.isUnsettable()
? OBJECT_HREF_SINGLE_UNSETTABLE
: OBJECT_HREF_SINGLE)
: ((f == UMLPackage.Literals.CONNECTABLE_ELEMENT__END
|| f == UMLPackage.Literals.VERTEX__INCOMING
|| f == UMLPackage.Literals.VERTEX__OUTGOING)
? OBJECT_HREF_MANY
: super.featureKind(f));
}
}
protected static final String CMOF_XMLNS = XMLResource.XML_NS + ':'
+ CMOF2UMLResource.CMOF_METAMODEL_NS_PREFIX;
protected static final String CMOF_URI = CMOF2UMLResource.CMOF_METAMODEL_NS_URI;
protected boolean declareCMOF = false;
public XMI2UMLSaveImpl(XMLHelper helper) {
super(helper);
}
@Override
public void addNamespaceDeclarations() {
super.addNamespaceDeclarations();
if (declareCMOF) {
doc.addAttribute(CMOF_XMLNS, CMOF_URI);
}
}
@Override
protected void init(XMLResource resource, Map<?, ?> options) {
super.init(resource, options);
featureTable = new Lookup(map, extendedMetaData);
}
@Override
protected void saveContainedMany(EObject eObject,
EStructuralFeature eStructuralFeature) {
if (eStructuralFeature == EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS) {
doc.startElement(EMOFExtendedMetaData.XMI_EXTENSION_ELEMENT);
doc.addAttribute(EMOFExtendedMetaData.XMI_EXTENDER_ATTRIBUTE,
EcorePackage.eNS_URI);
super.saveContainedMany(eObject, eStructuralFeature);
doc.endElement();
} else if (eStructuralFeature == UMLPackage.Literals.NAMESPACE__ELEMENT_IMPORT) {
if (eObject instanceof Profile) {
@SuppressWarnings("unchecked")
List<? extends InternalEObject> metaclassReferences = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.PROFILE__METACLASS_REFERENCE))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, metaclassReferences.contains(value)
? UMLPackage.Literals.PROFILE__METACLASS_REFERENCE
: UMLPackage.Literals.NAMESPACE__ELEMENT_IMPORT);
}
}
} else {
super.saveContainedMany(eObject, eStructuralFeature);
}
} else if (eStructuralFeature == UMLPackage.Literals.NAMESPACE__OWNED_RULE) {
if (eObject instanceof Behavior) {
@SuppressWarnings("unchecked")
List<? extends InternalEObject> postcondition = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.BEHAVIOR__POSTCONDITION))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> precondition = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.BEHAVIOR__PRECONDITION))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, postcondition.contains(value)
? UMLPackage.Literals.BEHAVIOR__POSTCONDITION
: (precondition.contains(value)
? UMLPackage.Literals.BEHAVIOR__PRECONDITION
: UMLPackage.Literals.NAMESPACE__OWNED_RULE));
}
}
} else if (eObject instanceof Operation) {
Object bodyCondition = helper.getValue(eObject,
UMLPackage.Literals.OPERATION__BODY_CONDITION);
@SuppressWarnings("unchecked")
List<? extends InternalEObject> postcondition = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.OPERATION__POSTCONDITION))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> precondition = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.OPERATION__PRECONDITION))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, bodyCondition == value
? UMLPackage.Literals.OPERATION__BODY_CONDITION
: (postcondition.contains(value)
? UMLPackage.Literals.OPERATION__POSTCONDITION
: (precondition.contains(value)
? UMLPackage.Literals.OPERATION__PRECONDITION
: UMLPackage.Literals.NAMESPACE__OWNED_RULE)));
}
}
} else if (eObject instanceof ProtocolTransition) {
Object postCondition = helper.getValue(eObject,
UMLPackage.Literals.PROTOCOL_TRANSITION__POST_CONDITION);
Object preCondition = helper.getValue(eObject,
UMLPackage.Literals.PROTOCOL_TRANSITION__PRE_CONDITION);
Object guard = helper.getValue(eObject,
UMLPackage.Literals.TRANSITION__GUARD);
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, postCondition == value
? UMLPackage.Literals.PROTOCOL_TRANSITION__POST_CONDITION
: (preCondition == value
? UMLPackage.Literals.PROTOCOL_TRANSITION__PRE_CONDITION
: (guard == value
? UMLPackage.Literals.TRANSITION__GUARD
: UMLPackage.Literals.NAMESPACE__OWNED_RULE)));
}
}
} else if (eObject instanceof State) {
Object stateInvariant = helper.getValue(eObject,
UMLPackage.Literals.STATE__STATE_INVARIANT);
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, stateInvariant == value
? UMLPackage.Literals.STATE__STATE_INVARIANT
: UMLPackage.Literals.NAMESPACE__OWNED_RULE);
}
}
} else if (eObject instanceof Transition) {
Object guard = helper.getValue(eObject,
UMLPackage.Literals.TRANSITION__GUARD);
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, guard == value
? UMLPackage.Literals.TRANSITION__GUARD
: UMLPackage.Literals.NAMESPACE__OWNED_RULE);
}
}
} else {
super.saveContainedMany(eObject, eStructuralFeature);
}
} else if (eStructuralFeature == UMLPackage.Literals.NAMESPACE__PACKAGE_IMPORT) {
if (eObject instanceof Profile) {
@SuppressWarnings("unchecked")
List<? extends InternalEObject> metamodelReferences = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject,
UMLPackage.Literals.PROFILE__METAMODEL_REFERENCE))
.basicList();
@SuppressWarnings("unchecked")
List<? extends InternalEObject> values = ((InternalEList<? extends InternalEObject>) helper
.getValue(eObject, eStructuralFeature)).basicList();
int size = values.size();
for (int i = 0; i < size; i++) {
InternalEObject value = values.get(i);
if (value != null) {
saveElement(value, metamodelReferences.contains(value)
? UMLPackage.Literals.PROFILE__METAMODEL_REFERENCE
: UMLPackage.Literals.NAMESPACE__PACKAGE_IMPORT);
}
}
} else {
super.saveContainedMany(eObject, eStructuralFeature);
}
} else {
super.saveContainedMany(eObject, eStructuralFeature);
}
}
@Override
protected Object writeTopObject(EObject top) {
return writeTopObjects(Collections.singletonList(top));
}
@Override
public Object writeTopObjects(List<? extends EObject> contents) {
if (!toDOM) {
doc.startElement(XMI_TAG_NS);
Object mark = doc.mark();
for (int i = 0, size = contents.size(); i < size; i++) {
EObject top = contents.get(i);
EClass eClass = top.eClass();
if (extendedMetaData == null
|| featureTable.getDocumentRoot(eClass.getEPackage()) != eClass) {
String name = helper.getQName(eClass);
doc.startElement(name);
root = top;
saveElementID(top);
} else {
doc.startElement(null);
root = top;
saveFeatures(top);
doc.addLine();
}
}
int index = contents.size();
for (Iterator<EObject> properContents = EcoreUtil
.getAllProperContents(contents, false); properContents
.hasNext();) {
EObject eObject = properContents.next();
if (eObject instanceof Profile) {
Profile profile = (Profile) eObject;
String nsPrefix = (String) UMLUtil.getTaggedValue(profile,
UMLUtil.PROFILE__ECORE + NamedElement.SEPARATOR
+ UMLUtil.STEREOTYPE__E_PACKAGE,
UMLUtil.TAG_DEFINITION__NS_PREFIX);
if (nsPrefix == null) {
nsPrefix = profile.getName();
}
if (!UML2Util.isEmpty(nsPrefix)) {
declareCMOF = true;
doc.startElement(CMOF2UMLExtendedMetaData.CMOF_TAG);
doc.addAttribute(idAttributeName, "_" + index++); //$NON-NLS-1$
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_NAME,
CMOF2UMLExtendedMetaData.XMI_TAG__NS_PREFIX);
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_VALUE, nsPrefix);
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_ELEMENT,
helper.getIDREF(profile));
doc.endEmptyElement();
}
String nsURI = (String) UMLUtil.getTaggedValue(profile,
UMLUtil.PROFILE__ECORE + NamedElement.SEPARATOR
+ UMLUtil.STEREOTYPE__E_PACKAGE,
UMLUtil.TAG_DEFINITION__NS_URI);
if (nsURI == null) {
nsURI = profile.getURI();
}
if (!UML2Util.isEmpty(nsURI)) {
declareCMOF = true;
doc.startElement(CMOF2UMLExtendedMetaData.CMOF_TAG);
doc.addAttribute(idAttributeName, "_" + index++); //$NON-NLS-1$
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_NAME,
CMOF2UMLExtendedMetaData.XMI_TAG__NS_URI);
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_VALUE, nsURI);
doc.addAttribute(
CMOF2UMLExtendedMetaData.CMOF_TAG_ELEMENT,
helper.getIDREF(profile));
doc.endEmptyElement();
}
}
}
doc.endElement();
return mark;
} else {
return super.writeTopObjects(contents);
}
}
}