/* $Id: CoreHelperMDRImpl.java 18923 2010-12-18 12:19:00Z bobtarling $ ***************************************************************************** * Copyright (c) 2009-2010 Contributors - see below * 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: * Thomas Neustupny * Michiel van der Wulp * Tom Morris ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 2005-2008 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.model.mdr; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.jmi.reflect.InvalidObjectException; import org.apache.log4j.Logger; import org.argouml.model.CoreFactory; import org.argouml.model.CoreHelper; import org.argouml.model.InvalidElementException; import org.argouml.model.Model; import org.argouml.model.ModelCommand; import org.argouml.model.ModelManagementHelper; import org.argouml.model.NotImplementedException; import org.argouml.model.mdr.UndoCoreHelperDecorator.StringSetter; import org.omg.uml.behavioralelements.activitygraphs.ActivityGraph; import org.omg.uml.behavioralelements.activitygraphs.ClassifierInState; import org.omg.uml.behavioralelements.activitygraphs.ObjectFlowState; import org.omg.uml.behavioralelements.activitygraphs.Partition; import org.omg.uml.behavioralelements.collaborations.AssociationEndRole; import org.omg.uml.behavioralelements.collaborations.AssociationRole; import org.omg.uml.behavioralelements.collaborations.ClassifierRole; import org.omg.uml.behavioralelements.collaborations.Collaboration; import org.omg.uml.behavioralelements.collaborations.CollaborationInstanceSet; import org.omg.uml.behavioralelements.collaborations.Interaction; import org.omg.uml.behavioralelements.collaborations.Message; import org.omg.uml.behavioralelements.commonbehavior.Action; import org.omg.uml.behavioralelements.commonbehavior.AttributeLink; import org.omg.uml.behavioralelements.commonbehavior.ComponentInstance; import org.omg.uml.behavioralelements.commonbehavior.DataValue; import org.omg.uml.behavioralelements.commonbehavior.Instance; import org.omg.uml.behavioralelements.commonbehavior.Link; import org.omg.uml.behavioralelements.commonbehavior.LinkEnd; import org.omg.uml.behavioralelements.commonbehavior.NodeInstance; import org.omg.uml.behavioralelements.commonbehavior.Reception; import org.omg.uml.behavioralelements.commonbehavior.Signal; import org.omg.uml.behavioralelements.commonbehavior.Stimulus; import org.omg.uml.behavioralelements.commonbehavior.SubsystemInstance; import org.omg.uml.behavioralelements.statemachines.CompositeState; import org.omg.uml.behavioralelements.statemachines.Event; import org.omg.uml.behavioralelements.statemachines.Guard; import org.omg.uml.behavioralelements.statemachines.Pseudostate; import org.omg.uml.behavioralelements.statemachines.State; import org.omg.uml.behavioralelements.statemachines.StateMachine; import org.omg.uml.behavioralelements.statemachines.StateVertex; import org.omg.uml.behavioralelements.statemachines.Transition; import org.omg.uml.behavioralelements.usecases.Actor; import org.omg.uml.behavioralelements.usecases.Extend; import org.omg.uml.behavioralelements.usecases.Include; import org.omg.uml.behavioralelements.usecases.UseCase; import org.omg.uml.behavioralelements.usecases.UseCaseInstance; import org.omg.uml.foundation.core.Abstraction; import org.omg.uml.foundation.core.AssociationEnd; import org.omg.uml.foundation.core.Attribute; import org.omg.uml.foundation.core.BehavioralFeature; import org.omg.uml.foundation.core.Binding; import org.omg.uml.foundation.core.Classifier; import org.omg.uml.foundation.core.Comment; import org.omg.uml.foundation.core.Component; import org.omg.uml.foundation.core.Constraint; import org.omg.uml.foundation.core.DataType; import org.omg.uml.foundation.core.Dependency; import org.omg.uml.foundation.core.ElementResidence; import org.omg.uml.foundation.core.Enumeration; import org.omg.uml.foundation.core.EnumerationLiteral; import org.omg.uml.foundation.core.Feature; import org.omg.uml.foundation.core.Flow; import org.omg.uml.foundation.core.GeneralizableElement; import org.omg.uml.foundation.core.Generalization; import org.omg.uml.foundation.core.Interface; import org.omg.uml.foundation.core.Method; import org.omg.uml.foundation.core.ModelElement; import org.omg.uml.foundation.core.Namespace; import org.omg.uml.foundation.core.Node; import org.omg.uml.foundation.core.Operation; import org.omg.uml.foundation.core.Parameter; import org.omg.uml.foundation.core.Permission; import org.omg.uml.foundation.core.Relationship; import org.omg.uml.foundation.core.Stereotype; import org.omg.uml.foundation.core.StructuralFeature; import org.omg.uml.foundation.core.TagDefinition; import org.omg.uml.foundation.core.TaggedValue; import org.omg.uml.foundation.core.TemplateArgument; import org.omg.uml.foundation.core.TemplateParameter; import org.omg.uml.foundation.core.UmlAssociation; import org.omg.uml.foundation.core.UmlClass; import org.omg.uml.foundation.datatypes.AggregationKind; import org.omg.uml.foundation.datatypes.AggregationKindEnum; import org.omg.uml.foundation.datatypes.BooleanExpression; import org.omg.uml.foundation.datatypes.CallConcurrencyKind; import org.omg.uml.foundation.datatypes.ChangeableKind; import org.omg.uml.foundation.datatypes.ChangeableKindEnum; import org.omg.uml.foundation.datatypes.Expression; import org.omg.uml.foundation.datatypes.Multiplicity; import org.omg.uml.foundation.datatypes.OrderingKind; import org.omg.uml.foundation.datatypes.ParameterDirectionKind; import org.omg.uml.foundation.datatypes.ParameterDirectionKindEnum; import org.omg.uml.foundation.datatypes.ProcedureExpression; import org.omg.uml.foundation.datatypes.PseudostateKind; import org.omg.uml.foundation.datatypes.ScopeKind; import org.omg.uml.foundation.datatypes.ScopeKindEnum; import org.omg.uml.foundation.datatypes.VisibilityKind; import org.omg.uml.foundation.datatypes.VisibilityKindEnum; import org.omg.uml.modelmanagement.ElementImport; import org.omg.uml.modelmanagement.Subsystem; import org.omg.uml.modelmanagement.UmlPackage; /** * The Core Helper implementation for MDR.<p> * * @since ARGO0.19.5 * @author Ludovic Maître * @author Tom Morris * derived from NSUML implementation by: * @author Linus Tolke */ class CoreHelperMDRImpl implements CoreHelper { /** * Logger. */ private static final Logger LOG = Logger.getLogger(CoreHelperMDRImpl.class); /** * The model implementation. */ private MDRModelImplementation modelImpl; /** * Constructor. * * @param theModelImpl * The MDRModelImplementation. */ public CoreHelperMDRImpl(MDRModelImplementation theModelImpl) { super(); modelImpl = theModelImpl; } /** * Return the first item from a collection using the most efficient method * possible. Returns null for an empty collection. * * @param c * The Collection. * @return the first element of a Collection. */ private static Object getFirstItemOrNull(Collection c) { if (c.size() == 0) { return null; } if (c instanceof List) { return ((List) c).get(0); } return c.iterator().next(); } public boolean isSubType(Object type, Object subType) { if (!(type instanceof Class) || !(subType instanceof Class)) { throw new IllegalArgumentException("Metatypes are expected"); } return ((Class) type).isAssignableFrom((Class) subType); } public Collection<GeneralizableElement> getAllSupertypes(Object cls1) { if (!(cls1 instanceof Classifier)) { throw new IllegalArgumentException(); } GeneralizableElement ge = (GeneralizableElement) cls1; Collection<GeneralizableElement> result = new HashSet<GeneralizableElement>(); try { Collection<GeneralizableElement> toBeAdded = getSupertypes(ge); do { Collection<GeneralizableElement> newlyAdded = new HashSet<GeneralizableElement>(); for (GeneralizableElement element : toBeAdded) { newlyAdded.addAll(getSupertypes(element)); } result.addAll(toBeAdded); toBeAdded = newlyAdded; toBeAdded.removeAll(result); } while (!toBeAdded.isEmpty()); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<GeneralizableElement> getSupertypes(Object genElement) { Collection<GeneralizableElement> result = new HashSet<GeneralizableElement>(); try { if (genElement instanceof GeneralizableElement) { for (Generalization gen : ((GeneralizableElement) genElement) .getGeneralization()) { result.add(gen.getParent()); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Object> getUtilizedElements(Object artifact) { throw new NotImplementedException("UML 1.4 artifacts have no manifestations with utilized elements"); } public Collection<AssociationEnd> getAssociateEndsInh(Object classifier1) { if (!(classifier1 instanceof Classifier)) { throw new IllegalArgumentException(); } Classifier classifier = (Classifier) classifier1; Collection<AssociationEnd> result = new ArrayList<AssociationEnd>(); try { result.addAll(modelImpl.getFacade().getAssociationEnds(classifier)); for (Generalization gen : classifier.getGeneralization()) { Object parent = gen.getParent(); result.addAll(getAssociateEndsInh(parent)); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public void removeFeature(Object cls, Object feature) { try { if (cls instanceof Classifier && feature instanceof Feature) { ((Classifier) cls).getFeature().remove(feature); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("classifier: " + cls + " or feature: " + feature); } public void removeLiteral(Object enu, Object literal) { try { if (enu instanceof Enumeration && literal instanceof EnumerationLiteral) { ((Enumeration) enu).getLiteral().remove(literal); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("enumeration: " + enu + " or literal: " + literal); } public void setOperations(Object classifier, List operations) { if (classifier instanceof Classifier) { Classifier mclassifier = (Classifier) classifier; List<Feature> result = new ArrayList<Feature>(mclassifier.getFeature()); for (Feature feature : mclassifier.getFeature()) { if (feature instanceof Operation) { result.remove(feature); } } result.addAll(operations); // TODO: A minimal update strategy would be better here to // minimize work and events firing, but it may be better to // deprecate the method and force calls to manage updates // themselves (since they probably usually want to just add // or remove a single element) - tfm 20061108 mclassifier.getFeature().clear(); mclassifier.getFeature().addAll(result); } } public void setAttributes(Object classifier, List attributes) { if (classifier instanceof Classifier) { Classifier mclassifier = (Classifier) classifier; List<Feature> result = new ArrayList<Feature>(mclassifier.getFeature()); for (Feature feature : mclassifier.getFeature()) { if (feature instanceof Attribute) { result.remove(feature); } } result.addAll(attributes); // TODO: This should use a minimal update strategy instead of // removing everything and adding it again. - tfm mclassifier.getFeature().clear(); mclassifier.getFeature().addAll(result); } } public Collection<Attribute> getAttributesInh(Object classifier) { if (!(classifier instanceof Classifier)) { throw new IllegalArgumentException(); } Collection result = new ArrayList(); try { result.addAll(modelImpl.getFacade().getStructuralFeatures( classifier)); for (Generalization gen : ((Classifier) classifier) .getGeneralization()) { result.addAll(getAttributesInh(gen.getParent())); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Operation> getOperationsInh(Object classifier) { if (!(classifier instanceof Classifier)) { throw new IllegalArgumentException(); } Collection<Operation> result = new ArrayList<Operation>(); try { result.addAll(modelImpl.getFacade().getOperations(classifier)); for (Generalization gen : ((Classifier) classifier) .getGeneralization()) { result.addAll(getOperationsInh(gen.getParent())); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<GeneralizableElement> getParents( Object generalizableElement) { if (!(generalizableElement instanceof GeneralizableElement)) { throw new IllegalArgumentException(); } try { return getParents((GeneralizableElement) generalizableElement); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } /** * Return the parents of a GeneralizableElement * @param ge generalizable element * @return parents of all generalizations */ static Collection<GeneralizableElement> getParents( GeneralizableElement ge) { Set<GeneralizableElement> result = new HashSet<GeneralizableElement>(); for (Generalization g : ge.getGeneralization()) { result.add(g.getParent()); } return result; } /** * Return the parents of a GeneralizableElement and parents of those parents * all the way up the hierarchy. * * @param ge generalizable element * @return parents of all generalizations */ static Collection<GeneralizableElement> getAllParents( GeneralizableElement ge) { Collection<GeneralizableElement> result = new HashSet<GeneralizableElement>(2000); getAllParents(result, ge); return result; } private static void getAllParents( final Collection<GeneralizableElement> result, final GeneralizableElement ge) { for (Generalization g : ge.getGeneralization()) { GeneralizableElement parent = g.getParent(); result.add(parent); getAllParents(result, parent); } } /** * A recursive method that iterates through generalizable elements to find * if the model element is visible from any super namespace. * * @param element the model element to test * @param ge the namespace which is a generalizable element * @param dupCheck Used to prevent recursion continuing endlessly due to * cyclic generalizations in the model. This should be an empty Set * except when this method calls itself recursively. * @return true if the model element is visible from any part of the * generalization hierarchy. */ private boolean isVisiblyOwned( final ModelElement element, final GeneralizableElement ge, final Set<ModelElement> dupCheck) { assert dupCheck != null; assert ge != null; assert element != null; final boolean alreadyChecked = !dupCheck.add(ge); if (alreadyChecked) { LOG.warn("Cyclic generalization found " + getFullName(ge)); return false; } for (final Generalization g : ge.getGeneralization()) { final GeneralizableElement parent = g.getParent(); if (parent instanceof Namespace && isVisiblyOwned(element, (Namespace) parent)) { return true; } } for (final Generalization g : ge.getGeneralization()) { // Recurse into ourself for each parent if (isVisiblyOwned(element, g.getParent(), dupCheck)) { return true; } } return false; } private String getFullName(ModelElement elem) { String name = elem.getName(); while (elem.getNamespace() != null) { elem = elem.getNamespace(); name = elem.getName() + "." + name; } return name; } public List<Parameter> getReturnParameters(Object bf) { List<Parameter> returnParams = new ArrayList<Parameter>(); try { for (Parameter parameter : ((BehavioralFeature) bf).getParameter()) { if (ParameterDirectionKindEnum.PDK_RETURN.equals(parameter .getKind())) { returnParams.add(parameter); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return returnParams; } public Object getSpecification(Object object) { if (!(object instanceof Method)) { throw new IllegalArgumentException("Not a method : " + object); } try { return ((Method) object).getSpecification(); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } public Collection<GeneralizableElement> getSubtypes(Object cls) { if (!(cls instanceof Classifier)) { throw new IllegalArgumentException(); } Collection<GeneralizableElement> result = new ArrayList<GeneralizableElement>(); try { Collection<Generalization> gens = Model.getFacade() .getSpecializations(cls); for (Generalization gen : gens) { result.add(gen.getChild()); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<BehavioralFeature> getAllBehavioralFeatures(Object element) { if (!(element instanceof ModelElement)) { throw new IllegalArgumentException(); } List contents = new ArrayList(); List<BehavioralFeature> result = new ArrayList<BehavioralFeature>(); try { contents.addAll(Model.getFacade() .getTaggedValuesCollection(element)); contents.addAll(((ModelElement) element).getTemplateParameter()); Iterator it = contents.iterator(); while (it.hasNext()) { Object o = it.next(); if (o instanceof Classifier) { Classifier clazz = (Classifier) o; if (!(clazz instanceof DataType)) { for (Object o1 : clazz.getFeature()) { if (o1 instanceof BehavioralFeature) { result.add((BehavioralFeature) o1); } } } } else { // TODO: 2nd next() for single hasNext() result.addAll(getAllBehavioralFeatures(it.next())); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public List<BehavioralFeature> getBehavioralFeatures(Object clazz) { if (clazz instanceof Classifier) { List<BehavioralFeature> ret = new ArrayList<BehavioralFeature>(); try { for (Object o : modelImpl.getFacade().getFeatures(clazz)) { if (o instanceof BehavioralFeature) { ret.add((BehavioralFeature) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return ret; } else { throw new IllegalArgumentException("Argument is not a classifier"); } } public Collection<Interface> getAllInterfaces(Object ns) { if (ns == null) { return Collections.EMPTY_SET; } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } List<Interface> result = new ArrayList<Interface>(); for (Object o : ((Namespace) ns).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllInterfaces(o)); } if (o instanceof Interface) { result.add((Interface) o); } } return result; } public Collection<UmlClass> getAllClasses(Object ns) { if (ns == null) { return Collections.EMPTY_SET; } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } List<UmlClass> result = new ArrayList<UmlClass>(); try { for (Object o : ((Namespace) ns).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllClasses(o)); } if (o instanceof UmlClass) { result.add((UmlClass) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Interface> getRealizedInterfaces(Object cls) { Classifier classifier = (Classifier) cls; if (classifier == null) { return Collections.emptyList(); } List<Interface> result = new ArrayList<Interface>(); // TODO: This should be using internalGetAllRealizedInterfaces() try { for (Dependency clientDependency : classifier.getClientDependency()) { if (clientDependency instanceof Abstraction) { Abstraction abstraction = (Abstraction) clientDependency; for (Stereotype stereo : abstraction.getStereotype()) { if (stereo != null && CoreFactory.REALIZE_STEREOTYPE.equals(stereo .getName()) // the following should always be true && stereo.getBaseClass() .contains("Abstraction")) { for (Object supplier : abstraction.getSupplier()) { if (supplier instanceof Interface) { result.add((Interface) supplier); } } } } } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Classifier> getExtendedClassifiers(Object clazz) { if (clazz == null) { return Collections.EMPTY_SET; } List<Classifier> result = new ArrayList<Classifier>(); try { for (Object gen : modelImpl.getFacade().getGeneralizations(clazz)) { GeneralizableElement parent = ((Generalization) gen).getParent(); if (parent != null) { // If we were handed a Classifier to start, // this must be a Classifier result.add((Classifier) parent); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Object getGeneralization(Object achild, Object aparent) { if (!(achild instanceof GeneralizableElement) || !(aparent instanceof GeneralizableElement)) { throw new IllegalArgumentException(); } GeneralizableElement child = (GeneralizableElement) achild; GeneralizableElement parent = (GeneralizableElement) aparent; try { Iterator it = modelImpl.getFacade().getGeneralizations(child).iterator(); while (it.hasNext()) { Generalization gen = (Generalization) it.next(); if (gen.getParent() == parent) { return gen; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return null; } public String getBody(Object comment) { if (comment instanceof Comment) { /* * In UML 1.3, the name is the only place to store text. * In UML 1.4, there is a body as well, but some tools * still seem to use name. */ try { return ((Comment) comment).getBody(); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } throw new IllegalArgumentException(); } public Collection<Flow> getFlows(Object source, Object target) { if (!(source instanceof ModelElement)) { throw new IllegalArgumentException("source"); } if (!(target instanceof ModelElement)) { throw new IllegalArgumentException("target"); } List<Flow> ret = new ArrayList<Flow>(); try { Collection<Flow> targetFlows = ((ModelElement) target).getTargetFlow(); for (Flow flow : ((ModelElement) source).getSourceFlow()) { if (targetFlows.contains(flow)) { ret.add(flow); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return ret; } public Collection<GeneralizableElement> getExtendingElements(Object clazz) { if (clazz == null) { return Collections.EMPTY_SET; } List<GeneralizableElement> list = new ArrayList<GeneralizableElement>(); try { for (Generalization gen : (Collection<Generalization>) modelImpl .getFacade().getSpecializations(clazz)) { GeneralizableElement client = gen.getChild(); if (client != null) { list.add(client); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return list; } public Collection<Classifier> getExtendingClassifiers(Object clazz) { if (clazz == null) { return Collections.EMPTY_SET; } if (!(clazz instanceof Classifier)) { throw new IllegalArgumentException(); } List<Classifier> result = new ArrayList<Classifier>(); try { for (Object gen : Model.getFacade().getSpecializations(clazz)) { GeneralizableElement client = ((Generalization) gen).getChild(); if (client instanceof Classifier) { result.add((Classifier) client); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Component> getAllComponents(Object ns) { if (ns == null) { return Collections.EMPTY_SET; } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } List<Component> result = new ArrayList<Component>(); try { for (Object o : ((Namespace) ns).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllComponents(o)); } if (o instanceof Component) { result.add((Component) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<DataType> getAllDataTypes(Object ns) { if (ns == null) { return Collections.EMPTY_SET; } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } List<DataType> result = new ArrayList<DataType>(); try { for (Object o : ((Namespace) ns).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllDataTypes(o)); } if (o instanceof DataType) { result.add((DataType) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Node> getAllNodes(Object ns) { if (ns == null) { return Collections.EMPTY_SET; } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } List<Node> result = new ArrayList<Node>(); try { for (Object o : ((Namespace) ns).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllNodes(o)); } if (o instanceof Node) { result.add((Node) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<Classifier> getAssociatedClassifiers(Object aclassifier) { Classifier classifier = (Classifier) aclassifier; if (classifier == null) { return Collections.EMPTY_SET; } List<Classifier> list = new ArrayList<Classifier>(); try { for (AssociationEnd end : (Collection<AssociationEnd>) Model .getFacade().getAssociationEnds(classifier)) { UmlAssociation assoc = end.getAssociation(); for (AssociationEnd end2 : assoc.getConnection()) { if (end2 != end) { list.add(end2.getParticipant()); } } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return list; } public Collection<UmlAssociation> getAssociations(Object from, Object to) { if (!(from instanceof Classifier) || !(to instanceof Classifier)) { throw new IllegalArgumentException(); } Set<UmlAssociation> ret = new HashSet<UmlAssociation>(); try { for (AssociationEnd end : (Collection<AssociationEnd>) Model .getFacade().getAssociationEnds(from)) { UmlAssociation assoc = end.getAssociation(); for (AssociationEnd end2 : assoc.getConnection()) { if (end2.getParticipant() == to) { ret.add(assoc); } } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return ret; } public Collection<Classifier> getAllClassifiers(Object namespace) { if (namespace == null) { throw new IllegalArgumentException(); } List<Classifier> result = new ArrayList<Classifier>(); try { for (Object o : ((Namespace) namespace).getOwnedElement()) { if (o instanceof Namespace) { result.addAll(getAllClassifiers(o)); } if (o instanceof Classifier) { result.add((Classifier) o); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public Collection<UmlAssociation> getAssociations(Object oclassifier) { Collection<UmlAssociation> result = new ArrayList<UmlAssociation>(); try { if (oclassifier instanceof Classifier) { for (Object end : Model.getFacade().getAssociationEnds( oclassifier)) { result.add(((AssociationEnd) end).getAssociation()); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } public AssociationEnd getAssociationEnd(Object type, Object assoc) { if (!(type instanceof Classifier)) { throw new IllegalArgumentException(); } if (!(assoc instanceof UmlAssociation)) { throw new IllegalArgumentException(); } try { for (AssociationEnd end : (Collection<AssociationEnd>) Model .getFacade().getAssociationEnds(type)) { if (((UmlAssociation) assoc).getConnection().contains(end)) { return end; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return null; } public Collection<Attribute> getAllAttributes(Object clazz) { if (clazz == null) { return Collections.emptySet(); } if (!(clazz instanceof Classifier)) { throw new IllegalArgumentException(); } List<Attribute> list = new ArrayList<Attribute>(); try { for (Feature feature : ((Classifier) clazz).getFeature()) { if (feature instanceof Attribute) { list.add((Attribute) feature); } } for (Object gen : modelImpl.getFacade().getGeneralizations(clazz)) { list.addAll(getAllAttributes(gen)); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return list; } public Collection<ModelElement> getAllVisibleElements(Object ns) { if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } try { return getAllVisibleElements((Namespace) ns); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } /** * Get all publicly visible elements in a namespace. * @param ns the namespace * @return all owned elements with a visibility of VK_PUBLIC */ static Collection<ModelElement> getAllVisibleElements(Namespace ns) { Collection<ModelElement> result = new ArrayList<ModelElement>(); for (ModelElement element : ns.getOwnedElement()) { if (VisibilityKindEnum.VK_PUBLIC.equals(element.getVisibility())) { result.add(element); } } return result; } public Object getSource(Object relationship) { if (!(relationship instanceof Relationship) && !(relationship instanceof Link) && !(relationship instanceof Message) && !(relationship instanceof AssociationEnd)) { throw new IllegalArgumentException("Argument " + relationship.toString() + " is not " + "a relationship"); } try { if (relationship instanceof Link) { Iterator it = modelImpl.getFacade() .getConnections(relationship).iterator(); if (it.hasNext()) { return modelImpl.getFacade().getInstance(it.next()); } else { return null; } } if (relationship instanceof UmlAssociation) { UmlAssociation assoc = (UmlAssociation) relationship; List<AssociationEnd> conns = assoc.getConnection(); if (conns == null || conns.isEmpty()) { return null; } return conns.get(0).getParticipant(); } if (relationship instanceof Generalization) { Generalization gen = (Generalization) relationship; return gen.getChild(); } if (relationship instanceof Dependency) { Dependency dep = (Dependency) relationship; Collection<ModelElement> col = dep.getClient(); if (col.isEmpty()) { return null; } return col.iterator().next(); } if (relationship instanceof Flow) { Flow flow = (Flow) relationship; Collection<ModelElement> col = flow.getSource(); if (col.isEmpty()) { return null; } return col.iterator().next(); } if (relationship instanceof Extend) { Extend extend = (Extend) relationship; return extend.getExtension(); // we have to follow the // arrows.. } if (relationship instanceof Include) { Include include = (Include) relationship; return modelImpl.getFacade().getBase(include); } if (relationship instanceof AssociationEnd) { return ((AssociationEnd) relationship).getAssociation(); } if (relationship instanceof Message) { return ((Message) relationship).getSender(); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return null; } public Object getDestination(Object relationship) { if (!(relationship instanceof Relationship) && !(relationship instanceof Link) && !(relationship instanceof Message) && !(relationship instanceof AssociationEnd)) { throw new IllegalArgumentException("Argument is not " + "a relationship"); } try { if (relationship instanceof Link) { Iterator it = modelImpl.getFacade() .getConnections(relationship).iterator(); if (it.hasNext()) { it.next(); if (it.hasNext()) { return modelImpl.getFacade().getInstance(it.next()); } else { return null; } } else { return null; } } if (relationship instanceof UmlAssociation) { UmlAssociation assoc = (UmlAssociation) relationship; List<AssociationEnd> conns = assoc.getConnection(); if (conns.size() <= 1) { return null; } return conns.get(1).getParticipant(); } if (relationship instanceof Generalization) { Generalization gen = (Generalization) relationship; return gen.getParent(); } if (relationship instanceof Dependency) { Dependency dep = (Dependency) relationship; Collection<ModelElement> col = dep.getSupplier(); if (col.isEmpty()) { return null; } return getFirstItemOrNull(col); } if (relationship instanceof Flow) { Flow flow = (Flow) relationship; Collection<ModelElement> col = flow.getTarget(); if (col.isEmpty()) { return null; } return getFirstItemOrNull(col); } if (relationship instanceof Extend) { Extend extend = (Extend) relationship; return extend.getBase(); } if (relationship instanceof Include) { Include include = (Include) relationship; return modelImpl.getFacade().getAddition(include); } if (relationship instanceof AssociationEnd) { return ((AssociationEnd) relationship).getParticipant(); } if (relationship instanceof Message) { return ((Message) relationship).getReceiver(); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return null; } public Collection<Dependency> getDependencies(Object supplierObj, Object clientObj) { if (!(supplierObj instanceof ModelElement) || !(clientObj instanceof ModelElement)) { throw new IllegalArgumentException("invalid argument(s)"); } ModelElement supplier = (ModelElement) supplierObj; ModelElement client = (ModelElement) clientObj; List<Dependency> ret = new ArrayList<Dependency>(); try { Collection<Dependency> clientDependencies = client .getClientDependency(); Iterator it = Model.getFacade().getSupplierDependencies(supplier).iterator(); while (it.hasNext()) { Dependency dep = (Dependency) it.next(); if (clientDependencies.contains(dep)) { ret.add(dep); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return ret; } public Collection<Permission> getPackageImports(Object client) { if (!(client instanceof Namespace)) { throw new IllegalArgumentException("invalid argument"); } List<Permission> result = new ArrayList<Permission>(); try { for (Dependency dependency : ((ModelElement) client) .getClientDependency()) { if (dependency instanceof Permission && hasImportStereotype((Permission) dependency)) { result.add((Permission) dependency); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return result; } /** * Return true if the given Permission has any of our acceptable * import stereotypes <code>import</code> or <code>access</code>. * <p> * NOTE: We don't currently consider the <code>friend</code> stereotype. * * @param permission Permission to test * @return true if this is an import permission */ private boolean hasImportStereotype(Permission permission) { return (Model.getExtensionMechanismsHelper().hasStereotype(permission, ModelManagementHelper.IMPORT_STEREOTYPE) || Model.getExtensionMechanismsHelper().hasStereotype( permission, ModelManagementHelper.ACCESS_STEREOTYPE) // TODO: Do we want to <<friend>> stereotypes too? // || Model.getExtensionMechanismsHelper().hasStereotype( // permission, ModelManagementHelper.FRIEND_STEREOTYPE) ); } public Permission getPackageImport(Object supplier, Object client) { for (Dependency dependency : getDependencies(supplier, client)) { if (dependency instanceof Permission && Model.getExtensionMechanismsHelper() .hasStereotype(dependency, ModelManagementHelper.IMPORT_STEREOTYPE)) { return (Permission) dependency; } } return null; } public Collection getRelationships(Object source, Object dest) { Set ret = new HashSet(); if (!(source instanceof ModelElement)) { throw new IllegalArgumentException("source"); } if (!(dest instanceof ModelElement)) { throw new IllegalArgumentException("dest"); } try { ret.addAll(getFlows(source, dest)); ret.addAll(getFlows(dest, source)); ret.addAll(getDependencies(source, dest)); ret.addAll(getDependencies(dest, source)); if (source instanceof GeneralizableElement && dest instanceof GeneralizableElement) { ret.add(getGeneralization(source, dest)); ret.add(getGeneralization(dest, source)); if (source instanceof Classifier && dest instanceof Classifier) { ret.addAll(getAssociations(source, dest)); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return ret; } public boolean isValidNamespace(Object mObj, Object nsObj) { if (!(mObj instanceof ModelElement) || !(nsObj instanceof Namespace)) { return false; } ModelElement modelElement = (ModelElement) mObj; Namespace ns = (Namespace) nsObj; try { if (modelElement == ns) { return false; } if (ns instanceof Interface || ns instanceof Actor || ns instanceof DataType || ns instanceof DataValue || ns instanceof NodeInstance || ns instanceof Signal // || ns instanceof UseCase // see comment below || ns instanceof UseCaseInstance || ns instanceof ClassifierInState) { return false; } else if (ns instanceof UseCase && modelElement instanceof Classifier) { /* * NOTE: Although WFR #3 in section 2.11.3.5 UseCase of the * UML 1.4 spec says "A UseCase cannot contain any * Classifiers," the OCL is actually self.contents->isEmpty * which would seem to imply it can't contain any elements * - tfm - 20060416 */ return false; } else if (ns instanceof Component) { return (modelElement instanceof Component && modelElement != ns); } else if (ns instanceof ComponentInstance) { return (modelElement instanceof ComponentInstance && modelElement != ns); } else if (ns instanceof org.omg.uml.behavioralelements.commonbehavior.Object) { // Made following changes from OCL in UML 1.4 section 2.9.3.16: // CollaborationInstance -> CollaborationInstanceSet // Stimuli -> Stimulus if (!(modelElement instanceof org.omg.uml.behavioralelements.commonbehavior.Object || modelElement instanceof DataValue || modelElement instanceof Link || modelElement instanceof UseCaseInstance || modelElement instanceof CollaborationInstanceSet || modelElement instanceof Stimulus)) { return false; } } else if (ns instanceof SubsystemInstance) { // Made following change from OCL in UML 1.4 section 2.9.3.22: // CollaborationInstance -> CollaborationInstanceSet if (!(modelElement instanceof org.omg.uml.behavioralelements.commonbehavior.Object || modelElement instanceof DataValue || modelElement instanceof Link || modelElement instanceof UseCaseInstance || modelElement instanceof CollaborationInstanceSet || modelElement instanceof SubsystemInstance || modelElement instanceof Stimulus)) { return false; } } else if (ns instanceof Subsystem) { if (!(modelElement instanceof UmlPackage || modelElement instanceof UmlClass || modelElement instanceof DataType || modelElement instanceof Interface || modelElement instanceof UseCase || modelElement instanceof Actor || modelElement instanceof Subsystem || modelElement instanceof Signal || modelElement instanceof UmlAssociation || modelElement instanceof Generalization || modelElement instanceof Dependency || modelElement instanceof Constraint || modelElement instanceof Collaboration || modelElement instanceof StateMachine || modelElement instanceof Stereotype)) { return false; } } else if (modelElement instanceof ClassifierRole) { return ns instanceof Collaboration; } else if (ns instanceof Collaboration) { /* * Although not represented in the OCL (or our Java), the * English text of WFR #4 of Section 2.10.3.4 in the UML 1.4 * spec is more restrictive - "[4] A Collaboration may only * contain ClassifierRoles and AssociationRoles, the * Generalizations and the Constraints between them, and * Actions used in the Collaboration's Interactions." */ if (!(modelElement instanceof ClassifierRole || modelElement instanceof AssociationRole || modelElement instanceof Generalization || modelElement instanceof Action || modelElement instanceof Constraint)) { return false; } } else if (ns instanceof UmlPackage) { // A Profile is a special package having the <<profile>> // stereotype which can only contain the following types if (isProfilePackage(ns)) { if (!(modelElement instanceof Stereotype || modelElement instanceof Constraint || modelElement instanceof TagDefinition || modelElement instanceof DataType)) { return false; } } else { if (!(modelElement instanceof UmlPackage || modelElement instanceof Classifier || modelElement instanceof UmlAssociation || modelElement instanceof Generalization || modelElement instanceof Dependency /* The next 2 needed for issue 2148: */ || modelElement instanceof Extend || modelElement instanceof Include || modelElement instanceof Constraint || modelElement instanceof Collaboration || modelElement instanceof StateMachine || modelElement instanceof Stereotype)) { return false; } } } else if (ns instanceof UmlClass) { if (!(modelElement instanceof UmlClass || modelElement instanceof UmlAssociation || modelElement instanceof Generalization || modelElement instanceof UseCase || modelElement instanceof Constraint || modelElement instanceof Dependency || modelElement instanceof Collaboration // Having StateMachine here would be non-standard. // See issue 4284. Hence removed: /* || modelElement instanceof StateMachine */ || modelElement instanceof DataType || modelElement instanceof Interface)) { return false; } } else if (ns instanceof ClassifierRole) { ClassifierRole cr = (ClassifierRole) ns; if (!(cr.getAvailableContents().contains(modelElement) || cr. getAvailableFeature().contains(modelElement))) { return false; } } if (modelElement instanceof StructuralFeature) { if (!isValidNamespace((StructuralFeature) modelElement, ns)) { return false; } // TODO: Issue 6144. It is proposed to allow any paclage to return as a potential // namespace. Commenting out until this is reviewed and clearly accepted by all. // } else if (modelElement instanceof GeneralizableElement) { // GeneralizableElement ge = (GeneralizableElement) modelElement; // if (!isValidNamespace(ge, ns)) { // return false; // } } else if (modelElement instanceof Generalization) { if (!isValidNamespace((Generalization) modelElement, ns)) { return false; } } if (modelElement instanceof UmlAssociation) { if (!isValidNamespace((UmlAssociation) modelElement, ns)) { return false; } } else if (modelElement instanceof Collaboration) { if (!isValidNamespace((Collaboration) modelElement, ns)) { return false; } } return true; } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } private boolean isProfilePackage(Namespace ns) { // A Profile is a special package having the <<profile>> stereotype return Model.getFacade().isStereotype(ns, "profile"); } /** * The base of a AssociationRole or ClassifierRole should be contained in * the given Namespace. If no base is set (yet), then allow any namespace. * * @param collab the given collaboration * @param ns the given candidate namespace * @return true if the given namespace may contain the collaboration */ private boolean isValidNamespace(Collaboration collab, Namespace ns) { for (ModelElement m : collab.getOwnedElement()) { if (m instanceof ClassifierRole) { ClassifierRole role = (ClassifierRole) m; for (Classifier base : role.getBase()) { if (!ns.getOwnedElement().contains(base)) { return false; } } } else if (m instanceof AssociationRole) { AssociationRole ar = (AssociationRole) m; UmlAssociation a = ar.getBase(); if (a != null && !ns.getOwnedElement().contains(a)) { return false; } } } return true; } private boolean isValidNamespace(Generalization gen, Namespace ns) { // TODO: Implement following WFR for GeneralizableElements // [4] The parent must be included in the Namespace of the // GeneralizableElement. // self.generalization->forAll(g | // self.namespace.allContents->includes(g.parent) ) // return ModelManagementHelperMDRImpl.getContents(ns).contains( // gen.getParent()); // There actually don't appear to be any restrictions on the // namespace for a Generalization. The UML 1.4 WFR 2.5.3.20 #3 // refers to GeneralizableElements, not Generalizations - tfm return true; // These old checks don't appear to be supported by the // UML 1.4 spec. - tfm 20080514 // if (gen.getParent() == null || gen.getChild() == null) { // return true; // } // Namespace ns1 = gen.getParent().getNamespace(); // Namespace ns2 = gen.getChild().getNamespace(); // if (ns == getFirstSharedNamespace(ns1, ns2)) { // return true; // } // return false; } private boolean isValidNamespace(StructuralFeature struc, Namespace ns) { // Technically this is legal, but a StructuralFeature should probably // only ever have an owner instead of a namespace. - tfm if (struc.getType() == null || struc.getOwner() == null) { return true; } /* * The following from the original NSUML implemenetation was attempting * to implement WFR #1 from section 2.5.3.32 of the UML 1.4 spec, but if * there is an owner set, no namespace is valid. The checks for this * WFR, if desired, need to go in setOwner() and setType() - tfm */ // return struc.getOwner().getNamespace().getOwnedElement().contains( // struc.getType()); return false; } private boolean isValidNamespace( final UmlAssociation assoc, final Namespace ns) { for (AssociationEnd end : assoc.getConnection()) { if (!isVisible(end.getParticipant(), ns)) { return false; } } return true; } /** * Return true if the given element is visible from this namespace. * <blockquote>The OCL that this is intended to check is this: * self.allConnections->forAll(r | self.namespace.allContents->includes (r.participant) ) or self.allConnections->forAll(r | self.namespace.allContents->excludes (r.participant) implies self.namespace.clientDependency->exists (d | d.oclIsTypeOf(Permission) and d.stereotype.name = 'access' and d.supplier.oclAsType(Namespace).ownedElement->select (e | e.elementOwnership.visibility = #public)->includes (r.participant) or d.supplier.oclAsType(GeneralizableElement). allParents.oclAsType(Namespace).ownedElement->select (e | e. elementOwnership.visibility = #public)->includes (r.participant) or d.supplier.oclAsType(Package).allImportedElements->select (e | e. elementImport.visibility = #public) ->includes (r.participant) ) ) </blockquote> * <p> * NOTE: This is very similar to the logic in * {@link ModelManagementHelperMDRImpl#getAllImportedElements(Object)} * which returns a collection of imported elements. Here we quit as soon * as we find the element that we're testing for (and we don't deal with * the <code>friend</code> or <code>access</code> stereotypes. * * @param ns * The namespace to check visibility from * @param element * the element to check for visibility * @return Return true if the given element is visible from this namespace. */ private boolean isVisible(ModelElement element, Namespace ns) { if (ns == null || element == null) { return false; } // self.allConnections->forAll(r // | self.namespace.allContents->includes(r.participant) ) Collection nsAllContents = modelImpl.getModelManagementHelper().getAllContents(ns); if (nsAllContents.contains(element)) { return true; } // or // self.allConnections->forAll( // r | self.namespace.allContents->excludes // (r.participant) implies // self.namespace.clientDependency->exists (d | // d.oclIsTypeOf(Permission) and // d.stereotype.name = 'access' and // TODO: this actually returns permissions with stereotypes // of both <<access>> and <<import>> when the spec calls for // only the former, but that seems to give different semantics // to the way package imports work. Review to see which is wrong. final Collection<Permission> permissions = getPackageImports(ns); for (Permission imp : permissions) { final Collection<ModelElement> suppliers = imp.getSupplier(); for (ModelElement me : suppliers) { // d.supplier.oclAsType(Namespace).ownedElement->select (e | // e.elementOwnership.visibility = // #public)->includes (r.participant) or if (me instanceof Namespace && isVisiblyOwned(element, (Namespace) me)) { return true; } // d.supplier.oclAsType(GeneralizableElement). // allParents.oclAsType(Namespace).ownedElement->select (e | // e. elementOwnership.visibility = // #public)->includes (r.participant) or if (me instanceof GeneralizableElement) { // TODO: Performance. Consider instantiating this just // once outside the for loops and clear at this point // instead. final Set<ModelElement> dupCheck = new HashSet<ModelElement>(10); if (isVisiblyOwned( element, (GeneralizableElement) me, dupCheck)) { return true; } } // d.supplier.oclAsType(Package).allImportedElements->select ( // e | e. elementImport.visibility = // #public) ->includes (r.participant) ) ) if (me instanceof UmlPackage) { final Collection<ElementImport> imports = ((UmlPackage) me).getElementImport(); for (ElementImport ei : imports) { if (element.equals(ei.getImportedElement()) && VisibilityKindEnum.VK_PUBLIC.equals(ei .getVisibility())) { return true; } } } } } return false; } /** * Returns true if ModelElement is owned by the given Namespace and it is * publicly visible. * * @param me ModelElement * @param ns Namespace * @return true if ModelElement is owned by the given Namespace and it is * publicly visible. */ private boolean isVisiblyOwned(ModelElement me, Namespace ns) { return ns.getOwnedElement().contains(me) && VisibilityKindEnum.VK_PUBLIC.equals(me.getVisibility()); } /** * This code tests WFR [4] of a GeneralizableElement, * according OMG UML 1.4.2 standard page 59: * * [4]The parent must be included in the Namespace * of the GeneralizableElement. * self.generalization->forAll(g | * self.namespace.allContents->includes(g.parent) ) */ // TODO: Issue 6144. It is proposed to allow any paclage to return as a potential // namespace. Commenting out until this is reviewed and clearly accepted by all. // private boolean isValidNamespace( // GeneralizableElement generalizableElement, // Namespace namespace) { // // Collection<Generalization> generalizations = // generalizableElement.getGeneralization(); // // ModelManagementHelperMDRImpl modelManagementHelper = // (ModelManagementHelperMDRImpl) modelImpl.getModelManagementHelper(); // // for (Generalization generalization : generalizations) { // final GeneralizableElement parent = generalization.getParent(); // final Set<ModelElement> results = new HashSet<ModelElement>(2000); // final Set<ModelElement> dupCheck = new HashSet<ModelElement>(2000); // modelManagementHelper.getAllContents(results, namespace, dupCheck); // if (!results.contains(parent)) { // return false; // } // } // return true; // } public Namespace getFirstSharedNamespace(Object ns1, Object ns2) { if (ns1 == null || ns2 == null) { throw new IllegalArgumentException("null argument"); } if (!(ns1 instanceof Namespace)) { throw new IllegalArgumentException( "Expecting a Namespace argument. Got a " + ns1.getClass().getName()); } if (!(ns2 instanceof Namespace)) { throw new IllegalArgumentException( "Expecting a Namespace argument. Got a " + ns2.getClass().getName()); } if (ns1 == ns2) { return (Namespace) ns1; } try { // Get the namespace hierarchy for each element Iterator<Namespace> path1 = getPath((Namespace) ns1).iterator(); Iterator<Namespace> path2 = getPath((Namespace) ns2).iterator(); // Traverse the lists looking for the last (innermost) match Namespace lastMatch = null; while (path1.hasNext() && path2.hasNext()) { Namespace element = path1.next(); if (element != path2.next()) { return lastMatch; } lastMatch = element; } return lastMatch; } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } /* * Return a list of namespaces enclosing this element. * The list is ordered outer to inner. i.e. it starts at the root model. */ private List<Namespace> getPath(Namespace element) { LinkedList<Namespace> path = new LinkedList<Namespace>(); path.add(element); Namespace ns = element.getNamespace(); while (ns != null) { path.addFirst(ns); ns = ns.getNamespace(); } return path; } public Collection<Namespace> getAllPossibleNamespaces(Object modelElement, Object model) { LOG.debug("getAllPossibleNamespaces start"); ModelElement m = (ModelElement) modelElement; Collection<Namespace> ret = new HashSet<Namespace> (); if (m == null) { LOG.debug("getAllPossibleNamespaces end"); return ret; } try { if (isValidNamespace(m, model)) { ret.add((Namespace) model); } Collection<Namespace> namespaces = modelImpl .getModelManagementHelper().getAllModelElementsOfKind( model, Namespace.class); for (Namespace ns : namespaces) { if (isValidNamespace(m, ns)) { ret.add(ns); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } if (LOG.isDebugEnabled()) { // This is an expensive method that we should ensure is called // rarely. Hence info level to track easily. LOG.debug( "getAllPossibleNamespaces returns " + ret.size() + " items"); } return ret; } public Collection<GeneralizableElement> getChildren(Object o) { if (o instanceof GeneralizableElement) { Collection<GeneralizableElement> col = new ArrayList<GeneralizableElement>(); Collection<Generalization> generalizations = new ArrayList<Generalization>(); try { if (o instanceof GeneralizableElement) { Collection<Generalization> specializations = Model.getFacade().getSpecializations(o); for (Generalization specialization : specializations) { getChildren(col, specialization, generalizations); } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return col; } throw new IllegalArgumentException("Illegal arguments: " + o); } /** * Adds all children recursively to the Collection in the first argument. * The algorithm assumes that there is a cycle when a node has been visited * twice using already known generalizations. * * @param currentChildren * collection to collect them in. * @param gen * element whose children are added. * @param generalizations * the list of already traversed generalizations. * @throws IllegalStateException * if there is a circular reference. */ private void getChildren(Collection<GeneralizableElement> currentChildren, Generalization gen, Collection<Generalization> generalizations) { GeneralizableElement child = gen.getChild(); if (currentChildren.contains(child) && generalizations.contains(gen)) { throw new IllegalStateException("Circular inheritance occured."); } else { currentChildren.add(child); generalizations.add(gen); } Collection<Generalization> specializations = Model.getFacade().getSpecializations(child); for (Generalization specialization : specializations) { getChildren(currentChildren, specialization, generalizations); } } public Collection getAllRealizedInterfaces(Object o) { try { return internalGetAllRealizedInterfaces(o, new ArrayList(), new HashSet()); } catch (InvalidObjectException e) { throw new InvalidElementException(e); } } /** * Helper method for getAllRealizedInterfaces. * * @param o * @param col * @param visited * @return Collection */ private Collection internalGetAllRealizedInterfaces(Object o, Collection col, Set visited) { visited.add(o); if (o != null) { if (o instanceof Classifier) { Classifier clazz = (Classifier) o; for (Dependency dependency : clazz.getClientDependency()) { Stereotype stereo = (Stereotype) getFirstItemOrNull( dependency.getStereotype()); if (dependency instanceof Abstraction && stereo != null && CoreFactory.REALIZE_STEREOTYPE.equals(stereo .getName()) && "Abstraction".equals(stereo.getBaseClass())) { col.addAll(dependency.getSupplier()); } } for (Object supertype : getSupertypes(o)) { if (!visited.contains(supertype)) { internalGetAllRealizedInterfaces(supertype, col, visited); } } } } return col; } public final boolean hasCompositeEnd(Object association) { if (!(association instanceof UmlAssociation)) { throw new IllegalArgumentException(); } UmlAssociation association1 = (UmlAssociation) association; try { for (AssociationEnd end : association1.getConnection()) { if (end.getAggregation() == AggregationKindEnum.AK_COMPOSITE) { return true; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return false; } public final boolean equalsAggregationKind(Object associationEnd, String kindType) { if (!(associationEnd instanceof AssociationEnd)) { throw new IllegalArgumentException(); } AssociationEnd associationEnd1 = (AssociationEnd) associationEnd; // TODO: This should either be extended to support all AggreationKinds // or it should be simplified/removed from the API - tfm - 20070331 if (kindType.equals("composite")) { return AggregationKindEnum.AK_COMPOSITE.equals(associationEnd1. getAggregation()); } else { throw new IllegalArgumentException("kindType: " + kindType + " not supported"); } } public void removeAnnotatedElement(Object handle, Object me) { if (handle instanceof Comment && me instanceof ModelElement) { try { if (((Comment) handle).getAnnotatedElement().contains(me)) { ((Comment) handle).getAnnotatedElement().remove(me); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } return; } throw new IllegalArgumentException("handle: " + handle + " or model element: " + me); } public void removeClientDependency(Object handle, Object dep) { try { if (handle instanceof ModelElement && dep instanceof Dependency) { ModelElement me = (ModelElement) handle; Collection deps = me.getClientDependency(); if (deps != null && deps.contains(dep)) { deps.remove(dep); } return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException(); } public void removeConnection(Object handle, Object connection) { try { if (handle instanceof UmlAssociation && connection instanceof AssociationEnd) { ((UmlAssociation) handle).getConnection().remove(connection); return; } if (handle instanceof Link && connection instanceof LinkEnd) { ((Link) handle).getConnection().remove(connection); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or connection: " + connection); } public void removeConstraint(Object handle, Object cons) { try { if (handle instanceof ModelElement && cons instanceof Constraint) { ((ModelElement) handle).getConstraint().remove(cons); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or cons: " + cons); } public void removeOwnedElement(Object handle, Object value) { try { if (handle instanceof Namespace && value instanceof ModelElement) { ModelElement elem = (ModelElement) value; if (!(elem.getNamespace().equals(handle))) { throw new IllegalStateException( "ModelElement isn't in Namespace"); } elem.setNamespace(null); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or value: " + value); } public void removeParameter(Object handle, Object parameter) { try { if (parameter instanceof Parameter) { if (handle instanceof ObjectFlowState) { ((ObjectFlowState) handle).getParameter().remove( parameter); return; } if (handle instanceof Event) { ((Event) handle).getParameter().remove(parameter); return; } if (handle instanceof BehavioralFeature) { ((BehavioralFeature) handle).getParameter().remove( parameter); return; } if (handle instanceof Classifier) { ((Parameter) parameter).setType(null); return; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void removeQualifier(Object handle, Object qualifier) { try { if (qualifier instanceof Attribute) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).getQualifier().remove( qualifier); return; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or qualifier: " + qualifier); } public void removeSourceFlow(Object handle, Object flow) { try { if (handle instanceof ModelElement && flow instanceof Flow) { ((ModelElement) handle).getSourceFlow().remove(flow); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or flow: " + flow); } public void removeSupplierDependency(Object supplier, Object dependency) { try { if (supplier instanceof ModelElement && dependency instanceof Dependency) { ((Dependency) dependency).getSupplier().remove(supplier); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("supplier: " + supplier + " or dependency: " + dependency); } public void removeTargetFlow(Object handle, Object flow) { try { if (handle instanceof ModelElement && flow instanceof Flow) { ((ModelElement) handle).getTargetFlow().remove(flow); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or flow: " + flow); } public void removeTemplateArgument(Object handle, Object argument) { try { if (argument instanceof TemplateArgument) { if (handle instanceof Binding) { ((Binding) handle).getArgument().remove(argument); return; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + argument); } public void removeTemplateParameter(Object handle, Object parameter) { try { if (parameter instanceof TemplateParameter) { if (handle instanceof ModelElement) { ((ModelElement) handle).getTemplateParameter().remove( parameter); return; } } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void addAnnotatedElement(Object comment, Object annotatedElement) { if (comment instanceof Comment && annotatedElement instanceof ModelElement) { ((Comment) comment).getAnnotatedElement().add((ModelElement) annotatedElement); return; } throw new IllegalArgumentException("comment: " + comment + " or annotatedElement: " + annotatedElement); } public void addClient(Object handle, Object element) { if (handle instanceof Dependency && element instanceof ModelElement) { ((Dependency) handle).getClient().add((ModelElement) element); return; } throw new IllegalArgumentException("handle: " + handle + " or element: " + element); } public void addClientDependency(Object handle, Object dependency) { if (handle instanceof ModelElement && dependency instanceof Dependency) { ((ModelElement) handle).getClientDependency().add( (Dependency) dependency); return; } throw new IllegalArgumentException("handle: " + handle + " or dependency: " + dependency); } public void addComment(Object element, Object comment) { if (element instanceof ModelElement && comment instanceof Comment) { ((ModelElement) element).getComment().add((Comment) comment); return; } throw new IllegalArgumentException("element: " + element); } public void addConnection(Object handle, Object connection) { if (handle instanceof UmlAssociation && connection instanceof AssociationEnd) { List<AssociationEnd> ends = ((UmlAssociation) handle).getConnection(); ends.add((AssociationEnd) connection); // UML 1.4 WFR 2.5.3.1 #3 if (ends.size() >= 3) { for (AssociationEnd end : ends) { end.setAggregation(AggregationKindEnum.AK_NONE); } } return; } if (handle instanceof Link && connection instanceof LinkEnd) { ((Link) handle).getConnection().add((LinkEnd) connection); return; } throw new IllegalArgumentException("handle: " + handle + " or connection: " + connection); } public void addConnection(Object handle, int position, Object connection) { if (handle instanceof UmlAssociation && connection instanceof AssociationEnd) { ((UmlAssociation) handle).getConnection().add(position, (AssociationEnd) connection); List<AssociationEnd> ends = ((UmlAssociation) handle).getConnection(); // UML 1.4 WFR 2.5.3.1 #3 - no aggregation for N-ary associations if (ends.size() >= 3) { for (AssociationEnd end : ends) { end.setAggregation(AggregationKindEnum.AK_NONE); } } return; } /* Strange, but the Link.getConnection() * returns a Collection, not a List! * This is a bug, compared to the UML standard (IMHO, mvw). * Hence, the LinkEnd is added to the end instead... */ if (handle instanceof Link && connection instanceof LinkEnd) { ((Link) handle).getConnection().add((LinkEnd) connection); return; } throw new IllegalArgumentException("handle: " + handle + " or connection: " + connection); } public void addConstraint(Object handle, Object mc) { if (handle instanceof ModelElement && mc instanceof Constraint) { ((ModelElement) handle).getConstraint().add((Constraint) mc); return; } throw new IllegalArgumentException("handle: " + handle + " or mc: " + mc); } public void addDeploymentLocation(Object handle, Object node) { if (handle instanceof Component && node instanceof Node) { ((Component) handle).getDeploymentLocation().add((Node) node); return; } throw new IllegalArgumentException("handle: " + handle + " or node: " + node); } public void addElementResidence(Object handle, Object node) { // TODO: This is ambiguous as to whether it should be adding a container // or resident. if (handle instanceof ModelElement && node instanceof ElementResidence) { ((ElementResidence) node).setResident((ModelElement) handle); return; } throw new IllegalArgumentException("handle: " + handle + " or node: " + node); } public void removeElementResidence(Object handle, Object node) { try { if (handle instanceof ModelElement && node instanceof ElementResidence) { ((ElementResidence) node).setResident(null); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or node: " + node); } /** * Get ElementResidences. * * TODO: Unused. Should be added to Facade? - tfm * * @param handle A modelElement * @return Collection The ElementResidence for this model element */ public Collection<ElementResidence> getElementResidence(Object handle) { try { if (handle instanceof ModelElement) { return ((org.omg.uml.UmlPackage) ((ModelElement) handle) .refOutermostPackage()).getCore() .getAResidentElementResidence().getElementResidence( (ModelElement) handle); } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle); } public void addFeature(Object handle, int index, Object f) { if (handle instanceof Classifier && f instanceof Feature) { ((Classifier) handle).getFeature().add(index, (Feature) f); return; } throw new IllegalArgumentException("handle: " + handle + " or f: " + f); } public void addLiteral(Object handle, int index, Object literal) { if (handle instanceof Enumeration && literal instanceof EnumerationLiteral) { ((Enumeration) handle).getLiteral().add(index, (EnumerationLiteral) literal); return; } throw new IllegalArgumentException("enumeration: " + handle + " or literal: " + literal); } public void addFeature(Object handle, Object f) { if (handle instanceof Classifier && f instanceof Feature) { ((Classifier) handle).getFeature().add((Feature) f); return; } throw new IllegalArgumentException("handle: " + handle); } public void addLink(Object handle, Object link) { if (handle instanceof UmlAssociation && link instanceof Link) { ((Link) link).setAssociation((UmlAssociation) handle); return; } throw new IllegalArgumentException("handle: " + handle + " or link: " + link); } public void addManifestation(Object handle, Object manifestation) { throw new NotImplementedException( "UML 1.4 has no manifestations"); } public void addMethod(Object handle, Object m) { if (handle instanceof Operation && m instanceof Method) { ((Method) m).setVisibility(((Operation) handle).getVisibility()); ((Method) m).setOwnerScope(((Operation) handle).getOwnerScope()); ((Method) m).setSpecification((Operation) handle); return; } throw new IllegalArgumentException("handle: " + handle + " or m: " + m); } public void addOwnedElement(Object handle, Object me) { if (handle instanceof Namespace && me instanceof ModelElement) { Namespace ns = (Namespace) handle; ModelElement elem = (ModelElement) me; elem.setNamespace(ns); ns.getOwnedElement().add(elem); return; } throw new IllegalArgumentException("handle: " + handle + " or me: " + me); } public void addParameter(Object handle, int index, Object parameter) { if (parameter instanceof Parameter) { if (handle instanceof Event) { ((Event) handle).getParameter().add(index, (Parameter) parameter); return; } if (handle instanceof BehavioralFeature) { ((BehavioralFeature) handle).getParameter().add(index, (Parameter) parameter); return; } } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void addParameter(Object handle, Object parameter) { if (parameter instanceof Parameter) { if (handle instanceof ObjectFlowState) { ((ObjectFlowState) handle).getParameter().add( (Parameter) parameter); return; } if (handle instanceof Event) { ((Event) handle).getParameter().add((Parameter) parameter); return; } if (handle instanceof BehavioralFeature) { ((BehavioralFeature) handle).getParameter().add( (Parameter) parameter); return; } if (handle instanceof Classifier) { ((Parameter) parameter).setType((Classifier) handle); return; } } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void addQualifier(Object handle, int index, Object qualifier) { if (qualifier instanceof Attribute) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).getQualifier().add(index, (Attribute) qualifier); return; } } throw new IllegalArgumentException("handle: " + handle + " or qualifier: " + qualifier); } public void addRaisedSignal(Object handle, Object sig) { if (sig instanceof Signal) { if (handle instanceof Message) { ((org.omg.uml.UmlPackage) ((Signal) sig) .refOutermostPackage()).getCommonBehavior() .getAContextRaisedSignal().add( (BehavioralFeature) handle, (Signal) sig); return; } if (handle instanceof Operation) { ((org.omg.uml.UmlPackage) ((Signal) sig).refOutermostPackage()) .getCommonBehavior().getAContextRaisedSignal().add( (BehavioralFeature) handle, (Signal) sig); return; } } throw new IllegalArgumentException("handle: " + handle + " or sig: " + sig); } /** * Dummy method for exceptions in MDR metamodel. * * @author Andreas Rueckert <a_rueckert@gmx.net> * * @see org.argouml.model.CoreHelper#addRaisedException(java.lang.Object, java.lang.Object) */ public void addRaisedException(Object handle, Object Exception) { throw new NotImplementedException( "UML 1.4 has no exceptions for operations"); } public void addSourceFlow(Object handle, Object flow) { if (handle instanceof ModelElement && flow instanceof Flow) { ((ModelElement) handle).getSourceFlow().add((Flow) flow); return; } throw new IllegalArgumentException("handle: " + handle + " or flow: " + flow); } public void addSupplier(Object handle, Object element) { if (handle instanceof Dependency && element instanceof ModelElement) { ((Dependency) handle).getSupplier().add((ModelElement) element); return; } throw new IllegalArgumentException("handle: " + handle + " or element: " + element); } public void addSupplierDependency(Object supplier, Object dependency) { if (supplier instanceof ModelElement && dependency instanceof Dependency) { ((Dependency) dependency).getSupplier() .add((ModelElement) supplier); return; } throw new IllegalArgumentException("supplier: " + supplier + " or dependency: " + dependency); } public void addTargetFlow(Object handle, Object flow) { if (handle instanceof ModelElement && flow instanceof Flow) { ((ModelElement) handle).getTargetFlow().add((Flow) flow); return; } throw new IllegalArgumentException("handle: " + handle + " or flow: " + flow); } public void addTemplateArgument(Object handle, int index, Object argument) { if (argument instanceof TemplateArgument) { if (handle instanceof Binding) { ((Binding) handle).getArgument().add(index, (TemplateArgument) argument); return; } } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + argument); } public void addTemplateArgument(Object handle, Object argument) { if (argument instanceof TemplateArgument && handle instanceof Binding) { ((Binding) handle).getArgument().add((TemplateArgument) argument); return; } throw new IllegalArgumentException("handle: " + handle + " or argument: " + argument); } public void addTemplateParameter(Object handle, int index, Object parameter) { if (parameter instanceof TemplateParameter) { if (handle instanceof ModelElement) { ((ModelElement) handle).getTemplateParameter().add( index, (TemplateParameter) parameter); return; } } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void addTemplateParameter(Object handle, Object parameter) { if (parameter instanceof TemplateParameter) { if (handle instanceof ModelElement) { ((ModelElement) handle).getTemplateParameter().add( (TemplateParameter) parameter); return; } } throw new IllegalArgumentException("handle: " + handle + " or parameter: " + parameter); } public void setAbstract(Object handle, boolean flag) { if (handle instanceof GeneralizableElement) { ((GeneralizableElement) handle).setAbstract(flag); return; } if (handle instanceof Operation) { ((Operation) handle).setAbstract(flag); return; } if (handle instanceof Reception) { ((Reception) handle).setAbstract(flag); return; } throw new IllegalArgumentException("handle: " + handle); } public void setActive(Object handle, boolean active) { if (handle instanceof UmlClass) { ((UmlClass) handle).setActive(active); return; } throw new IllegalArgumentException("handle: " + handle); } public void setAggregation(Object handle, Object aggregationKind) { if (handle instanceof AssociationEnd && aggregationKind instanceof AggregationKind) { AggregationKind ak = (AggregationKind) aggregationKind; AssociationEnd ae = (AssociationEnd) handle; // We silently ignore requests which conflict with // UML 1.4 WFR 2.5.3.1 #3 - no aggregation for n-ary associations if (ak == AggregationKindEnum.AK_NONE || ae.getAssociation().getConnection().size() < 3) { ae.setAggregation(ak); } else { ae.setAggregation(AggregationKindEnum.AK_NONE); } // If we made something aggregate, make sure the other ends conform // to UML 1.4 WFR 2.5.3.1 #2 - no more than one aggregate end if (ak == AggregationKindEnum.AK_AGGREGATE || ak == AggregationKindEnum.AK_COMPOSITE) { for (AssociationEnd end : ae.getAssociation().getConnection()) { if (!end.equals(ae) && end.getAggregation() != AggregationKindEnum.AK_NONE) { end.setAggregation(AggregationKindEnum.AK_NONE); } } } return; } throw new IllegalArgumentException("handle: " + handle + " or aggregationKind: " + aggregationKind); } public void setAnnotatedElements(Object handle, Collection elems) { if (handle instanceof Comment && elems instanceof List) { CollectionHelper.update( ((Comment) handle).getAnnotatedElement(), elems); return; } throw new IllegalArgumentException("handle: " + handle); } public void setAssociation(Object handle, Object association) { if (association instanceof UmlAssociation) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle). setAssociation((UmlAssociation) association); return; } if (handle instanceof Link) { ((Link) handle).setAssociation((UmlAssociation) association); return; } } else if (association instanceof AssociationRole) { if (handle instanceof AssociationEndRole) { ((AssociationEndRole) handle). setAssociation((AssociationRole) association); return; } } throw new IllegalArgumentException("handle: " + handle + " or association: " + association); } public void setLeaf(Object handle, boolean flag) { if (handle instanceof Reception) { ((Reception) handle).setLeaf(flag); return; } if (handle instanceof Operation) { ((Operation) handle).setLeaf(flag); return; } if (handle instanceof GeneralizableElement) { ((GeneralizableElement) handle).setLeaf(flag); return; } throw new IllegalArgumentException("handle: " + handle); } public void setRaisedSignals(Object handle, Collection raisedSignals) { throw new NotImplementedException(); } public void setBody(Object handle, Object expr) { if (handle instanceof Method && (expr == null || expr instanceof ProcedureExpression)) { ProcedureExpression oldPe = ((Method)handle).getBody(); if (!equal(oldPe, (ProcedureExpression) expr)) { ((Method) handle).setBody(null); if (oldPe != null) { Model.getUmlFactory().delete(oldPe); } ((Method) handle).setBody((ProcedureExpression) expr); } return; } if (handle instanceof Constraint && (expr == null || expr instanceof BooleanExpression)) { BooleanExpression oldBe = ((Constraint)handle).getBody(); if (!equal(oldBe, (BooleanExpression) expr)) { ((Constraint) handle).setBody((BooleanExpression) expr); if (oldBe != null) { Model.getUmlFactory().delete(oldBe); } } return; } throw new IllegalArgumentException("handle: " + handle + " or expr: " + expr); } private boolean equal(Expression expr1, Expression expr2) { if (expr1 == null) { if (expr2 == null) { return true; } else { return false; } } else { return expr1.equals(expr2); } } @Deprecated public void setChangeability(Object handle, Object ck) { if (ck == null || ck instanceof ChangeableKind) { ChangeableKind changeableKind = (ChangeableKind) ck; if (handle instanceof StructuralFeature) { ((StructuralFeature) handle).setChangeability(changeableKind); return; } if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).setChangeability(changeableKind); return; } } throw new IllegalArgumentException("handle: " + handle + " or ck: " + ck); } public void setReadOnly(Object handle, boolean isReadOnly) { setChangeability(handle, isReadOnly ? ChangeableKindEnum.CK_FROZEN : ChangeableKindEnum.CK_CHANGEABLE); } public void setChild(Object handle, Object child) { if (handle instanceof Generalization) { ((Generalization) handle).setChild((GeneralizableElement) child); return; } throw new IllegalArgumentException("handle: " + handle + " or child: " + child); } public void setConcurrency(Object handle, Object concurrencyKind) { if (handle instanceof Operation && concurrencyKind instanceof CallConcurrencyKind) { ((Operation) handle). setConcurrency((CallConcurrencyKind) concurrencyKind); return; } throw new IllegalArgumentException("handle: " + handle + " or concurrencyKind: " + concurrencyKind); } public void setConnections(Object handle, Collection elems) { if (handle instanceof UmlAssociation && elems instanceof List) { List<AssociationEnd> ends = ((UmlAssociation) handle).getConnection(); CollectionHelper.update(ends, elems); // UML 1.4 WFR 2.5.3.1 #3 - no aggregation for N-ary associations if (ends.size() >= 3) { for (AssociationEnd end : ends) { end.setAggregation(AggregationKindEnum.AK_NONE); } } return; } if (handle instanceof Link && elems instanceof List) { CollectionHelper.update( ((Link) handle).getConnection(), elems); return; } throw new IllegalArgumentException("handle: " + handle); } public void setDefaultElement(Object handle, Object element) { if (handle instanceof TemplateParameter && element instanceof ModelElement) { ((TemplateParameter) handle) .setDefaultElement((ModelElement) element); return; } throw new IllegalArgumentException("handle: " + handle + " or model element: " + element); } public void setDefaultValue(Object handle, Object expr) { if (handle instanceof Parameter && (expr == null || expr instanceof Expression)) { Expression oldExp = ((Parameter) handle).getDefaultValue(); if (!equal(oldExp, (Expression) expr)) { ((Parameter) handle).setDefaultValue((Expression) expr); if (oldExp != null) { Model.getUmlFactory().delete(oldExp); } } return; } throw new IllegalArgumentException("handle: " + handle + " or expr: " + expr); } public void setDiscriminator(Object handle, String discriminator) { if (handle instanceof Generalization) { ((Generalization) handle).setDiscriminator(discriminator); return; } throw new IllegalArgumentException("handle: " + handle); } public void setFeature(Object elem, int i, Object impl) { if (elem instanceof Classifier && impl instanceof Feature) { ((Classifier) elem).getFeature().add(i, (Feature) impl); return; } throw new IllegalArgumentException("elem: " + elem + " or impl: " + impl); } public void setFeatures(Object handle, Collection features) { if (handle instanceof Classifier) { List featuresList = null; if (features instanceof List) { featuresList = (List) features; } else { featuresList = new ArrayList(features); } // TODO: A minimal update strategy would be better here to // minimize work and events firing, but it may be better to // deprecate the method and force calls to manage updates // themselves (since they probably usually want to just add // or remove a single element) - tfm 20061108 ((Classifier) handle).getFeature().clear(); ((Classifier) handle).getFeature().addAll(featuresList); return; } throw new IllegalArgumentException("handle: " + handle); } public void setContainer(Object handle, Object container) { if (handle instanceof ElementResidence && (container instanceof Component || container == null)) { ElementResidence er = (ElementResidence) handle; er.setContainer((Component) container); } else { throw new IllegalArgumentException("handle: " + handle + " or container: " + container); } } public void setInitialValue(Object at, Object expr) { if (at instanceof Attribute && (expr == null || expr instanceof Expression)) { Expression oldExp = ((Attribute) at).getInitialValue(); if (!equal(oldExp, (Expression) expr)) { ((Attribute) at).setInitialValue((Expression) expr); if (oldExp != null) { Model.getUmlFactory().delete(oldExp); } } return; } throw new IllegalArgumentException("at: " + at + " or expr: " + expr); } public void setKind(Object handle, Object kind) { if (handle instanceof Parameter && kind instanceof ParameterDirectionKind) { ((Parameter) handle).setKind((ParameterDirectionKind) kind); return; } if (handle instanceof Pseudostate && kind instanceof PseudostateKind) { ((Pseudostate) handle).setKind((PseudostateKind) kind); return; } throw new IllegalArgumentException("handle: " + handle + " or kind: " + kind); } public void setModelElementContainer(Object handle, Object container) { /* * <em>Warning: when changing the implementation of this method be * warned that the sequence of the if then else tree DOES matter.</em> * Most notabely, do not move the setNamespace method any level up in * the tree.<p> */ if (handle instanceof Partition && container instanceof ActivityGraph) { ((Partition) handle).setActivityGraph((ActivityGraph) container); } else if (handle instanceof ModelElement && container instanceof Partition) { ((Partition) container).getContents().add((ModelElement) handle); } else if (handle instanceof Constraint && container instanceof Stereotype) { ((Stereotype) container).getStereotypeConstraint().add( (Constraint) handle); } else if (handle instanceof Interaction && container instanceof Collaboration) { ((Interaction) handle).setContext((Collaboration) container); } else if (handle instanceof ElementResidence && (container instanceof Component || container == null)) { ElementResidence er = (ElementResidence) handle; er.setContainer((Component) container); } else if (handle instanceof AttributeLink && container instanceof Instance) { ((AttributeLink) handle).setInstance((Instance) container); } else if (handle instanceof Message && container instanceof Interaction) { ((Message) handle).setInteraction((Interaction) container); } else if (handle instanceof LinkEnd && container instanceof Link) { ((LinkEnd) handle).setLink((Link) container); } else if (handle instanceof AttributeLink && container instanceof LinkEnd) { ((AttributeLink) handle).setLinkEnd((LinkEnd) container); } else if (handle instanceof TaggedValue && container instanceof Stereotype) { ((TaggedValue) handle).getStereotype().clear(); ((TaggedValue) handle).getStereotype().add((Stereotype) container); } else if (handle instanceof TaggedValue && container instanceof ModelElement) { ((TaggedValue) handle).setModelElement((ModelElement) container); } else if (handle instanceof StateVertex && container instanceof CompositeState) { ((StateVertex) handle).setContainer((CompositeState) container); } else if (handle instanceof ElementImport && container instanceof UmlPackage) { ((ElementImport) handle).setUmlPackage((UmlPackage) container); } else if (handle instanceof Transition && container instanceof State) { ((State) container).getInternalTransition() .add((Transition) handle); } else if (handle instanceof State && container instanceof StateMachine) { ((State) handle).setStateMachine((StateMachine) container); } else if (handle instanceof Transition && container instanceof StateMachine) { ((Transition) handle).setStateMachine((StateMachine) container); } else if (handle instanceof Action && container instanceof Transition) { ((Transition) container).setEffect((Action) handle); } else if (handle instanceof Guard && container instanceof Transition) { ((Guard) handle).setTransition((Transition) container); } else if (handle instanceof ModelElement && container instanceof Namespace) { ((ModelElement) handle).setNamespace((Namespace) container); } else { throw new IllegalArgumentException("handle: " + handle + " or container: " + container); } } public void setMultiplicity(Object handle, String arg) { setMultiplicity(handle,createMultiplicity(arg)); } private void setMultiplicity(Object handle, Multiplicity arg) { Multiplicity previousMult = (Multiplicity) Model.getFacade().getMultiplicity(handle); if (handle instanceof AssociationRole) { ((AssociationRole) handle).setMultiplicity(arg); } else if (handle instanceof ClassifierRole) { ((ClassifierRole) handle).setMultiplicity(arg); } else if (handle instanceof StructuralFeature) { ((StructuralFeature) handle).setMultiplicity(arg); } else if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).setMultiplicity(arg); } else if (handle instanceof TagDefinition) { ((TagDefinition) handle).setMultiplicity(arg); } if (previousMult != null && Model.getFacade().getModelElementContainer(previousMult) == null) { if (LOG.isDebugEnabled()) { LOG.debug("Previous multiplicity of " + handle + " will be deleted." + arg); } Model.getUmlFactory().delete(previousMult); } } @Deprecated public void setMultiplicity(Object handle, Object arg) { if (arg instanceof String) { setMultiplicity(handle, (String) arg); return; } if (arg == null || arg instanceof Multiplicity) { setMultiplicity(handle, (Multiplicity) arg); } else { throw new IllegalArgumentException("handle: " + handle + " or arg: " + arg); } } private Multiplicity createMultiplicity(String sarg) { boolean allDigits = true; for (int i=0; i < sarg.length(); ++i) { if (!Character.isDigit(sarg.charAt(i))) { allDigits = false; } } if (allDigits || sarg.indexOf('.') > -1 || sarg.indexOf(',') > -1) { return modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(sarg); } else { // TODO: We have multiple string representations for multiplicities // these should be consolidated. This form is used by // org.argouml.uml.reveng if ("1_N".equals(sarg)) { return modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(1, -1); } else { return modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(1, 1); } } } public void setMultiplicity(Object handle, int lower, int upper) { Multiplicity arg = modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(lower, upper); setMultiplicity(handle, arg); } public void setName(final Object handle, final String name) { if (handle instanceof ModelElement) { createCommand( new StringSetter() { public void set(String value) { ((ModelElement) handle).setName(value); } }, name, Model.getFacade().getName(handle), "name = " + name); return; } throw new IllegalArgumentException("handle: " + handle + " or name: " + name); } public void setBody(Object handle, String body) { if ((handle instanceof Comment) && (body != null)) { // All text was stored in name field in UML 1.3 ((Comment) handle).setBody(body); } } public void setNamespace(Object handle, Object ns) { if (handle instanceof ModelElement && (ns == null || ns instanceof Namespace)) { Namespace oldNs = ((ModelElement) handle).getNamespace(); if (((ns == null) && (oldNs == null)) || ((oldNs != null) && oldNs.equals(ns))) { return; } ((ModelElement) handle).setNamespace((Namespace) ns); return; } throw new IllegalArgumentException("handle: " + handle + " or ns: " + ns); } public void setNavigable(Object handle, boolean flag) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).setNavigable(flag); return; } throw new IllegalArgumentException("handle: " + handle); } public void setOrdering(Object handle, Object ok) { if (handle instanceof AssociationEnd && ok instanceof OrderingKind) { ((AssociationEnd) handle).setOrdering((OrderingKind) ok); return; } throw new IllegalArgumentException("handle: " + handle + " or ok: " + ok); } public void setOwner(Object handle, Object owner) { if (handle instanceof Feature && (owner == null || owner instanceof Classifier)) { setNamespace(handle, null); ((Feature) handle).setOwner((Classifier) owner); return; } if (handle instanceof TagDefinition && (owner == null || owner instanceof Stereotype)) { setNamespace(handle, null); ((TagDefinition) handle).setOwner((Stereotype) owner); if (owner != null) { ((Stereotype) owner).getDefinedTag() .add((TagDefinition) handle); } return; } throw new IllegalArgumentException("handle: " + handle + " or owner: " + owner); } public void setStatic(Object handle, boolean isStatic) { if (handle instanceof Feature) { ((Feature) handle) .setOwnerScope(isStatic ? ScopeKindEnum.SK_CLASSIFIER : ScopeKindEnum.SK_INSTANCE); return; } if (handle instanceof AssociationEnd) { ((AssociationEnd) handle) .setTargetScope(isStatic ? ScopeKindEnum.SK_CLASSIFIER : ScopeKindEnum.SK_INSTANCE); return; } throw new IllegalArgumentException("handle: " + handle); } public void setParameter(Object handle, Object parameter) { if (handle instanceof TemplateParameter && parameter instanceof ModelElement) { ((TemplateParameter) handle).setParameter((ModelElement) parameter); return; } throw new IllegalArgumentException("handle: " + handle + " or parameters: " + parameter); } public void setParameters(Object handle, Collection parameters) { if (handle instanceof ObjectFlowState || handle instanceof Classifier || handle instanceof Event || handle instanceof BehavioralFeature) { Collection params = Model.getFacade().getParameters(handle); if (!params.isEmpty()) { Collection actualParams = new ArrayList(params); for (Object param : actualParams) { removeParameter(handle, param); } } for (Object param : parameters) { addParameter(handle, param); } return; } throw new IllegalArgumentException("handle: " + handle + " or parameters: " + parameters); } public void setParent(Object handle, Object parent) { if (handle instanceof Generalization && parent instanceof GeneralizableElement) { ((Generalization) handle).setParent((GeneralizableElement) parent); return; } throw new IllegalArgumentException("handle: " + handle + " or parent: " + parent); } public void setPowertype(Object handle, Object pt) { if (handle instanceof Generalization && (pt == null || pt instanceof Classifier)) { ((Generalization) handle).setPowertype((Classifier) pt); return; } throw new IllegalArgumentException("handle: " + handle + " or pt: " + pt); } public void setQualifiers(Object handle, List elems) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).getQualifier().clear(); ((AssociationEnd) handle).getQualifier().addAll(elems); return; } throw new IllegalArgumentException("handle: " + handle); } public void setQuery(Object handle, boolean flag) { if (handle instanceof BehavioralFeature) { ((BehavioralFeature) handle).setQuery(flag); return; } throw new IllegalArgumentException("handle: " + handle); } public void setResident(Object handle, Object resident) { if (handle instanceof ElementResidence && (resident == null || resident instanceof ModelElement)) { ((ElementResidence) handle).setResident((ModelElement) resident); return; } throw new IllegalArgumentException("handle: " + handle + " or resident: " + resident); } public void setResidents(Object handle, Collection residents) { if (handle instanceof NodeInstance) { CollectionHelper.update( ((NodeInstance) handle).getResident(), residents); return; } if (handle instanceof ComponentInstance) { CollectionHelper.update( ((ComponentInstance) handle).getResident(), residents); return; } throw new IllegalArgumentException("handle: " + handle); } public void setRoot(Object handle, boolean flag) { if (handle instanceof Reception) { ((Reception) handle).setRoot(flag); return; } if (handle instanceof Operation) { ((Operation) handle).setRoot(flag); return; } if (handle instanceof GeneralizableElement) { ((GeneralizableElement) handle).setRoot(flag); return; } throw new IllegalArgumentException("handle: " + handle); } public void setSources(Object handle, Collection specifications) { if (handle instanceof Flow) { CollectionHelper.update( ((Flow) handle).getSource(), specifications); return; } throw new IllegalArgumentException("handle: " + handle); } public void setSpecification(Object handle, boolean specification) { if (handle instanceof ModelElement) { ((ModelElement) handle).setSpecification(specification); return; } throw new IllegalArgumentException("handle: " + handle); } public void setSpecification(Object operation, String specification) { if (operation instanceof Operation) { ((Operation) operation).setSpecification(specification); return; } if (operation instanceof Reception) { ((Reception) operation).setSpecification(specification); return; } throw new IllegalArgumentException("operation: " + operation); } public void setSpecification(Object method, Object specification) { if (method instanceof Method && specification instanceof Operation) { ((Method) method).setSpecification((Operation) specification); return; } throw new IllegalArgumentException("method: " + method + " or operation: " + specification); } public void setSpecifications(Object handle, Collection specifications) { if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).getSpecification().addAll(specifications); return; } throw new IllegalArgumentException("handle: " + handle); } @Deprecated public void setTaggedValue(Object handle, String tag, String value) { if (handle instanceof ModelElement) { TaggedValue tv = (TaggedValue) modelImpl.getFacade().getTaggedValue(handle, tag); if (tv == null) { tv = (TaggedValue) modelImpl.getExtensionMechanismsFactory(). buildTaggedValue(tag, value); ((ModelElement) handle).getTaggedValue().add(tv); } else { modelImpl.getExtensionMechanismsHelper().setDataValues(tv, new String[] {value}); } return; } throw new IllegalArgumentException("handle: " + handle); } @Deprecated public void setTargetScope(Object handle, Object scopeKind) { if (scopeKind instanceof ScopeKind) { if (handle instanceof StructuralFeature) { ((StructuralFeature) handle). setTargetScope((ScopeKind) scopeKind); return; } if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).setTargetScope((ScopeKind) scopeKind); return; } } throw new IllegalArgumentException("handle: " + handle + " or scopeKind: " + scopeKind); } public void setType(Object handle, Object type) { if (type == null || type instanceof Classifier) { if (handle instanceof ObjectFlowState) { ((ObjectFlowState) handle).setType((Classifier) type); return; } if (handle instanceof ClassifierInState) { ((ClassifierInState) handle).setType((Classifier) type); return; } if (handle instanceof Parameter) { ((Parameter) handle).setType((Classifier) type); return; } if (handle instanceof AssociationEnd) { ((AssociationEnd) handle).setParticipant((Classifier) type); return; } if (handle instanceof StructuralFeature) { ((StructuralFeature) handle).setType((Classifier) type); return; } } throw new IllegalArgumentException("handle: " + handle + " or type: " + type); } public void setVisibility(Object handle, Object visibility) { if (visibility instanceof VisibilityKind) { if (handle instanceof ModelElement) { ((ModelElement) handle). setVisibility((VisibilityKind) visibility); return; } if (handle instanceof ElementResidence) { ((ElementResidence) handle). setVisibility((VisibilityKind) visibility); return; } if (handle instanceof ElementImport) { ((ElementImport) handle). setVisibility((VisibilityKind) visibility); return; } } throw new IllegalArgumentException("handle: " + handle + " or visibility: " + visibility); } public void removeDeploymentLocation(Object handle, Object node) { try { if (handle instanceof Component && node instanceof Node) { ((Component) handle).getDeploymentLocation().remove(node); return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + handle + " or node: " + node); } public void addStereotype(Object modelElement, Object stereo) { if (modelElement instanceof ModelElement && stereo instanceof Stereotype) { ModelElement me = (ModelElement) modelElement; Stereotype stereotype = (Stereotype) stereo; if (!(me.getStereotype().contains(stereo))) { me.getStereotype().add(stereotype); } return; } throw new IllegalArgumentException("handle: " + modelElement + " or stereo: " + stereo); } public void addAllStereotypes(Object modelElement, Collection stereos) { if (modelElement instanceof ModelElement) { ModelElement me = (ModelElement) modelElement; me.getStereotype().addAll(stereos); return; } throw new IllegalArgumentException("handle: " + modelElement + " or stereos: " + stereos); } public void removeStereotype(Object modelElement, Object stereo) { try { if (modelElement instanceof ModelElement && stereo instanceof Stereotype) { ModelElement me = (ModelElement) modelElement; Stereotype stereotype = (Stereotype) stereo; if (me.getStereotype().contains(stereo)) { me.getStereotype().remove(stereotype); } return; } } catch (InvalidObjectException e) { throw new InvalidElementException(e); } throw new IllegalArgumentException("handle: " + modelElement + " or stereo: " + stereo); } /* * @see org.argouml.model.CoreHelper#clearStereotypes(java.lang.Object) */ public void clearStereotypes(Object modelElement) { if (modelElement instanceof ModelElement) { ((ModelElement) modelElement).getStereotype().clear(); return; } throw new IllegalArgumentException("handle: " + modelElement); } public void setEnumerationLiterals(Object enumeration, List literals) { if (enumeration instanceof Enumeration) { ((Enumeration) enumeration).getLiteral().clear(); ((Enumeration) enumeration).getLiteral().addAll(literals); } } public Collection<String> getAllMetatypeNames() { Set<String> names = new HashSet<String>(); for (Object element : modelImpl.getModelPackage().getMofClass() .refAllOfClass()) { String name = ((javax.jmi.model.ModelElement) element).getName(); if (names.add(name)) { LOG.debug(" Class " + name); } else { LOG.error("Found duplicate class " + name + " in metamodel"); } } return names; } public Collection<String> getAllMetaDatatypeNames() { Set<String> names = new HashSet<String>(); // Returns nothing for (Object element : modelImpl.getModelPackage().getDataType() .refAllOfClass()) { String name = ((javax.jmi.model.DataType) element).getName(); if (names.add(name)) { LOG.debug(" DataType " + name); } else { LOG.error("Found duplicate datatype " + name + " in metamodel"); } } // ScopeKind, VisibilityKind, PseudostateKind, etc // Doesn't include Boolean though, despite what UML 1.4 spec says for (Object element : modelImpl.getModelPackage().getEnumerationType() .refAllOfClass()) { String name = ((javax.jmi.model.EnumerationType) element).getName(); if (names.add(name)) { LOG.debug(" EnumerationType " + name); } else { LOG.error("Found duplicate EnumerationType " + name + " in metamodel"); } } // Boolean, String, Integer, Long, Float, Double, etc for (Object element : modelImpl.getModelPackage().getPrimitiveType() .refAllOfClass()) { String name = ((javax.jmi.model.PrimitiveType) element).getName(); if (names.add(name)) { LOG.debug(" PrimitiveType " + name); } else { LOG.error("Found duplicate primitive type " + name + " in metamodel"); } } return names; } /** * Create a command for a setter of a String value. * * @param accesser The accesser. * @param newValue The new value. * @param oldValue The old value. */ private void createCommand( final StringSetter accesser, final String newValue, final String oldValue, final String descr) { if (newValue == oldValue) { return; } if (newValue != null && newValue.equals(oldValue)) { return; } ModelCommand command = new ModelCommand() { public void undo() { accesser.set(oldValue); } public Object execute() { accesser.set(newValue); return null; } public boolean isUndoable() { return true; } public boolean isRedoable() { return true; } public String toString() { return descr; } }; Model.execute(command); } }