blob: c5bdd7745e28a14a702f7ea5ef86689d615bc694 [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.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
/**
* This class represents a predecessor list of an item provider for a work
* breakdown element. It calculates the predecessors based on the currently
* selected configuration and according to variability rules. It can refresh
* itself upon change in predecessor list of work breakdown element.
*
* @author Phong Nguyen Le
* @since 1.0
*/
public class PredecessorList extends ArrayList {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 3617853092570412082L;
public static final PredecessorList EMPTY_LIST = new PredecessorList() {
/**
* Comment for <code>serialVersionUID</code>
*/
private static final long serialVersionUID = 3904676098217097016L;
public void refresh() {
}
public void add(int index, Object element) {
}
public boolean add(Object o) {
throw new UnsupportedOperationException();
}
public boolean addAll(java.util.Collection c) {
throw new UnsupportedOperationException();
}
public boolean addAll(int index, java.util.Collection c) {
throw new UnsupportedOperationException();
}
};
private AdapterFactory adapterFactory;
private Object object;
private Adapter listener = new AdapterImpl() {
public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
switch (msg.getFeatureID(BreakdownElement.class)) {
case UmaPackage.WORK_BREAKDOWN_ELEMENT__LINK_TO_PREDECESSOR:
refresh();
return;
}
}
};
private PredecessorList() {
}
public PredecessorList(AdapterFactory adapterFactory, Object object) {
this.adapterFactory = adapterFactory;
this.object = object;
BreakdownElement e = (BreakdownElement) TngUtil.unwrap(object);
e.eAdapters().add(0, listener);
initialize();
}
public void dispose() {
Object e = TngUtil.unwrap(object);
if (e instanceof EObject) {
((EObject) e).eAdapters().remove(listener);
}
clear();
}
/**
* Gets the right top item in the breakdown structure tree to search for
* item providers of predecessors
*
* @return
*/
private Object getTopItem() {
if (object instanceof BreakdownElementWrapperItemProvider) {
BreakdownElementWrapperItemProvider itemProvider = (BreakdownElementWrapperItemProvider) object;
if (itemProvider.isReadOnly()) {
// this represents an inherited breakdown element
//
BreakdownElement e = (BreakdownElement) TngUtil.unwrap(object);
Process proc = TngUtil.getOwningProcess(e);
Object top = itemProvider;
for (Object parent = itemProvider.getParent(object); parent != null;) {
top = parent;
BreakdownElement parentElement = (BreakdownElement) TngUtil
.unwrap(parent);
Process parentProc = TngUtil
.getOwningProcess(parentElement);
if (parentProc != proc) {
break;
}
if (parent instanceof ITreeItemContentProvider) {
parent = ((ITreeItemContentProvider) parent)
.getParent(parent);
} else {
ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
.adapt(parent, ITreeItemContentProvider.class);
parent = adapter.getParent(parent);
}
}
return top;
} else {
return itemProvider.getTopItem();
}
} else {
IBSItemProvider adapter = (IBSItemProvider) adapterFactory.adapt(
object, ITreeItemContentProvider.class);
return adapter.getTopItem();
}
}
private void initialize() {
if (TngUtil.unwrap(object) instanceof WorkBreakdownElement) {
WorkBreakdownElement e = (WorkBreakdownElement) TngUtil
.unwrap(object);
List workOrders = e.getLinkToPredecessor();
if (workOrders.isEmpty())
return;
Object top = getTopItem();
AdapterFactoryTreeIterator iter = new AdapterFactoryTreeIterator(
adapterFactory, top);
// copy the tree to a map of breakdown element / item provider for
// reuse
//
HashMap map = new HashMap();
while (iter.hasNext()) {
Object obj = iter.next();
Object be = TngUtil.unwrap(obj);
Object ip = adapterFactory.adapt(obj,
ITreeItemContentProvider.class);
map.put(be, ip);
if (be instanceof VariabilityElement) {
VariabilityElement ve = (VariabilityElement) be;
if (ve.getVariabilityBasedOnElement() != null) {
map.put(ve.getVariabilityBasedOnElement(), ip);
}
}
}
if (!workOrders.isEmpty()) {
int n = workOrders.size();
for (int i = 0; i < n; i++) {
WorkOrder workOrder = (WorkOrder) workOrders.get(i);
BreakdownElement pred = workOrder.getPred();
IBSItemProvider bsItemProvider = (IBSItemProvider) map
.get(pred);
if (bsItemProvider != null) {
add(bsItemProvider);
}
}
}
}
}
protected void refresh() {
clear();
initialize();
}
/*
* (non-Javadoc)
*
* @see java.util.AbstractCollection#toString()
*/
public String toString() {
return toUnSuppressedString(null);
}
public String toUnSuppressedString(Suppression sup) {
// remove the item providers of the deleted elements
//
for (Iterator iter = iterator(); iter.hasNext();) {
Object e = TngUtil.unwrap(iter.next());
if (e instanceof ItemProviderAdapter) {
e = ((ItemProviderAdapter) e).getTarget();
if (e == null) {
// object deleted
//
iter.remove();
}
}
if (e instanceof BreakdownElement) {
BreakdownElement be = (BreakdownElement) e;
Activity superAct = be.getSuperActivities();
if (superAct == null && TngUtil.getOwningProcess(be) != be) {
iter.remove();
}
}
}
if (isEmpty())
return ""; //$NON-NLS-1$
StringBuffer strBuf = new StringBuffer();
int n = size() - 1;
for (int i = 0; i < n; i++) {
IBSItemProvider bsItemProvider = (IBSItemProvider) get(i);
if ((sup == null) || !sup.isSuppressed(bsItemProvider)) {
strBuf.append(bsItemProvider.getId()).append(',');
}
}
IBSItemProvider bsItemProvider = (IBSItemProvider) get(n);
if ((sup == null) || !sup.isSuppressed(bsItemProvider)) {
strBuf.append(bsItemProvider.getId());
}
return strBuf.toString();
}
}