blob: 131b84bb0fa444e1eb8edd8c5dc374fbae19dada [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.edit.process.command;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ActivityHandler;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.DescribableElement;
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.ProcessPackage;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.Viewer;
/**
* Drop command for activity that supports extend, copy, and deep copy.
*
* @author Phong Nguyen Le
* @since 1.0
*/
public class ActivityDropCommand extends BSDropCommand {
private Viewer viewer;
private List oldPatterns;
private List patterns;
private Process targetProcess;
private boolean isDeliveryProcess;
private boolean canExtend;
private int type;
private Collection appliedActivities;
private AdapterFactory adapterFactory;
private ActivityHandler activityHandler;
protected boolean preExecuted;
protected HashSet addedObjects;
public ActivityDropCommand(Activity target, List activities, Viewer viewer, AdapterFactory adapterFactory) {
super(target, activities);
setLabel(LibraryEditResources.ActivityDropCommand_label);
this.viewer = viewer;
this.adapterFactory = adapterFactory;
targetProcess = TngUtil.getOwningProcess(target);
isDeliveryProcess = targetProcess instanceof DeliveryProcess;
if (isDeliveryProcess) {
oldPatterns = new ArrayList(((DeliveryProcess) targetProcess)
.getIncludesPatterns());
}
}
public void setType(int type) {
this.type = type;
if(type == IActionTypeProvider.DEEP_COPY) {
runAsJob = true;
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.command.BSDropCommand#execute()
*/
public void execute() {
IActionTypeProvider actionTypeProvider = (IActionTypeProvider) viewer;
canExtend = true;
for (Iterator iter = dropElements.iterator(); canExtend && iter.hasNext();) {
// BreakdownElement element = (BreakdownElement) iter.next();
//
// if ((ProcessUtil.hasContributorOrReplacer((Activity) element))){
// canExtend = false;
// break;
// }
//
// Process proc = TngUtil.getOwningProcess(element);
// if (targetProcess.getVariabilityBasedOnElement() == proc) {
// canExtend = false;
// break;
// }
//
// if (proc instanceof CapabilityPattern && proc != targetProcess) {
// canExtend = true;
// break;
// }
Activity act = (Activity) iter.next();
Process srcProc = TngUtil.getOwningProcess(act);
if(srcProc instanceof DeliveryProcess) {
// cannot extend a delivery process nor any of its activities
//
canExtend = false;
break;
}
if (DependencyChecker.newCheckAct) {
canExtend = DependencyChecker.checkCircularForMovingVariabilityElement
(activity, Collections.singletonList(act), true);
} else {
canExtend = DependencyChecker.checkCircularDependency(act, activity).isOK();
}
}
if ( viewer != null) {
viewer = null;
// delegate the execution of this command
//
actionTypeProvider.execute(this, canExtend);
return;
}
activityHandler = new ActivityHandler();
if(type == IActionTypeProvider.DEEP_COPY) {
doDeepCopy();
}
else {
super.execute();
}
}
/**
*
*/
private void doDeepCopy() {
if(!UserInteractionHelper.confirmDeepCopy(dropElements)) {
return;
}
MethodConfiguration deepCopyConfig = null;
try {
deepCopyConfig = UserInteractionHelper.chooseDeepCopyConfiguration(targetProcess, adapterFactory);
}
catch(OperationCanceledException e) {
return;
}
activityHandler.setDeepCopyConfig(deepCopyConfig);
activityHandler.setTargetProcess(targetProcess);
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
activityHandler.setMonitor(monitor);
preExecuted = preExecute();
}
};
UserInteractionHelper.runWithProgress(runnable, getLabel());
if (preExecuted) {
redo();
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.command.BSDropCommand#preExecute()
*/
protected boolean preExecute() {
if (!super.preExecute())
return false;
// process the selected activities and deep-copy the valid ones
//
if (isDeliveryProcess) {
patterns = new ArrayList();
}
for (Iterator iter = dropElements.iterator(); iter.hasNext();) {
Object element = (Object) iter.next();
if ((element instanceof Activity)
// && element != target
) {
Activity act = (Activity) element;
// if(type == IActionTypeProvider.DEEP_COPY) {
// activityHandler.deepCopy(act);
// }
// else {
// Process proc = TngUtil.getOwningProcess(act);
// if (proc instanceof CapabilityPattern && proc != targetProcess) {
// if (type == IActionTypeProvider.EXTEND) {
// activityHandler.extend(act);
// if (patterns != null)
// patterns.add(proc);
// } else {
// activityHandler.copy(act);
// }
// } else {
// activityHandler.copy(act);
// }
// }
switch(type) {
case IActionTypeProvider.DEEP_COPY:
activityHandler.deepCopy(act);
break;
case IActionTypeProvider.EXTEND:
activityHandler.extend(act);
if (patterns != null) {
Process proc = TngUtil.getOwningProcess(act);
if(proc != null) {
patterns.add(proc);
}
}
break;
case IActionTypeProvider.COPY:
activityHandler.copy(act);
break;
}
}
}
appliedActivities = activityHandler.getActivities();
return !appliedActivities.isEmpty();
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.command.BSDropCommand#doExecute()
*/
protected void doExecute() {
Iterator itor = appliedActivities.iterator();
ProcessPackage pkg = (ProcessPackage) activity.eContainer();
while (itor.hasNext()) {
Activity act = (Activity) itor.next();
if (act.eContainer() != null
&& act.eContainer().eContainer() != pkg) {
pkg.getChildPackages().add(act.eContainer());
}
if (patterns != null && !patterns.isEmpty()) {
DeliveryProcess proc = (DeliveryProcess) targetProcess;
for (Iterator iter = patterns.iterator(); iter.hasNext();) {
Object pattern = iter.next();
if (!proc.getIncludesPatterns().contains(pattern)) {
proc.getIncludesPatterns().add(pattern);
}
}
}
}
activity.getBreakdownElements().addAll(appliedActivities);
if(!activityHandler.getDeepCopies().isEmpty()) {
postDeepCopy();
}
// Hack to refresh providers forcefully before calling fixDuplicateNames
ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory.adapt(activity, ITreeItemContentProvider.class);
adapter.getChildren(activity);
// fix duplicate names of newly added elements
fixDuplicateNames();
getModifiedResources().add(activity.eResource());
}
/**
*
*/
private void postDeepCopy() {
Runnable runnable = new Runnable() {
public void run() {
// add to default configuratation of the target process any missing content
//
if(addedObjects == null) {
addedObjects = new HashSet();
}
else {
addedObjects.clear();
}
boolean defaultConfigChanged = false;
for (Iterator iter = activityHandler.getDeepCopies().iterator(); iter.hasNext();) {
Iterator iterator = new AbstractTreeIterator(iter.next()) {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 1L;
protected Iterator getChildren(Object object) {
if(object instanceof Activity) {
return ((Activity)object).getBreakdownElements().iterator();
}
return Collections.EMPTY_LIST.iterator();
}
};
while(iterator.hasNext()) {
Object e = iterator.next();
if(e instanceof Descriptor) {
MethodElement me = ProcessUtil.getAssociatedElement((Descriptor) e);
int size = addedObjects.size();
ProcessUtil.addToDefaultConfiguration(targetProcess, me, addedObjects);
if(!defaultConfigChanged && (size != addedObjects.size())) {
getModifiedResources().add(targetProcess.getDefaultContext().eResource());
defaultConfigChanged = true;
}
}
}
}
}
};
UserInteractionHelper.runInUI(runnable, getLabel());
MethodConfiguration deepCopyConfig = activityHandler.getDeepCopyConfig();
if(deepCopyConfig != null) {
// synchronize the deep copies with deep copy configuration
//
final SynchronizeCommand synchCmd = new SynchronizeCommand(activityHandler.getDeepCopies(), deepCopyConfig, null, false);
try {
runnable = new Runnable() {
public void run() {
synchCmd.initilize();
}
};
UserInteractionHelper.runWithProgress(runnable, LibraryEditResources.ProcessAutoSynchronizeAction_prepare);
if(synchCmd.isIntialized()) {
synchCmd.execute();
}
}
finally {
synchCmd.dispose();
}
}
}
/**
* Fixes duplicate names of newly added elements
*/
private void fixDuplicateNames() {
Suppression suppression = Suppression.getSuppression(targetProcess);
for (Iterator iter = appliedActivities.iterator(); iter.hasNext();) {
Activity act = (Activity) iter.next();
fixDuplicateNames(act, suppression);
fixTeamProfileDuplicateNames(act, suppression);
}
}
private void fixDuplicateNames(BreakdownElement e, Suppression suppression) {
fixDuplicateNames(e, suppression, adapterFactory);
}
private static void fixDuplicateNames(BreakdownElement e, Suppression suppression, AdapterFactory adapterFactory) {
String baseName = e.getName();
if (ProcessUtil.checkBreakdownElementName(adapterFactory, e, baseName, suppression) != null) {
for (int i = 1; true; i++) {
String name = baseName + '_' + i;
if (ProcessUtil.checkBreakdownElementName(adapterFactory, e, name, suppression) == null) {
e.setName(name);
break;
}
}
}
baseName = ProcessUtil.getPresentationName(e);
if (ProcessUtil.checkBreakdownElementPresentationName(adapterFactory, e, baseName, suppression) != null) {
for (int i = 1; true; i++) {
String name = baseName + '_' + i;
if (ProcessUtil.checkBreakdownElementPresentationName(adapterFactory, e, name, suppression) == null) {
e.setPresentationName(name);
break;
}
}
}
}
private void fixTeamProfileDuplicateNames(Activity act, Suppression suppression) {
for (int i = act.getBreakdownElements().size() - 1; i > -1; i--) {
Object element = act.getBreakdownElements().get(i);
if(element instanceof TeamProfile) {
fixDuplicateNames((BreakdownElement) element, suppression, TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory());
}
else if(element instanceof Activity) {
fixTeamProfileDuplicateNames((Activity) element, suppression);
}
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.command.BSDropCommand#doUndo()
*/
protected void doUndo() {
activity.getBreakdownElements().removeAll(appliedActivities);
if (isDeliveryProcess) {
DeliveryProcess proc = (DeliveryProcess) targetProcess;
proc.getIncludesPatterns().clear();
proc.getIncludesPatterns().addAll(oldPatterns);
}
}
public static void setName(List siblings, Activity e) {
String baseName = e.getName();
if (!isNameTaken(siblings, e, baseName)) {
return;
}
for (int i = 1; true; i++) {
String name = baseName + '_' + i;
if (!isNameTaken(siblings, e, name)) {
e.setName(name);
return;
}
}
}
public static void setDefaultPresentationName(List siblings, Activity e) {
// if(e.getPresentationName() != null &&
// e.getPresentationName().trim().length() > 0) return;
String basePresentationName = ProcessUtil.getPresentationName(e);
if (!isPresentationNameTaken(siblings, e, basePresentationName)) {
// e.setPresentationName(basePresentationName);
return;
}
for (int i = 1; true; i++) {
String name = basePresentationName + '_' + i;
if (!isPresentationNameTaken(siblings, e, name)) {
e.setPresentationName(name);
return;
}
}
}
private static boolean isNameTaken(List siblings, DescribableElement e,
String name) {
for (int i = siblings.size() - 1; i > -1; i--) {
BreakdownElement sibling = (BreakdownElement) siblings.get(i);
// if(sibling != e && name.equals(sibling.getPresentationName())) {
if (sibling != e && name.equals(sibling.getName())) {
return true;
}
}
return false;
}
private static boolean isPresentationNameTaken(List siblings,
DescribableElement e, String name) {
for (int i = siblings.size() - 1; i > -1; i--) {
BreakdownElement sibling = (BreakdownElement) siblings.get(i);
// if(sibling != e && name.equals(sibling.getPresentationName())) {
if (sibling != e
&& name.equals(ProcessUtil.getPresentationName(sibling))) {
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.command.AbstractCommand#getAffectedObjects()
*/
public Collection getAffectedObjects() {
if(executed) {
return appliedActivities;
}
else {
return Collections.EMPTY_LIST;
}
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.command.AbstractCommand#getResult()
*/
public Collection getResult() {
return getAffectedObjects();
}
public ActivityHandler getActivityHandler() {
return activityHandler;
}
public Activity getActivity(){
return activity;
}
public int getType(){
return type;
}
}