blob: be572efd0a32b151ee7f2ea537adf6c2d21dd5b6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2012 David A Carlson and others.
* 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:
* David A Carlson (XMLmodeling.com) - initial API and implementation
* John T.E. Timm (IBM Corporation) - added template parameter
* Christian W. Damus - generate multiple OCL constraints from one property (artf3121)
* - discriminate multiple property constraints (artf3185)
* - implement terminology constraint dependencies (artf3030)
* - support nested datatype subclasses (artf3350)
*
* $Id$
*******************************************************************************/
package org.eclipse.mdht.uml.transform;
import java.util.Collection;
import java.util.Map;
import org.eclipse.mdht.uml.common.util.UMLUtil;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.util.UMLSwitch;
/**
* Abstract base class for model transformations.
*/
public abstract class AbstractTransform extends UMLSwitch<Object> {
protected TransformerOptions transformerOptions;
protected final IBaseModelReflection baseModelReflection;
public AbstractTransform(TransformerOptions options, IBaseModelReflection baseModelReflection) {
transformerOptions = options;
this.baseModelReflection = baseModelReflection;
}
public void removeModelElement(Element element) {
if (element != null && !isRemoved(element)) {
transformerOptions.getDeletedElementList().add(element);
}
}
public boolean isRemoved(Element element) {
return transformerOptions.getDeletedElementList().contains(element);
}
protected <C extends Classifier> C getBaseClass(C userClass) {
return baseModelReflection.getBaseClass(userClass);
}
protected Package getBaseModel(Classifier userClass) {
Package result = baseModelReflection.getBaseModel(userClass);
if (result == null) {
// maybe it's not explicitly imported
Classifier baseClass = getBaseClass(userClass);
if (baseClass != null) {
result = UMLUtil.getTopPackage(baseClass);
}
}
return result;
}
protected boolean isBaseModel(Element userElement, Element baseElement) {
return baseModelReflection.isBaseModelElement(userElement, baseElement);
}
protected boolean isDatatypesModelElement(Element context, Element base) {
return baseModelReflection.isDatatypesModelElement(context, base);
}
protected Property getBaseProperty(Property templateProperty) {
return baseModelReflection.getBaseProperty((Classifier) templateProperty.getOwner(), templateProperty);
}
/**
* Gets the datatype from the base datatypes model that the specified {@code umlDatatype} specializes, if any, and only if the {@code umlDatatype}
* is defined
* locally to the given {@code context} element (in the same model as it).
*
* @param umlDatatype
* a class that may or may not be a specialization of a base datatype
* @param context
* the context in which the datatype is used, or {code null} if the locality check is not required. This is often a {@link Property}
* that is typed by the {@code umlDatatype}
*
* @return the base datatype of which the {@code umlDatatype} is a local subclass, or {@code null} if the {@code umlDatatype} is not a local
* subclass of a base datatype
*/
protected <C extends Classifier> C getBaseDatatype(C umlDatatype, Element context) {
C result = baseModelReflection.getBaseDatatype(umlDatatype);
if (result != null) {
// check conditions for distinguishing the base datatype from the original
if ((result == umlDatatype) || ((context != null) &&
!org.eclipse.mdht.uml.common.util.UMLUtil.isSameModel(umlDatatype, context))) {
result = null;
}
}
return result;
}
protected boolean isDatatypesModel(Element userElement, Element baseElement) {
return baseModelReflection.isDatatypesModelElement(userElement, baseElement);
}
/**
* Returns the nearest inherited property with the same name, or null if not found.
*/
protected Property getInheritedProperty(Property templateProperty) {
// for CDA, we restrict to Classes, not other classifiers
if (templateProperty.getClass_() == null) {
return null;
}
return org.eclipse.mdht.uml.common.util.UMLUtil.getInheritedProperty(templateProperty);
}
public static String normalizeCodeName(String name) {
String result = "";
String[] parts = name.split(" ");
for (String part : parts) {
result += part.substring(0, 1).toUpperCase() + part.substring(1);
}
result = UML2Util.getValidJavaIdentifier(result);
return result;
}
public static String pluralize(String name) {
if (name.endsWith("y")) {
return name.substring(0, name.length() - 1) + "ies";
}
if (name.endsWith("ia")) {
return name;
}
return name + "s";
}
public static String capitalize(String name) {
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Add an {@code element} to a {@code collection} if it's not {@code null}. Handy for a fluent style.
*
* @return the {@code collection}, for convenience of method chaining
*/
public static <E, C extends Collection<? super E>> C addIfNotNull(E element, C collection) {
if (element != null) {
collection.add(element);
}
return collection;
}
/**
* Add an {@code element} to a {@code map} if it's not {@code null}. Handy for a fluent style.
*
* @return the {@code map}, for convenience of method chaining
*/
public static <K, V, M extends Map<? super K, ? super V>> M putIfNotNull(K key, V element, M map) {
if (element != null) {
map.put(key, element);
}
return map;
}
}