blob: c27e3cb4feae5deadce283074eb8e85748294bfc [file] [log] [blame]
package org.eclipse.epf.library.realization.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.meta.TypeDefUtil;
import org.eclipse.epf.library.edit.process.command.CustomizeDescriptorCommand;
import org.eclipse.epf.library.edit.process.command.ProcessCommandUtil;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.realization.IRealizedDescriptor;
import org.eclipse.epf.library.edit.realization.IRealizedElement;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.PropUtil;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
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.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
public class RealizationManager implements IRealizationManager {
private Map<MethodElement, IRealizedElement> elementMap;
private MethodConfiguration config;
private MethodConfiguration dynamicConfig;
private boolean caching = false;
private IPerspectiveListener perspectiveListener;
private boolean localTiming = true;
public boolean isCaching() {
return caching;
}
public void setCaching(boolean caching) {
this.caching = caching;
}
private Map<MethodElement, IRealizedElement> getElementMap() {
if (elementMap == null) {
elementMap = new HashMap<MethodElement, IRealizedElement>();
}
return elementMap;
}
public RealizationManager(MethodConfiguration config) {
this.config = config;
init();
}
public void clearCacheData() {
for (IRealizedElement element : getElementMap().values()) {
((RealizedElement) element).dispose();
}
elementMap = null;
}
public void dispose() {
clearCacheData();
IWorkbenchWindow window = LibraryUtil.getActiveWorkbenchWindow();
if (window != null && perspectiveListener != null) {
window.removePerspectiveListener(perspectiveListener);
}
}
public MethodConfiguration getConfig() {
if (config == null) { //Default RealizationManager instance would not have a null config
return dynamicConfig;
}
return config;
}
public IRealizedElement getRealizedElement(MethodElement element) {
IRealizedElement rElement = getElementMap().get(element);
if (rElement == null) {
rElement = newRealizedElement(element);
getElementMap().put(element, rElement);
}
return rElement;
}
public IRealizedElement removeRealizedElement(MethodElement element) {
return getElementMap().remove(element);
}
private void init() {
IWorkbenchWindow window = LibraryUtil.getActiveWorkbenchWindow();
if (window != null) {
perspectiveListener = new IPerspectiveListener() {
public void perspectiveActivated(IWorkbenchPage page,
IPerspectiveDescriptor desc) {
clearCacheData();
}
public void perspectiveChanged(IWorkbenchPage page,
IPerspectiveDescriptor desc, String id) {
clearCacheData();
}
};
window.addPerspectiveListener(perspectiveListener);
}
}
private IRealizedElement newRealizedElement(MethodElement element) {
RealizedElement rElement = null;
if (element instanceof TaskDescriptor) {
rElement = new RealizedTaskDescriptor((TaskDescriptor) element);
} else if (element instanceof RoleDescriptor) {
rElement = new RealizedRoleDescriptor((RoleDescriptor) element);
} else if (element instanceof WorkProductDescriptor) {
rElement = new RealizedWorkProductDescriptor((WorkProductDescriptor) element);
} else if (element instanceof BreakdownElement) {
rElement = new RealizedBreakdownElement((BreakdownElement) element);
}
rElement.setMgr(this);
return rElement;
}
private MethodElement getLinkedElement(MethodElement element) {
if (element instanceof RoleDescriptor) {
return ((RoleDescriptor) element).getRole();
}
if (element instanceof WorkProductDescriptor) {
return ((WorkProductDescriptor) element).getWorkProduct();
}
if (element instanceof TaskDescriptor) {
return ((TaskDescriptor) element).getTask();
}
return PropUtil.getPropUtil().getLinkedElement(element);
}
public Descriptor getDescriptor(Descriptor referencingDes, Activity parentAct, MethodElement element, EReference feature) {
Descriptor descriptor = getDescriptor_(referencingDes, parentAct, element, feature);
if (feature == IRealizedDescriptor.ArtifactDescriptor_ContainedArtifacts) {
return descriptor;
}
boolean oldDeliver = referencingDes.eDeliver();
referencingDes.eSetDeliver(false);
LibraryEditUtil libEditUtil = LibraryEditUtil.getInstance();
try {
if (feature.isMany()) {
// List listValue = (List) referencingDes.eGet(feature);
List listValue = (List) TypeDefUtil.getInstance().eGet(referencingDes, feature, true);
if (listValue != null) {
listValue.add(descriptor);
libEditUtil.addOppositeFeature(referencingDes, descriptor, feature);
}
} else {
referencingDes.eSet(feature, descriptor);
libEditUtil.addOppositeFeature(referencingDes, descriptor, feature);
}
} finally {
referencingDes.eSetDeliver(oldDeliver);
}
return descriptor;
}
private Descriptor getDescriptor_(Descriptor referencingDes, Activity parentAct, MethodElement element, EReference feature) {
if (parentAct == null) {
return null;
}
Object foundDes = ProcessCommandUtil.getBestDescriptor(element, parentAct, getConfig());
if (foundDes instanceof Descriptor) {
return (Descriptor) foundDes;
}
foundDes = ProcessCommandUtil.getInheritedDescriptor(element, parentAct, getConfig());
if (foundDes instanceof Descriptor) {
return (Descriptor) foundDes;
}
Descriptor descriptor = null;
if (element instanceof Role) {
RoleDescriptor rd = UmaFactory.eINSTANCE.createRoleDescriptor();
rd.setRole((Role) element);
descriptor = rd;
} else if (element instanceof Task) {
TaskDescriptor td = UmaFactory.eINSTANCE.createTaskDescriptor();
td.setTask((Task) element);
descriptor = td;
} else if (element instanceof WorkProduct) {
WorkProductDescriptor wpd = UmaFactory.eINSTANCE.createWorkProductDescriptor();
wpd.setWorkProduct((WorkProduct) element);
descriptor = wpd;
}
if (debug) {
System.out.println("LD> Creating descriptor: " + descriptor); //$NON-NLS-1$
}
if (descriptor == null) {
return null;
}
DescriptorPropUtil.getDesciptorPropUtil().setCreatedByReference(descriptor, true);
String presentationName = element.getPresentationName();
descriptor.setName(element.getName());
descriptor.setPresentationName(StrUtil.isBlank(presentationName) ? element
.getName() : presentationName);
String guid = UmaUtil.generateGUID();
descriptor.setBriefDescription(element.getBriefDescription());
addToProcess(parentAct, descriptor, feature);
return descriptor;
}
private void addToProcess(Activity parent, Descriptor referencedDes,
EReference feature) {
UmaPackage up = UmaPackage.eINSTANCE;
ProcessPackage pkg = (ProcessPackage) parent.eContainer();
boolean oldParentDeliver = parent.eDeliver();
boolean oldPkgDeliver = pkg.eDeliver();
boolean oldReferencedDesDeliver = referencedDes.eDeliver();
parent.eSetDeliver(false);
pkg.eSetDeliver(false);
try {
parent.getBreakdownElements().add(referencedDes);
pkg.getProcessElements().add(referencedDes);
if (feature == up.getWorkProductDescriptor_DeliverableParts()) {
referencedDes.eSetDeliver(false);
referencedDes.setSuperActivities(null);
}
} finally {
parent.eSetDeliver(oldParentDeliver);
pkg.eSetDeliver(oldPkgDeliver);
if (referencedDes.eDeliver() != oldReferencedDesDeliver) {
referencedDes.eSetDeliver(oldReferencedDesDeliver);
}
}
}
public void updateProcessModel(Process proc) {
clearCacheData();
setCaching(true);
updateProcessModel(proc, new HashSet<Activity>());
clearCacheData();
setCaching(false);
}
public void elementUpdateProcessModel(Process proc,
Set<MethodElement> changedElementSet) {
Set<Activity> actCollectedSet = new HashSet<Activity>();
collectActivitiesToUpdate(proc, actCollectedSet,
new HashSet<Activity>(), changedElementSet);
Set<Activity> updatedActSet = new HashSet<Activity>();
clearCacheData();
setCaching(true);
for (Activity act : actCollectedSet) {
this.updateModelImpl(act, updatedActSet, false);
}
clearCacheData();
setCaching(false);
}
private void collectActivitiesToUpdate(Activity act,
Set<Activity> actCollectedSet, Set<Activity> actProcessedSet,
Set<MethodElement> changedElementSet) {
if (actProcessedSet.contains(act)) { // extra precaution to prevent infinite loop
return;
}
actProcessedSet.add(act);
Activity baseAct = (Activity) act.getVariabilityBasedOnElement();
if (baseAct != null) {
collectActivitiesToUpdate(baseAct, actCollectedSet, actProcessedSet, changedElementSet);
}
List<BreakdownElement> beList = act.getBreakdownElements();
for (int i = 0; i < beList.size(); i++) {
BreakdownElement be = beList.get(i);
if (!actCollectedSet.contains(act)) {
MethodElement element = getLinkedElement(be);
if (element != null) {
if (changedElementSet.contains(element)) {
actCollectedSet.add(act);
} else if (be instanceof Descriptor) {
if (changedElementSet.contains(be)) {
actCollectedSet.add(act);
}
}
}
}
if (be instanceof Activity) {
collectActivitiesToUpdate((Activity) be, actCollectedSet,
actProcessedSet, changedElementSet);
}
}
}
private void updateProcessModel(Process proc, Set<Activity> updatedActSet) {
if (! ProcessUtil.isSynFree()) {
if (! ProcessScopeUtil.getInstance().isConfigFree(proc)) {
return;
}
}
if (! canBeAutoSyned(proc)) {
return;
}
long time = 0;
if (timing && localTiming) {
time = System.currentTimeMillis();
}
updateModelImpl(proc, updatedActSet, true);
if (timing && localTiming) {
time = System.currentTimeMillis() - time;
System.out.println("LD> updateModel: " + time); //$NON-NLS-1$
}
}
public void updateActivityModel(Activity act) {
if (act instanceof Process) {
if (! canBeAutoSyned((Process) act)) {
return;
}
}
clearCacheData();
setCaching(true);
updateModelImpl(act, new HashSet<Activity>(), false);
clearCacheData();
setCaching(false);
}
private void updateModelImpl(Activity act, Set<Activity> updatedActSet, boolean recursive) {
if (updatedActSet.contains(act)) {
return;
}
//System.out.println("LD> updateModelImpl, act: " + act);
updatedActSet.add(act);
Activity baseAct = (Activity) act.getVariabilityBasedOnElement();
if (baseAct != null) {
updateModelImpl(baseAct, updatedActSet, recursive);
}
if (! ProcessUtil.isSynFree()) {
Process proc = ProcessUtil.getProcess(act);
if (proc == null || ! ProcessScopeUtil.getInstance().isConfigFree(proc)) {
return;
}
}
if (config == null) {
Process proc = ProcessUtil.getProcess(act);
Scope scope = ProcessScopeUtil.getInstance().getScope(proc);
if (scope != null) {
dynamicConfig = scope;
} else {
dynamicConfig = LibraryService.getInstance()
.getCurrentMethodConfiguration();
}
}
DescriptorPropUtil propUtil = DescriptorPropUtil.getDesciptorPropUtil();
Set<Descriptor> tdReferencedSet = new HashSet<Descriptor>();
Set<Descriptor> seenSet = new HashSet<Descriptor>();
List<Descriptor> rdwpdList = new ArrayList<Descriptor>();
List<BreakdownElement> beList = act.getBreakdownElements();
Set<Descriptor> localUseSet = new HashSet<Descriptor>();
for (int i = 0; i < beList.size(); i++) {
BreakdownElement be = beList.get(i);
if (be instanceof Activity) {
if (recursive) {
updateModelImpl((Activity) be, updatedActSet, recursive);
}
} else if (be instanceof TaskDescriptor) {
TaskDescriptor td = (TaskDescriptor) be;
Descriptor greenParent = propUtil.getGreenParentDescriptor(td);
if (greenParent != null) {
CustomizeDescriptorCommand.updateFromGreenParent(greenParent, td, false);
}
collectAllReferences(td, tdReferencedSet, seenSet);
} else if (be instanceof RoleDescriptor) {
RoleDescriptor rd = (RoleDescriptor) be;
rdwpdList.add(rd);
} else if (be instanceof WorkProductDescriptor) {
WorkProductDescriptor wpd = (WorkProductDescriptor) be;
rdwpdList.add(wpd);
}
if (be instanceof Descriptor) {
localUseSet.addAll(propUtil.getLocalUsedDescriptors((Descriptor) be));
}
}
Set<Descriptor> toRemovedSet = new HashSet<Descriptor>();
for (Descriptor des : rdwpdList) {
collectAllReferences(des, null, seenSet);
if (des instanceof TaskDescriptor || localUseSet.contains(des) ||
! propUtil.isCreatedByReference(des)) {
continue;
}
if (!tdReferencedSet.contains(des)) {
// act.getBreakdownElements().remove(des);
toRemovedSet.add(des);
}
}
for (Descriptor des : toRemovedSet) {
if (! ProcessUtil.checkDescriptorReferences(toRemovedSet, des)) {
act.getBreakdownElements().remove(des);
}
}
beList = act.getBreakdownElements();
for (int i = 0; i < beList.size(); i++) {
BreakdownElement be = beList.get(i);
if (be instanceof Descriptor) {
RealizedDescriptor rdes = (RealizedDescriptor) getRealizedElement(be);
rdes.updateStringValues();
} else {
RealizedBreakdownElement rBe = (RealizedBreakdownElement) getRealizedElement(be);
rBe.updateAndGetAllReferenced();
rBe.updateStringValues();
}
}
}
private void collectAllReferences(Descriptor des, Set<Descriptor> collectingSet, Set<Descriptor> seenSet) {
if (seenSet.contains(des)) {
return;
}
seenSet.add(des);
RealizedDescriptor rdes = (RealizedDescriptor) getRealizedElement(des);
Set<Descriptor> references = rdes.updateAndGetAllReferenced();
if (collectingSet != null) {
collectingSet.addAll(references);
}
for (Descriptor ref : references) {
collectAllReferences(ref, collectingSet, seenSet);
}
}
public void updateAllProcesseModels() {
boolean oldLocalTiming = localTiming;
long time = 0;
if (timing) {
time = System.currentTimeMillis();
localTiming = false;
}
Set<Activity> updatedActSet = new HashSet<Activity>();
clearCacheData();
setCaching(true);
for (Process proc : LibraryEditUtil.getInstance().collectProcessesFromConfig(
getConfig())) {
updateProcessModel(proc, updatedActSet);
}
clearCacheData();
setCaching(false);
if (timing) {
time = System.currentTimeMillis() - time;
System.out.println("LD> beginPublish: " + time); //$NON-NLS-1$
localTiming = oldLocalTiming;
}
}
private boolean canBeAutoSyned(Process proc) {
boolean ret = ConfigurationHelper.getDelegate().canBeConfigFree(proc);
return ret;
}
}