ExtensionMechanismsFactoryMDRImpl.java
/* $Id$
*****************************************************************************
* Copyright (c) 2009-2011 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:
* Tom Morris
* Michiel van der Wulp
*****************************************************************************
*
* Some portions of this file was previously release using the BSD License:
*/
// Copyright (c) 1996-2007 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.Collection;
import java.util.Iterator;
import org.argouml.model.CoreHelper;
import org.argouml.model.ExtensionMechanismsFactory;
import org.argouml.model.ExtensionMechanismsHelper;
import org.omg.uml.foundation.core.ModelElement;
import org.omg.uml.foundation.core.Namespace;
import org.omg.uml.foundation.core.Stereotype;
import org.omg.uml.foundation.core.TagDefinition;
import org.omg.uml.foundation.core.TaggedValue;
/**
* Factory to create UML classes for the UML ExtensionMechanisms
* package.<p>
*
* @since ARGO0.19.5
* @author Ludovic Maître
* @author Tom Morris
* <p>
* derived from NSUML implementation by:
* @author Thierry Lach
*/
class ExtensionMechanismsFactoryMDRImpl extends
AbstractUmlModelFactoryMDR implements ExtensionMechanismsFactory {
/**
* The model implementation.
*/
private MDRModelImplementation modelImpl;
/**
* The extension mechanism helper.
*/
private ExtensionMechanismsHelper extensionHelper;
/**
* Don't allow instantiation.
*
* @param implementation
* To get other helpers and factories.
*/
ExtensionMechanismsFactoryMDRImpl(MDRModelImplementation implementation) {
modelImpl = implementation;
extensionHelper = implementation.getExtensionMechanismsHelper();
}
/*
* @see org.argouml.model.ExtensionMechanismsFactory#createTaggedValue()
*/
public TaggedValue createTaggedValue() {
TaggedValue tv = modelImpl.getUmlPackage().getCore().getTaggedValue().
createTaggedValue();
super.initialize(tv);
return tv;
}
/**
* Get an instance of a UML TagDefinition.
*
* @param tagName The name of the TagDefinition to create/retrieve
* @return an initialized UML TaggedValue instance.
*/
TagDefinition getTagDefinition(String tagName) {
if (tagName == null) {
throw new IllegalArgumentException("Argument may not be null");
}
// Look for a TagDefinition matching the given name
for (Iterator i = modelImpl.getUmlPackage().getCore().getTagDefinition()
.refAllOfClass().iterator(); i.hasNext();) {
TagDefinition td = (TagDefinition) i.next();
if (tagName.equals(td.getName())) {
return td;
}
}
// Create a new TagDefinition if none found
Object rootModel = modelImpl.getModelManagementFactory().getRootModel();
TagDefinition td = buildTagDefinition(tagName, null, rootModel);
super.initialize(td);
return td;
}
/*
* TODO: MVW: This needs rethinking/rework! I have the following questions:
* Why does it not search for a stereotype in the namespace using properties
* and only create a new stereotype if it will actually be used? Ie, why is
* there not a getStereotype(String name, String baseClass)? (edited by
* d00mst) <these comments imported from NSUML implementation - tfm>
*
* @see org.argouml.model.ExtensionMechanismsFactory#buildStereotype(java.lang.Object, java.lang.Object, java.lang.Object)
*/
public Stereotype buildStereotype(
Object theModelElementObject,
Object theName,
Object theNamespaceObject) {
if (theModelElementObject == null || theName == null
|| theNamespaceObject == null) {
throw new IllegalArgumentException(
"one of the arguments is null: modelElement="
+ theModelElementObject
+ " name=" + theName
+ " namespace=" + theNamespaceObject);
}
ModelElement me = (ModelElement) theModelElementObject;
String text = (String) theName;
Namespace ns = (Namespace) theNamespaceObject;
Stereotype stereo = buildStereotype(text);
stereo.getBaseClass().add(modelImpl.getMetaTypes().getName(me));
// TODO: this doesn't look right - review - tfm
Stereotype stereo2 = (Stereotype) extensionHelper.getStereotype(ns,
stereo);
if (stereo2 != null) {
me.getStereotype().add(stereo2);
modelImpl.getUmlFactory().delete(stereo);
return stereo2;
}
stereo.setNamespace(ns);
me.getStereotype().add(stereo);
return stereo;
}
public Stereotype buildStereotype(
Object theModelElementObject,
String theName,
Object model,
Collection models) {
ModelElement me = (ModelElement) theModelElementObject;
Stereotype stereo = buildStereotype(theName);
stereo.getBaseClass().add(modelImpl.getMetaTypes().getName(me));
Stereotype stereo2 = (Stereotype) extensionHelper.getStereotype(models,
stereo);
if (stereo2 != null) {
me.getStereotype().add(stereo2);
modelImpl.getUmlFactory().delete(stereo);
return stereo2;
}
stereo.setNamespace((org.omg.uml.modelmanagement.Model) model);
if (me != null) {
me.getStereotype().add(stereo);
}
return stereo;
}
/*
* Builds an initialized stereotype with no namespace. A stereotype must
* have a namespace so this method is unsafe. Use buildStereotype(String,
* Object).
*
* @param text
* is the name of the stereotype
* @return an initialized stereotype.
*/
private Stereotype buildStereotype(String text) {
Stereotype stereotype = modelImpl.getUmlPackage().getCore().
getStereotype().createStereotype();
super.initialize(stereotype);
stereotype.setName(text);
return stereotype;
}
public Stereotype buildStereotype(String text, Object namespace) {
if (!(namespace instanceof Namespace)) {
throw new IllegalArgumentException(
"Namespace is wrong type - text:" + text + ",ns:"
+ namespace);
}
Namespace ns = (Namespace) namespace;
org.omg.uml.UmlPackage umlPkg = ((org.omg.uml.UmlPackage) ns
.refOutermostPackage());
Stereotype stereotype = umlPkg.getCore().getStereotype()
.createStereotype();
super.initialize(stereotype);
stereotype.setName(text);
stereotype.setNamespace(ns);
return stereotype;
}
@Deprecated
public TaggedValue buildTaggedValue(String tag, String value) {
TaggedValue tv = buildTaggedValue(getTagDefinition(tag));
if (value != null) {
tv.getDataValue().add(value);
}
return tv;
}
private TaggedValue buildTaggedValue(TagDefinition type) {
TaggedValue tv = createTaggedValue();
tv.setType(type);
return tv;
}
public TaggedValue buildTaggedValue(Object type, String[] values) {
if (!(type instanceof TagDefinition)) {
throw new IllegalArgumentException(
"TagDefinition required, received - " + type);
}
TaggedValue tv = buildTaggedValue((TagDefinition) type);
for (String value : values) {
tv.getDataValue().add(value);
}
return tv;
}
public void copyTaggedValues(Object source, Object target) {
if (!(source instanceof ModelElement)
|| !(target instanceof ModelElement)) {
throw new IllegalArgumentException();
}
Iterator it = ((ModelElement) source).getTaggedValue().iterator();
Collection taggedValues = ((ModelElement) target).getTaggedValue();
// Clear target so that multiple copies have no effect
// (other than inefficiency)
taggedValues.clear();
while (it.hasNext()) {
taggedValues.add(copyTaggedValue((TaggedValue) it.next()));
}
}
/**
* Copy a single TaggedValue and return the copy.
*
* @param source the TaggedValue to copy
* @return the newly cloned copy
*/
private Object copyTaggedValue(TaggedValue source) {
TaggedValue tv = createTaggedValue();
tv.setType(source.getType());
tv.getDataValue().addAll(source.getDataValue());
tv.getReferenceValue().addAll(source.getReferenceValue());
return tv;
}
/**
* @param elem
* the stereotype
*/
void deleteStereotype(Object elem) {
if (!(elem instanceof Stereotype)) {
throw new IllegalArgumentException();
}
modelImpl.getUmlHelper().deleteCollection(
((Stereotype) elem).getDefinedTag());
modelImpl.getUmlHelper().deleteCollection(
((Stereotype) elem).getStereotypeConstraint());
}
/**
* @param elem
* the taggedvalue
*/
void deleteTaggedValue(Object elem) {
if (!(elem instanceof TaggedValue)) {
throw new IllegalArgumentException();
}
}
/**
* Delete a TagDefinition.
*
* @param elem the element to be deleted
*/
void deleteTagDefinition(Object elem) {
if (!(elem instanceof TagDefinition)) {
throw new IllegalArgumentException();
}
// Delete all TaggedValues with this type
TagDefinition td = (TagDefinition) elem;
modelImpl.getUmlHelper().deleteCollection(
((org.omg.uml.UmlPackage) td.refOutermostPackage()).getCore()
.getATypeTypedValue().getTypedValue(td));
}
public Object copyStereotype(Object source, Object ns) {
if (!(source instanceof Stereotype)) {
throw new IllegalArgumentException("source");
}
if (!(ns instanceof Namespace)) {
throw new IllegalArgumentException("namespace");
}
Stereotype st = buildStereotype(null, ns);
doCopyStereotype((Stereotype) source, st);
return st;
}
/*
* Used by the copy functions. Do not call this function directly.
*
* @param source
* The stereotype to copy from.
* @param target
* The object becoming a copy.
*/
private void doCopyStereotype(Stereotype source, Stereotype target) {
((CoreFactoryMDRImpl) modelImpl.getCoreFactory())
.doCopyGeneralizableElement(source, target);
target.getBaseClass().clear();
target.getBaseClass().addAll(source.getBaseClass());
target.setIcon(source.getIcon());
// TODO: constraints
// TODO: required tags
}
public TagDefinition buildTagDefinition(String name, Object owner,
Object namespace) {
return buildTagDefinition(name, owner, namespace, null); // "Element");
}
public TagDefinition buildTagDefinition(String name, Object owner,
Object ns, String tagType) {
if (owner != null) {
if (!(owner instanceof Stereotype)) {
throw new IllegalArgumentException("owner: " + owner);
}
if (ns != null) {
throw new IllegalArgumentException(
"only one of owner & namespace may be specified");
}
} else if (!(ns instanceof Namespace)) {
throw new IllegalArgumentException("namespace: " + ns);
}
TagDefinition td = (TagDefinition) createTagDefinition();
CoreHelper coreHelper = org.argouml.model.Model.getCoreHelper();
if (owner != null) {
coreHelper.setOwner(td, owner);
} else {
coreHelper.setNamespace(td, ns);
}
coreHelper.setName(td, name);
coreHelper.setMultiplicity(td, 0, 1);
td.setTagType(tagType);
return td;
}
public Object createTagDefinition() {
TagDefinition td = modelImpl.getUmlPackage().getCore()
.getTagDefinition().createTagDefinition();
super.initialize(td);
return td;
}
public Object createStereotype() {
Stereotype st = modelImpl.getUmlPackage().getCore().getStereotype()
.createStereotype();
super.initialize(st);
return st;
}
public Object copyTagDefinition(Object anElement, Object aNs) {
if (!(anElement instanceof TagDefinition)) {
throw new IllegalArgumentException("source: " + anElement);
}
if (!(aNs instanceof Namespace || aNs instanceof Stereotype)) {
throw new IllegalArgumentException("namespace: " + aNs);
}
TagDefinition source = (TagDefinition) anElement;
TagDefinition td = (TagDefinition) createTagDefinition();
if (aNs instanceof Namespace) {
td.setNamespace((Namespace) aNs);
} else {
td.setOwner((Stereotype) aNs);
}
doCopyTagDefinition(source, td);
return td;
}
/*
* Used by the copy functions. Do not call this function directly.
*
* @param source
* The stereotype to copy from.
* @param target
* The object becoming a copy.
*/
private void doCopyTagDefinition(TagDefinition source,
TagDefinition target) {
((CoreFactoryMDRImpl) modelImpl.getCoreFactory())
.doCopyModelElement(source, target);
target.setTagType(source.getTagType());
String srcMult = org.argouml.model.Model.getFacade().toString(
source.getMultiplicity());
target.setMultiplicity(modelImpl.getDataTypesFactoryInternal()
.createMultiplicityInternal(srcMult));
}
}