166438: Sync Wizard does not sync "replace" variability correctly for configurations that do not contain replacing elements
diff --git a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/process/command/SynchronizeCommand.java b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/process/command/SynchronizeCommand.java
index a827523..75288a1 100755
--- a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/process/command/SynchronizeCommand.java
+++ b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/process/command/SynchronizeCommand.java
@@ -13,10 +13,12 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.CommonPlugin;
@@ -25,29 +27,33 @@
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.library.edit.IConfigurator;
-import org.eclipse.epf.library.edit.LibraryEditPlugin;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.TngAdapterFactory;
+import org.eclipse.epf.library.edit.command.BatchCommand;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.Messenger;
+import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
+import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.TeamProfile;
+import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.swt.custom.BusyIndicator;
@@ -88,6 +94,9 @@
private boolean showSuccessfulMsg = true;
private boolean intialized;
+
+ private BatchCommand batchCommand = new BatchCommand(false);
+ private Map<VariabilityElement, VariabilityElement> replacerToBaseMap = new HashMap<VariabilityElement, VariabilityElement>();
// private Object UIContext;
@@ -131,6 +140,8 @@
}
private boolean doInitialize() {
+ commandList.clear();
+
if (elements == null || elements.isEmpty()) {
return false;
}
@@ -146,7 +157,7 @@
}
}
elements.removeAll(deleteList);
-
+
for (Iterator iter = elements.iterator(); iter.hasNext();) {
Object object = iter.next();
if (object instanceof Descriptor) {
@@ -169,12 +180,18 @@
if (object instanceof TaskDescriptor) {
Task task = ((TaskDescriptor) object).getTask();
if (task != null) {
+ if(replacerToBaseMap.containsKey(task)) {
+ task = (Task) replacerToBaseMap.get(task);
+ }
append(new WBSDropCommand(act, Collections
.singletonList(task), config, synchFeatures));
}
} else if (object instanceof RoleDescriptor) {
Role role = ((RoleDescriptor) object).getRole();
if (role != null) {
+ if(replacerToBaseMap.containsKey(role)) {
+ role = (Role) replacerToBaseMap.get(role);
+ }
append(new OBSDropCommand(act, Collections
.singletonList(role), config, synchFeatures, configurator));
}
@@ -182,6 +199,9 @@
WorkProduct wp = ((WorkProductDescriptor) object)
.getWorkProduct();
if (wp != null) {
+ if(replacerToBaseMap.containsKey(wp)) {
+ wp = (WorkProduct) replacerToBaseMap.get(wp);
+ }
append(new PBSDropCommand(act, Collections
.singletonList(wp), config, synchFeatures, configurator));
}
@@ -302,8 +322,11 @@
public Collection getModifiedResources() {
HashSet modifiedResources = new HashSet();
for (Iterator iter = commandList.iterator(); iter.hasNext();) {
- IResourceAwareCommand cmd = (IResourceAwareCommand) iter.next();
- modifiedResources.addAll(cmd.getModifiedResources());
+
+ Object cmd = iter.next();
+ if(cmd instanceof IResourceAwareCommand) {
+ modifiedResources.addAll(((IResourceAwareCommand)cmd).getModifiedResources());
+ }
}
return modifiedResources;
}
@@ -327,7 +350,9 @@
deleteCommandList.add(cmd);
}
}
-
+
+ batchCommand.execute();
+
if (!aborted) {
// IRunnableWithProgress runnable = new IRunnableWithProgress() {
//
@@ -461,7 +486,29 @@
private void addToDeleteList(Object element, List deleteList) {
if (element instanceof Descriptor) {
if (!getConfigurator().accept(element)) {
- deleteList.add(element);
+ MethodElement linkedElement = ProcessUtil.getAssociatedElement((Descriptor) element);
+ if(linkedElement instanceof VariabilityElement && TngUtil.isReplacer((VariabilityElement) linkedElement)) {
+ // if the linked element of the descriptor is a replacer, delete the descriptor in this synchronization
+ // only if the base of linked element is not in the configuration
+ //
+ VariabilityElement base = ((VariabilityElement)linkedElement).getVariabilityBasedOnElement();
+ while(base != null && TngUtil.isContributorOrReplacer(base)) {
+ base = base.getVariabilityBasedOnElement();
+ }
+ if(base != null) {
+ if(!getConfigurator().accept(base)) {
+ deleteList.add(element);
+ }
+ else {
+ batchCommand.addFeatureValue((EObject) element,
+ ProcessUtil.getLinkReference((Descriptor) element), base);
+ replacerToBaseMap.put((VariabilityElement) linkedElement, base);
+ }
+ }
+ }
+ else {
+ deleteList.add(element);
+ }
}
} else if (element instanceof Activity) {
for (Iterator iter = ((Activity) element).getBreakdownElements()
@@ -517,6 +564,8 @@
}
superUndo();
+
+ batchCommand.undo();
}
});
diff --git a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/ProcessUtil.java b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/ProcessUtil.java
index b69d0cf..62f0f9d 100755
--- a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/ProcessUtil.java
+++ b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/ProcessUtil.java
@@ -31,6 +31,7 @@
import org.eclipse.emf.ecore.EAttribute;
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.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.IChangeNotifier;
@@ -982,6 +983,18 @@
}
return null;
}
+
+ public static EReference getLinkReference(Descriptor descriptor) {
+ if (descriptor instanceof RoleDescriptor) {
+ return UmaPackage.eINSTANCE.getRoleDescriptor_Role();
+ } else if (descriptor instanceof TaskDescriptor) {
+ return UmaPackage.eINSTANCE.getTaskDescriptor_Task();
+ } else if (descriptor instanceof WorkProductDescriptor) {
+ return UmaPackage.eINSTANCE.getWorkProductDescriptor_WorkProduct();
+ }
+ return null;
+
+ }
public static void disposeWrappers(Collection children) {
if (children == null)
diff --git a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/TngUtil.java b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/TngUtil.java
index f6403d5..d8a4281 100755
--- a/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/TngUtil.java
+++ b/plugins/org.eclipse.epf.library.edit/src/org/eclipse/epf/library/edit/util/TngUtil.java
@@ -2050,6 +2050,11 @@
&& (e.getVariabilityType() == VariabilityType.CONTRIBUTES_LITERAL);
}
+ public static boolean isReplacer(VariabilityElement e) {
+ return e.getVariabilityBasedOnElement() != null
+ && (e.getVariabilityType() == VariabilityType.REPLACES_LITERAL);
+ }
+
public static boolean isContributorOrReplacer(VariabilityElement e) {
VariabilityElement base = e.getVariabilityBasedOnElement();
VariabilityType type = e.getVariabilityType();