| /* |
| * 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; |
| } |
| |
| } |
| |
| } |