blob: 581474fee7e7177cb06e1e6de0911a2d49363ba8 [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.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.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage.Literals;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CopyCommand;
import org.eclipse.emf.edit.command.CreateCopyCommand;
import org.eclipse.emf.edit.command.InitializeCopyCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.IConfigurator;
import org.eclipse.epf.library.edit.IFilter;
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.VariabilityInfo;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.util.ConfigurationSetter;
import org.eclipse.epf.library.edit.util.ConstraintManager;
import org.eclipse.epf.library.edit.util.DepthLevelAdapterFactoryTreeIterator;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ITextReferenceReplacer;
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.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.Constraint;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand;
import org.eclipse.osgi.util.NLS;
/**
* Physically copies an activity with all of its direct or inherited structural features and references.
*
* @author Phong Nguyen Le - Jun 21, 2006
* @since 1.0
*/
public class ActivityDeepCopyCommand extends CopyCommand {
private static final AdapterFactory[] adapterFactories = {
TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(),
TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory(),
TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory()
};
private static final int[] diagramTypes = {
IDiagramManager.ACTIVITY_DETAIL_DIAGRAM,
IDiagramManager.ACTIVITY_DIAGRAM,
IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM
};
public static AdapterFactory[] getAdapterFactories() {
return adapterFactories;
}
private class EditingDomain extends AdapterFactoryEditingDomain {
/**
* @param adapterFactory
* @param commandStack
*/
public EditingDomain() {
super(TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory(), new BasicCommandStack());
}
/* (non-Javadoc)
* @see org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain#createCommand(java.lang.Class, org.eclipse.emf.edit.command.CommandParameter)
*/
public Command createCommand(Class commandClass, CommandParameter commandParameter) {
if(commandClass == CreateCopyCommand.class) {
return new CreateDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
}
if(commandClass == InitializeCopyCommand.class) {
return new InitializeDeepCopyCommand(this, commandParameter.getEOwner(), (Helper) commandParameter.getValue());
}
return super.createCommand(commandClass, commandParameter);
}
}
@Override
protected void addCreateCopyCommands(CompoundCommand compoundCommand,
EObject object) {
// Operation to handle copy replacers of the child activities
//
if (copyExternalVariations && object instanceof ProcessPackage && object != this.activity.eContainer()) {
ProcessPackage pkg = (ProcessPackage)object;
boolean isReplaced = false;
Activity replacer = null;
Activity orignalActivity = null;
for(Object procesElement : pkg.getProcessElements()){
if (procesElement instanceof Activity) {
Activity childAct = (Activity) procesElement;
if(childAct.getSuperActivities() == this.activity) {
replacer = getReplacer( (Activity)procesElement );
if (replacer != null ) {
isReplaced = true;
orignalActivity = (Activity)procesElement;
}
break;
}
}
}
if (isReplaced) {
// reset the deferredInitializationCount so
// InitializeCopyCommand can be created for the following
// ActivityDeepCopyCommand. See
// org.eclipse.emf.edit.command.CopyCommand.prepare() for more
// details.
//
copyHelper.decrementDeferredInitializationCount();
ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(replacer, (CopyHelper)copyHelper, config,
targetProcess, monitor, false,activityDeepCopyConfigurator);
cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, orignalActivity));
try {
cmd.execute();
ProcessPackage pkgCopy = cmd.pkgCopy;
//basic put: original prc pkg to copied pkg based on replaced package.
((CopyHelper)copyHelper).basicPut(object, pkgCopy);
//basic put original activity to the copy of replacer activity.
((CopyHelper)copyHelper).basicPut(orignalActivity, copyHelper.get(replacer));
}finally{
cmd.dispose();
}
// restore the deferredInitializationCount so
// InitializeCopyCommand can be created for this
// ActivityDeepCopyCommand
copyHelper.incrementDeferredInitializationCount();
return;
}
}
super.addCreateCopyCommands(compoundCommand, object);
}
/**
* Checks for the replacer of activity in the copy based configuration.
*
* @param activity target activity
* @return replcacer or null if it doesn't have one
*/
protected Activity getReplacer(Activity activity){
ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
try {
if (activityDeepCopyConfigurator != null ) {
MethodConfiguration currentConfig = configSetter.getOldConfiguration();
MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
: targetProcess.getDefaultContext())
: config;
activityDeepCopyConfigurator.setMethodConfiguration(copyConfig);
VariabilityInfo variabilityInfo = activityDeepCopyConfigurator.getVariabilityInfo(activity);
if (variabilityInfo != null && ! variabilityInfo.getInheritanceList().isEmpty() ) {
Activity replacer = (Activity)variabilityInfo.getInheritanceList().get(0);
return replacer == activity ? null : replacer;
}
}
return null;
} finally{
if (configSetter != null ) {
configSetter.restore();
}
}
}
/**
* Checks for the contributors of activity in the copy based configuration.
* @param activity
* @return a list including contributors or empty list
*/
protected List getContributors(Activity activity){
ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
try {
if (activityDeepCopyConfigurator != null ) {
MethodConfiguration currentConfig = configSetter.getOldConfiguration();
MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
: targetProcess.getDefaultContext())
: config;
activityDeepCopyConfigurator.setMethodConfiguration(copyConfig);
VariabilityInfo variabilityInfo = activityDeepCopyConfigurator.getVariabilityInfo(activity);
if (variabilityInfo != null ) {
return variabilityInfo.getContributors();
}
}
return Collections.EMPTY_LIST;
} finally{
if (configSetter != null ) {
configSetter.restore();
}
}
}
private class CreateDeepCopyCommand extends CreateCopyCommand {
/**
* @param domain
* @param owner
* @param copyHelper
*/
public CreateDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
super(domain, owner, copyHelper);
}
/* (non-Javadoc)
* @see org.eclipse.emf.edit.command.CreateCopyCommand#doGetChildrenToCopy()
*/
public Collection<?> doGetChildrenToCopy() {
ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
try {
configSetter.set(config);
IConfigurator configurator = configSetter.getConfigurator();
// Create commands to create copies of the children.
//
List<Object> result = new ArrayList<Object>();
for (Iterator<EObject> i = owner.eContents().iterator(); i.hasNext(); )
{
Object o = i.next();
if(o instanceof Activity) {
// make sure that Activity will be copied first
// so references to its inherited elements can be resolved
// properly
//
if(configurator == null || configurator.accept(o)) {
result.add(0, o);
}
}
else {
result.add(o);
}
}
return result;
}
finally {
configSetter.restore();
}
}
}
private class InitializeDeepCopyCommand extends MethodElementInitializeCopyCommand {
/**
* List of GUIDs of activity starting from the top process to
*/
private List<String> guidList;
/**
* @param domain
* @param owner
* @param copyHelper
*/
public InitializeDeepCopyCommand(EditingDomain domain, EObject owner, Helper copyHelper) {
super(domain, owner, copyHelper);
copy = (EObject) copyHelper.get(owner);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.edit.command.MethodElementInitializeCopyCommand#copyReferences()
*/
protected void copyReferences() {
Activity base = null;
Activity baseCopy = null;
Collection<Object> childBaseCopies = new HashSet<Object>();
ConfigurationSetter configSetter = null;
IConfigurator configurator = null;
boolean baseAccepted = false;
try {
if(owner instanceof Activity) {
Activity activity = (Activity) owner;
if(ProcessUtil.isExtendingOrLocallyContributing(activity)) {
configSetter = new ConfigurationSetter(getAdapterFactory());
configSetter.set(config);
configurator = configSetter.getConfigurator();
// copy inherited elements by deep-copying base activity
//
// deep copy of base activity at this point is essential so references to predecessors
// will be copied correctly
//
base = (Activity) activity.getVariabilityBasedOnElement();
baseAccepted = configurator == null || configurator.accept(base);
if(baseAccepted) {
CopyHelper helper = (CopyHelper)copyHelper;
Activity oldBaseCopy = (Activity) helper.get(base);
// this will redirect any reference to copy of base in diagram to the copy of the activity
//
helper.putVariabilityElement(base, activity);
ArrayList childBases = new ArrayList();
for (Iterator iter = activity.getBreakdownElements().iterator(); iter.hasNext();) {
Object e = iter.next();
if(e instanceof VariabilityElement) {
VariabilityElement ve = (VariabilityElement) e;
VariabilityElement baseElement = ve.getVariabilityBasedOnElement();
if(baseElement != null &&
(ve.getVariabilityType() == VariabilityType.LOCAL_CONTRIBUTION || ve.getVariabilityType() == VariabilityType.LOCAL_REPLACEMENT))
{
helper.putVariabilityElement(baseElement, ve);
childBases.add(baseElement);
}
}
}
ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(base, helper, config, targetProcess, monitor, false,activityDeepCopyConfigurator);
cmd.copyExternalVariations = copyExternalVariations;
cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, activity));
try {
cmd.execute();
baseCopy = (Activity) helper.get(base);
if(activity.getVariabilityType() == VariabilityType.EXTENDS) {
// keep activity only as backup copy of base
//
helper.removeVariabilityElement(base);
helper.putBackupCopy(base, activity);
// put back oldBaseCopy
if(oldBaseCopy != null) {
helper.basicPut(base, oldBaseCopy);
}
}
// remove the copies of all base since base copies are not added to the process
//
helper.remove(base);
for (Iterator iter = childBases.iterator(); iter.hasNext();) {
EObject childBaseCopy = (EObject) helper.remove(iter.next());
if(childBaseCopy != null) {
childBaseCopies.add(childBaseCopy);
EcoreUtil.remove(childBaseCopy.eContainer());
}
}
Activity activityCopy = (Activity) copy;
// remove the copies of base diagram if the activity already have diagram of the same type
//
for (int i = 0; i < diagramTypes.length; i++) {
int type = diagramTypes[i];
if(diagramMgr.getDiagram(activity, type) != null) {
Diagram diagram = diagramMgr.getDiagram(activityCopy, type);
if(diagram != null) {
EcoreUtil.remove(diagram);
}
}
}
// move content of base package over to the activity's package
//
moveContent(cmd.pkgCopy, activityCopy);
// record the copy of the wrappers
//
for (Iterator iterator = baseCopy.getBreakdownElements().iterator(); iterator
.hasNext();) {
BreakdownElement e = (BreakdownElement) iterator.next();
if(!childBaseCopies.contains(e)) {
BreakdownElement original = (BreakdownElement) helper.getOriginal(e);
List<String> list = new ArrayList<String>(cmd.guidList);
list.add(original.getGuid());
helper.putWrapperCopy(ProcessUtil.toGuidPath(list), e);
}
}
}
finally {
cmd.dispose();
}
}
}
}
super.copyReferences();
if(base != null) {
Activity activity = (Activity) owner;
Activity activityCopy = ((Activity) copy);
if(baseAccepted) {
// copy inherited breakdown elements from the base activity in the right order
//
MethodConfiguration currentConfig = configSetter.getOldConfiguration();
// Add breakdown elements from base copy to the activity copy.
// Don't add copy of base element of the existing children
//
List<BreakdownElement> breakdownElements = new ArrayList<BreakdownElement>();
for (Iterator<BreakdownElement> iter = baseCopy.getBreakdownElements().iterator(); iter.hasNext();) {
BreakdownElement e = iter.next();
if(!childBaseCopies.contains(e) && (configurator == null || configurator.accept(e))) {
breakdownElements.add(e);
}
}
activityCopy.getBreakdownElements().addAll(0, breakdownElements);
baseCopy.setSuperActivities(null);
EcoreUtil.remove(baseCopy);
// copy other string attributes as well after realize them
//
MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
: targetProcess.getDefaultContext())
: config;
for (EAttribute attribute : getAttributesToCopy()) {
if (attribute.isChangeable() && !attribute.isDerived()) {
Object value = Providers.getConfigurationApplicator().getAttribute(activity, attribute, copyConfig);
activityCopy.eSet(attribute, value);
}
}
ContentDescription content = activity.getPresentation();
for (EAttribute attribute : content.eClass().getEAllAttributes()) {
if (attribute.isChangeable() && !attribute.isDerived()
&& attribute.getEAttributeType().getInstanceClass() == Literals.STRING.getInstanceClass())
{
Object value = Providers.getConfigurationApplicator().getAttribute(content, activity, attribute, copyConfig);
activityCopy.getPresentation().eSet(attribute, value);
}
}
}
// copy presentation name
//
activityCopy.setPresentationName(ProcessUtil.getPresentationName(activity));
}
// copy contributors
if (copyExternalVariations && owner instanceof Activity && (copyContributors || owner != ActivityDeepCopyCommand.this.activity)) {
Activity activity = (Activity)owner;
List contributors = getContributors(activity);
if (!contributors.isEmpty()) {
doCopyContributors(contributors,activity);
}
}
// clear the variability data
//
if (copy instanceof Activity) {
Activity activityCopy = ((Activity) copy);
activityCopy.setVariabilityBasedOnElement(null);
activityCopy.setVariabilityType(null);
}
}
finally {
if(configSetter != null) {
configSetter.restore();
}
}
if(copy instanceof Activity) {
Activity activityCopy = ((Activity) copy);
// clear suppression data
//
Constraint rule = ConstraintManager.getConstraint(activityCopy, ConstraintManager.PROCESS_SUPPRESSION, false);
if(rule != null) {
EcoreUtil.remove(rule);
}
}
}
/**
* Copy contributors
* @param contributors
*/
protected void doCopyContributors(List contributors, Activity owner ) {
ConfigurationSetter configSetter = new ConfigurationSetter(getAdapterFactory());
try {
MethodConfiguration currentConfig = configSetter.getOldConfiguration();
MethodConfiguration copyConfig = config == null ? (currentConfig != null ? currentConfig
: targetProcess.getDefaultContext())
: config;
configSetter.set(copyConfig);
IConfigurator configurator = configSetter.getConfigurator();
for (Iterator iterator = contributors.iterator(); iterator.hasNext();) {
Activity contributedActivity = (Activity) iterator.next();
CopyHelper helper = (CopyHelper)copyHelper;
Activity contributorCopy = (Activity) helper.get(contributedActivity);
ActivityDeepCopyCommand cmd = new ActivityDeepCopyCommand(contributedActivity, helper,
config, targetProcess, monitor, false,activityDeepCopyConfigurator);
cmd.copyContributors = false; // don't copy contributor's contributors since they already are included in the given contributors list
cmd.guidList = new LinkedList<String>(ActivityDeepCopyCommand.this.guidList);
cmd.guidList.addAll(ProcessUtil.getGuidList(ActivityDeepCopyCommand.this.activity, owner));
try {
cmd.execute();
contributorCopy = (Activity) helper.get(contributedActivity);
Activity activityCopy = (Activity) copy;
// remove the copies of base diagram if the activity already have diagram of the same type
//
for (int i = 0; i < diagramTypes.length; i++) {
int type = diagramTypes[i];
if(diagramMgr.getDiagram(activity, type) != null) {
Diagram diagram = diagramMgr.getDiagram(activityCopy, type);
if(diagram != null) {
EcoreUtil.remove(diagram);
}
}
}
// move content of base package over to the activity's package
//
moveContent(cmd.pkgCopy, activityCopy);
List<BreakdownElement> breakdownElements = new ArrayList<BreakdownElement>();
for (Iterator<BreakdownElement> iter = contributorCopy.getBreakdownElements().iterator(); iter.hasNext();) {
BreakdownElement e = iter.next();
if(configurator == null || configurator.accept(e)){
breakdownElements.add(e);
}
}
activityCopy.getBreakdownElements().addAll(breakdownElements);
contributorCopy.setSuperActivities(null);
EcoreUtil.remove(contributorCopy);
}
finally {
cmd.dispose();
}
}
}finally{
if (configSetter != null ) {
configSetter.restore();
}
}
}
}
protected ProcessPackage pkgCopy;
protected MethodConfiguration config;
protected IDiagramManager diagramMgr;
protected Process targetProcess;
protected IProgressMonitor monitor;
protected Activity activity;
private LinkedList<String> guidList;
private BreakdownElementWrapperItemProvider wrapper;
//used to retrieve replacers and contributors
private IConfigurator activityDeepCopyConfigurator;
private boolean copyExternalVariations = true;
private boolean copyContributors = true;
private ActivityDeepCopyCommand(Activity activity, CopyHelper copyHelper,
MethodConfiguration config, Process targetProcess,
IProgressMonitor monitor, boolean initGuidList,IConfigurator activityDeepCopyConfigurator) {
super(null, activity.eContainer(), copyHelper);
Assert.isTrue(activity.eContainer() instanceof ProcessPackage, "Activity's container must be a ProcessPackage"); //$NON-NLS-1$
this.activity = activity;
domain = new EditingDomain();
this.config = config;
this.targetProcess = targetProcess;
diagramMgr = ExtensionManager.getDiagramManager();
Assert.isNotNull(diagramMgr, "Could not load diagram manager"); //$NON-NLS-1$
this.monitor = monitor;
if(initGuidList) {
guidList = ProcessUtil.getGuidList(null, this.activity);
}
this.activityDeepCopyConfigurator = activityDeepCopyConfigurator;
}
public ActivityDeepCopyCommand(Activity activity, CopyHelper copyHelper,
MethodConfiguration config, Process targetProcess,
IProgressMonitor monitor, IConfigurator activityDeepCopyConfigurator) {
this(activity, copyHelper, config, targetProcess, monitor, true,activityDeepCopyConfigurator);
}
public ActivityDeepCopyCommand(Object activityOrWrapper, CopyHelper copyHelper, MethodConfiguration config,
Process targetProcess, IProgressMonitor monitor, IConfigurator activityDeepCopyConfigurator) {
this((Activity)TngUtil.unwrap(activityOrWrapper), copyHelper, config, targetProcess, monitor,
activityOrWrapper instanceof Activity,activityDeepCopyConfigurator);
if(activityOrWrapper instanceof BreakdownElementWrapperItemProvider) {
wrapper = (BreakdownElementWrapperItemProvider) activityOrWrapper;
guidList = ProcessUtil.getGuidList(wrapper);
}
}
public void setCopyExternalVariations(boolean copyExternalVariations) {
this.copyExternalVariations = copyExternalVariations;
}
public AdapterFactory getAdapterFactory() {
return ((AdapterFactoryEditingDomain)domain).getAdapterFactory();
}
/* (non-Javadoc)
* @see org.eclipse.emf.edit.command.CopyCommand#execute()
*/
public void execute() {
monitor.subTask(NLS.bind(LibraryEditResources.copyingActivities_msg, ProcessUtil.getPresentationName(activity)));
super.execute();
Collection<?> result = super.getResult();
if(!result.isEmpty()) {
pkgCopy = (ProcessPackage) result.iterator().next();
fixProcessComponent();
replaceTextReferences();
}
}
/**
* fix the process component to make it a process package.
* This method might be overriden by subclass to achive difference result.
* For example,
*/
protected void fixProcessComponent() {
if(pkgCopy instanceof ProcessComponent) {
// replace the ProcessComponent with a equivalent ProcessPackage
//
ProcessPackage pkg = UmaFactory.eINSTANCE.createProcessPackage();
Collection features = new ArrayList(pkgCopy.eClass().getEAllStructuralFeatures());
features.retainAll(pkg.eClass().getEAllStructuralFeatures());
for (Iterator iter = features.iterator(); iter.hasNext();) {
EStructuralFeature feature = (EStructuralFeature) iter.next();
Object value = pkgCopy.eGet(feature);
pkg.eSet(feature, value);
}
Process proc = ((ProcessComponent)pkgCopy).getProcess();
if(proc != null) {
pkg.getProcessElements().add(0, proc);
}
pkgCopy = pkg;
}
}
/**
* If textual descriptions in the copied elements contain references (URLs) to other elements
* within the same copied process then replace these references with references that point to
* the new elements in the copied structures.
*/
protected void replaceTextReferences() {
ITextReferenceReplacer txtRefReplacer = ExtensionManager.getTextReferenceReplacer();
if(txtRefReplacer == null) return;
Map oldToNewObjectMap = ((CopyHelper) copyHelper).getObjectToCopyMap();
for (Iterator iter = pkgCopy.eAllContents(); iter.hasNext();) {
EObject element = (EObject) iter.next();
for (Iterator attributes = element.eClass().getEAllAttributes().iterator(); attributes.hasNext(); )
{
EAttribute attribute = (EAttribute) attributes.next();
if (attribute.isChangeable() && !attribute.isDerived() && (attribute.isMany() || element.eIsSet(attribute))
&& attribute.getEAttributeType().getInstanceClass() == Literals.STRING.getInstanceClass())
{
String text = (String) element.eGet(attribute);
if(text != null) {
text = txtRefReplacer.replace(text, targetProcess, oldToNewObjectMap);
element.eSet(attribute, text);
}
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.emf.common.command.CompoundCommand#getResult()
*/
public Collection<?> getResult() {
if(pkgCopy != null) {
Activity act = ProcessUtil.findActivity(pkgCopy);
if(act != null) {
return Collections.singletonList(act);
}
}
return Collections.EMPTY_LIST;
}
/**
* Moves content of source object <code>src</code> over to the target objec <code>target</code>
* @param src
* @param target
*/
private static void moveContent(ProcessPackage src, Activity act) {
ProcessPackage target = (ProcessPackage) act.eContainer();
// move content of base package over to the activity's package
for (Iterator iter = new ArrayList(src.eContents()).iterator(); iter.hasNext();) {
EObject e = (EObject) iter.next();
EStructuralFeature f = e.eContainingFeature();
if(f.isMany()) {
((List)target.eGet(f)).add(e);
}
}
if(src instanceof ProcessComponent) {
Process baseCopy = ((ProcessComponent)src).getProcess();
target.getProcessElements().add(baseCopy);
}
}
private static BreakdownElement getTopElement(BreakdownElement e) {
if(e == null) {
return null;
}
BreakdownElement top = e;
for(BreakdownElement o = e.getSuperActivities(); o != null; o = o.getSuperActivities()) {
top = o;
}
return top;
}
public void copySuppressionStates() {
Collection<?> result = getResult();
if(result.isEmpty()) {
return;
}
String wrapperPath = wrapper != null ? ProcessUtil.toGuidPath(guidList) : null;
for (int i = 0; i < adapterFactories.length; i++) {
AdapterFactory adapterFactory = adapterFactories[i];
boolean isWBS = adapterFactory == TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
IFilter filter = ProcessUtil.getFilter(adapterFactory);
IConfigurator configurator = null;
MethodConfiguration currentConfig = null;
if(filter instanceof IConfigurator) {
configurator = (IConfigurator) filter;
currentConfig = configurator.getMethodConfiguration();
configurator.setMethodConfiguration(config);
}
try {
Activity act = ProcessUtil.findActivity((ProcessPackage) owner);
ProcessUtil.initializeItemProviderPath(act, adapterFactory);
Process proc = TngUtil.getOwningProcess(act);
Suppression suppression = Suppression.getSuppression(proc);
DepthLevelAdapterFactoryTreeIterator<?> iter = new DepthLevelAdapterFactoryTreeIterator<Object>(adapterFactory, proc);
int depthLevel = -1;
find_deep_copied_activity:
while(iter.hasNext()) {
Object child = iter.next();
// set depth level if the current child is the deep-copied activity
//
if(wrapper == null) {
if(child == activity) {
depthLevel = iter.getDepthLevel();
break find_deep_copied_activity;
}
}
else {
if(child instanceof BreakdownElementWrapperItemProvider) {
String path = Suppression.getPathWithoutViewType((BreakdownElementWrapperItemProvider) child).toString();
if(wrapperPath.equals(path)) {
depthLevel = iter.getDepthLevel();
break find_deep_copied_activity;
}
}
}
}
// copy suppression state of all suppressed elements under deep-copied activity
//
CopyHelper helper = (CopyHelper)copyHelper;
Map<?, ?> originalToCopyMap = helper.getObjectToCopyMap();
Map<Object, Object> elementOrWrapperToCopyMap = null;
if(isWBS) {
elementOrWrapperToCopyMap = new HashMap<Object, Object>();
Activity deepCopy = (Activity) result.iterator().next();
elementOrWrapperToCopyMap.put(wrapper != null ? wrapper : activity, deepCopy);
}
while(iter.hasNext()) {
Object child = iter.next();
if(iter.getDepthLevel() > depthLevel) {
Object e = TngUtil.unwrap(child);
if(e instanceof BreakdownElement) {
if(!isWBS && e instanceof Activity) {
// skip copying suppression state and ordering
// breakdown elements for activity in other view
// than WBS
//
continue;
}
// BreakdownElement original = (BreakdownElement) e;
// BreakdownElement copy = (BreakdownElement) originalToCopyMap.get(original);
//
// if(TngUtil.DEBUG) {
// String copyName = (copy != null ? copy.getName() : null);
// BreakdownElement top = getTopElement(copy);
// if(copy == null || !original.getName().equals(copyName) || top != deepCopy) {
// System.err.println("original: '" + original.getName() + "', copy: '" + copyName + "', copy's top activity: " + top);
// }
// }
BreakdownElement copy = null;
boolean isSuppressed = suppression.isSuppressed(child);
// find copy to suppress or, if element is an activity, to reorder its breakdown elements
//
if(isSuppressed || isWBS) {
if(child == e) {
copy = (BreakdownElement) originalToCopyMap.get(e);
}
else if(child instanceof BreakdownElementWrapperItemProvider) {
BreakdownElementWrapperItemProvider childWrapper = (BreakdownElementWrapperItemProvider) child;
if(childWrapper.isInherited()) {
String guidPath = Suppression.getPathWithoutViewType(childWrapper).toString();
copy = helper.getWrapperCopy(guidPath);
}
}
if(copy != null) {
if(isSuppressed) {
copy.setSuppressed(Boolean.TRUE);
}
if(isWBS) {
elementOrWrapperToCopyMap.put(child, copy);
}
}
}
}
}
else {
break;
}
}
// reorder breakdown elements of activities
//
if(isWBS) {
for (Map.Entry<Object, Object> entry : elementOrWrapperToCopyMap.entrySet()) {
Object o = entry.getKey();
Object copy = entry.getValue();
if(copy instanceof Activity) {
ITreeItemContentProvider ip = (ITreeItemContentProvider) adapterFactory.adapt(o, ITreeItemContentProvider.class);
Collection<?> children = ip.getChildren(o);
EList<?> list = (EList<?>) ((Activity) copy).getBreakdownElements();
List<?> childrenList = children instanceof List<?> ? (List<?>) children : new ArrayList<Object>(children);
int size = childrenList.size();
for (int j = 0; j < size; j++) {
Object child = childrenList.get(j);
Object childCopy = elementOrWrapperToCopyMap.get(child);
if(childCopy != null) {
if(j < size - 1) {
Object nextChild = childrenList.get(j + 1);
Object nextChildCopy = elementOrWrapperToCopyMap.get(nextChild);
if(nextChildCopy != null) {
int succId = list.indexOf(nextChildCopy);
if(succId != -1) {
int id = list.indexOf(childCopy);
if(id != succId - 1) {
if(id < succId) {
list.move(succId - 1, id);
}
else {
list.move(id, succId);
}
}
}
}
else if(TngUtil.DEBUG) {
System.err.println("Element does not have copy: " + nextChild); //$NON-NLS-1$
}
}
}
else if(TngUtil.DEBUG) {
System.err.println("Element does not have copy: " + child); //$NON-NLS-1$
}
}
}
}
}
}
finally {
if(configurator != null) {
configurator.setMethodConfiguration(currentConfig);
}
}
}
}
public CopyHelper getCopyHelper() {
return (CopyHelper) copyHelper;
}
}