/******************************************************************************* * Copyright (c) 2011, 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.ui.internal.tabbed; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.jface.viewers.Viewer; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWTException; import org.eclipse.swt.widgets.Control; import org.eclipse.tcf.protocol.Protocol; import org.eclipse.tcf.te.core.interfaces.IConnectable; import org.eclipse.tcf.te.core.utils.ConnectStateHelper; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.persistence.utils.DataHelper; import org.eclipse.tcf.te.runtime.properties.PropertiesContainer; import org.eclipse.tcf.te.runtime.services.ServiceUtils; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode; import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProperties; import org.eclipse.tcf.te.tcf.locator.utils.CommonUtils; import org.eclipse.tcf.te.ui.interfaces.services.INodePropertiesTableUIDelegate; import org.eclipse.tcf.te.ui.tables.properties.NodePropertiesTableTableNode; import org.eclipse.tcf.te.ui.views.extensions.LabelProviderDelegateExtensionPointManager; import org.eclipse.ui.forms.widgets.Section; /** * Peer properties general section table content provider implementation. */ public class PeerNodePropertiesSectionContentProvider implements IStructuredContentProvider { // Flag to control if the content provide may update the parent section title private final boolean updateParentSectionTitle; /** * Constructor. * * @param updateParentSectionTitle Specify <code>true</code> to allow the content provider to update * the parent section title, <code>false</code> if no title update is desired. */ public PeerNodePropertiesSectionContentProvider(boolean updateParentSectionTitle) { this.updateParentSectionTitle = updateParentSectionTitle; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IContentProvider#dispose() */ @Override public void dispose() { } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ @Override public Object[] getElements(final Object inputElement) { if (inputElement instanceof IPeerNode) { // Get all custom properties of the node final Map<String, Object> properties = new HashMap<String, Object>(); final Map<String, Object> debugProperties = new HashMap<String, Object>(); // And get all native properties of the peer if (Protocol.isDispatchThread()) { properties.putAll(((IPeerNode)inputElement).getPeer().getAttributes()); } else { Protocol.invokeAndWait(new Runnable() { @Override public void run() { IPeerNode peerNode = (IPeerNode)inputElement; properties.putAll(peerNode.getPeer().getAttributes()); properties.put(IPeerNodeProperties.PROPERTY_CONNECT_STATE, ConnectStateHelper.getConnectState(peerNode.getConnectState())); String error = CommonUtils.getPeerError(peerNode); if (error != null) { properties.put(IPeerNodeProperties.PROPERTY_ERROR, error); } Map<String,String> warnings = CommonUtils.getPeerWarnings(peerNode); if (warnings != null && !warnings.isEmpty()) { IPropertiesContainer container = new PropertiesContainer(); container.addProperties(warnings); properties.put(IPeerNodeProperties.PROPERTY_WARNINGS, DataHelper.encodePropertiesContainer(container)); } if (peerNode.getConnectState() == IConnectable.STATE_CONNECTED) { properties.put(IPeerNodeProperties.PROPERTY_LOCAL_SERVICES, peerNode.getStringProperty(IPeerNodeProperties.PROPERTY_LOCAL_SERVICES)); properties.put(IPeerNodeProperties.PROPERTY_REMOTE_SERVICES, peerNode.getStringProperty(IPeerNodeProperties.PROPERTY_REMOTE_SERVICES)); } if (Platform.inDebugMode()) { debugProperties.putAll(peerNode.getProperties()); } } }); } INodePropertiesTableUIDelegate delegate = ServiceUtils.getUIServiceDelegate(inputElement, inputElement, INodePropertiesTableUIDelegate.class); List<NodePropertiesTableTableNode> nodes = new ArrayList<NodePropertiesTableTableNode>(); for (Entry<String, Object> entry : properties.entrySet()) { String name = entry.getKey(); // Check if the property is filtered if (Platform.inDebugMode() || (!name.endsWith(".silent") && !name.contains(".transient") && //$NON-NLS-1$ //$NON-NLS-2$ (delegate == null || !delegate.isFiltered(inputElement, name, entry.getValue())))) { nodes.add(new NodePropertiesTableTableNode(name, entry.getValue() != null ? entry.getValue().toString() : "")); //$NON-NLS-1$ } } Collections.sort(nodes, new Comparator<NodePropertiesTableTableNode>() { @Override public int compare(NodePropertiesTableTableNode arg0, NodePropertiesTableTableNode arg1) { return arg0.name.compareToIgnoreCase(arg1.name); } }); if (delegate != null) delegate.expandNodesAfterSort(inputElement, nodes); ILabelProvider provider = ServiceUtils.getUIServiceDelegate(inputElement, inputElement, ILabelProvider.class); List<NodePropertiesTableTableNode> result = new ArrayList<NodePropertiesTableTableNode>(); for (NodePropertiesTableTableNode node : nodes) { // Possible replacement for the node properties table table node value String text = null; // Get the label provider delegate for the input element ILabelProvider[] delegates = LabelProviderDelegateExtensionPointManager.getInstance().getDelegates(inputElement, false); if (delegates != null && delegates.length > 0) { text = delegates[0].getText(node); } // Fallback to the label provider if (text == null && provider != null) { text = provider.getText(node); } // Replace the node properties table table node value if (text != null && !"".equals(text)) { //$NON-NLS-1$ node = new NodePropertiesTableTableNode(node.name, text); } result.add(node); } if (!debugProperties.isEmpty()) { nodes.clear(); for (Entry<String, Object> entry : debugProperties.entrySet()) { String name = entry.getKey(); if (!name.equals(IPeerNodeProperties.PROPERTY_CONNECT_STATE) && !name.equals(IPeerNodeProperties.PROPERTY_ERROR) && !name.equals(IPeerNodeProperties.PROPERTY_WARNINGS) && !name.equals(IPeerNodeProperties.PROPERTY_LOCAL_SERVICES) && !name.equals(IPeerNodeProperties.PROPERTY_REMOTE_SERVICES)) { nodes.add(new NodePropertiesTableTableNode(name, entry.getValue() != null ? entry.getValue().toString() : "")); //$NON-NLS-1$ } } Collections.sort(nodes, new Comparator<NodePropertiesTableTableNode>() { @Override public int compare(NodePropertiesTableTableNode arg0, NodePropertiesTableTableNode arg1) { return arg0.name.compareToIgnoreCase(arg1.name); } }); result.add(new NodePropertiesTableTableNode("", "")); //$NON-NLS-1$ //$NON-NLS-2$ result.addAll(nodes); } return result.toArray(new NodePropertiesTableTableNode[result.size()]); } return new Object[0]; } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // Do nothing if we shall not update the section title if (!updateParentSectionTitle) return; String sectionTitle = null; Object element = null; // If the input is a tree selection, extract the element from the tree path if (newInput instanceof ITreeSelection && !((ITreeSelection)newInput).isEmpty()) { // Cast to the correct type ITreeSelection selection = (ITreeSelection)newInput; // Get the selected tree pathes TreePath[] pathes = selection.getPaths(); // If there are more than one elements selected, we care only about the first path TreePath path = pathes.length > 0 ? pathes[0] : null; // Get the last element within the tree path element = path != null ? path.getLastSegment() : null; } // If the input is a peer model node, set it directly if (newInput instanceof IPeerNode) element = newInput; // Determine the section header text if (element instanceof IPeerNode) { sectionTitle = NLS.bind(org.eclipse.tcf.te.ui.nls.Messages.NodePropertiesTableControl_section_title, "Peer"); //$NON-NLS-1$ } // Set the standard (no selection) section title if none could be determined if (sectionTitle == null || "".equals(sectionTitle.trim())) sectionTitle = org.eclipse.tcf.te.ui.nls.Messages.NodePropertiesTableControl_section_title_noSelection; //$NON-NLS-1$ // Stretch to a length of 40 characters to make sure the title can be changed // to hold and show text up to this length if (sectionTitle.length() < 40) { StringBuilder buffer = new StringBuilder(sectionTitle); while (buffer.length() < 40) buffer.append(" "); //$NON-NLS-1$ sectionTitle = buffer.toString(); } // Find the parent section the node properties tables is embedded in Control control = viewer.getControl(); while (control != null && !control.isDisposed()) { if (control instanceof Section) { Section section = (Section)control; // We cannot get access to the Label control used to set the text, so just catch the // probably SWTException try { section.setText(sectionTitle); } catch(SWTException e) { /* ignored on purpose */ } break; } control = control.getParent(); } } }