/******************************************************************************* * 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.launch.ui.viewer; import java.util.ArrayList; import java.util.EventObject; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.tcf.te.launch.core.lm.interfaces.ICommonLaunchAttributes; import org.eclipse.tcf.te.launch.core.persistence.DefaultPersistenceDelegate; import org.eclipse.tcf.te.launch.ui.model.LaunchModel; import org.eclipse.tcf.te.launch.ui.model.LaunchNode; import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; import org.eclipse.tcf.te.runtime.events.ChangeEvent; import org.eclipse.tcf.te.runtime.events.EventManager; import org.eclipse.tcf.te.runtime.interfaces.events.IEventListener; import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode; import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; import org.eclipse.ui.PlatformUI; /** * Launches content provider for the common navigator of Target Explorer. */ public class LaunchNavigatorContentProvider implements ITreeContentProvider, IEventListener { private final static Object[] NO_ELEMENTS = new Object[0]; // The viewer private Viewer viewer; /** * Constructor. */ public LaunchNavigatorContentProvider() { super(); EventManager.getInstance().addEventListener(this, ChangeEvent.class); } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) */ @Override public Object[] getChildren(Object element) { if (element instanceof LaunchNode) { LaunchNode node = (LaunchNode)element; if (node.getModel().getModelRoot() instanceof IProject) { node.getModel(); } List<IModelNode> children = new ArrayList<IModelNode>(); if (node.isType(LaunchNode.TYPE_ROOT)) { if (isTypeNodeVisible()) { // return all type nodes of the model if (isEmptyTypeNodeVisible()) { return node.getChildren(); } // return only _not_ empty type nodes of the model for (IModelNode typeNode : node.getChildren()) { if (((IContainerModelNode)typeNode).hasChildren()) { children.add(typeNode); } } return children.toArray(); } // return all config nodes of all type nodes of the model for (IModelNode typeNode : node.getChildren()) { for (IModelNode configNode : ((IContainerModelNode)typeNode).getChildren()) { children.add(configNode); } } return children.toArray(); } return node.getChildren(); } LaunchModel model = LaunchModel.getLaunchModel(element); if (model != null) { if (isRootNodeVisible() && model.getRootNode().hasChildren()) { return new Object[]{model.getRootNode()}; } return getChildren(model.getRootNode()); } return NO_ELEMENTS; } /* * (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) */ @Override public boolean hasChildren(Object element) { if (element instanceof LaunchNode) { LaunchNode node = (LaunchNode)element; List<IModelNode> children = new ArrayList<IModelNode>(); if (node.isType(LaunchNode.TYPE_ROOT)) { if (isTypeNodeVisible()) { // return all type nodes of the model if (isEmptyTypeNodeVisible()) { return ((LaunchNode)element).hasChildren(); } // return only _not_ empty type nodes of the model for (IModelNode typeNode : node.getChildren()) { if (((IContainerModelNode)typeNode).hasChildren()) { children.add(typeNode); } } return !children.isEmpty(); } // return all config nodes of all type nodes of the model for (IModelNode typeNode : node.getChildren()) { for (IModelNode configNode : ((IContainerModelNode)typeNode).getChildren()) { children.add(configNode); } } return !children.isEmpty(); } return ((LaunchNode)element).hasChildren(); } LaunchModel model = LaunchModel.getLaunchModel(element); if (model != null) { if (isRootNodeVisible()) { return true; } return hasChildren(model.getRootNode()); } return false; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) */ @Override public Object getParent(Object element) { if (element instanceof LaunchNode) { LaunchNode node = (LaunchNode)element; if (node.getParent() == null || node.isType(LaunchNode.TYPE_ROOT) || (!isTypeNodeVisible() && node.isType(LaunchNode.TYPE_LAUNCH_CONFIG)) || (!isRootNodeVisible() && node.isType(LaunchNode.TYPE_LAUNCH_CONFIG_TYPE))) { return node.getModel().getModelRoot(); } return node.getParent(); } return null; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object) */ @Override public Object[] getElements(Object inputElement) { return getChildren(inputElement); } /* * (non-Javadoc) * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public void inputChanged(final Viewer viewer, Object oldInput, Object newInput) { this.viewer = viewer; if (newInput != null && !newInput.equals(oldInput)) { LaunchModel model = LaunchModel.getLaunchModel(newInput); if (model != null) { LaunchNode lastLaunchedNode = null; long nodeValue = -1; for (IModelNode typeNode : model.getRootNode().getChildren()) { for (IModelNode launchNode : ((IContainerModelNode)typeNode).getChildren()) { ILaunchConfiguration config = ((LaunchNode)launchNode).getLaunchConfiguration(); String lastLaunched = DefaultPersistenceDelegate.getAttribute(config, ICommonLaunchAttributes.ATTR_LAST_LAUNCHED, (String)null); if (lastLaunched != null) { long last = Long.parseLong(lastLaunched); if (last > nodeValue) { nodeValue = last; lastLaunchedNode = (LaunchNode)launchNode; } } } } if (lastLaunchedNode != null) { final LaunchNode node = lastLaunchedNode; ExecutorsUtil.executeInUI(new Runnable() { @Override public void run() { viewer.setSelection(new StructuredSelection(node)); } }); } } } } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#dispose() */ @Override public void dispose() { EventManager.getInstance().removeEventListener(this); } /** * If the root node of the tree is visible. * * @return true if it is visible. */ protected boolean isRootNodeVisible() { return true; } /** * If the launch configuration type node in the tree is visible. * * @return true if it is visible. */ protected boolean isTypeNodeVisible() { return true; } /** * If an empty launch config type node in the tree is visible. * * @return true if it is visible. */ protected boolean isEmptyTypeNodeVisible() { return true; } /* (non-Javadoc) * @see org.eclipse.tcf.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject) */ @Override public void eventFired(EventObject event) { final Viewer viewer = this.viewer; if (event.getSource() instanceof LaunchModel) { final LaunchModel model = (LaunchModel)event.getSource(); if (model != null && viewer instanceof TreeViewer) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { @Override public void run() { if (viewer.getControl() != null && !viewer.getControl().isDisposed()) { ((TreeViewer)viewer).refresh((isRootNodeVisible() ? model.getRootNode() : model.getModelRoot()), true); } } }); } } } }