blob: b7660dceed936fe6e3b80226e1c40debf36d5938 [file] [log] [blame]
/*
* Copyright (c) 2006, 2007 Borland Software Corp
*
* 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:
* vano - initial API and implementation
*/
package org.eclipse.gmf.mappings.presentation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.gmf.mappings.CanvasMapping;
import org.eclipse.gmf.mappings.ChildReference;
import org.eclipse.gmf.mappings.CompartmentMapping;
import org.eclipse.gmf.mappings.FeatureInitializer;
import org.eclipse.gmf.mappings.FeatureSeqInitializer;
import org.eclipse.gmf.mappings.LinkMapping;
import org.eclipse.gmf.mappings.Mapping;
import org.eclipse.gmf.mappings.MappingEntry;
import org.eclipse.gmf.mappings.NodeMapping;
import org.eclipse.gmf.mappings.NodeReference;
import org.eclipse.gmf.mappings.TopNodeReference;
public class FilterUtil {
public static <T> List<T> sort(Collection<T> eObjects) {
ArrayList<T> result = new ArrayList<T>(eObjects);
Collections.sort(result, new EObjectsComparator());
return result;
}
public static <T extends EObject> List<T> filterByResourceSet(Collection<T> eClasses, ResourceSet resourceSet) {
return sort(filterValidEObjectsFrom(eClasses, resourceSet));
}
public static List<EClass> filterByContainmentFeature(Collection<EClass> eClasses, MappingEntry mappingEntry) {
EClass superType = null;
if (mappingEntry instanceof NodeMapping) {
NodeReference nodeReference = (NodeReference) mappingEntry.eContainer();
if (nodeReference != null) {
EReference modelReference = nodeReference.getChildrenFeature() != null ? nodeReference.getChildrenFeature() : nodeReference.getContainmentFeature();
if (modelReference != null) {
superType = modelReference.getEReferenceType();
}
}
} else if (mappingEntry instanceof LinkMapping) {
if (((LinkMapping) mappingEntry).getContainmentFeature() != null) {
superType = ((LinkMapping) mappingEntry).getContainmentFeature().getEReferenceType();
}
}
return sort(getConcreteEClasses(getSubtypesOf(filterValidEObjectsFrom(eClasses, mappingEntry.eResource().getResourceSet()), superType)));
}
public static List<EStructuralFeature> filterByContainerMetaclass(Collection<EStructuralFeature> eReferences, MappingEntry mappingEntry) {
EClass containerMetaClass = mappingEntry.getDomainMetaElement();
return sort(getEStructuralFeaturesOf(eReferences, containerMetaClass));
}
public static List<EReference> filterByContainerMetaclass(Collection<EReference> eReferences, NodeReference nodeReference, boolean containmentOnly) {
EClass containerMetaClass = null;
EClass targetMetaClass = null;
if (nodeReference instanceof ChildReference) {
containerMetaClass = ((ChildReference) nodeReference).getParentNode().getDomainMetaElement();
} else if (nodeReference instanceof TopNodeReference) {
CanvasMapping diagram = ((Mapping) nodeReference.eContainer()).getDiagram();
if (diagram != null) {
containerMetaClass = diagram.getDomainMetaElement();
}
}
if (nodeReference.isSetChild()) {
targetMetaClass = nodeReference.getChild().getDomainMetaElement();
}
List<EReference> fromHierarchy = sort(getEReferences(getEStructuralFeaturesOf(eReferences, containerMetaClass), containmentOnly));
if (targetMetaClass == null) {
// no child known, thus can take references from metaelement's hierarchy only
return fromHierarchy;
}
List<EReference> targetsToChild = sort(getEReferences(getEReferencesOfType(eReferences, targetMetaClass), containmentOnly));
for (Iterator<EReference> it = targetsToChild.iterator(); it.hasNext();) {
if (fromHierarchy.contains(it.next())) {
it.remove();
}
}
ArrayList<EReference> rv = new ArrayList<EReference>(fromHierarchy.size() + targetsToChild.size());
rv.addAll(fromHierarchy);
rv.addAll(targetsToChild);
return rv;
}
public static List<EReference> filterByReferenceType(Collection<EReference> eReferences, LinkMapping linkMapping) {
EClass referenceType = linkMapping.getDomainMetaElement();
return sort(getEReferences(getEReferencesOfType(eReferences, referenceType), true));
}
public static Collection<EObject> filterByNodeMapping(Collection<EObject> childReferences, CompartmentMapping mapping) {
return sort(getChildrenOf(childReferences, mapping.getParentNode(), false));
}
public static Collection<EObject> filterByNodeMapping(Collection<EObject> compartments, ChildReference childReference) {
return getChildrenOf(compartments, childReference.getParentNode(), true);
}
public static Collection<?> filterBySuperClasses(Collection<?> instances, Class<?>[] classes) {
return sort(getSubClassesOf(instances, classes));
}
public static Collection<EStructuralFeature> filterByFeatureInitializer(Collection<EStructuralFeature> features, FeatureInitializer featureInitializer) {
if(featureInitializer.getFeatureSeqInitializer() == null ||
featureInitializer.getFeatureSeqInitializer().getElementClass() == null) {
return features;
}
EClass eClass = featureInitializer.getFeatureSeqInitializer().getElementClass();
List<EStructuralFeature> result = new ArrayList<EStructuralFeature>(getEStructuralFeaturesOf(features, eClass));
for (Iterator<EStructuralFeature> it = result.iterator(); it.hasNext();) {
EStructuralFeature nextFeature = it.next();
if(nextFeature == null || !nextFeature.isChangeable()) {
it.remove();
}
}
return result;
}
public static Collection<EClass> filterByFeatureSeqInitializer(Collection<EClass> eClasses, FeatureSeqInitializer featureSeqInitializer) {
if(featureSeqInitializer.getCreatingInitializer() != null) {
EStructuralFeature feature = featureSeqInitializer.getCreatingInitializer().getFeature();
if(feature != null && feature.getEType() instanceof EClass) {
for (Iterator<EClass> it = eClasses.iterator(); it.hasNext();) {
EClass nextEClass = it.next();
EClass typeEClass = (EClass)feature.getEType();
if(nextEClass == null || nextEClass.isAbstract() || nextEClass.isInterface() || !typeEClass.isSuperTypeOf(nextEClass)) {
it.remove();
}
}
}
} else if(featureSeqInitializer.getElementClass() != null) {
return Collections.singleton(featureSeqInitializer.getElementClass());
}
return eClasses;
}
public static Collection<EClass> getSubtypesOf(Collection<EClass> eClasses, EClass superType) {
if (superType == null) {
return eClasses;
}
for (Iterator<EClass> it = eClasses.iterator(); it.hasNext();) {
EClass nextEClass = it.next();
if (nextEClass != null && !superType.isSuperTypeOf(nextEClass)) {
it.remove();
}
}
return eClasses;
}
public static Collection<EClass> getConcreteEClasses(Collection<EClass> eClasses) {
for (Iterator<EClass> it = eClasses.iterator(); it.hasNext();) {
EClass nextEClass = it.next();
if (nextEClass != null && (nextEClass.isAbstract() || nextEClass.isInterface())) {
it.remove();
}
}
return eClasses;
}
public static Collection<EReference> getEReferences(Collection<EReference> eReferences, boolean containmentOnly) {
if (!containmentOnly) {
return eReferences;
}
for (Iterator<EReference> it = eReferences.iterator(); it.hasNext();) {
EReference nextReference = it.next();
if (nextReference != null && !nextReference.isContainment()) {
it.remove();
}
}
return eReferences;
}
public static <T extends EStructuralFeature> Collection<T> getEStructuralFeaturesOf(Collection<T> structuralFeatures, EClass featureContainerEClass) {
Collection<T> result = getValidEStructuralFeatures(structuralFeatures);
if (featureContainerEClass == null) {
return result;
}
for (Iterator<T> it = result.iterator(); it.hasNext();) {
EStructuralFeature nextFeature = it.next();
if (nextFeature != null && !nextFeature.getEContainingClass().isSuperTypeOf(featureContainerEClass)) {
it.remove();
}
}
return result;
}
public static Collection<EReference> getEReferencesOfType(Collection<EReference> references, EClass referenceType) {
Collection<EReference> result = getValidEStructuralFeatures(references);
if (referenceType == null) {
return result;
}
for (Iterator<EReference> it = result.iterator(); it.hasNext();) {
EReference nextFeature = it.next();
if (nextFeature != null && !nextFeature.getEReferenceType().isSuperTypeOf(referenceType)) {
it.remove();
}
}
return result;
}
public static <T extends EStructuralFeature> Collection<T> getValidEStructuralFeatures(Collection<T> structuralFeatures) {
Collection<T> result = getValidEObjects(structuralFeatures);
for (Iterator<T> it = result.iterator(); it.hasNext();) {
EStructuralFeature nextFeature = it.next();
if (nextFeature != null && (nextFeature.getEContainingClass() == null)) {
it.remove();
}
}
return result;
}
public static <T extends EObject> Collection<T> filterValidEObjectsFrom(Collection<T> eClasses, ResourceSet resourceSet) {
Collection<T> result = getValidEObjects(eClasses);
for (Iterator<T> it = result.iterator(); it.hasNext();) {
EObject nextEClass = it.next();
if (nextEClass == null) {
continue;
}
if (nextEClass.eResource().getResourceSet() != resourceSet) {
it.remove();
}
}
return result;
}
public static <T extends EObject> Collection<T> getValidEObjects(Collection<T> eObjects) {
LinkedList<T> result = new LinkedList<T>();
for (T nextEObject : eObjects) {
if (nextEObject != null && (nextEObject.eContainer() == null)) {
continue;
}
result.add(nextEObject);
}
return result;
}
public static <T extends EObject> Collection<T> getChildrenOf(Collection<T> elements, EObject container, boolean addNull) {
LinkedList<T> result = new LinkedList<T>();
for (T nextEObject : elements) {
if (nextEObject == null ? addNull : nextEObject.eContainer() == container) {
result.add(nextEObject);
}
}
return result;
}
public static Collection<?> getSubClassesOf(Collection<?> instances, Class<?>[] classes) {
LinkedList<Object> result = new LinkedList<Object>();
for (Object nextInstance : instances) {
for (int i = 0; i < classes.length; i++) {
if (nextInstance == null || classes[i].isAssignableFrom(nextInstance.getClass())) {
result.add(nextInstance);
break;
}
}
}
return result;
}
private static class EObjectsComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) {
if (o1 instanceof EObject && o2 instanceof EObject) {
EObject firstEObject = (EObject) o1;
EObject secondEObject = (EObject) o2;
return compareLabels(firstEObject, secondEObject);
}
return compareObjects(o1, o2);
}
private int compareObjects(Object o1, Object o2) {
if (o1 == null) {
return o2 == null ? 0 : 1;
} else {
return o2 == null ? -1 : 0;
}
}
private int compareLabels(EObject firstEObject, EObject secondEObject) {
String firstLabel = getLabel(firstEObject);
String secondLabel = getLabel(secondEObject);
return firstLabel == null ? (secondLabel == null ? 0 : 1) : (secondLabel == null ? -1 : firstLabel.compareTo(secondLabel));
}
private String getLabel(EObject eObject) {
AdapterFactory adapterFactory = getAdapterFactory(eObject);
if (adapterFactory == null) {
return "";
}
IItemLabelProvider itemLabelProvider = (IItemLabelProvider) adapterFactory.adapt(eObject, IItemLabelProvider.class);
return itemLabelProvider != null ? itemLabelProvider.getText(eObject) : eObject == null ? "" : eObject.toString();
}
private AdapterFactory getAdapterFactory(EObject eObject) {
EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
if (editingDomain instanceof AdapterFactoryEditingDomain) {
return ((AdapterFactoryEditingDomain) editingDomain).getAdapterFactory();
}
return null;
}
}
}