CoreFactoryMDRImpl.java
/* $Id$
*****************************************************************************
* Copyright (c) 2009-2012 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 java.util.logging.Level;
import java.util.logging.Logger;
import javax.jmi.reflect.InvalidObjectException;
import javax.jmi.reflect.RefObject;
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.getName());
/**
* 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.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.log(Level.WARNING, "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.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.log(Level.FINE, "Deleting namespace {0}", 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.log(Level.FINE, "Deleting ownedElement {0}", 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);
}
}