/******************************************************************************* * Copyright 2012 Markus Scheidgen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.hub.emffrag.util; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.common.util.AbstractTreeIterator; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EAnnotation; 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.util.EcoreUtil; import de.hub.emffrag.fragmentation.FInternalObject; import de.hub.emffrag.fragmentation.FInternalObjectImpl; import de.hub.emffrag.fragmentation.FObjectImpl; import de.hub.emffrag.fragmentation.FStoreImpl; import de.hub.emffrag.fragmentation.Fragment; import de.hub.emffrag.fragmentation.FragmentedModel; public class EMFFragUtil { public enum FragmentationType { None, FragmentsContainment, FragmentsIndexedContainment, IndexedReferences }; private static final Map<EStructuralFeature, FragmentationType> fragmentatinoTypeCache = new HashMap<EStructuralFeature, EMFFragUtil.FragmentationType>(); public static FragmentationType getFragmentationType(EStructuralFeature feature) { FragmentationType result = fragmentatinoTypeCache.get(feature); if (result == null) { EAnnotation annotation = feature.getEAnnotation("de.hub.emffrag"); if (!(feature instanceof EReference) || annotation == null) { result = FragmentationType.None; } else { EMap<String, String> details = annotation.getDetails(); if (((EReference)feature).isContainment()) { if (details.get("indexes") != null) { result = FragmentationType.FragmentsIndexedContainment; } else if (details.get("fragments") != null) { result = FragmentationType.FragmentsContainment; } else { result = FragmentationType.None; } } else { if (details.get("indexes") != null) { result = FragmentationType.IndexedReferences; } else { result = FragmentationType.None; } } } fragmentatinoTypeCache.put(feature, result); } return result; } @SuppressWarnings("unchecked") public static void collectAllNonFragmentingContents(FInternalObject object, Collection<FInternalObject> collection) { if (object == null) { return; } collection.add(object); for (EStructuralFeature feature: object.eClass().getEStructuralFeatures()) { if (feature instanceof EReference && ((EReference)feature).isContainment() && EMFFragUtil.getFragmentationType((EReference)feature) == FragmentationType.None) { if (feature.isMany()) { for (FInternalObject child: (EList<FInternalObject>)object.eGet(feature)) { collectAllNonFragmentingContents(child, collection); } } else { collectAllNonFragmentingContents((FInternalObject)object.eGet(feature), collection); } } } } public static Collection<FInternalObject> getAllNonFragmentingContents(FInternalObject object) { Collection<FInternalObject> result = new ArrayList<FInternalObject>(); collectAllNonFragmentingContents(object, result); return result; } public static Collection<FInternalObject> getAllNonFragmentingContents(Fragment fragment) { Collection<FInternalObject> result = new ArrayList<FInternalObject>(); for (EObject object: fragment.getContents()) { collectAllNonFragmentingContents((FInternalObject)object, result); } return result; } public static TreeIterator<EObject> getAllNonFragmentingContentsIterator(EObject eObject) { return new AbstractTreeIterator<EObject>(eObject) { private static final long serialVersionUID = 1L; @Override protected Iterator<? extends EObject> getChildren(Object o) { return prepareChildrenList((EObject)o).iterator(); } }; } @SuppressWarnings("unchecked") private static Collection<EObject> prepareChildrenList(EObject object) { Collection<EObject> children = new ArrayList<EObject>(); for (EStructuralFeature feature: object.eClass().getEAllStructuralFeatures()) { if (feature instanceof EReference && ((EReference)feature).isContainment() && EMFFragUtil.getFragmentationType((EReference)feature) == FragmentationType.None) { if (feature.isMany()) { children.addAll((EList<EObject>)object.eGet(feature)); } else { EObject value = (EObject)object.eGet(feature); if (value != null) { children.add(value); } } } } return children; } public static TreeIterator<EObject> getAllNonFragmentingContentsIterator(List<EObject> contents) { return new AbstractTreeIterator<EObject>(contents, false) { private static final long serialVersionUID = 1L; @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected Iterator<? extends EObject> getChildren(Object o) { if (o instanceof List) { return ((List)o).iterator(); } else { return prepareChildrenList((EObject)o).iterator(); } } }; } public static boolean test(EObject object, String className, String attributeName, Object attributeValue) { EClass eClass = object.eClass(); if (eClass.getName().equals(className)) { EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(attributeName); if (attributeValue.equals(object.eGet(eStructuralFeature))) { return true; } else { return false; } } else { return false; } } public static URI getURI(EObject eObject) { return EcoreUtil.getURI(((FObjectImpl)eObject).fInternalObject()); } public static EObject resolveURI(URI uri, FragmentedModel fragmentation) { return FStoreImpl.getInstance().getUserObject((FInternalObjectImpl)fragmentation.resolveObjectURI(uri)); } }