https://bugs.eclipse.org/bugs/show_bug.cgi?id=170060
diff --git a/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java b/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java index 958116f..1e97262 100644 --- a/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java +++ b/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
@@ -25,6 +25,7 @@ import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.epf.authoring.ui.AuthoringUIPlugin; import org.eclipse.epf.authoring.ui.AuthoringUIResources; +import org.eclipse.epf.authoring.ui.util.UIHelper; import org.eclipse.epf.authoring.ui.views.ViewHelper; import org.eclipse.epf.common.serviceability.MsgDialog; import org.eclipse.epf.library.LibraryService; @@ -34,6 +35,7 @@ import org.eclipse.epf.library.edit.command.MethodElementAddCommand.MoveOperation; import org.eclipse.epf.library.edit.ui.UserInteractionHelper; import org.eclipse.epf.library.edit.util.TngUtil; +import org.eclipse.epf.uma.Artifact; import org.eclipse.epf.uma.ContentCategory; import org.eclipse.epf.uma.MethodElement; import org.eclipse.jface.dialogs.Dialog; @@ -284,6 +286,13 @@ // AuthoringUIPlugin.getDefault().getLogger().logError(ex); // return false; // } + + // Sub Artifact circular check code + if(destination instanceof Artifact){ + return UIHelper.checkCircularForArtifacts((Artifact)destination, + elements); + } + Command addCommand = AddCommand.create(editingDomain, destination, null, elements);
diff --git a/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java b/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java index a6a2c23..952b0f9 100644 --- a/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java +++ b/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
@@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import org.eclipse.core.runtime.OperationCanceledException; @@ -32,6 +33,7 @@ import org.eclipse.epf.library.edit.validation.internal.ValidatorFactory; import org.eclipse.epf.library.ui.LibraryUIText; import org.eclipse.epf.uma.Activity; +import org.eclipse.epf.uma.Artifact; import org.eclipse.epf.uma.ContentElement; import org.eclipse.epf.uma.Deliverable; import org.eclipse.epf.uma.Guidance; @@ -167,6 +169,73 @@ } } + public static boolean checkCircularForArtifacts(Artifact destination, + Collection sourceElements) { + HashSet variantSet = new HashSet(); + collectVariantSet(destination, variantSet, VariabilityType.REPLACES_LITERAL); + collectVariantSet(destination, variantSet, VariabilityType.EXTENDS_LITERAL); + if (! checkCircularForArtifacts1(destination, sourceElements, variantSet)) { + return false; + } + return checkCircularForArtifacts2(destination, sourceElements); + } + + private static boolean checkCircularForArtifacts1(Artifact destination, + Collection sourceElements, HashSet variantSet) { + if (sourceElements == null) { + return true; + } + for (Iterator iter = sourceElements.iterator(); iter.hasNext();) { + Object obj = iter.next(); + if(obj instanceof Artifact){ + Artifact artifact = (Artifact) obj; + if (variantSet.contains(artifact)) { + return false; + } + if (! checkCircularForArtifacts1(destination, artifact.getContainedArtifacts(), variantSet)) { + return false; + } + } + } + return true; + } + + private static boolean checkCircularForArtifacts2(Artifact destination, + Collection sourceElements) { + for (Iterator iter = sourceElements.iterator(); iter.hasNext();) { + Object obj = iter.next(); + if (obj instanceof Artifact && sourceIsOrAboveMe((Artifact) obj, destination)) { + return false; + } + } + return true; + } + + private static boolean sourceIsOrAboveMe(Artifact source, Artifact me) { + if (source == me) { + return true; + } + Object obj = me.getContainerArtifact(); + if (obj instanceof Artifact && sourceIsOrAboveMe(source, (Artifact) obj)) { + return true; + } + obj = me.getVariabilityBasedOnElement(); + if (obj instanceof Artifact && sourceIsOrAboveMe(source, (Artifact) obj)) { + return true; + } + return false; + } + + //Collect all variants of "a" and "a"s ancestror Artifact objects + private static void collectVariantSet(Artifact a, HashSet variantSet, VariabilityType type) { + while (a != null) { + for (Iterator iter = TngUtil.getGeneralizers(a, type); iter.hasNext();) { + variantSet.add(iter.next()); + } + a = a.getContainerArtifact(); + } + } + /** * @param oldGuidance * @param newGuidance