blob: f4b679c58cc09dd96c5bc472cf19f3d365e585bd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2012 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 API and implementation
*******************************************************************************/
package org.eclipse.bpel.ui.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.eclipse.bpel.model.Activity;
import org.eclipse.bpel.model.Flow;
import org.eclipse.bpel.model.Link;
import org.eclipse.bpel.model.Source;
import org.eclipse.bpel.model.Sources;
import org.eclipse.bpel.model.Target;
import org.eclipse.bpel.model.Targets;
import org.eclipse.bpel.model.util.BPELUtils;
import org.eclipse.bpel.ui.commands.util.AutoUndoCommand;
import org.eclipse.bpel.ui.util.FlowLinkUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
/**
* Revalidate all the links for which the given activity(s) are the source or target.
*
* For each link, the link should be contained in the innermost enclosing Flow which
* contains both the source and the target. If there is no such flow, the link is
* deleted. If there is such a flow and the Link is not currently owned by it, the
* Link is moved into that Flow (and renamed, if necessary, to prevent naming collisions).
*/
public class RevalidateLinksCommand extends AutoUndoCommand {
List<Activity> activities;
CompoundCommand deleteLinksCmd;
public RevalidateLinksCommand(Collection activityCollection) {
super(new ArrayList(1));
this.activities = new ArrayList(activityCollection.size());
this.activities.addAll(activityCollection);
if (!activityCollection.isEmpty()) {
addModelRoot(BPELUtils.getProcess(activityCollection.iterator().next()));
}
}
// TODO: can we use the unique name support instead?
protected boolean isAcceptableLinkName(Flow flow, String proposedName) {
for (Iterator it = FlowLinkUtil.getFlowLinks(flow).iterator(); it.hasNext(); ) {
Link link = (Link)it.next();
if (proposedName.equals(link.getName())) return false;
}
return true;
}
protected void revalidateLink(Link link) {
Flow linkFlow = (Flow)(link.eContainer().eContainer());
Activity source = FlowLinkUtil.getLinkSource(link);
Activity target = FlowLinkUtil.getLinkTarget(link);
Flow commonFlow = FlowLinkUtil.getCommonFlow(source, target);
if (commonFlow == null) {
// We must delete this link. Queue it up for deletion (don't delete
// right away, as that would disturb the list(s) of sources/targets
// which we are iterating over).
deleteLinksCmd.add(new DeleteLinkCommand(link));
} else if (commonFlow != linkFlow) {
// Move this link into the commonFlow.
// First, make sure none of the links in the commonFlow has the same name!
if (!isAcceptableLinkName(commonFlow, link.getName())) {
String s;
int i = 0;
do {
++i; s = link.getName()+"_"+i; //$NON-NLS-1$
} while (!isAcceptableLinkName(commonFlow, s));
link.setName(s);
}
FlowLinkUtil.removeFlowLink(linkFlow, link);
FlowLinkUtil.addFlowLink(commonFlow, link);
}
}
@Override
public void doExecute() {
deleteLinksCmd = new CompoundCommand();
// Figure out which model objects are being moved.
HashSet revalidatingSet = new HashSet();
for (Iterator<Activity> it = activities.iterator(); it.hasNext(); ) {
Activity activity = it.next();
ModelHelper.addSubtreeToCollection(activity, revalidatingSet);
}
for (Iterator it = revalidatingSet.iterator(); it.hasNext(); ) {
Object object = it.next();
if (object instanceof Activity) {
Activity activity = (Activity)object;
Sources sources = activity.getSources();
if (sources != null) {
Iterator<Source> it2 = sources.getChildren().iterator();
while (it2.hasNext()) revalidateLink((it2.next()).getLink());
}
Targets targets = activity.getTargets();
if (targets != null) {
Iterator<Target> it2 = targets.getChildren().iterator();
while (it2.hasNext()) revalidateLink((it2.next()).getLink());
}
}
}
// delete any links that we queued up for deletion.
if (!deleteLinksCmd.isEmpty()) deleteLinksCmd.execute();
}
}