/******************************************************************************* | |
* 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(); | |
} | |
} |