diff --git a/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/.ratings b/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/.ratings index 7c56142f7d1f62a0beee52ac6272bd687efbfdf3..5705d7eb2938cdb7199fdc7755b348ca0f79420a 100644 --- a/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/.ratings +++ b/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/.ratings @@ -1,5 +1,5 @@ IReuseProvider.java 18d293f7f1f072883188f16fb6eeb52c8d6042cf GREEN IReuseProviderService.java bcc70de0bb8d39c330e3a25d884abc7092dc1b7e GREEN LayoutedReuseProviderBase.java b0e4ce3cda818b0723ec37b925a4c4c3d0c41909 GREEN -ReuseProviderBase.java c956ba13df1b7b5c8dbd7cd1a9205a06b5cebba1 YELLOW +ReuseProviderBase.java d7b615677c9b147f93943a8b87c631c26f6e5b4d YELLOW ReuseProviderService.java c4ef33283002d6dac6167f9c6c8f71d2c2ce39d1 GREEN diff --git a/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/ReuseProviderBase.java b/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/ReuseProviderBase.java index c956ba13df1b7b5c8dbd7cd1a9205a06b5cebba1..d7b615677c9b147f93943a8b87c631c26f6e5b4d 100644 --- a/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/ReuseProviderBase.java +++ b/org.fortiss.tooling.ext.reuse/src/org/fortiss/tooling/ext/reuse/service/ReuseProviderBase.java @@ -17,11 +17,14 @@ package org.fortiss.tooling.ext.reuse.service; import static org.eclipse.emf.ecore.util.EcoreUtil.replace; import static org.fortiss.tooling.ext.variability.util.VariabilityUtils.getOptVarPointSpecification; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType; import static org.fortiss.tooling.kernel.utils.EcoreUtils.replaceEObjectReferences; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; @@ -137,8 +140,19 @@ public class ReuseProviderBase<T extends EObject> implements IReuseProvider<T> { * @param eObj * The {@link EObject} for which all reference targets shall be removed. */ - @SuppressWarnings("unchecked") private void removeExternalReferences(EObject eObj) { + // whitelist all contained elements as reference targets. + Set<EObject> whitelist = new HashSet<EObject>(getChildrenWithType(eObj, EObject.class)); + + removeReferences(eObj, whitelist); + } + + /** + * Recursively removes all reference targets from this and all contained {@link EObject}s which + * are not contained in the given whitelist. + */ + @SuppressWarnings("unchecked") + private void removeReferences(EObject eObj, Set<EObject> whitelist) { for(EReference ref : eObj.eClass().getEReferences()) { Object refTarget = eObj.eGet(ref); @@ -146,17 +160,29 @@ public class ReuseProviderBase<T extends EObject> implements IReuseProvider<T> { continue; } - if(ref.isContainment()) { - // Containment relations must not be removed. Yet, references of childs need to be - // removed recursively. - if(refTarget instanceof Collection<?>) { - ((Collection<EObject>)refTarget).stream() - .forEach(t -> removeExternalReferences(t)); + if(refTarget instanceof Collection<?>) { + Collection<EObject> refTargetCollection = (Collection<EObject>)refTarget; + + if(ref.isContainment()) { + // Containment relations must not be removed. Yet, references of childs need to + // be removed recursively. + refTargetCollection.stream().forEach(t -> removeReferences(t, whitelist)); } else { - removeExternalReferences((EObject)refTarget); + for(EObject t : refTargetCollection) { + if(!whitelist.contains(t)) { + refTargetCollection.remove(t); + } + } } } else { - eObj.eSet(ref, null); + if(ref.isContainment()) { + // Keep reference target and make recursive call. + removeReferences((EObject)refTarget, whitelist); + } else { + if(!whitelist.contains(refTarget)) { + eObj.eSet(ref, null); + } + } } } }