package de.twentyeleven.skysail.skysail.server.ext.osgideps; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JFrame; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.zest.core.widgets.Graph; import org.eclipse.zest.core.widgets.GraphConnection; import org.eclipse.zest.core.widgets.GraphNode; import org.eclipse.zest.core.widgets.ZestStyles; import org.eclipse.zest.layouts.LayoutStyles; import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ZestOsgiServicesVisualizer extends JFrame { private static final long serialVersionUID = 7110246569384550189L; private static final Logger logger = LoggerFactory.getLogger(ZestOsgiServicesVisualizer.class); private Map<String, Object> verticesMap = new HashMap<String, Object>(); private Graph graph; public ZestOsgiServicesVisualizer() { super("skysail OSGi services visualization"); } public void buildGraphFromOsgiContext(BundleContext bundleContext) { Display d = new Display(); Shell shell = new Shell(d); shell.setText("GraphSnippet1"); shell.setLayout(new FillLayout()); shell.setSize(400, 400); graph = new Graph(shell, SWT.NONE); // Now a few nodes GraphNode node1 = new GraphNode(graph, SWT.NONE, "Jim"); GraphNode node2 = new GraphNode(graph, SWT.NONE, "Jack"); GraphNode node3 = new GraphNode(graph, SWT.NONE, "Joe"); GraphNode node4 = new GraphNode(graph, SWT.NONE, "Bill"); // Lets have a directed connection new GraphConnection(graph, ZestStyles.CONNECTIONS_DIRECTED, node1, node2); // Lets have a dotted graph connection new GraphConnection(graph, ZestStyles.CONNECTIONS_DOT, node2, node3); // Standard connection new GraphConnection(graph, SWT.NONE, node3, node1); // Change line color and line width GraphConnection graphConnection = new GraphConnection(graph, SWT.NONE, node1, node4); graphConnection.changeLineColor(shell.getDisplay().getSystemColor(SWT.COLOR_GREEN)); // Also set a text graphConnection.setText("This is a text"); graphConnection.setHighlightColor(shell.getDisplay().getSystemColor(SWT.COLOR_RED)); graphConnection.setLineWidth(3); graph.setLayoutAlgorithm(new SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING), true); // Selection listener on graphConnect or GraphNode is not supported // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=236528 graph.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { System.out.println(e); } }); } public void run() { } private List<Bundle> determineSkysailBundles(BundleContext bundleContext) { List<Bundle> relevantBundles = new ArrayList<Bundle>(); Bundle[] bundles = bundleContext.getBundles(); for (Bundle bundle : bundles) { if (bundle.getSymbolicName().contains("skysail")) { relevantBundles.add(bundle); } } return relevantBundles; } private ServiceReference[] getServiceReferences(BundleContext bundleContext) { ServiceReference[] allServiceReferences = new ServiceReference[0]; try { allServiceReferences = bundleContext.getAllServiceReferences(null, null); } catch (InvalidSyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } return allServiceReferences; } private void createGraph(Object parent, List<Bundle> skysailBundles, ServiceReference[] allServiceReferences) { addInitialVertices(parent, skysailBundles); addEdges(allServiceReferences); removeEdgesWithoutReferences(); } private void addInitialVertices(Object parent, List<Bundle> skysailBundles) { for (Bundle bundle : skysailBundles) { addVertex(bundle); } } private void addVertex(Bundle bundle) { // if (!verticesMap.containsKey(bundle.getSymbolicName())) { // logger.info("adding {} to vertices", bundle.getSymbolicName()); // String vertexName = bundle.getSymbolicName() + " [" + bundle.getBundleId() + "]"; // Object vertex = graph.insertVertex(shell, null, vertexName, 20, 20, 180, 30); // verticesMap.put(bundle.getSymbolicName(), vertex); // } } private void addEdges(ServiceReference[] allServiceReferences) { for (ServiceReference ref : allServiceReferences) { analyseServiceReference(ref); } } private void analyseServiceReference(ServiceReference ref) { Bundle registeringBundle = ref.getBundle(); Bundle[] usingBundles = ref.getUsingBundles(); if (usingBundles == null) { return; } logger.info("checking {} for services", registeringBundle.getSymbolicName()); addVertex(registeringBundle); for (Bundle referencingBundle : usingBundles) { if (!verticesMap.containsKey(referencingBundle.getSymbolicName())) { addVertex(registeringBundle); } String edgeLabel = getEdgeLabel(ref); // graph.insertEdge(graph.getDefaultParent(), null, edgeLabel, // verticesMap.get(referencingBundle.getSymbolicName()), // verticesMap.get(registeringBundle.getSymbolicName())); } } private String getEdgeLabel(ServiceReference ref) { Long serviceId = (Long) ref.getProperty(Constants.SERVICE_ID); String[] serviceClass = (String[]) ref.getProperty(Constants.OBJECTCLASS); StringBuilder sb = new StringBuilder(); sb.append("ServiceID: "); sb.append(serviceId).append("\n"); if (serviceClass.length > 0) { for (String classname : serviceClass) { String[] split = classname.split("\\."); sb.append(split[split.length - 1]); sb.append(" / "); } sb.delete(sb.length() - 3, sb.length() - 1); } return sb.toString(); } private void removeEdgesWithoutReferences() { // for (String bundleName : verticesMap.keySet()) { // mxCell bundle = (mxCell) verticesMap.get(bundleName); // Object[] allEdges = graph.getAllEdges(new mxCell[] { bundle }); // if (allEdges.length == 0) { // logger.info("removing vertex for '{}' as it does not have any edges attached", bundleName); // // graph.removeCells(new mxCell[] { bundle }); // } // } } }