/* $Id: CoreFactoryMDRImpl.java 18767 2010-09-18 23:19:19Z tfmorris $ ***************************************************************************** * 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: * bobtarling * Thomas Neustupny * Tom Morris ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 1996-2009 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.Iterator; import java.util.List; import javax.jmi.reflect.InvalidObjectException; import javax.jmi.reflect.RefObject; import org.apache.log4j.Logger; import org.argouml.model.CoreFactory; import org.argouml.model.Model; import org.argouml.model.ModelCommand; import org.argouml.model.ModelManagementHelper; import org.argouml.model.NotImplementedException; import org.omg.uml.behavioralelements.activitygraphs.ObjectFlowState; import org.omg.uml.behavioralelements.commonbehavior.Reception; import org.omg.uml.behavioralelements.commonbehavior.Signal; import org.omg.uml.behavioralelements.statemachines.Event; import org.omg.uml.foundation.core.Abstraction; import org.omg.uml.foundation.core.Artifact; import org.omg.uml.foundation.core.AssociationClass; 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.CorePackage; import org.omg.uml.foundation.core.DataType; import org.omg.uml.foundation.core.Dependency; import org.omg.uml.foundation.core.Element; 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.PresentationElement; import org.omg.uml.foundation.core.Primitive; import org.omg.uml.foundation.core.ProgrammingLanguageDataType; 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.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.core.Usage; 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.CallConcurrencyKindEnum; 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.MultiplicityRange; import org.omg.uml.foundation.datatypes.OrderingKind; import org.omg.uml.foundation.datatypes.OrderingKindEnum; import org.omg.uml.foundation.datatypes.ParameterDirectionKindEnum; import org.omg.uml.foundation.datatypes.ProcedureExpression; 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.UmlPackage; /** * Factory to create UML classes for the UML Foundation::Core package. * <p> * Feature, StructuralFeature, and PresentationElement do not have a create * method since they are called an "abstract metaclass" in the UML * specifications. * <p> * @since ARGO0.19.5 * @author Ludovic Maître * @author Tom Morris * <p> * Derived from NSUML implementation by: * @author Thierry Lach * @author Jaap Branderhorst */ class CoreFactoryMDRImpl extends AbstractUmlModelFactoryMDR implements CoreFactory { private static final Logger LOG = Logger .getLogger(CoreFactoryMDRImpl.class); /** * The model implementation. */ private MDRModelImplementation modelImpl; /** * Constructor. * * @param implementation * To get other helpers and factories. */ CoreFactoryMDRImpl(MDRModelImplementation implementation) { modelImpl = implementation; } private CorePackage getCorePackage() { return modelImpl.getUmlPackage().getCore(); } public Abstraction createAbstraction() { Abstraction myAbstraction = getCorePackage().getAbstraction() .createAbstraction(); super.initialize(myAbstraction); return myAbstraction; } public Abstraction buildAbstraction(String name, Object supplier, Object client) { if (!(client instanceof Classifier) || !(supplier instanceof Classifier)) { throw new IllegalArgumentException( "The supplier and client of an abstraction" + "should be classifiers"); } if (client.equals(supplier)) { throw new IllegalArgumentException("The supplier and the client " + "must be different elements"); } Abstraction abstraction = createAbstraction(); abstraction.setName(name); abstraction.getClient().add((Classifier) client); abstraction.getSupplier().add((Classifier) supplier); return abstraction; } public Artifact createArtifact() { Artifact artifact = getCorePackage().getArtifact().createArtifact(); super.initialize(artifact); return artifact; } @Deprecated public UmlAssociation createAssociation() { return createAssociation(modelImpl.getUmlPackage()); } public UmlAssociation createAssociation(Object extent) { UmlAssociation assoc = ((org.omg.uml.UmlPackage) extent).getCore() .getUmlAssociation().createUmlAssociation(); super.initialize(assoc); return assoc; } public AssociationClass createAssociationClass() { AssociationClass assoc = getCorePackage().getAssociationClass() .createAssociationClass(); super.initialize(assoc); return assoc; } public AssociationEnd createAssociationEnd() { AssociationEnd assocEnd = getCorePackage().getAssociationEnd() .createAssociationEnd(); super.initialize(assocEnd); return assocEnd; } public Attribute createAttribute() { Attribute myAttribute = getCorePackage().getAttribute().createAttribute(); super.initialize(myAttribute); return myAttribute; } public Binding createBinding() { Binding myBinding = getCorePackage().getBinding().createBinding(); super.initialize(myBinding); return myBinding; } public UmlClass createClass() { return createClass(modelImpl.getUmlPackage()); } public UmlClass createClass(org.omg.uml.UmlPackage extent) { UmlClass myClass = extent.getCore().getUmlClass().createUmlClass(); super.initialize(myClass); return myClass; } public Comment createComment() { Comment myComment = getCorePackage().getComment().createComment(); super.initialize(myComment); return myComment; } public Component createComponent() { Component myComponent = getCorePackage().getComponent().createComponent(); super.initialize(myComponent); return myComponent; } public Constraint createConstraint() { Constraint myConstraint = getCorePackage().getConstraint() .createConstraint(); super.initialize(myConstraint); return myConstraint; } public DataType createDataType() { DataType dataType = getCorePackage().getDataType().createDataType(); super.initialize(dataType); return dataType; } public Dependency createDependency() { Dependency myDependency = getCorePackage().getDependency() .createDependency(); super.initialize(myDependency); return myDependency; } public ElementResidence createElementResidence() { ElementResidence myElementResidence = getCorePackage(). getElementResidence().createElementResidence(); super.initialize(myElementResidence); return myElementResidence; } public ElementResidence buildElementResidence(Object me, Object component) { ElementResidence myElementResidence = ((org.omg.uml.UmlPackage) ((ModelElement) me) .refOutermostPackage()).getCore().getElementResidence() .createElementResidence(); super.initialize(myElementResidence); myElementResidence.setContainer((Component) component); myElementResidence.setResident((ModelElement) me); return myElementResidence; } public Enumeration createEnumeration() { Enumeration myEnumeration = getCorePackage().getEnumeration() .createEnumeration(); super.initialize(myEnumeration); return myEnumeration; } public EnumerationLiteral createEnumerationLiteral() { EnumerationLiteral myEnumerationLiteral = getCorePackage() .getEnumerationLiteral().createEnumerationLiteral(); super.initialize(myEnumerationLiteral); return myEnumerationLiteral; } public EnumerationLiteral buildEnumerationLiteral(String name, Object enumeration) { EnumerationLiteral el = createEnumerationLiteral(); el.setName(name); el.setEnumeration((Enumeration) enumeration); return el; } public Flow createFlow() { Flow myFlow = getCorePackage().getFlow().createFlow(); super.initialize(myFlow); return myFlow; } @Deprecated public Generalization createGeneralization() { return createGeneralization(modelImpl.getUmlPackage()); } public Generalization createGeneralization(Object extent) { Generalization myGeneralization = ((org.omg.uml.UmlPackage) extent) .getCore().getGeneralization().createGeneralization(); super.initialize(myGeneralization); return myGeneralization; } public Interface createInterface() { Interface myInterface = getCorePackage() .getInterface().createInterface(); super.initialize(myInterface); return myInterface; } public Method createMethod() { Method myMethod = getCorePackage().getMethod() .createMethod(); super.initialize(myMethod); return myMethod; } public Node createNode() { Node myNode = getCorePackage().getNode().createNode(); super.initialize(myNode); return myNode; } public Operation createOperation() { Operation myOperation = getCorePackage() .getOperation().createOperation(); super.initialize(myOperation); return myOperation; } public Parameter createParameter() { Parameter myParameter = getCorePackage() .getParameter().createParameter(); super.initialize(myParameter); return myParameter; } @Deprecated public Permission createPermission() { return createPackageImport(); } public Permission createPackageImport() { Permission myPermission = getCorePackage() .getPermission().createPermission(); super.initialize(myPermission); return myPermission; } public Primitive createPrimitiveType() { Primitive obj = getCorePackage().getPrimitive().createPrimitive(); super.initialize(obj); return obj; } public TemplateArgument createTemplateArgument() { return createTemplateArgument(modelImpl.getUmlPackage()); } private TemplateArgument createTemplateArgument( org.omg.uml.UmlPackage extent) { TemplateArgument obj = extent.getCore().getTemplateArgument() .createTemplateArgument(); super.initialize(obj); return obj; } public TemplateParameter createTemplateParameter() { return createTemplateParameter(modelImpl.getUmlPackage()); } private TemplateParameter createTemplateParameter( org.omg.uml.UmlPackage extent) { TemplateParameter myTemplateParameter = extent.getCore() .getTemplateParameter().createTemplateParameter(); super.initialize(myTemplateParameter); return myTemplateParameter; } public Usage createUsage() { Usage myUsage = getCorePackage().getUsage().createUsage(); super.initialize(myUsage); return myUsage; } /** * Builds a default binary association with two default association ends. * * @param c1 * The first classifier to connect to * @param nav1 * The navigability of the Associaton end * @param agg1 * The aggregation type of the second Associaton end * @param c2 * The second classifier to connect to * @param nav2 * The navigability of the second Associaton end * @param agg2 * The aggregation type of the second Associaton end * @return a newly created Association * @throws IllegalArgumentException * if either Classifier is null */ private UmlAssociation buildAssociation(Classifier c1, boolean nav1, AggregationKind agg1, Classifier c2, boolean nav2, AggregationKind agg2) { if (c1 == null || c2 == null) { throw new IllegalArgumentException("one of " + "the classifiers to be " + "connected is null"); } Namespace ns1 = c1.getNamespace(); Namespace ns2 = c2.getNamespace(); if (ns1 == null || ns2 == null) { throw new IllegalArgumentException("one of " + "the classifiers does not " + "belong to a namespace"); } // We'll put the association in the namespace of whichever end // is not navigable and is writeable. If they both are, we'll use the // namepace of c1. Namespace ns = null; if (nav2 && !modelImpl.getModelManagementHelper().isReadOnly(ns1)) { ns = ns1; } else if (nav1 && !modelImpl.getModelManagementHelper().isReadOnly(ns2)) { ns = ns2; } else { throw new IllegalArgumentException( "At least one end must be navigable"); } UmlAssociation assoc = createAssociation(ns.refOutermostPackage()); assoc.setName(""); assoc.setNamespace(ns); buildAssociationEnd(assoc, null, c1, null, null, nav1, null, agg1, null, null, null); buildAssociationEnd(assoc, null, c2, null, null, nav2, null, agg2, null, null, null); return assoc; } @Deprecated public UmlAssociation buildAssociation(Object fromClassifier, Object aggregationKind1, Object toClassifier, Object aggregationKind2, Boolean unidirectional) { if (unidirectional == null) { return buildAssociation(fromClassifier, aggregationKind1, toClassifier, aggregationKind2, false); } else { return buildAssociation(fromClassifier, aggregationKind1, toClassifier, aggregationKind2, unidirectional .booleanValue()); } } public UmlAssociation buildAssociation(Object fromClassifier, Object aggregationKind1, Object toClassifier, Object aggregationKind2, boolean unidirectional) { if (fromClassifier == null || toClassifier == null) { throw new IllegalArgumentException("one of " + "the classifiers to be " + "connected is null"); } Classifier from = (Classifier) fromClassifier; Classifier to = (Classifier) toClassifier; AggregationKind agg1 = (AggregationKind) aggregationKind1; AggregationKind agg2 = (AggregationKind) aggregationKind2; Namespace ns = from.getNamespace(); if (ns == null || modelImpl.getModelManagementHelper().isReadOnly(ns)) { ns = to.getNamespace(); if (ns == null || modelImpl.getModelManagementHelper().isReadOnly(ns)) { throw new IllegalArgumentException( "At least one namespace must be non-null and writeable"); } } UmlAssociation assoc = createAssociation(ns.refOutermostPackage()); assoc.setName(""); assoc.setNamespace(ns); final boolean nav1 = !unidirectional; final boolean nav2 = true; buildAssociationEnd(assoc, null, from, null, null, nav1, null, agg1, null, null, null); buildAssociationEnd(assoc, null, to, null, null, nav2, null, agg2, null, null, null); return assoc; } public UmlAssociation buildAssociation(Object classifier1, Object classifier2) { Classifier c1 = (Classifier) classifier1; Classifier c2 = (Classifier) classifier2; return buildAssociation(c1, true, AggregationKindEnum.AK_NONE, c2, true, AggregationKindEnum.AK_NONE); } public UmlAssociation buildAssociation(Object c1, boolean nav1, Object c2, boolean nav2, String name) { UmlAssociation assoc = buildAssociation((Classifier) c1, nav1, AggregationKindEnum.AK_NONE, (Classifier) c2, nav2, AggregationKindEnum.AK_NONE); if (assoc != null) { assoc.setName(name); } return assoc; } public AssociationClass buildAssociationClass(Object end1, Object end2) { if (end1 == null || end2 == null || !(end1 instanceof Classifier) || !(end2 instanceof Classifier)) { throw new IllegalArgumentException( "either one of the arguments was null"); } final Classifier classifier1 = (Classifier) end1; final Classifier classifier2 = (Classifier) end2; AssociationClass assocClass = createAssociationClass(); assocClass.setNamespace(classifier1.getNamespace()); assocClass.setName(""); assocClass.setAbstract(false); assocClass.setActive(false); assocClass.setRoot(false); assocClass.setLeaf(false); assocClass.setSpecification(false); assocClass.setVisibility(VisibilityKindEnum.VK_PUBLIC); buildAssociationEnd( assocClass, null, classifier1, null, null, true, null, null, null, null, null); buildAssociationEnd( assocClass, null, classifier2, null, null, true, null, null, null, null, null); return assocClass; } public AssociationEnd buildAssociationEnd(Object assoc, String name, Object type, Integer[] multiplicity, Object stereo, boolean navigable, Object order, Object aggregation, Object scope, Object changeable, Object visibility) { if (aggregation != null && aggregation.equals(AggregationKindEnum.AK_COMPOSITE) && multiplicity != null && (multiplicity[1] > 1 || multiplicity[1] == -1) ) { throw new IllegalArgumentException("aggregation is composite " + "and multiplicity > 1"); } AssociationEnd ae = buildAssociationEndInternal(assoc, name, type, stereo, navigable, order, aggregation, scope, changeable, visibility); if (multiplicity != null) { Multiplicity m = modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(multiplicity[0], multiplicity[1]); ae.setMultiplicity(m); } return ae; } @Deprecated public AssociationEnd buildAssociationEnd(Object assoc, String name, Object type, Object multi, Object stereo, boolean navigable, Object order, Object aggregation, Object scope, Object changeable, Object visibility) { if (multi != null && !(multi instanceof Multiplicity)) { throw new IllegalArgumentException("Multiplicity"); } if (aggregation != null && aggregation.equals(AggregationKindEnum.AK_COMPOSITE) && multi != null && compareMultiplicity(getMaxUpper((Multiplicity) multi), 1) > 0) { throw new IllegalArgumentException("aggregation is composite " + "and multiplicity > 1"); } AssociationEnd ae = buildAssociationEndInternal(assoc, name, type, stereo, navigable, order, aggregation, scope, changeable, visibility); if (multi == null) { ae.setMultiplicity(getMultiplicity11()); } else if (multi instanceof Multiplicity) { ae.setMultiplicity((Multiplicity) multi); } else if (multi instanceof String) { Multiplicity m = modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal((String) multi); ae.setMultiplicity(m); } return ae; } private AssociationEnd buildAssociationEndInternal (Object assoc, String name, Object type, Object stereo, boolean navigable, Object order, Object aggregation, Object scope, Object changeable, Object visibility) { // wellformednessrules and preconditions if (assoc == null || !(assoc instanceof UmlAssociation) || type == null || !(type instanceof Classifier)) { throw new IllegalArgumentException("either type or association " + "are null"); } if (stereo != null && !(stereo instanceof Stereotype)) { throw new IllegalArgumentException("Stereotype"); } if (order != null && !(order instanceof OrderingKind)) { throw new IllegalArgumentException("OrderingKind"); } if (aggregation != null && !(aggregation instanceof AggregationKind)) { throw new IllegalArgumentException("AggregationKind"); } if (scope != null && !(scope instanceof ScopeKind)) { throw new IllegalArgumentException("ScopeKind"); } if (changeable != null && !(changeable instanceof ChangeableKind)) { throw new IllegalArgumentException("ChangeableKind"); } if (visibility != null && !(visibility instanceof VisibilityKind)) { throw new IllegalArgumentException("VisibilityKind"); } AssociationEnd end = createAssociationEnd(); end.setAssociation((UmlAssociation) assoc); end.setParticipant((Classifier) type); end.setName(name); // UML 1.4 WFR 2.5.3.1 #3 - no aggregation for N-ary associations List<AssociationEnd> ends = ((UmlAssociation) assoc).getConnection(); if (ends.size() >= 3) { for (AssociationEnd e : ends) { e.setAggregation(AggregationKindEnum.AK_NONE); } } if (stereo != null) { end.getStereotype().clear(); end.getStereotype().add((Stereotype) stereo); } end.setNavigable(navigable); if (order != null) { end.setOrdering((OrderingKind) order); } else { end.setOrdering(OrderingKindEnum.OK_UNORDERED); } if (aggregation != null) { end.setAggregation((AggregationKind) aggregation); } else { end.setAggregation(AggregationKindEnum.AK_NONE); } if (scope != null) { end.setTargetScope((ScopeKind) scope); } else { end.setTargetScope(ScopeKindEnum.SK_INSTANCE); } if (changeable != null) { end.setChangeability((ChangeableKind) changeable); } else { end.setChangeability(ChangeableKindEnum.CK_CHANGEABLE); } if (visibility != null) { end.setVisibility((VisibilityKind) visibility); } else { end.setVisibility(VisibilityKindEnum.VK_PUBLIC); } return end; } private static final int MULT_UNLIMITED = -1; /** * Get the maximum value of a multiplicity * * @param m * the Multiplicity * @return upper range */ private int getMaxUpper(Multiplicity m) { int max = 0; for (MultiplicityRange mr : m.getRange()) { int value = mr.getUpper(); if (value == MULT_UNLIMITED) { max = value; } else if (max != MULT_UNLIMITED && value > max) { max = value; } } return max; } /** * Compare two multiplicities taking care of the value 'unlimited' (-1). * * @param mult1 first multiplicity * @param mult2 second multiplicity * @return 0 if equal, a positive integer (not necessarily 1) if mult1 is * greater than mult2 and a negative integer if mult2 is greater.. */ private static int compareMultiplicity(int mult1, int mult2) { if (mult1 == MULT_UNLIMITED) { if (mult2 == MULT_UNLIMITED) { return 0; // equal } return 1; // greater } else if (mult2 == MULT_UNLIMITED) { return -1; // less than } return mult1 - mult2; } /** * Get a 1..1 multiplicity */ private Multiplicity getMultiplicity11() { return modelImpl.getDataTypesFactoryInternal() .createMultiplicityInternal(1, 1); } public AssociationEnd buildAssociationEnd(Object type, Object assoc) { if (type == null || !(type instanceof Classifier) || assoc == null || !(assoc instanceof UmlAssociation)) { throw new IllegalArgumentException("one of the arguments is null"); } return buildAssociationEnd(assoc, "", type, null, null, true, null, null, null, null, VisibilityKindEnum.VK_PUBLIC); } public Attribute buildAttribute(Object model, Object theType) { return buildAttribute2(theType); } public Attribute buildAttribute2(Object theType) { Attribute attr = buildAttribute(); attr.setType((Classifier) theType); return attr; } /** * Build a new attribute with no type * @return the new attribute */ Attribute buildAttribute() { Attribute attr = createAttribute(); attr.setName("newAttr"); attr.setMultiplicity(getMultiplicity11()); attr.setVisibility(VisibilityKindEnum.VK_PUBLIC); attr.setOwnerScope(ScopeKindEnum.SK_INSTANCE); attr.setChangeability(ChangeableKindEnum.CK_CHANGEABLE); attr.setTargetScope(ScopeKindEnum.SK_INSTANCE); return attr; } public Attribute buildAttribute2(Object handle, Object type) { Attribute attr = buildAttribute2(type); if (handle instanceof Classifier) { Classifier cls = (Classifier) handle; cls.getFeature().add(attr); } else if (handle instanceof AssociationEnd) { AssociationEnd assend = (AssociationEnd) handle; assend.getQualifier().add(attr); } else { throw new IllegalArgumentException(); } return attr; } public UmlClass buildClass() { return buildClass((Object) null); } private static void initClass(UmlClass cl) { cl.setName(""); cl.setAbstract(false); cl.setActive(false); cl.setRoot(false); cl.setLeaf(false); cl.setSpecification(false); cl.setVisibility(VisibilityKindEnum.VK_PUBLIC); } public UmlClass buildClass(final Object owner) { ModelCommand command = new ModelCommand() { private UmlClass cl; public UmlClass execute() { if (owner == null) { cl = createClass(); } else { cl = createClass(getExtent(owner)); } initClass(cl); return cl; } public void undo() { try { cl.refDelete(); } catch (InvalidObjectException e) { LOG.warn("Object already deleted " + cl); } } public boolean isUndoable() { return true; } public boolean isRedoable() { return false; } }; UmlClass clazz = (UmlClass) org.argouml.model.Model.execute(command); if (owner instanceof Namespace) { modelImpl.getCoreHelper().setNamespace(clazz, owner); } return clazz; } private org.omg.uml.UmlPackage getExtent(Object element) { return (org.omg.uml.UmlPackage) ((RefObject) element) .refOutermostPackage(); } public UmlClass buildClass(String name) { UmlClass clazz = buildClass(); clazz.setName(name); return clazz; } public UmlClass buildClass(String name, Object owner) { UmlClass clazz = buildClass(); clazz.setName(name); if (owner instanceof Namespace) { modelImpl.getCoreHelper().setNamespace(clazz, owner); } return clazz; } public Interface buildInterface() { Interface cl = createInterface(); cl.setName(""); cl.setAbstract(false); cl.setRoot(false); cl.setLeaf(false); cl.setSpecification(false); cl.setVisibility(VisibilityKindEnum.VK_PUBLIC); return cl; } public Interface buildInterface(Object owner) { Interface cl = buildInterface(); if (owner instanceof Namespace) { cl.setNamespace((Namespace) owner); } return cl; } public Interface buildInterface(String name) { Interface cl = buildInterface(); cl.setName(name); return cl; } public Interface buildInterface(String name, Object owner) { Interface cl = buildInterface(); cl.setName(name); if (owner instanceof Namespace) { cl.setNamespace((Namespace) owner); } return cl; } public DataType buildDataType(String name, Object owner) { DataType dt = createDataType(); dt.setName(name); if (owner instanceof Namespace) { dt.setNamespace((Namespace) owner); } return dt; } public Enumeration buildEnumeration(String name, Object owner) { Enumeration e = createEnumeration(); e.setName(name); if (owner instanceof Namespace) { e.setNamespace((Namespace) owner); } return e; } public Dependency buildDependency(Object clientObj, Object supplierObj) { ModelElement client = (ModelElement) clientObj; ModelElement supplier = (ModelElement) supplierObj; if (client == null || supplier == null) { throw new IllegalArgumentException("client or supplier is null " + "client = " + client + " supplier = " + supplier); } Dependency dep = createDependency(); dep.getSupplier().add(supplier); dep.getClient().add(client); if (client instanceof Namespace) { dep.setNamespace((Namespace) client); } else if (client.getNamespace() != null) { dep.setNamespace(client.getNamespace()); } return dep; } public Permission buildPackageImport(Object client, Object supplier) { if (!(client instanceof Namespace) || !(supplier instanceof UmlPackage)) { throw new IllegalArgumentException("client is not a Namespace" + " or supplier is not a Package"); } Permission per = buildPermissionInternal((ModelElement) client, (UmlPackage) supplier); // TODO: This should fetch the stereotype from our profile modelImpl.getExtensionMechanismsFactory().buildStereotype(per, ModelManagementHelper.IMPORT_STEREOTYPE, per.getNamespace()); return per; } private Permission buildPermissionInternal(ModelElement client, ModelElement supplier) { Permission permission = createPackageImport(); permission.getSupplier().add(supplier); permission.getClient().add(client); if (client instanceof Namespace) { permission.setNamespace((Namespace) client); } else if (client.getNamespace() != null) { permission.setNamespace(client.getNamespace()); } return permission; } public Permission buildPackageAccess(Object client, Object supplier) { if (!(client instanceof Namespace) || !(supplier instanceof UmlPackage)) { throw new IllegalArgumentException("client or " + "supplier is not a Namespace"); } Permission per = buildPermissionInternal((ModelElement) client, (UmlPackage) supplier); // TODO: This should fetch the stereotype from our profile modelImpl.getExtensionMechanismsFactory().buildStereotype(per, ModelManagementHelper.ACCESS_STEREOTYPE, per.getNamespace()); return per; } public Generalization buildGeneralization(Object child1, Object parent1) { // TODO: This is a part implementation of well-formedness rule // UML1.4.2 - 4.5.3.20 [3] Circular inheritance is not allowed. // not self.allParents->includes(self) if (!(child1 instanceof GeneralizableElement && parent1 instanceof GeneralizableElement && child1 != parent1)) { throw new IllegalArgumentException( "Both items must be different generalizable elements"); } GeneralizableElement child = (GeneralizableElement) child1; GeneralizableElement parent = (GeneralizableElement) parent1; // Check that the two elements aren't already linked the opposite way // TODO: This is a part implementation of well-formedness rule // UML1.4.2 - 4.5.3.20 [3] Circular inheritance is not allowed. // not self.allParents->includes(self) for (Generalization gen : parent.getGeneralization()) { if (gen.getParent().equals(child)) { throw new IllegalArgumentException("Generalization exists" + " in opposite direction"); } } // TODO: This is well-formedness rule from UML1.4.2 // 4.5.3.20 [2] No GeneralizableElement can have a parent // Generalization to an element that is a leaf. // self.parent->forAll(s | not s.isLeaf) if (parent.isLeaf()) { throw new IllegalArgumentException("parent is leaf"); } // TODO: This is well-formedness rule from UML1.4.2 // 4.5.3.20 [1] A root cannot have any Generalizations. // self.isRoot implies self.generalization->isEmpty if (child.isRoot()) { throw new IllegalArgumentException("child is root"); } Namespace ns = child.getNamespace(); if ((ns == null || modelImpl.getModelManagementHelper().isReadOnly(ns)) && child instanceof Namespace) { ns = (Namespace) child; } if (ns == null || modelImpl.getModelManagementHelper().isReadOnly(ns)) { throw new IllegalArgumentException("No valid writeable namespace"); } Generalization gen = createGeneralization(ns.refOutermostPackage()); gen.setParent(parent); gen.setChild(child); gen.setNamespace(ns); return gen; } public Object buildManifestation(Object utilizedElement) { throw new NotImplementedException( "UML 1.4 has no manifestations"); } public Method buildMethod(String name) { Method method = createMethod(); if (method != null) { method.setName(name); } return method; } public Operation buildOperation(Object classifier, Object returnType) { if (!(classifier instanceof Classifier)) { throw new IllegalArgumentException("Handle is not a classifier"); } Classifier cls = (Classifier) classifier; Operation oper = createOperation(); oper.setName("newOperation"); oper.setOwner(cls); oper.setVisibility(VisibilityKindEnum.VK_PUBLIC); oper.setAbstract(false); oper.setLeaf(false); oper.setRoot(false); oper.setQuery(false); oper.setOwnerScope(ScopeKindEnum.SK_INSTANCE); oper.setConcurrency(CallConcurrencyKindEnum.CCK_SEQUENTIAL); Parameter returnParameter = buildParameter(oper, returnType); returnParameter.setKind(ParameterDirectionKindEnum.PDK_RETURN); returnParameter.setName("return"); return oper; } public Operation buildOperation2(Object cls, Object returnType, String name) { Operation oper = buildOperation(cls, returnType); if (oper != null) { oper.setName(name); } return oper; } /** * Constructs a default parameter. * * @return The newly created parameter. */ private Parameter buildParameter(Classifier type, javax.jmi.reflect.RefObject ref) { Parameter param = ((org.omg.uml.UmlPackage) ref.refOutermostPackage()) .getCore().getParameter().createParameter(); param.setType(type); return param; } public Parameter buildParameter(Object o, Object type) { if (o instanceof Event) { Event event = (Event) o; Parameter res = buildParameter((Classifier) type, event); res.setKind(ParameterDirectionKindEnum.PDK_IN); event.getParameter().add(res); res.setName("arg" + event.getParameter().size()); return res; } else if (o instanceof ObjectFlowState) { ObjectFlowState ofs = (ObjectFlowState) o; Parameter res = buildParameter((Classifier) type, ofs); res.setKind(ParameterDirectionKindEnum.PDK_IN); ofs.getParameter().add(res); res.setName("arg" + ofs.getParameter().size()); return res; } else if (o instanceof BehavioralFeature) { BehavioralFeature oper = (BehavioralFeature) o; Parameter res = buildParameter((Classifier) type, oper); res.setKind(ParameterDirectionKindEnum.PDK_IN); oper.getParameter().add(res); res.setName("arg" + oper.getParameter().size()); return res; } else if (o == null) { throw new IllegalArgumentException( "A containing element must be supplied for the parameter"); } else { throw new IllegalArgumentException( "Unsupported contining element for parameter " + o.getClass().getName()); } } public Abstraction buildRealization(Object clnt, Object spplr, Object model) { ModelElement client = (ModelElement) clnt; ModelElement supplier = (ModelElement) spplr; if (client == null || supplier == null || client.getNamespace() == null || supplier.getNamespace() == null || client.equals(supplier)) { throw new IllegalArgumentException("faulty arguments."); } Abstraction realization = createAbstraction(); Namespace nsc = client.getNamespace(); Namespace nss = supplier.getNamespace(); Namespace ns = null; if (nsc.equals(nss)) { ns = nsc; } else { ns = (Namespace) model; } realization.setNamespace(nsc); modelImpl.getExtensionMechanismsFactory().buildStereotype(realization, CoreFactory.REALIZE_STEREOTYPE, ns); realization.getClient().add(client); realization.getSupplier().add(supplier); return realization; } public TemplateArgument buildTemplateArgument(Object element) { TemplateArgument ta = createTemplateArgument(); ta.setModelElement((ModelElement) element); return ta; } public TemplateArgument buildTemplateArgument(Object binding, Object element) { if (!(binding instanceof Binding && element instanceof ModelElement)) { throw new IllegalArgumentException(); } TemplateArgument ta = createTemplateArgument(getExtent(binding)); ta.setModelElement((ModelElement) element); ta.setBinding((Binding) binding); return ta; } public Object buildTemplateParameter(Object template, Object parameter, Object defaultElement) { if (!(template instanceof ModelElement)) { throw new IllegalArgumentException( "Template must be a model element"); } if (!(parameter instanceof ModelElement)) { if (parameter == null) { parameter = createClass(getExtent(template)); } else { throw new IllegalArgumentException( "Parameter must be a model element"); } } if (defaultElement != null && !(defaultElement instanceof ModelElement)) { throw new IllegalArgumentException( "Default element must be a model element"); } TemplateParameter templateParam = createTemplateParameter(getExtent(template)); templateParam.setParameter((ModelElement) parameter); if (defaultElement != null) { templateParam.setDefaultElement((ModelElement) defaultElement); } templateParam.setTemplate((ModelElement) template); return templateParam; } public Usage buildUsage(Object client, Object supplier) { if (client == null || supplier == null) { throw new IllegalArgumentException("In buildUsage null arguments."); } if (!(client instanceof ModelElement)) { throw new IllegalArgumentException("client ModelElement"); } if (!(supplier instanceof ModelElement)) { throw new IllegalArgumentException("supplier ModelElement"); } // TODO: UML 1.4 spec requires both client and supplier to be // in the same model - tfm Usage usage = createUsage(); usage.getSupplier().add((ModelElement) supplier); usage.getClient().add((ModelElement) client); if (((ModelElement) supplier).getNamespace() != null) { usage.setNamespace(((ModelElement) supplier).getNamespace()); } else if (((ModelElement) client).getNamespace() != null) { usage.setNamespace(((ModelElement) client).getNamespace()); } // TODO: Add standard stereotype? Set is open ended, but // predefined names include: call, create, instantiate, send return usage; } public Comment buildComment(Object element, Object model) { if (model == null) { throw new IllegalArgumentException("A namespace must be supplied."); } ModelElement elementToAnnotate = (ModelElement) element; Comment comment = createComment(); Namespace commentsModel = null; if (elementToAnnotate != null) { comment.getAnnotatedElement().add(elementToAnnotate); commentsModel = elementToAnnotate.getNamespace(); } else { commentsModel = (Namespace) model; } comment.setNamespace(commentsModel); return comment; } public Constraint buildConstraint(Object constrElement) { ModelElement constrainedElement = (ModelElement) constrElement; if (constrainedElement == null) { throw new IllegalArgumentException("the constrained element is " + "mandatory and may not be " + "null."); } Constraint con = createConstraint(); con.getConstrainedElement().add(constrainedElement); con.setNamespace(constrainedElement.getNamespace()); return con; } public Constraint buildConstraint(String name, Object bexpr) { if (bexpr == null || !(bexpr instanceof BooleanExpression)) { throw new IllegalArgumentException("invalid boolean expression."); } Constraint con = createConstraint(); if (name != null) { con.setName(name); } con.setBody((BooleanExpression) bexpr); return con; } public Binding buildBinding(Object client, Object supplier, List arguments) { Collection<Dependency> clientDeps = ((ModelElement) client) .getClientDependency(); for (Dependency dep : clientDeps) { if (dep instanceof Binding) { throw new IllegalArgumentException( "client is already client of another Binding"); } } // Check arguments against parameters for type and number // TODO: Perhaps move this to a critic instead? - tfm - 20070326 if (arguments != null) { List<TemplateParameter> params = ((ModelElement) supplier).getTemplateParameter(); if (params.size() != arguments.size()) { throw new IllegalArgumentException( "number of arguments doesn't match number of params"); } Iterator<TemplateArgument> ita = arguments.iterator(); for (TemplateParameter param : params) { TemplateArgument ta = ita.next(); // TODO: Before allowing this, we should really check that // TemplateParameter.defaultElement is defined if (ta == null || ta.getModelElement() == null) { continue; } if (!(param.getParameter().getClass().equals( ta.getModelElement().getClass()))) { throw new IllegalArgumentException( "type of argument doesn't match type of parameter"); } } } Binding binding = createBinding(); binding.getClient().add((ModelElement) client); binding.getSupplier().add((ModelElement) supplier); if (arguments != null) { binding.getArgument().addAll(arguments); } return binding; } /** * @param elem * the abstraction to be deleted */ void deleteAbstraction(Object elem) { if (!(elem instanceof Abstraction)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the artifact to be deleted */ void deleteArtifact(Object elem) { if (!(elem instanceof Artifact)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the association to be deleted */ void deleteAssociation(Object elem) { if (!(elem instanceof UmlAssociation)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the a. to be deleted */ void deleteAssociationClass(Object elem) { if (!(elem instanceof AssociationClass)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Does a 'cascading delete' to all modelelements that are associated with * this element that would be in an illegal state after deletion of the * element. This method should not be called directly. * <p> * * In the case of an AssociationEnd these are the following elements: * <ul> * <li>Binary Associations that lose one of the AssociationEnds by this * deletion. * <li>LinkEnds associated with this AssociationEnd. * </ul> * * * @param elem * @see UmlFactoryMDRImpl#delete(Object) */ void deleteAssociationEnd(Object elem) { if (!(elem instanceof AssociationEnd)) { throw new IllegalArgumentException("elem: " + elem); } AssociationEnd ae = (AssociationEnd) elem; UmlAssociation assoc = ae.getAssociation(); if (assoc != null && assoc.getConnection() != null && assoc.getConnection().size() == 2) { // binary association modelImpl.getUmlFactory().delete(assoc); } // delete LinkEnds which have this as their associationEnd modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) ae.refOutermostPackage()) .getCommonBehavior().getAAssociationEndLinkEnd() .getLinkEnd(ae)); } /** * @param elem * the attribute to be deleted */ void deleteAttribute(Object elem) { if (!(elem instanceof Attribute)) { throw new IllegalArgumentException("elem: " + elem); } // delete AttributeLinks where this is the Attribute Attribute attr = (Attribute) elem; modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) attr.refOutermostPackage()) .getCommonBehavior().getAAttributeLinkAttribute() .getAttributeLink(attr)); } /** * @param elem the element to be deleted */ void deleteBehavioralFeature(Object elem) { if (!(elem instanceof BehavioralFeature)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteBinding(Object elem) { if (!(elem instanceof Binding)) { throw new IllegalArgumentException("elem: " + elem); } Binding binding = (Binding) elem; modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) binding.refOutermostPackage()) .getCore().getABindingArgument().getArgument(binding)); } /** * @param elem * the element to be deleted */ void deleteClass(Object elem) { if (!(elem instanceof UmlClass)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Does a 'cascading delete' to all modelelements that are associated with * this element that would be in an illegal state after deletion of the * element. Does not do an cascading delete for elements that are deleted by * the MDR method remove. This method should not be called directly. * <p> * * In the case of a classifier these are the following elements: * <ul> * <li>AssociationEnds that have this classifier as type * </ul> * * @param elem * @see UmlFactoryMDRImpl#delete(Object) */ void deleteClassifier(Object elem) { if (!(elem instanceof Classifier)) { throw new IllegalArgumentException("elem: " + elem); } modelImpl.getUmlHelper().deleteCollection( modelImpl.getFacade().getAssociationEnds(elem)); Classifier cls = (Classifier) elem; // delete CreateActions which have this as their instantiation modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) cls.refOutermostPackage()) .getCommonBehavior().getACreateActionInstantiation() .getCreateAction(cls)); // TODO: ?delete Instances which have this as their classifier? // or should we leave them since they contain so much state that the // user would have to recreate?? // nsmodel.getUmlHelper().deleteCollection( // nsmodel.getUmlPackage().getCommonBehavior() // .getAInstanceClassifier().getInstance(cls)); // TODO: ?delete ObjectFlowStates which have this as their type? // nsmodel.getUmlHelper().deleteCollection( // nsmodel.getUmlPackage().getActivityGraphs() // .getATypeObjectFlowState().getObjectFlowState(cls)); // TODO: ?delete ClassifierInStates which have this as their type? modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) cls.refOutermostPackage()) .getActivityGraphs().getATypeClassifierInState() .getClassifierInState(cls)); } /** * @param elem * the element to be deleted */ void deleteComment(Object elem) { if (!(elem instanceof Comment)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteComponent(Object elem) { if (!(elem instanceof Component)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteConstraint(Object elem) { if (!(elem instanceof Constraint)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteDataType(Object elem) { if (!(elem instanceof DataType)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteDependency(Object elem) { if (!(elem instanceof Dependency)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteElement(Object elem) { if (!(elem instanceof Element)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteElementResidence(Object elem) { if (!(elem instanceof ElementResidence)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteFeature(Object elem) { if (!(elem instanceof Feature)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteFlow(Object elem) { if (!(elem instanceof Flow)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteGeneralizableElement(Object elem) { if (!(elem instanceof GeneralizableElement)) { throw new IllegalArgumentException("elem: " + elem); } GeneralizableElement ge = (GeneralizableElement) elem; modelImpl.getUmlHelper().deleteCollection(ge.getGeneralization()); modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) ge.refOutermostPackage()).getCore() .getAParentSpecialization().getSpecialization(ge)); } /** * @param elem the element to be deleted */ void deleteGeneralization(Object elem) { if (!(elem instanceof Generalization)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteInterface(Object elem) { if (!(elem instanceof Interface)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteMethod(Object elem) { if (!(elem instanceof Method)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Does a 'cascading delete' to all modelelements that are associated with * this element that would be in an illegal state after deletion of the * element. Does not do an cascading delete for elements that are deleted by * MDR automatically. This method should not be called directly. * <p> * * In the case of a modelelement these are the following elements: * <ul> * <li>Dependencies that have the modelelement as supplier or as a client * and are binary. (that is, they only have one supplier and one client) * <li>Behaviors, TemplateArguments, and ElementImports which require * this ModelElement * </ul> * * @param elem * @see UmlFactoryMDRImpl#delete(Object) */ void deleteModelElement(Object elem) { if (!(elem instanceof ModelElement)) { throw new IllegalArgumentException("elem: " + elem); } // Delete dependencies where this is the only client Collection<Dependency> deps = org.argouml.model.Model.getFacade() .getClientDependencies(elem); for (Dependency dep : deps) { if (dep.getClient().size() < 2 && dep.getClient().contains(elem)) { modelImpl.getUmlFactory().delete(dep); } } // Delete dependencies where this is the only supplier deps = org.argouml.model.Model.getFacade() .getSupplierDependencies(elem); for (Dependency dep : deps) { if (dep.getSupplier().size() < 2 && dep.getSupplier().contains(elem)) { modelImpl.getUmlFactory().delete(dep); } } /* Do not delete behaviors here! * The behavior-context relation in the UML model * is an aggregate, not composition. See issue 4281. */ ModelElement me = (ModelElement) elem; modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) me.refOutermostPackage()).getCore() .getAModelElementTemplateArgument() .getTemplateArgument(me)); modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) me.refOutermostPackage()) .getModelManagement() .getAImportedElementElementImport() .getElementImport(me)); } /** * A namespace deletes its owned elements. * * @param elem * is the namespace. */ void deleteNamespace(Object elem) { LOG.debug("Deleting namespace " + elem); if (!(elem instanceof Namespace)) { throw new IllegalArgumentException("elem: " + elem); } List<ModelElement> ownedElements = new ArrayList<ModelElement>(); // TODO: This is a composite association, so these will get deleted // automatically. The only thing we need to do is check for any // additional elements that need to be deleted as a result. ownedElements.addAll(((Namespace) elem).getOwnedElement()); for (ModelElement element : ownedElements) { LOG.debug("Deleting ownedElement " + element); modelImpl.getUmlFactory().delete(element); } } /** * @param elem * the element to be deleted */ void deleteNode(Object elem) { if (!(elem instanceof Node)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteOperation(Object elem) { if (!(elem instanceof Operation)) { throw new IllegalArgumentException("elem: " + elem); } Operation oper = (Operation) elem; // delete CallActions which have this as their operation modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) oper.refOutermostPackage()) .getCommonBehavior().getACallActionOperation() .getCallAction(oper)); // delete CallEvents which have this as their operation modelImpl.getUmlHelper().deleteCollection( ((org.omg.uml.UmlPackage) oper.refOutermostPackage()) .getStateMachines().getAOccurrenceOperation() .getOccurrence(oper)); } /** * @param elem * the element to be deleted */ void deleteParameter(Object elem) { if (!(elem instanceof Parameter)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deletePermission(Object elem) { if (!(elem instanceof Permission)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deletePresentationElement(Object elem) { if (!(elem instanceof PresentationElement)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteRelationship(Object elem) { if (!(elem instanceof Relationship)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteStructuralFeature(Object elem) { if (!(elem instanceof StructuralFeature)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteTemplateArgument(Object elem) { if (!(elem instanceof TemplateArgument)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteTemplateParameter(Object elem) { if (!(elem instanceof TemplateParameter)) { throw new IllegalArgumentException("elem: " + elem); } } /** * @param elem * the element to be deleted */ void deleteUsage(Object elem) { if (!(elem instanceof Usage)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Delete an Enumeration. * @param elem * the element to be deleted * @since UML 1.4 */ void deleteEnumeration(Object elem) { if (!(elem instanceof Enumeration)) { throw new IllegalArgumentException("elem: " + elem); } // EnumerationLiterals should get deleted implicitly // since they are associated by composition } /** * Delete EnumerationLiteral. * @param elem * the element to be deleted * @since UML 1.4 */ void deleteEnumerationLiteral(Object elem) { if (!(elem instanceof EnumerationLiteral)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Delete the given UML Primitive. * * @param elem the element to be deleted * @since UML 1.4 */ void deletePrimitive(Object elem) { if (!(elem instanceof Primitive)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Delete the given ProgrammingLanguageDataType. * * @param elem the element to be deleted * @since UML 1.4 */ void deleteProgrammingLanguageDataType(Object elem) { if (!(elem instanceof ProgrammingLanguageDataType)) { throw new IllegalArgumentException("elem: " + elem); } } /** * Copies a class, and it's features. This may also require other * classifiers to be copied. * * @param source * is the class to copy. * @param ns * is the namespace to put the copy in. * @return a newly created class. */ public UmlClass copyClass(Object source, Object ns) { if (!(source instanceof UmlClass && ns instanceof Namespace)) { throw new IllegalArgumentException("source: " + source + ",ns: " + ns); } UmlClass c = createClass(); ((Namespace) ns).getOwnedElement().add(c); doCopyClass(source, c); return c; } /** * Copies a feature from one classifier to another. * * @param source is the feature to copy. * @param classifier is the classifier to put the copy in. * @return a newly created feature. */ public Feature copyFeature(Object source, Object classifier) { if (!(source instanceof Feature && classifier instanceof Classifier)) { throw new IllegalArgumentException("source: " + source + ",classifier: " + classifier); } Feature f = null; if (source instanceof Attribute) { Attribute attr = createAttribute(); doCopyAttribute((Attribute) source, attr); f = attr; } else if (source instanceof Operation) { Operation oper = createOperation(); doCopyOperation((Operation) source, oper); // TODO: build a return parameter f = oper; } else if (source instanceof Method) { Method method = createMethod(); doCopyMethod((Method) source, method); f = method; } else if (source instanceof Reception) { Reception reception = (Reception) modelImpl.getCommonBehaviorFactory().createReception(); doCopyReception((Reception) source, reception); f = reception; } else { throw new IllegalArgumentException("source: " + source); } f.setOwner((Classifier) classifier); ((Classifier) classifier).getFeature().add(f); return f; } /** * Copies a datatype, and it's features. This may also require other * classifiers to be copied. * * @param source * is the datatype to copy. * @param ns * is the namespace to put the copy in. * @return a newly created data type. */ public DataType copyDataType(Object source, Object ns) { if (!(source instanceof DataType)) { throw new IllegalArgumentException(); } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } DataType i = createDataType(); ((Namespace) ns).getOwnedElement().add(i); doCopyDataType(source, i); return i; } /** * Copies an interface, and it's features. This may also require other * classifiers to be copied. * * @param source * is the interface to copy. * @param ns * is the namespace to put the copy in. * @return a newly created interface. */ public Interface copyInterface(Object source, Object ns) { if (!(source instanceof Interface)) { throw new IllegalArgumentException(); } if (!(ns instanceof Namespace)) { throw new IllegalArgumentException(); } Interface i = createInterface(); ((Namespace) ns).getOwnedElement().add(i); doCopyInterface(source, i); return i; } /** * * @param from * The object which own the enumeration to copy * @param to * The object to which copy the enumeration */ public void copyEnumeration(Object from, Object to) { doCopyModelElement(from, to); List listFrom = ((Enumeration) from).getLiteral(); List listTo = ((Enumeration) to).getLiteral(); Object literalFrom; Object literalTo; for (int i = 0; i < listFrom.size(); i++) { literalFrom = listFrom.get(i); if (listTo.size() > i) { literalTo = listTo.get(i); } else { literalTo = createEnumerationLiteral(); listTo.add(literalTo); } doCopyModelElement(literalFrom, literalTo); ((EnumerationLiteral) literalTo).setEnumeration((Enumeration) to); } } /** * Used by the copy functions. Do not call this function directly. */ private void doCopyElement(Object source, Object target) { // Nothing more to do. } /** * Used by the copy functions. Do not call this function directly. * * @param source * the source class * @param target * the target class */ public void doCopyClass(Object source, Object target) { if (!(source instanceof UmlClass)) { throw new IllegalArgumentException(); } if (!(target instanceof UmlClass)) { throw new IllegalArgumentException(); } doCopyClassifier(source, target); ((UmlClass) target).setActive(((UmlClass) source).isActive()); } /* * TODO: All the ToDos in the doCopyFoo methods below are inherited from the * NSUML implementation and do not reflect new issues. One additional thing * which does need to be dealt with is the copying of any attributes which * have been added since this code was implemented for UML 1.3. */ /** * Used by the copy functions. Do not call this function directly. * TODO: actions? instances? collaborations etc? * * @param source * the source classifier * @param target * the target classifier */ public void doCopyClassifier(Object source, Object target) { if (!(source instanceof Classifier)) { throw new IllegalArgumentException(); } if (!(target instanceof Classifier)) { throw new IllegalArgumentException(); } // TODO: how to merge multiple inheritance? Necessary? // This currently copies the common ancestors multiple times doCopyNamespace(source, target); doCopyGeneralizableElement(source, target); // Copy all the Features for (Feature f : ((Classifier) source).getFeature()) { copyFeature(f, target); } } /** * Used by the copy functions. Do not call this function directly. * * @param source * the source datatype * @param target * the target datatype */ public void doCopyDataType(Object source, Object target) { if (!(source instanceof DataType)) { throw new IllegalArgumentException(); } if (!(target instanceof DataType)) { throw new IllegalArgumentException(); } doCopyClassifier(source, target); } /** * Used by the copy functions. Do not call this function directly. * TODO: generalizations, specializations? * * @param source * the source generalizable element * @param target * the target generalizable element */ public void doCopyGeneralizableElement(Object source, Object target) { if (!(source instanceof GeneralizableElement && target instanceof GeneralizableElement)) { throw new IllegalArgumentException("source: " + source + ",target: " + target); } doCopyModelElement(source, target); GeneralizableElement targetGE = ((GeneralizableElement) target); GeneralizableElement sourceGE = ((GeneralizableElement) source); targetGE.setAbstract(sourceGE.isAbstract()); targetGE.setLeaf(sourceGE.isLeaf()); targetGE.setRoot(sourceGE.isRoot()); } /** * Used by the copy functions. Do not call this function directly. * * @param source * the source interface * @param target * the target interface */ public void doCopyInterface(Object source, Object target) { if (!(source instanceof Interface)) { throw new IllegalArgumentException(); } if (!(target instanceof Interface)) { throw new IllegalArgumentException(); } doCopyClassifier(source, target); } /** * Used by the copy functions. Do not call this function directly. * TODO: template parameters, default type * TODO: constraining elements * TODO: flows, dependencies, comments, bindings, contexts ??? * TODO: contents, residences ??? * * @param source * the source me * @param target * the target me */ public void doCopyModelElement(Object source, Object target) { if (!(source instanceof ModelElement)) { throw new IllegalArgumentException(); } if (!(target instanceof ModelElement)) { throw new IllegalArgumentException(); } // Set the name so that superclasses can find the newly // created element in the model, if necessary. ModelElement targetME = ((ModelElement) target); ModelElement sourceME = ((ModelElement) source); targetME.setName(sourceME.getName()); doCopyElement(source, target); targetME.setSpecification(sourceME.isSpecification()); targetME.setVisibility(sourceME.getVisibility()); modelImpl.getExtensionMechanismsFactory() .copyTaggedValues(source, target); if (!sourceME.getStereotype().isEmpty()) { // Note that if we're copying this element then we // must also be allowed to copy other necessary // objects. for (Stereotype s : sourceME.getStereotype()) { targetME.getStereotype().add(s); } } } /** * Used by the copy functions. Do not call this function directly. * * @param source * the source namespace * @param target * the target namespace */ public void doCopyNamespace(Object source, Object target) { if (!(source instanceof Namespace)) { throw new IllegalArgumentException(); } if (!(target instanceof Namespace)) { throw new IllegalArgumentException(); } doCopyModelElement(source, target); // Nothing more to do, don't copy owned elements. } /** * Copy the meta-attributes of an Attribute to another. * * @param source the source attribute * @param target the new attribute to be adapted */ void doCopyAttribute(Attribute source, Attribute target) { // TODO: Delete old multiplicity? Why is "copy" using hard coded value? - tfm target.setMultiplicity(getMultiplicity11()); target.setChangeability(source.getChangeability()); target.setTargetScope(source.getTargetScope()); target.setType(source.getType()); doCopyFeature(source, target); } /** * Copy the attributes of an Operation to another. * * @param source the source operation * @param target the new operation to be modified */ void doCopyOperation(Operation source, Operation target) { target.setAbstract(source.isAbstract()); target.setLeaf(source.isLeaf()); target.setRoot(source.isRoot()); target.setConcurrency(source.getConcurrency()); target.setSpecification(source.getSpecification()); doCopyBehavioralFeature(source, target); } /** * Copy the attributes of one Method to another. * * @param source the method to copy attributes from * @param target the method to be adapted */ void doCopyMethod(Method source, Method target) { ProcedureExpression pe = source.getBody(); ProcedureExpression oldPe = target.getBody(); if (!equal(oldPe,pe)) { target.setBody((ProcedureExpression) modelImpl.getDataTypesFactory().createProcedureExpression( pe.getLanguage(), pe.getBody())); if (oldPe != null) { Model.getUmlFactory().delete(oldPe); } } doCopyBehavioralFeature(source, target); } private boolean equal(Expression expr1, Expression expr2) { if (expr1 == null) { if (expr2 == null) { return true; } else { return false; } } else { return expr1.equals(expr2); } } /** * Copy the attributes of one Reception to another. * * @param source the reception to copy attributes from * @param target the reception to be adapted */ void doCopyReception(Reception source, Reception target) { target.setAbstract(source.isAbstract()); target.setLeaf(source.isLeaf()); target.setRoot(source.isRoot()); target.setSpecification(source.getSpecification()); target.setSignal(source.getSignal()); doCopyBehavioralFeature(source, target); } /** * Copy the attributes of one BehavioralFeature to another. * * @param source the BehavioralFeature to copy from * @param target the BehavioralFeature to b adapted */ void doCopyBehavioralFeature(BehavioralFeature source, BehavioralFeature target) { target.setQuery(source.isQuery()); // copy raised signals: Collection<Signal> raisedSignals = ((org.omg.uml.UmlPackage) source .refOutermostPackage()).getCommonBehavior() .getAContextRaisedSignal().getRaisedSignal(source); for (Signal signal : raisedSignals) { ((org.omg.uml.UmlPackage) source.refOutermostPackage()) .getCommonBehavior().getAContextRaisedSignal().add(target, signal); } doCopyFeature(source, target); } /** * Copy the attributes of one Feature to another. * * @param source the Feature to copy from * @param target the Feature to copy to */ void doCopyFeature(Feature source, Feature target) { target.setVisibility(source.getVisibility()); target.setOwnerScope(source.getOwnerScope()); doCopyModelElement(source, target); } }