https://bugs.eclipse.org/bugs/show_bug.cgi?id=170060
diff --git a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
index 958116f..1e97262 100755
--- a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
+++ b/plugins/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/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
index a6a2c23..952b0f9 100755
--- a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
+++ b/plugins/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