blob: c02123dd9b17f59ebf8d9cfe866c22e4c3f41e34 [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;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.Disposable;
import org.eclipse.emf.edit.provider.ITableItemLabelProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.epf.library.edit.ICachedChildrenItemProvider;
import org.eclipse.epf.library.edit.IConfigurable;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.IWrapperItemProviderFactory;
import org.eclipse.epf.library.edit.IWrapperItemProviderFactoryProvider;
import org.eclipse.epf.library.edit.Providers;
import org.eclipse.epf.library.edit.VariabilityInfo;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.process.command.ActivityAddCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.GraphicalData;
import org.eclipse.epf.library.edit.util.PredecessorList;
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.Descriptor;
import org.eclipse.epf.uma.Iteration;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.provider.ActivityItemProvider;
import org.eclipse.epf.uma.util.AssociationHelper;
/**
* Abstract base class for activity's item providers used by the Process Editor.
*
* @author Phong Nguyen Le
* @since 1.0
*/
public abstract class BSActivityItemProvider extends ActivityItemProvider
implements IProcessItemProvider, IBSItemProvider,
ITableItemLabelProvider, IConfigurable, ICachedChildrenItemProvider {
private static final Set<VariabilityType> localVariabilityTypes = new HashSet<VariabilityType>(Arrays.asList(new VariabilityType[] {
VariabilityType.LOCAL_CONTRIBUTION,
VariabilityType.LOCAL_REPLACEMENT
}));
private Object parent;
private int id;
protected Object topItem = null;
private boolean rolledUp;
private GraphicalData graphicalData;
private PredecessorList predecessors;
private Boolean expanded;
protected Adapter baseListener;
private IFilter childFilter = new IFilter() {
public boolean accept(Object obj) {
return acceptAsChild(obj);
}
};
private boolean refreshAllIDsRequired;
private IFilter filter;
protected List cachedChildren;
protected List cachedRollupChildren;
private IConfigurator configurator;
private Disposable contributedWrappers;
private VariabilityInfo variabilityInfo;
private boolean enableVariabilityInfo = true;
private Disposable rolledUpWrappers;
/**
* @param adapterFactory
*/
public BSActivityItemProvider(AdapterFactory adapterFactory) {
super(adapterFactory);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#dispose()
*/
public void dispose() {
if(baseListener != null) {
EObject currentBase = (EObject) baseListener.getTarget();
if(currentBase != null) {
currentBase.eAdapters().remove(baseListener);
}
if (getTarget() instanceof Activity) {
Activity act = (Activity) getTarget();
VariabilityElement base = act.getVariabilityBasedOnElement();
if (base != null) {
base.eAdapters().remove(baseListener);
}
}
}
if (predecessors != null) {
predecessors.dispose();
}
if(cachedChildren != null) {
cachedChildren.clear();
cachedChildren = null;
}
if(cachedRollupChildren != null) {
cachedRollupChildren.clear();
cachedRollupChildren = null;
}
if(contributedWrappers != null) {
contributedWrappers.dispose();
contributedWrappers = null;
}
if(rolledUpWrappers != null) {
rolledUpWrappers.dispose();
rolledUpWrappers = null;
}
super.dispose();
}
/**
* Checks if the given object can be accepted as a child.
*/
protected boolean acceptAsChild(Object child) {
if (filter != null) {
return filter.accept(child);
}
return true;
}
/**
* Checks if the given object can be accepted as a rolled-up child.
*/
protected boolean acceptAsRolledUpChild(Object child) {
child = TngUtil.unwrap(child);
if (filter != null && !(child instanceof Activity)
&& !(child instanceof TeamProfile)) {
return filter.accept(child);
}
return true;
}
/**
* Gets the object associated with the given descriptor (e.g: a
* TaskDescriptor is associated with a Task).
*/
protected abstract Object getObject(Descriptor descriptor);
public Collection getNewChildDescriptors(Object object, EditingDomain editingDomain, Object sibling) {
// disallow creating new child if this item provider is rolled up
//
if(isRolledUp()) {
return Collections.EMPTY_LIST;
}
return super.getNewChildDescriptors(object, editingDomain, sibling);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#collectNewChildDescriptors(java.util.Collection,
* java.lang.Object)
*/
protected void collectNewChildDescriptors(Collection newChildDescriptors,
Object object) {
// if(isTopActivity(object)) {
// newChildDescriptors.add
// (createChildParameter
// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
// UmaFactory.eINSTANCE.createPhase()));
// newChildDescriptors.add
// (createChildParameter
// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
// UmaFactory.eINSTANCE.createIteration()));
// }
// else if(object instanceof Phase) {
// newChildDescriptors.add
// (createChildParameter
// (UmaPackage.eINSTANCE.getActivity_BreakdownElements(),
// UmaFactory.eINSTANCE.createIteration()));
// }
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#isExpanded()
*/
public Boolean isExpanded() {
return expanded;
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#setExpanded(boolean)
*/
public void setExpanded(Boolean b) {
expanded = b;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getId()
*/
public int getId() {
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getTopItem()
*/
public Object getTopItem() {
if (topItem == null) {
if(ProcessUtil.isTopProcess(target)) {
return target;
}
Object parent = getParent(target);
if(parent != null) {
Object ip = getRootAdapterFactory().adapt(parent, ITreeItemContentProvider.class);
if(ip instanceof IBSItemProvider) {
IBSItemProvider adapter = (IBSItemProvider) ip;
if (adapter != null) {
Object top = adapter.getTopItem();
if (top == null && parent instanceof Process
&& ((Process) parent).getSuperActivities() == null) {
top = parent;
adapter.setTopItem(top);
}
return top;
}
}
}
}
return topItem;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.tng.process.IBSItemProvider#setId(int)
*/
public void setId(int id) {
this.id = id;
}
private static boolean isTopActivity(Object object) {
EObject eObj = (EObject) object;
Object parent = eObj.eContainer();
if (parent instanceof ProcessComponent) {
ProcessComponent pc = (ProcessComponent) parent;
return object == pc.getProcess();
}
return false;
}
/**
* @param object
* @return
*/
protected static boolean hasChildDescriptor(Activity act) {
for (Iterator iter = act.getBreakdownElements().iterator(); iter
.hasNext();) {
Object element = iter.next();
if (element instanceof Descriptor) {
return true;
}
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildrenFeatures(java.lang.Object)
*/
public Collection getChildrenFeatures(Object object) {
if (childrenFeatures == null) {
childrenFeatures = new ArrayList();
childrenFeatures.add(UmaPackage.eINSTANCE
.getActivity_BreakdownElements());
}
return childrenFeatures;
}
protected void setParentFor(Object child, Object parent) {
ProcessUtil.setParent(child, parent, getRootAdapterFactory());
}
// private Collection getDirectChildren(Object object) {
// List myChildren;
// ChildrenStore store = getChildrenStore(object);
// if (store != null) {
// myChildren = store.getChildren();
// } else {
// // store = createChildrenStore(object);
// List result = store != null ? null : new ArrayList();
// EObject eObject = (EObject) object;
//
// for (Iterator i = getChildrenFeatures(object).iterator(); i
// .hasNext();) {
// EStructuralFeature feature = (EStructuralFeature) i.next();
// if (feature.isMany()) {
// List children = (List) eObject.eGet(feature);
//
//// //Change for Activity Variability. To do realization for
//// //Browsing and Publishing.
//// List children = new ArrayList();
//// if(filter != null && filter instanceof IConfigurator){
//// children.addAll(((IConfigurator)filter).getChildren(object, feature));
//// }
//// else{
//// children = (List) eObject.eGet(feature);
//// }
//
// int index = 0;
// for (Iterator ci = children.iterator(); ci.hasNext(); index++) {
// Object child = ci.next();
// if (acceptAsChild(child)) {
// child = wrap(eObject, feature, child, index);
// setParentFor(child, object);
// // IBSItemProvider adapter = (IBSItemProvider)
// // getBestAdapterFactory().adapt(child,
// // ITreeItemContentProvider.class);
// // adapter.setRolledUp(false);
// if (store != null) {
// store.getList(feature).add(child);
// } else {
// result.add(child);
// }
// }
// }
// } else {
// Object child = eObject.eGet(feature);
// if (acceptAsChild(child)) {
// child = wrap(eObject, feature, child,
// CommandParameter.NO_INDEX);
// setParentFor(child, object);
// // IBSItemProvider adapter = (IBSItemProvider)
// // getBestAdapterFactory().adapt(child,
// // ITreeItemContentProvider.class);
// // adapter.setRolledUp(false);
//
// if (store != null) {
// store.setValue(feature, child);
// } else {
// result.add(child);
// }
// }
// }
// }
// myChildren = store != null ? store.getChildren() : result;
// }
// Collection children = addInherited(object, myChildren);
// return children;
// }
private Collection getImmediateChildren(Object object) {
Collection children = new ArrayList();
for (Iterator iter = super.getChildren(object).iterator(); iter.hasNext();) {
Object child = (Object) iter.next();
if(acceptAsChild(child)) {
if(configurator != null) {
child = configurator.resolve(child);
}
if(child != null && !children.contains(child)) {
setParentFor(child, object);
children.add(child);
}
}
}
children = addInherited(object, (List) children);
return children;
}
private Collection getRolledUpChildren(Object object) {
if (rolledUpWrappers != null) {
rolledUpWrappers.dispose();
}
List children = new ArrayList();
AbstractTreeIterator iter = new AbstractTreeIterator(object, false) {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -3159537629619737368L;
protected Iterator getChildren(Object object) {
if (object instanceof Activity) {
BSActivityItemProvider adapter = (BSActivityItemProvider) adapterFactory.adapt(object, ITreeItemContentProvider.class);
Iterator iterator;
boolean b = adapter.isRolledUp();
try {
adapter.basicSetRolledUp(false);
iterator = adapter.getChildren(object).iterator();
}
finally {
adapter.basicSetRolledUp(b);
}
return iterator;
} else if (object instanceof BreakdownElementWrapperItemProvider
&& !(object instanceof TeamProfileWrapperItemProvider)) {
return ((BreakdownElementWrapperItemProvider) object)
.getChildren(object).iterator();
}
return Collections.EMPTY_LIST.iterator();
}
};
// make sure that only one descriptor for each content element in the roll-up list
//
List descriptors = new ArrayList();
while (iter.hasNext()) {
Object child = iter.next();
if (acceptAsRolledUpChild(child)) {
Object e = TngUtil.unwrap(child);
if(e instanceof Descriptor) {
Object desc = findDescriptor(descriptors, e);
if(desc == null) {
if(isWrappingRollupNeeded(child)) {
child = createRollupWrapper(child, object, adapterFactory);
}
children.add(child);
descriptors.add(child);
}
else {
if(isWrappingRollupNeeded(child)) {
ComposedBreakdownElementWrapperItemProvider composedWrapper = ProcessUtil.getComposedWrapper(desc);
if(composedWrapper != null) {
composedWrapper.addElement(child);
}
}
}
}
else {
children.add(child);
}
}
}
descriptors.clear();
descriptors = null;
return children;
}
/**
* Checks if wrapping of the specified rollup element is needed. If it's
* needed, the caller will use
* {@link #createRollupWrapper(Object, Object, AdapterFactory)} to create
* wrapper for the rollup element.
*
* @param object
* @return
*/
protected boolean isWrappingRollupNeeded(Object object) {
return false;
}
protected ComposedBreakdownElementWrapperItemProvider createComposedWrapper(Object object, Object owner, AdapterFactory adapterFactory) {
return new ComposedBreakdownElementWrapperItemProvider(object, owner, adapterFactory);
}
protected Object createRollupWrapper(Object object, Object owner, AdapterFactory adapterFactory) {
ComposedBreakdownElementWrapperItemProvider wrapper = createComposedWrapper(object, owner, adapterFactory);
wrapper.readOnly = true;
wrapper.isRollupChild = true;
if(rolledUpWrappers == null) {
rolledUpWrappers = new Disposable();
}
rolledUpWrappers.add(wrapper);
return wrapper;
}
private Collection doGetChildren(Object object) {
if(isRolledUp()) {
return getRolledUpChildren(object);
}
else {
return getImmediateChildren(object);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getChildren(java.lang.Object)
*/
public Collection getChildren(Object object) {
Activity activity = (Activity) object;
if(configurator != null) {
//TODO: remove the enableVariabilityInfoFlag and
// create an interface or do differently
if(enableVariabilityInfo)
variabilityInfo = configurator.getVariabilityInfo(activity);
else
variabilityInfo = null;
}
else {
variabilityInfo = null;
}
if(variabilityInfo != null) {
Object resolved = variabilityInfo.getInheritanceList().get(0);
BSActivityItemProvider ip = (BSActivityItemProvider) adapterFactory.adapt(resolved, ITreeItemContentProvider.class);
Collection children;
boolean b = ip.isRolledUp();
try {
ip.basicSetRolledUp(isRolledUp());
children = ip.doGetChildren(resolved);
}
finally {
ip.basicSetRolledUp(b);
}
if(!variabilityInfo.getContributors().isEmpty()) {
ArrayList contributedChildren = new ArrayList();
for (Iterator iter = variabilityInfo.getContributors().iterator(); iter.hasNext();) {
Object e = iter.next();
Object adapter = adapterFactory.adapt(e, ITreeItemContentProvider.class);
if(adapter instanceof BSActivityItemProvider) {
ip = ((BSActivityItemProvider)adapter);
b = ip.isRolledUp();
try {
ip.basicSetRolledUp(isRolledUp());
for (Iterator iterator = ip.getImmediateChildren(e).iterator(); iterator
.hasNext();) {
e = iterator.next();
e = Providers.getConfigurationApplicator().resolve(e, configurator.getMethodConfiguration());
if(e != null && !TngUtil.contains(children, e)) {
contributedChildren.add(e);
}
}
}
finally {
ip.basicSetRolledUp(b);
}
}
}
if(!contributedChildren.isEmpty()) {
children.addAll(wrapContributed(activity, contributedChildren));
}
}
return children;
}
return doGetChildren(object);
}
protected void updateCachedChildren(Collection children) {
// if(isRolledUp()) {
// if(cachedRollupChildren == null) {
// cachedRollupChildren = new ArrayList(children);
// }
// else {
// cachedRollupChildren.clear();
// cachedRollupChildren.addAll(children);
// }
// }
// else {
// if(cachedChildren == null) {
// cachedChildren = new ArrayList(children);
// }
// else {
// cachedChildren.clear();
// cachedChildren.addAll(children);
// }
// }
}
/* (non-Javadoc)
* @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getChildrenFromCache()
*/
public Collection getChildrenFromCache() {
if(cachedChildren == null) {
getChildren(target);
}
return cachedChildren;
}
/* (non-Javadoc)
* @see org.eclipse.epf.library.edit.ICachedChildrenItemProvider#getRollupChildrenFromCache()
*/
public Collection getRollupChildrenFromCache() {
if(cachedRollupChildren == null) {
boolean oldRolledUp = rolledUp;
try {
rolledUp = true;
getChildren(target);
}
finally {
rolledUp = oldRolledUp;
}
}
return cachedRollupChildren;
}
private BreakdownElementWrapperItemProvider findWrapper(Object owner, Object value) {
// find if a wrapper already exist for the given value and owner
//
Object adapter = adapterFactory.adapt(value,
ITreeItemContentProvider.class);
BreakdownElementWrapperItemProvider wrapper = null;
if (adapter instanceof IBSItemProvider) {
List listeners = ((IBSItemProvider) adapter).getListeners();
if (listeners != null) {
find_wrapper_loop: for (Iterator iter = listeners.iterator(); iter
.hasNext();) {
Object element = (Object) iter.next();
if (element instanceof BreakdownElementWrapperItemProvider) {
wrapper = (BreakdownElementWrapperItemProvider) element;
if (wrapper.getValue() == value
&& wrapper.getParent(value) == owner) {
break find_wrapper_loop;
} else {
wrapper = null;
}
}
}
}
}
return wrapper;
}
private List wrapInherited(Activity owner, Collection breakdownElements) {
if (wrappers == null) {
wrappers = new Disposable();
}
return wrap(owner, breakdownElements, true, false, wrappers);
}
private List wrapContributed(Activity owner, Collection breakdownElements) {
if(contributedWrappers == null) {
contributedWrappers = new Disposable();
}
return wrap(owner, breakdownElements, false, true, contributedWrappers);
}
private IWrapperItemProviderFactory getWrapperItemProviderFactory() {
IWrapperItemProviderFactory factory = null;
if(adapterFactory instanceof IWrapperItemProviderFactoryProvider) {
factory = ((IWrapperItemProviderFactoryProvider)adapterFactory).getWrapperItemProviderFactory();
}
if(factory == null) {
factory = IBreakdownElementWrapperItemProviderFactory.INSTANCE;
}
return factory;
}
private List<?> wrap(Activity owner, Collection<?> breakdownElements, boolean inherited, boolean contributed, Disposable wrappers) {
ArrayList<Object> wrapperList = new ArrayList<Object>();
IWrapperItemProviderFactory wrapperFactory = getWrapperItemProviderFactory();
for (Iterator<?> iter = breakdownElements.iterator(); iter.hasNext();) {
Object object = iter.next();
Object unWrapped = TngUtil.unwrap(object);
if (unWrapped instanceof BreakdownElement) {
BreakdownElement e = (BreakdownElement) unWrapped;
if (!TngUtil.isBase(owner.getBreakdownElements(), e, localVariabilityTypes)) {
Object child = getWrapper(owner, e, wrappers);
if(child == null) {
child = wrapperFactory.createWrapper(e, owner, adapterFactory);
if(child instanceof BreakdownElementWrapperItemProvider) {
BreakdownElementWrapperItemProvider beWrapper = (BreakdownElementWrapperItemProvider) child;
if(inherited) {
beWrapper.isInherited = true;
}
else if(contributed) {
beWrapper.contributed = true;
if(object instanceof BreakdownElementWrapperItemProvider
&& ((BreakdownElementWrapperItemProvider)object).isInherited()) {
beWrapper.isInherited = true;
}
}
}
}
else {
wrappers.remove(child);
}
wrapperList.add(child);
}
}
}
wrappers.dispose();
wrappers.addAll(wrapperList);
return wrapperList;
}
private static Object getWrapper(Activity owner, BreakdownElement e, Collection wrappers) {
for (Iterator iter = wrappers.iterator(); iter.hasNext();) {
IWrapperItemProvider wrapper = (IWrapperItemProvider) iter.next();
if(wrapper.getOwner() == owner && wrapper.getValue() == e) {
return wrapper;
}
}
return null;
}
protected Adapter createBaseListener() {
if (baseListener == null) {
baseListener = new AdapterImpl() {
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.provider.ActivityItemProvider#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
public void notifyChanged(final Notification notification) {
Activity act = (Activity) BSActivityItemProvider.this
.getTarget();
switch (notification.getFeatureID(Activity.class)) {
case UmaPackage.ACTIVITY__PRESENTATION_NAME:
if (ProcessUtil.isExtendingOrLocallyContributing(act)) {
fireNotifyChanged(new ViewerNotification(
notification, act, false, true));
}
break;
case UmaPackage.ACTIVITY__NAME:
if (act.getVariabilityBasedOnElement() != null) {
fireNotifyChanged(new ViewerNotification(
notification, act, false, true));
}
break;
case UmaPackage.ACTIVITY__SUPPRESSED:
fireNotifyChanged(new ViewerNotification(notification,
act, true, false));
break;
case UmaPackage.ACTIVITY__VARIABILITY_BASED_ON_ELEMENT:
fireNotifyChanged(new ViewerNotification(notification,
act, true, true));
refreshAffectedViewers();
break;
case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS: {
if(handleReplaceBreakdownElement(notification)) {
break;
}
List list = getAffectedChildren(notification);
if (!list.isEmpty()) {
boolean updateLabel = refreshChildrenData(
notification, list);
// forward notification
//
fireNotifyChanged(new ViewerNotification(
notification, act, true, updateLabel));
// ProcessUtil.refreshViewer(getRootAdapterFactory(),
// (Process) getTopItem());
refreshAffectedViewers();
}
break;
}
}
}
};
}
return baseListener;
}
protected Activity listenToBaseActivity() {
Activity act = (Activity) target;
if (!ProcessUtil.isExtendingOrLocallyContributing(act)) {
return null;
}
Activity baseAct;
if(variabilityInfo != null) {
if(variabilityInfo.getInheritanceList().size() > 1) {
baseAct = (Activity) variabilityInfo.getInheritanceList().get(1);
}
else {
baseAct = (Activity) configurator.resolve(act.getVariabilityBasedOnElement());
}
}
else {
baseAct = (Activity) act.getVariabilityBasedOnElement();
}
if (baseAct == null) {
return null;
}
createBaseListener();
// remove baseListener from old base, if there is any
//
EObject oldBase = (EObject) baseListener.getTarget();
if(oldBase != null) {
oldBase.eAdapters().remove(baseListener);
}
if (!baseAct.eAdapters().contains(baseListener)) {
baseAct.eAdapters().add(baseListener);
}
Object ip = adapterFactory.adapt(baseAct, ITreeItemContentProvider.class);
if(ip instanceof BSActivityItemProvider) {
BSActivityItemProvider adapter = (BSActivityItemProvider) ip;
adapter.listenToBaseActivity();
}
else {
System.out.println();
}
return baseAct;
}
protected Collection addInherited(Object object, List myChildren) {
if (object instanceof Activity) {
Activity act = (Activity) object;
Activity baseAct = listenToBaseActivity();
if (baseAct != null) {
VariabilityType extendType = act.getVariabilityType();
if (extendType == VariabilityType.LOCAL_REPLACEMENT) {
return myChildren;
} else if (extendType == VariabilityType.LOCAL_CONTRIBUTION
|| extendType == VariabilityType.EXTENDS) {
BSActivityItemProvider adapter = (BSActivityItemProvider) getRootAdapterFactory()
.adapt(baseAct, ITreeItemContentProvider.class);
List allChildren;
boolean oldRolledUp = adapter.isRolledUp();
try {
if(oldRolledUp) {
adapter.basicSetRolledUp(false);
}
allChildren = wrapInherited(act, adapter.getChildren(baseAct));
}
finally {
if(oldRolledUp) {
adapter.basicSetRolledUp(true);
}
}
// // go thru own children list and insert it to the combined
// // child list at the right place.
// //
// for (Iterator iter = myChildren.iterator(); iter.hasNext();) {
// BreakdownElement element = (BreakdownElement) iter
// .next();
// TngUtil.addTo(allChildren, element, object, TngUtil
// .getBestAdapterFactory(adapterFactory));
// }
if(allChildren.isEmpty()) {
return myChildren;
}
else {
TngUtil.addAllTo(allChildren, myChildren);
return allChildren;
}
}
}
}
return myChildren;
}
/**
* Checks if there is no descriptor in <code>children</code> referring to
* the same object as the specified descriptor <code>child</code> does.
*
* @param children
* @param child
* @return true if no descriptor is found in the children list that refers
* to the same object as the specified child does, false otherwise.
*/
protected boolean isNewDescriptor(List children, Object child) {
return findDescriptor(children, child) == null;
}
protected Object findDescriptor(List children, Object child) {
Object obj = getObject((Descriptor) TngUtil.unwrap(child));
if (obj == null)
return null;
for (int i = children.size() - 1; i > -1; i--) {
Object o = children.get(i);
if (obj == getObject((Descriptor) TngUtil.unwrap(o)))
return o;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.command.CreateChildCommand.Helper#getCreateChildImage(java.lang.Object,
* java.lang.Object, java.lang.Object, java.util.Collection)
*/
public Object getCreateChildImage(Object owner, Object feature,
Object child, Collection selection) {
// return
// TngEditPlugin.INSTANCE.getImage("full/ctool16/CreateActivity_breakdownElements_Activity");
return getImage(child);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#createRemoveCommand(org.eclipse.emf.edit.domain.EditingDomain,
* org.eclipse.emf.ecore.EObject,
* org.eclipse.emf.ecore.EStructuralFeature, java.util.Collection)
*/
protected Command createRemoveCommand(EditingDomain domain, EObject owner,
EStructuralFeature feature, Collection collection) {
return super.createRemoveCommand(domain, owner, feature, collection);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.tng.process.IBSItemProvider#getItemProvider(org.eclipse.emf.ecore.EObject)
*/
public IBSItemProvider getItemProvider(EObject eObj) {
return (IBSItemProvider) TngUtil
.getAdapter(eObj, IBSItemProvider.class);
}
public void setParent(Object object) {
parent = object;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getParent(java.lang.Object)
*/
public Object getParent(Object object) {
if(parent == null) {
if(target instanceof Activity) {
return ((Activity)target).getSuperActivities();
}
}
return parent;
}
/**
* Gets the list of children that had been affected after a an ADD, REMOVE,
* or MOVE operation.
*/
protected List getAffectedChildren(Notification notification) {
return ProcessUtil.getAffectedElements(notification, childFilter);
}
protected boolean refreshChildrenData(Notification notification,
List affectedChildren) {
return false;
}
protected void doRefreshChildren(Notification notification,
List affectedChildren) {
refreshChildrenData(notification, affectedChildren);
Process topAct = (Process) getTopItem();
AdapterFactory rootAdapterFactory = getRootAdapterFactory();
ProcessUtil.refreshViewer(rootAdapterFactory, topAct);
}
protected void refreshChildren(final Notification notification,
final List newOrOldChildren) {
if (!newOrOldChildren.isEmpty()) {
Runnable runnable = new Runnable() {
public void run() {
doRefreshChildren(notification, newOrOldChildren);
}
};
UserInteractionHelper.getUIHelper().runSafely(runnable, false);
}
}
protected void refreshAffectedViewers() {
Runnable runnable = new Runnable() {
public void run() {
doRefreshAffectedViewers();
}
};
UserInteractionHelper.getUIHelper().runSafely(runnable, false);
}
protected void doRefreshAffectedViewers() {
}
protected boolean handlePredecessorListChange(Notification notification) {
return TngUtil.handlePredecessorListChange(this, notification);
}
protected boolean handleReplaceBreakdownElement(Notification notification) {
if(notification.getEventType() == Notification.SET && notification.getNewValue() != notification.getOldValue()) {
if(notification.getNewValue() instanceof WorkBreakdownElement) {
WorkBreakdownElement e = (WorkBreakdownElement) notification.getNewValue();
if(!AssociationHelper.getLinkToSuccessor(e).isEmpty()) {
ProcessUtil.refreshPredeccessorLists(adapterFactory, (Process) getTopItem());
}
}
fireNotifyChanged(new ViewerNotification(notification,
getTarget(), true, false));
refreshAffectedViewers();
return true;
}
return false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
public void notifyChanged(Notification notification) {
updateChildren(notification);
if (handlePredecessorListChange(notification))
return;
switch (notification.getFeatureID(Activity.class)) {
case UmaPackage.ACTIVITY__BREAKDOWN_ELEMENTS:
if(handleReplaceBreakdownElement(notification)) {
return;
}
List newOrOldChildren = getAffectedChildren(notification);
if (!newOrOldChildren.isEmpty()) {
switch (notification.getEventType()) {
case Notification.ADD:
case Notification.ADD_MANY:
createOrMovePackageFor(newOrOldChildren);
break;
}
fireNotifyChanged(new ViewerNotification(notification,
notification.getNotifier(), true, false));
// refreshChildren(notification, newOrOldChildren);
refreshAffectedViewers();
}
return;
case UmaPackage.ACTIVITY__SUPPRESSED:
fireNotifyChanged(new ViewerNotification(notification, notification
.getNotifier(), true, true));
return;
case UmaPackage.ACTIVITY__VARIABILITY_TYPE:
case UmaPackage.ACTIVITY__VARIABILITY_BASED_ON_ELEMENT:
fireNotifyChanged(new ViewerNotification(notification, notification
.getNotifier(), true, true));
// ProcessUtil.refreshViewer(getRootAdapterFactory(), (Process)
// getTopItem());
refreshAffectedViewers();
return;
}
super.notifyChanged(notification);
}
/**
* @param newOrOldChildren
*/
protected void createOrMovePackageFor(List<?> newChildren) {
ProcessPackage pkg = (ProcessPackage) ((EObject) target).eContainer();
if(pkg == null) {
return;
}
for (Object element : newChildren) {
if (element instanceof Activity) {
Activity act = (Activity) element;
if (act.eContainer() == null) {
// create new ProcessPackage for the activity
//
ProcessPackage newPkg = UmaFactory.eINSTANCE
.createProcessPackage();
newPkg.setName(act.getName());
pkg.getChildPackages().add(newPkg);
newPkg.getProcessElements().add(act);
} else {
// Check if the activity's ProcessPackage is at the right
// place.
// If not, move it to the right ProcessComponent.
//
ProcessPackage oldPkg = (ProcessPackage) act.eContainer();
if (oldPkg.eContainer() != pkg) {
pkg.getChildPackages().add(oldPkg);
}
}
} else if(element instanceof ProcessElement) {
pkg.getProcessElements().add((ProcessElement) element);
}
}
}
private static void getAllBreakdownElements(Set set, BreakdownElement e) {
boolean ret = set.add(e);
if (ret && (e instanceof Activity)) {
for (Iterator iter = ((Activity) e).getBreakdownElements()
.iterator(); iter.hasNext();) {
BreakdownElement element = (BreakdownElement) iter.next();
getAllBreakdownElements(set, element);
}
}
}
/**
* Refresh the comma-separated list of predecessor IDs in the viewer
*
* @param affectedBreakdownElements
*/
private void refreshPredecessors(Notification msg,
List affectedBreakdownElements) {
Set refreshList = new HashSet();
Set allBreakdownElements = new HashSet();
for (Iterator iter = affectedBreakdownElements.iterator(); iter
.hasNext();) {
BreakdownElement e = (BreakdownElement) iter.next();
if (msg.getEventType() == Notification.REMOVE
|| msg.getEventType() == Notification.REMOVE_MANY) {
setParentFor(e, null);
}
getAllBreakdownElements(allBreakdownElements, e);
}
// System.out.println("BSActivityItemProvider.refreshPredecessors():
// allBreakdownElements="+allBreakdownElements);
for (Iterator iterator = allBreakdownElements.iterator(); iterator
.hasNext();) {
BreakdownElement element = (BreakdownElement) iterator.next();
for (Iterator iterator1 = AssociationHelper.getLinkToSuccessor(
element).iterator(); iterator1.hasNext();) {
WorkOrder workOrder = (WorkOrder) iterator1.next();
BreakdownElement succ = AssociationHelper
.getSuccessor(workOrder);
if (!allBreakdownElements.contains(succ)) {
refreshList.add(succ);
}
}
}
// System.out.println("BSActivityItemProvider.refreshPredecessors():
// refreshList=" + refreshList);
for (Iterator iter = refreshList.iterator(); iter.hasNext();) {
Object child = iter.next();
fireNotifyChanged(new ViewerNotification(msg, child, false, true));
}
}
/**
* @param activity
*/
private void createPackageFor(Activity activity, EObject parentActivity) {
ProcessPackage parent = (ProcessPackage) parentActivity.eContainer();
ProcessPackage newPkg = UmaFactory.eINSTANCE.createProcessPackage();
newPkg.setName(activity.getName());
parent.getChildPackages().add(newPkg);
ArrayList breakdownElements = new ArrayList();
breakdownElements.add(activity);
breakdownElements.addAll(activity.getBreakdownElements());
newPkg.getProcessElements().addAll(breakdownElements);
}
protected String getColumnName(int columnIndex) {
AdapterFactory rootAdapterFactory = getRootAdapterFactory();
if (rootAdapterFactory instanceof IColumnAware) {
Map columnIndexToNameMap = ((IColumnAware) rootAdapterFactory)
.getColumnIndexToNameMap();
if (columnIndexToNameMap != null) {
return (String) columnIndexToNameMap.get(new Integer(
columnIndex));
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ITableItemLabelProvider#getColumnImage(java.lang.Object,
* int)
*/
public Object getColumnImage(Object object, int columnIndex) {
String colName = getColumnName(columnIndex);
return TngUtil.getColumnImage(object, colName);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ITableItemLabelProvider#getColumnText(java.lang.Object,
* int)
*/
public String getColumnText(Object object, int columnIndex) {
String colName = getColumnName(columnIndex);
return getAttribute(object, colName);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#getText(java.lang.Object)
*/
public String getText(Object object) {
return TngUtil.getLabel(object);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.tng.process.IBSItemProvider#setTopItem(java.lang.Object)
*/
public void setTopItem(Object top) {
topItem = top;
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#isRolledUp()
*/
public boolean isRolledUp() {
return rolledUp;
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#setRolledUp(boolean)
*/
public void setRolledUp(boolean b) {
rolledUp = b;
if (!rolledUp) {
// user roll down this activity, set rolledUp flag of all its
// offstring to false
//
Iterator iter = new AbstractTreeIterator(target, false) {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = -7840687264753640250L;
protected Iterator getChildren(Object object) {
ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
.adapt(object, ITreeItemContentProvider.class);
return adapter.getChildren(object).iterator();
}
};
while (iter.hasNext()) {
Object child = (Object) iter.next();
Object adapter = adapterFactory.adapt(child,
ITreeItemContentProvider.class);
if (adapter instanceof IBSItemProvider) {
((IBSItemProvider) adapter).setRolledUp(false);
}
}
}
}
public GraphicalData getGraphicalData() {
return graphicalData;
}
public void setGraphicalData(GraphicalData data) {
graphicalData = data;
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#getAttribute(java.lang.Object,
* java.lang.String)
*/
public String getAttribute(Object object, String property) {
return ProcessUtil.getAttribute(object, property, this);
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#setAttribute(java.lang.Object,
* java.lang.String, java.lang.String)
*/
public void setAttribute(Object object, String prop, String txt) {
Activity e = (Activity) object;
ProcessUtil.setAttribute(e, prop, txt);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.edit.provider.ItemProviderAdapter#createCreateChildCommand(org.eclipse.emf.edit.domain.EditingDomain,
* org.eclipse.emf.ecore.EObject,
* org.eclipse.emf.ecore.EStructuralFeature, java.lang.Object, int,
* java.util.Collection)
*/
protected Command createCreateChildCommand(EditingDomain domain,
EObject owner, EStructuralFeature feature, Object value, int index,
Collection collection) {
if (value instanceof Iteration) {
((Iteration) value).setIsRepeatable(Boolean.TRUE);
}
return super.createCreateChildCommand(domain, owner, feature, value,
index, collection);
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#getListeners()
*/
public List getListeners() {
if (changeNotifier == null)
return null;
return Collections.unmodifiableList((List) changeNotifier);
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#getPredecessors()
*/
public PredecessorList getPredecessors() {
if (predecessors == null) {
predecessors = new PredecessorList(TngUtil
.getBestAdapterFactory(adapterFactory), target);
}
return predecessors;
}
public boolean isFirstElement(Object obj) {
return ProcessUtil.isFirstElement(getRootAdapterFactory(), this, obj);
}
public boolean isLastElement(Object obj) {
return ProcessUtil.isLastElement(getRootAdapterFactory(), this, obj);
}
public void moveUp(Object obj, IActionManager actionMgr) {
Object parent = this.getParent(obj);
if ((parent != null) && (parent instanceof Activity)) {
TngUtil.moveUp((Activity) parent, obj, getEClasses(), actionMgr);
}
}
public void moveDown(Object obj, IActionManager actionMgr) {
Object parent = this.getParent(obj);
if ((parent != null) && (parent instanceof Activity)) {
TngUtil.moveDown((Activity) parent, obj, getEClasses(), actionMgr);
}
}
protected Command createAddCommand(EditingDomain domain, EObject owner,
EStructuralFeature feature, Collection collection, int index) {
return new ActivityAddCommand((AddCommand) super.createAddCommand(
domain, owner, feature, collection, index));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.provider.ActivityItemProvider#getImage(java.lang.Object)
*/
public Object getImage(Object object) {
Object img = TngUtil.getImage(object);
return img != null ? img : super.getImage(object);
}
public IFilter getChildFilter() {
return childFilter;
}
public void setRefreshAllIDsRequired(boolean b) {
refreshAllIDsRequired = b;
}
public boolean isRefreshAllIDsRequired() {
return refreshAllIDsRequired;
}
public IFilter getFilter() {
return this.filter;
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.IConfigurable#setFilter(com.ibm.library.edit.IFilter)
*/
public void setFilter(IFilter filter) {
this.filter = filter;
if(filter instanceof IConfigurator) {
configurator = (IConfigurator)filter;
}
else {
configurator = null;
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.IConfigurable#setLabel(java.lang.String)
*/
public void setLabel(String label) {
}
/*
* (non-Javadoc)
*
* @see com.ibm.library.edit.process.IBSItemProvider#createDropCommand(java.lang.Object,
* java.util.List)
*/
public IResourceAwareCommand createDropCommand(Object owner,
List dropElements) {
return null;
}
public void basicSetRolledUp(boolean b) {
rolledUp = b;
}
/**
* @return the enableVariabilityInfo
*/
public boolean isEnableVariabilityInfo() {
return enableVariabilityInfo;
}
/**
* @param enableVariabilityInfo the enableVariabilityInfo to set
*/
public void setEnableVariabilityInfo(boolean enableVariabilityInfo) {
this.enableVariabilityInfo = enableVariabilityInfo;
}
private class MoveCommandEx extends MoveCommand implements IResourceAwareCommand {
private Set<Resource> modifiedResources;
public MoveCommandEx(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, int index) {
super(domain, owner, feature, value, index);
}
@Override
public void doExecute() {
// translate view index to index in breakdown elements list
//
List children = (List) getChildren(getTarget());
Object child = children.get(index);
index = ownerList.indexOf(child);
if(index != -1) {
super.doExecute();
}
//TODO: move in between green elements
}
public Collection getModifiedResources() {
if(modifiedResources == null) {
Resource resource = owner.eResource();
if(resource != null) {
modifiedResources = Collections.singleton(resource);
}
else {
modifiedResources = Collections.EMPTY_SET;
}
}
return modifiedResources;
}
}
@Override
protected Command createMoveCommand(EditingDomain domain, EObject owner, EStructuralFeature feature, Object value, int index) {
return new MoveCommandEx(domain, owner, feature, value, index);
}
}