diff options
Diffstat (limited to 'extraplugins/qompass/designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/Utils.java')
-rw-r--r-- | extraplugins/qompass/designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/Utils.java | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/extraplugins/qompass/designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/Utils.java b/extraplugins/qompass/designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/Utils.java new file mode 100644 index 00000000000..ea3a43f07c7 --- /dev/null +++ b/extraplugins/qompass/designer/org.eclipse.papyrus.qompass.designer.core/src/org/eclipse/papyrus/qompass/designer/core/Utils.java @@ -0,0 +1,471 @@ +/***************************************************************************** + * Copyright (c) 2013 CEA LIST. + * + * + * 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: + * Ansgar Radermacher ansgar.radermacher@cea.fr + * + *****************************************************************************/ + +package org.eclipse.papyrus.qompass.designer.core; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.UniqueEList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.papyrus.FCM.Assembly; +import org.eclipse.papyrus.FCM.ContainerRule; +import org.eclipse.papyrus.FCM.InteractionComponent; +import org.eclipse.papyrus.FCM.Singleton; +import org.eclipse.papyrus.qompass.designer.core.preferences.QompassPreferenceConstants; +import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil; +import org.eclipse.uml2.uml.AggregationKind; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.InstanceSpecification; +import org.eclipse.uml2.uml.Interface; +import org.eclipse.uml2.uml.NamedElement; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.Port; +import org.eclipse.uml2.uml.Property; +import org.eclipse.uml2.uml.Type; +import org.eclipse.uml2.uml.util.UMLUtil; + +public class Utils { + + public static final String QUOTE = "\""; //$NON-NLS-1$ + + /** + * Retrieve an element from a list of named elements via its name + * + * @param namedElementList + * @param name + * @return + */ + public static NamedElement getNamedElementFromList( + EList<? extends NamedElement> namedElementList, String name) { + Iterator<? extends NamedElement> namedElements = namedElementList + .iterator(); + while (namedElements.hasNext()) { + NamedElement namedElement = namedElements.next(); + if (namedElement.getName().equals(name)) { + return namedElement; + } + } + return null; + } + + /** + * return the top-level owner of an element. This function returns the same + * value as getModel, if the top-level element is a model. While this is the + * case for models, model libraries have a top-level package (not a model). + * In this case, getTop returns the top-level package whereas getModel would + * return null. + * + * @param element + * @return the top-level owning package + * @deprecated Use getRootPackage method in oep.uml.tools.utils.PackageUtil + */ + @Deprecated + public static Package getTop(Element element) { + while (element != null) { + Element owner = element.getOwner(); + if (owner == null) { + if (element instanceof Package) { + return (Package) element; + } + } + element = owner; + } + return null; + } + + /** + * Return package at first level. Useful, since last model transformation + * will put elements under a new "root" + * + * @param element + * @return + */ + public static Package getFirstLevel(Element element) { + Element lastElement = element; + while (element != null) { + Element owner = element.getOwner(); + if (owner == null) { + if (lastElement instanceof Package) { + return (Package) lastElement; + } + } + lastElement = element; + element = owner; + } + return null; + } + + /** + * @param element + * an element which is owned by a model. + * @param subfolder + * the name of a sub-folder within root (created, if not + * existent) + * @return a reference to the sub folder within the root of the model that + * belongs to the passed element. + */ + public static Package getRoot(Element element, String subfolder) { + Package root = getTop(element); + if (root.getNestedPackage(subfolder) != null) { + return root.getNestedPackage(subfolder); + } else { + return root.createNestedPackage(subfolder); + } + } + + /** + * Convenience method enabling to apply getOwnedOperation equally to classes + * and interfaces + * + * @param cl + * @param name + * @param paramNames + * @param paramTypes + * @return + */ + public static Operation createOwnedOperation(Classifier cl, String name, + EList<String> paramNames, EList<Type> paramTypes, Type retType) { + if (cl instanceof Class) { + return ((Class) cl).createOwnedOperation(name, paramNames, + paramTypes, retType); + } else if (cl instanceof Interface) { + return ((Interface) cl).createOwnedOperation(name, paramNames, + paramTypes, retType); + } else { + return null; + } + } + + public static Operation getOwnedOperation(Classifier cl, String name, + EList<String> paramNames, EList<Type> paramTypes) { + if (cl instanceof Class) { + return ((Class) cl).getOwnedOperation(name, paramNames, paramTypes); + } else if (cl instanceof Interface) { + return ((Interface) cl).getOwnedOperation(name, paramNames, + paramTypes); + } else { + return null; + } + } + + /** + * this method returns the component type of an implementation. It is based + * on the modeling convention that implementations inherit from types. + */ + public static Class componentType(Class implementation) { + if (Utils.isCompImpl(implementation)) { + Iterator<Class> superclasses = implementation.getSuperClasses() + .iterator(); + while (superclasses.hasNext()) { + Class componentType = superclasses.next(); + if (Utils.isCompType(componentType)) { + return componentType; + } + } + } + return null; + } + + /** + * return true, if a component (implementation) is a composite, i.e. has + * inner parts + */ + public static boolean isComposite(Class implementation) { + return Utils.isCompImpl(implementation) + && (getParts(implementation).size() > 0); + } + + public static EList<Property> getParts(Class implementation) { + if (treatNoneAsComposite()) { + EList<Property> parts = new BasicEList<Property>(); + for (Property part : implementation.getAttributes()) { + if (part.getAggregation() != AggregationKind.SHARED_LITERAL) { + parts.add(part); + } + } + return parts; + } + else { + return implementation.getParts(); + } + } + + + /** + * @param attribute + * an attribute + * @return true, if the aggregation kind is considered as a composition + */ + public static boolean isComposition(Property attribute) { + if (treatNoneAsComposite()) { + return (attribute.getAggregation() != AggregationKind.SHARED_LITERAL); + } + else { + return (attribute.getAggregation() == AggregationKind.COMPOSITE_LITERAL); + } + } + + /** + * return true, if an instance specification is a composite, i.e. has > 1 + * slots TODO: distinguish parts and configuration attributes + */ + + public static boolean isComposite(InstanceSpecification is) { + return (is.getSlots().size() > 0); + } + + /** + * Get an element via its qualified name. Will find elements from the root + * model and elements in imported models. Also supports target model in + * which imports have been copied (while keeping the top-level name) + * + * @param root + * @param qualifiedName + * @return + */ + public static NamedElement getQualifiedElement(Package root, + String qualifiedName) { + NamedElement namedElement = null; + int index = qualifiedName.indexOf("::"); //$NON-NLS-1$ + if (index != -1) { + // first try using a path without top element (since + // getQualifiedElement is typically used for + // imported elements) + String remainder = qualifiedName.substring(index + 2); + namedElement = getQualifiedElement(root, remainder, qualifiedName); + } + if (namedElement == null) { + // try with complete name as path name, but assume that the element + // has been copied into the model, + // i.e. qualifiedName is prefixed by model name + namedElement = getQualifiedElement(root, qualifiedName, + root.getName() + "::" + qualifiedName); //$NON-NLS-1$ + } + return namedElement; + } + + /** + * Retrieve an element via its qualified name within a package The segments + * of the package may be non unique due to imports + * + * @return the found element, if it exists + */ + public static NamedElement getQualifiedElement(Package root, + String remainingPath, String qualifiedName) { + if (root == null) { + return null; + } + if (!remainingPath.contains(NamedElement.SEPARATOR)) { + for (NamedElement candidate : root.getMembers()) { + String name = candidate.getName(); + if ((name != null) && name.equals(remainingPath)) { + if (candidate.getQualifiedName().equals(qualifiedName)) { + return candidate; + } + } + } + } else { + String segment = remainingPath.split(NamedElement.SEPARATOR)[0]; + String remainder = remainingPath.substring(segment.length() + 2); + for (Element element : root.getMembers()) { + if (element instanceof Package) { + if (((NamedElement) element).getName().equals(segment)) { + NamedElement foundElement = getQualifiedElement( + (Package) element, remainder, qualifiedName); + // return, if not found + if (foundElement != null) { + return foundElement; + } + } + } + } + } + return null; + } + + /** + * Simple check whether an element is in a different model than the passed + * package It will return true, whenever the the top elements do not match. + * This is always true, if the 2nd belongs to a different model, whether + * imported or not. This distinction is however not required in our context. + */ + public static boolean isElementInDifferentModel(Package model, + NamedElement namedElement) { + return model != getTop(namedElement); + } + + /** + * /** + * Check whether a class contains a non-port attribute of a given name + * + * @param cl + * @return + */ + public static boolean hasNonPortOwnedAttribute(Class cl, String name) { + for (Property p : cl.getOwnedAttributes()) { + if (!(p instanceof Port)) { + if (p.getName().equals(name)) { + return true; + } + } + } + return false; + } + + public static <T extends EObject> EList<T> getAllElementsOfType(Element examineElement, java.lang.Class<T> clazz) + { + EList<Element> visitedPackages = new BasicEList<Element>(); + return getAllElementsOfType(examineElement, clazz, visitedPackages); + } + + @SuppressWarnings("unchecked") + public static <T extends EObject> EList<T> getAllElementsOfType(Element examineElement, java.lang.Class<T> clazz, EList<Element> visitedPackages) + { + EList<T> list = new UniqueEList<T>(); + for (Element element : examineElement.allOwnedElements()) { + if (element instanceof Package) { + if (!visitedPackages.contains(element)) { + visitedPackages.add(element); + list.addAll(getAllElementsOfType(element, clazz, + visitedPackages)); + } + } else if (clazz.isInstance(element)) { + list.add((T) element); + } + } + return list; + } + + /** + * @param a + * potential implementation + * @return true, if passed classifier is an implementation (i.e. declared + * via stereotypes as component or connector implementation (a sub-type of component implementations, + * therefore no additional check is required) + */ + public static boolean isCompImpl(Classifier implementation) { + return !implementation.isAbstract(); + } + + /** + * Check whether the passed class is a component type (and not a component implementation). + * This includes connector and container types as well. + * + * @param component + * @return + */ + public static boolean isCompType(Class component) { + return component.isAbstract(); + } + + public static boolean isInteractionComponent(Classifier component) { + return StereotypeUtil.isApplied(component, InteractionComponent.class); + } + + public static boolean isSingleton(Class component) { + return StereotypeUtil.isApplied(component, Singleton.class); + } + + public static boolean isAssembly(Class component) { + return StereotypeUtil.isApplied(component, Assembly.class); + } + + public static boolean treatNoneAsComposite() { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + return store.getBoolean(QompassPreferenceConstants.P_TREAT_NONE_AS_COMPOSITE); + } + + public static boolean allAttributesAreConfigAttributs() { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + return store.getBoolean(QompassPreferenceConstants.P_ALL_ATTRIBUTES_ARE_CONFIG_ATTRIBUTES); + } + + /** + * True, if either a component implementation or a type + * + * @param component + * @return + */ + public static boolean isComponent(Class component) { + return (isCompType(component) || isCompImpl(component)); + } + + /** + * Return the absolute file name to a file name given e.g. in the form platform:/plugin/xxx + * + * @param fileName + * the file name using eclipse elements such as platform:/plugin + * @return the absolute file name + */ + public static String getAbsoluteFN(String fileName) { + try { + URL absoluteURL = FileLocator.toFileURL(new URL(fileName)); + return absoluteURL.getFile(); + } catch (MalformedURLException e) { + } catch (IOException e) { + } + return null; + } + + // TODO: need a generic utility function for getting all elements obeying a certain + // criteria from a model + public static EList<ContainerRule> getAllRules(Package pkg) { + EList<Package> visitedPackages = new BasicEList<Package>(); + EList<ContainerRule> contRuleList = new BasicEList<ContainerRule>(); + getAllRules(pkg, visitedPackages, contRuleList); + return contRuleList; + } + + public static void getAllRules(Package pkg, EList<Package> visitedPackages, EList<ContainerRule> contRuleList) { + for (Element el : pkg.getMembers()) { + if (el instanceof Package) { + if (!visitedPackages.contains(el)) { + visitedPackages.add((Package) el); + getAllRules((Package) el, visitedPackages, contRuleList); + } + } + else if (el instanceof Class) { + if (StereotypeUtil.isApplied(el, ContainerRule.class)) { + ContainerRule rule = UMLUtil.getStereotypeApplication(el, ContainerRule.class); + contRuleList.add(rule); + } + } + } + } + + /** + * Put quotes around a string, unless string already starts with a quote. + * + * @param str + * @return + */ + public static String quoteString(String str) { + if (str.startsWith(QUOTE)) { + return str; + } + else { + return QUOTE + str + QUOTE; + } + } +} |