/******************************************************************************* * Copyright (c) 2011 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.tm.te.tcf.ui.tables; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; 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.tm.tcf.protocol.Protocol; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModel; import org.eclipse.tm.te.tcf.locator.interfaces.nodes.IPeerModelProperties; import org.eclipse.tm.te.tcf.ui.nls.Messages; import org.eclipse.tm.te.ui.tables.properties.NodePropertiesTableTableNode; import org.eclipse.ui.forms.widgets.Section; /** * TCF node properties table content provider implementation. */ public class NodePropertiesContentProvider implements IStructuredContentProvider { /** * The list of properties to filter out and not to show within the table. */ protected final static String[] FILTERED_PROPERTIES = new String[] { "name", "typeLabel", //$NON-NLS-1$ //$NON-NLS-2$ "instance", "childrenQueried", //$NON-NLS-1$ //$NON-NLS-2$ IPeerModelProperties.PROP_CHANNEL_REF_COUNTER, "Path", //$NON-NLS-1$ "hasTabularProperties" //$NON-NLS-1$ }; // 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 NodePropertiesContentProvider(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) { List<NodePropertiesTableTableNode> nodes = new ArrayList<NodePropertiesTableTableNode>(); if (inputElement instanceof IPeerModel) { NodePropertiesTableTableNode lastErrorNode = null; // Get all custom properties of the node final Map<String, Object> properties = new HashMap<String, Object>(); // And get all native properties of the peer if (Protocol.isDispatchThread()) { properties.putAll(((IPeerModel)inputElement).getProperties()); properties.putAll(((IPeerModel)inputElement).getPeer().getAttributes()); } else { Protocol.invokeAndWait(new Runnable() { @Override public void run() { properties.putAll(((IPeerModel)inputElement).getProperties()); properties.putAll(((IPeerModel)inputElement).getPeer().getAttributes()); } }); } for (String name : properties.keySet()) { // Check if the property is filtered if (name.endsWith(".silent") || Arrays.asList(FILTERED_PROPERTIES).contains(name)) continue; //$NON-NLS-1$ // Create the properties node, if not one of the services nodes if (!IPeerModelProperties.PROP_LOCAL_SERVICES.equals(name) && !IPeerModelProperties.PROP_REMOTE_SERVICES.equals(name)) { NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(name, properties.get(name) != null ? properties.get(name).toString() : ""); //$NON-NLS-1$ if (!IPeerModelProperties.PROP_LAST_SCANNER_ERROR.equals(name)) nodes.add(propertiesNode); else lastErrorNode = propertiesNode; } else { // For the services nodes, additional nodes might be necessary to make // reading all the service names in the table easier String services = properties.get(name) != null ? properties.get(name).toString() : ""; //$NON-NLS-1$ if (services.split(",").length > 6) { //$NON-NLS-1$ // More than 6 services listed -> generate nodes with 6 service names each String[] serviceNames = services.split(","); //$NON-NLS-1$ boolean withName = true; StringBuilder nodeValue = new StringBuilder(); int counter = 1; for (String serviceName : serviceNames) { nodeValue.append(serviceName.trim()); nodeValue.append(", "); //$NON-NLS-1$ if (counter < 6) { counter++; } else { NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(withName ? name : "\t", nodeValue.toString()); //$NON-NLS-1$ nodes.add(propertiesNode); if (withName) withName = false; counter = 1; nodeValue = new StringBuilder(); } } // Anything left in the string builder? if (nodeValue.toString().trim().length() > 0) { String value = nodeValue.toString(); if (value.endsWith(", ")) value = value.substring(0, value.length() - 2); //$NON-NLS-1$ if (value.trim().length() > 0) { NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(withName ? name : "\t", value); //$NON-NLS-1$ nodes.add(propertiesNode); } } } else { // Less than 6 service names listed -> generate a single node NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode(name, services); nodes.add(propertiesNode); } } } if (lastErrorNode != null) { // Add an empty line before the error NodePropertiesTableTableNode propertiesNode = new NodePropertiesTableTableNode("", ""); //$NON-NLS-1$ //$NON-NLS-2$ nodes.add(propertiesNode); nodes.add(lastErrorNode); } } return nodes.toArray(new NodePropertiesTableTableNode[nodes.size()]); } /* (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 IPeerModel) element = newInput; // Determine the section header text if (element instanceof IPeerModel) { sectionTitle = NLS.bind(org.eclipse.tm.te.ui.nls.Messages.NodePropertiesTableControl_section_title, Messages.NodePropertiesContentProvider_peerNode_sectionTitle); } // Set the standard (no selection) section title if none could be determined if (sectionTitle == null || "".equals(sectionTitle.trim())) sectionTitle = org.eclipse.tm.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 while (sectionTitle.length() < 40) sectionTitle += " "; //$NON-NLS-1$ // 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(); } } }