/*******************************************************************************
* Copyright (c) 2012, 2014 Wind River Systems, Inc. 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:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.tcf.te.tcf.processes.ui.handler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.tcf.protocol.Protocol;
import org.eclipse.tcf.te.runtime.callback.Callback;
import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
import org.eclipse.tcf.te.tcf.processes.core.model.interfaces.IProcessContextNode;
import org.eclipse.tcf.te.tcf.processes.core.model.steps.AttachStep;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Attach to process command handler implementation.
*/
public class AttachHandler extends AbstractHandler {
/* (non-Javadoc)
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
*/
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
Runnable runnable = new Runnable() {
@Override
public void run() {
execute(event, (IStructuredSelection)selection);
}
};
Protocol.invokeLater(runnable);
}
return null;
}
/**
* Executes the attach for the given selection.
* <p>
* <b>Note:</b> This method must be called from within the TCF dispatch thread.
*
* @param event The execution event.
* @param selection The selection. Must not be <code>null</code>.
*/
protected void execute(final ExecutionEvent event, final IStructuredSelection selection) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
Assert.isNotNull(selection);
// Analyze the selection and collect all nodes per parent peer model node.
final Map<IPeerNode, List<IProcessContextNode>> contexts = new HashMap<IPeerNode, List<IProcessContextNode>>();
Iterator<?> iterator = selection.iterator();
while (iterator.hasNext()) {
Object candidate = iterator.next();
if (candidate instanceof IProcessContextNode) {
IProcessContextNode node = (IProcessContextNode)candidate;
IPeerNode peerNode = (IPeerNode)node.getAdapter(IPeerNode.class);
if (peerNode != null) {
List<IProcessContextNode> nodes = contexts.get(peerNode);
if (nodes == null) {
nodes = new ArrayList<IProcessContextNode>();
contexts.put(peerNode, nodes);
}
if (!nodes.contains(node)) nodes.add(node);
}
}
}
// If not empty, attach to all nodes of the original selection per parent peer model node.
if (!contexts.isEmpty()) {
for (Entry<IPeerNode, List<IProcessContextNode>> entry : contexts.entrySet()) {
IPeerNode peerNode = entry.getKey();
List<IProcessContextNode> nodes = entry.getValue();
doAttach(event, peerNode, nodes.toArray(new IProcessContextNode[nodes.size()]));
}
}
}
/**
* Executes the attach to the given process context nodes.
* <p>
* <b>Note:</b> This method must be called from within the TCF dispatch thread.
*
* @param event The execution event.
* @param nodes The list of process context nodes. Must not be <code>null</code>.
*/
protected void doAttach(final ExecutionEvent event, final IPeerNode peerNode, final IProcessContextNode[] nodes) {
Assert.isTrue(Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$
Assert.isNotNull(peerNode);
Assert.isNotNull(nodes);
if (nodes.length > 0) {
AttachStep step = new AttachStep();
step.executeAttach(peerNode, nodes, new Callback());
}
}
}