// $Id: ExtensionMechanismsHelperEUMLImpl.java 18901 2010-12-08 09:50:27Z thn $
/*******************************************************************************
* Copyright (c) 2007,2010 Tom Morris and other contributors
* 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:
* Tom Morris - initial framework
* thn
*****************************************************************************/
package org.argouml.model.euml;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.argouml.model.ExtensionMechanismsHelper;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Extension;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;
/**
* The implementation of the ExtensionMechanismsHelper for EUML2.
*/
class ExtensionMechanismsHelperEUMLImpl implements ExtensionMechanismsHelper {
/**
* The model implementation.
*/
private EUMLModelImplementation modelImpl;
/**
* Constructor.
*
* @param implementation The ModelImplementation.
*/
public ExtensionMechanismsHelperEUMLImpl(
EUMLModelImplementation implementation) {
modelImpl = implementation;
}
public void addBaseClass(Object handle, Object baseClass) {
if (handle instanceof Stereotype) {
org.eclipse.uml2.uml.Class metaclass = getMetaclass(baseClass);
Profile profile = ((Stereotype) handle).getProfile();
if (metaclass != null && profile != null) {
profile.createMetaclassReference(metaclass);
((Stereotype) handle).createExtension(metaclass, false);
return;
}
}
throw new IllegalArgumentException(
"Not a Stereotype or illegal base class"); //$NON-NLS-1$
}
public void addCopyStereotype(Object modelElement, Object stereotype) {
modelImpl.getCoreHelper().addStereotype(modelElement, stereotype);
}
public void addExtendedElement(Object handle, Object extendedElement) {
// TODO: Auto-generated method stub
}
public void addTaggedValue(Object handle, Object taggedValue) {
// TODO: Auto-generated method stub
}
public void applyProfile(Object handle, Object profile) {
if (profile instanceof Profile) {
if (((Profile) profile).isDefined()) {
if (handle instanceof Model) {
((Model) handle).applyProfile((Profile) profile);
} else if (handle instanceof Profile) {
((Profile) handle).applyProfile((Profile) profile);
}
}
// also apply subprofiles:
Iterator<Package> iter = ((Profile) profile).getNestedPackages()
.iterator();
while (iter.hasNext()) {
Package p = iter.next();
if (p instanceof Profile) {
applyProfile(handle, p);
}
}
}
}
public Collection getAllPossibleStereotypes(Collection models,
Object modelElement) {
List<Stereotype> ret = new ArrayList<Stereotype>();
if (modelElement instanceof Element) {
for (Stereotype stereo : getStereotypes(models)) {
if (((Element) modelElement).isStereotypeApplicable(stereo)) {
ret.add(stereo);
}
}
}
return ret;
}
@Deprecated
public String getMetaModelName(Object m) {
if (m instanceof Element) {
return getMetaModelName(m.getClass());
}
throw new IllegalArgumentException("Not an Element"); //$NON-NLS-1$
}
/**
* @param clazz the UML class
* @return the meta name of the UML class
*/
protected String getMetaModelName(Class clazz) {
return modelImpl.getMetaTypes().getName(clazz);
}
public Object getStereotype(Object ns, Object stereo) {
if (!(ns instanceof Profile)) {
throw new IllegalArgumentException("profile"); //$NON-NLS-1$
}
if (!(stereo instanceof Stereotype)) {
throw new IllegalArgumentException("stereotype"); //$NON-NLS-1$
}
String name = ((Stereotype) stereo).getName();
Collection<Class> baseClasses = ((Stereotype) stereo)
.getAllExtendedMetaclasses();
if (name == null || baseClasses.size() != 1) {
return null;
}
Class baseClass = baseClasses.iterator().next();
for (Stereotype o : getStereotypes(ns)) {
if (name.equals(o.getName())
&& o.getAllExtendedMetaclasses().contains(baseClass)) {
return o;
}
}
return null;
}
public Object getStereotype(Collection models, Object stereo) {
if (stereo == null) {
throw new IllegalArgumentException("null argument"); //$NON-NLS-1$
}
if (!(stereo instanceof Stereotype)) {
throw new IllegalArgumentException("stereotype"); //$NON-NLS-1$
}
String name = ((Stereotype) stereo).getName();
Collection<Class> baseClasses = ((Stereotype) stereo)
.getAllExtendedMetaclasses();
if (name == null || baseClasses.size() != 1) {
return null;
}
Class baseClass = baseClasses.iterator().next();
for (Model model : ((Collection<Model>) models)) {
// TODO: this should call the single namespace form
// getStereotype(it2.next(); stereo);
for (Stereotype o : getStereotypes(model)) {
if (name.equals(o.getName())
&& o.getAllExtendedMetaclasses().contains(baseClass)) {
return o;
}
}
}
return null;
}
public Collection<Stereotype> getStereotypes(Object ns) {
if (ns instanceof Profile) {
return new ArrayList<Stereotype>(((Profile) ns).getOwnedStereotypes());
}
return Collections.emptySet();
}
public Collection<Stereotype> getStereotypes(Collection models) {
Collection<Stereotype> l = new ArrayList<Stereotype>();
if (models != null) {
for (Object ns : models) {
if (ns instanceof Profile) {
l.addAll(((Profile) ns).getOwnedStereotypes());
// TODO: Do we really want stereotypes from nested packages?
Iterator<Package> iter = ((Profile) ns).getNestedPackages()
.iterator();
while (iter.hasNext()) {
Package p = iter.next();
if (p instanceof Profile) {
l.addAll(getAllStereotypesIn((Profile) p));
}
}
}
}
}
return l;
}
public boolean hasStereotype(Object handle, String name) {
if (name == null || !(handle instanceof Element)) {
throw new IllegalArgumentException();
}
Element element = (Element) handle;
if (element.getAppliedStereotype(name) != null) {
return true;
}
return false;
}
public boolean isStereotype(Object object, String name, String base) {
if (!(object instanceof Stereotype)) {
return false;
}
Stereotype st = (Stereotype) object;
if (name == null && st.getName() != null) {
return false;
}
if (base == null && !(st.getAllExtendedMetaclasses().isEmpty())) {
return false;
}
for (Class c : st.getAllExtendedMetaclasses()) {
if (c.getName().equals(base)) {
return true;
}
}
return false;
}
public boolean isStereotypeInh(Object object, String name, String base) {
if (!(object instanceof Stereotype)) {
return false;
}
if (isStereotype(object, name, base)) {
return true;
}
/*
* TODO: mvw: do we really look into super-types of the stereotype, or
* should we be looking into super-types of the baseclass?
*/
Iterator it = modelImpl.getCoreHelper().getSupertypes(object)
.iterator();
while (it.hasNext()) {
if (isStereotypeInh(it.next(), name, base)) {
return true;
}
}
return false;
}
public boolean isValidStereotype(Object theModelElement,
Object theStereotype) {
if (theModelElement instanceof Element
&& theStereotype instanceof Stereotype) {
return ((Element) theModelElement)
.isStereotypeApplicable((Stereotype) theStereotype);
}
return false;
}
public void removeBaseClass(Object handle, Object baseClass) {
if (handle instanceof Stereotype) {
org.eclipse.uml2.uml.Class metaclass = getMetaclass(baseClass);
Profile profile = ((Stereotype) handle).getProfile();
if (metaclass != null && profile != null) {
Stereotype st = (Stereotype) handle;
for (Extension ext : profile.getOwnedExtensions(false)) {
if (ext.getMetaclass() == metaclass
&& ext.getEndTypes().contains(st)) {
for (Property p : st.getAttributes()) {
Association assoc = p.getAssociation();
if (assoc != null && assoc == ext) {
// additional cleanup needed, because
// this would not be removed by ext.destroy():
p.destroy();
break;
}
}
// remove base class by destroying the extension
ext.destroy();
break;
}
}
return;
}
}
throw new IllegalArgumentException(
"Not a Stereotype or illegal base class"); //$NON-NLS-1$
}
public void removeTaggedValue(Object handle, Object taggedValue) {
// TODO: Auto-generated method stub
}
public void setIcon(Object handle, Object icon) {
// TODO: Auto-generated method stub
}
public void setTaggedValue(Object handle, Collection taggedValues) {
// TODO: Auto-generated method stub
}
public void setTagType(Object handle, String tagType) {
// TODO: Auto-generated method stub
}
public void setType(Object handle, Object type) {
// TODO: Auto-generated method stub
}
public void setValueOfTag(Object handle, String value) {
// TODO: Auto-generated method stub
}
public void setDataValues(Object handle, String[] value) {
// TODO: Auto-generated method stub
}
public void unapplyProfile(Object handle, Object profile) {
if (profile instanceof Profile) {
if (handle instanceof Package) {
((Model) handle).unapplyProfile((Profile) profile);
} else if (handle instanceof Profile) {
((Profile) handle).unapplyProfile((Profile) profile);
}
// also unapply subprofiles:
Iterator<Package> iter = ((Profile) profile).getNestedPackages()
.iterator();
while (iter.hasNext()) {
Package p = iter.next();
if (p instanceof Profile) {
unapplyProfile(handle, p);
}
}
}
}
public Object makeProfileApplicable(Object handle) {
Object result = null;
if (handle instanceof Profile) {
result = ((Profile) handle).define();
// also define subprofiles:
Iterator<Package> iter = ((Profile) handle).getNestedPackages()
.iterator();
while (iter.hasNext()) {
Package p = iter.next();
if (p instanceof Profile) {
makeProfileApplicable(p);
}
}
}
return result;
}
private Collection<Stereotype> getAllStereotypesIn(Profile p) {
List<Stereotype> l = new ArrayList<Stereotype>();
Iterator<Element> iter = p.getOwnedElements().iterator();
while (iter.hasNext()) {
Element elem = iter.next();
if (elem instanceof Stereotype) {
l.add((Stereotype) elem);
} else if (elem instanceof Profile) {
l.addAll(getAllStereotypesIn((Profile) elem));
}
}
return l;
}
private org.eclipse.uml2.uml.Class getMetaclass(Object baseClass) {
org.eclipse.uml2.uml.Class metaclass = null;
if (baseClass instanceof String) {
URI uri = URI.createURI(UMLResource.UML_METAMODEL_URI);
ResourceSet rs = modelImpl.getEditingDomain().getResourceSet();
Resource res = rs.getResource(uri, true);
Model m = (Model) EcoreUtil.getObjectByType(res.getContents(),
UMLPackage.Literals.PACKAGE);
metaclass = (org.eclipse.uml2.uml.Class) m
.getOwnedType((String) baseClass);
} else if (baseClass instanceof org.eclipse.uml2.uml.Class) {
metaclass = (org.eclipse.uml2.uml.Class) baseClass;
}
return metaclass;
}
}