]> git.argeo.org Git - lgpl/argeo-commons.git/blob - osgi/plugins/org.argeo.osgi.ui.explorer/src/main/java/org/argeo/osgi/ui/explorer/views/ModulesView.java
Introduce OSGi Explorer
[lgpl/argeo-commons.git] / osgi / plugins / org.argeo.osgi.ui.explorer / src / main / java / org / argeo / osgi / ui / explorer / views / ModulesView.java
1 package org.argeo.osgi.ui.explorer.views;
2
3 import java.util.Comparator;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.Set;
7 import java.util.TreeMap;
8 import java.util.TreeSet;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12 import org.argeo.eclipse.ui.TreeParent;
13 import org.argeo.osgi.ui.explorer.OsgiExplorerPlugin;
14 import org.eclipse.jface.viewers.ITableLabelProvider;
15 import org.eclipse.jface.viewers.ITreeContentProvider;
16 import org.eclipse.jface.viewers.LabelProvider;
17 import org.eclipse.jface.viewers.TreeViewer;
18 import org.eclipse.jface.viewers.Viewer;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.graphics.Image;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.ui.part.ViewPart;
23 import org.osgi.framework.Bundle;
24 import org.osgi.framework.BundleContext;
25 import org.osgi.framework.ServiceReference;
26 import org.osgi.service.packageadmin.ExportedPackage;
27 import org.osgi.service.packageadmin.PackageAdmin;
28
29 /** <b>Experimental</b> The OSGi runtime from a module perspective. */
30 public class ModulesView extends ViewPart {
31 private final static Log log = LogFactory.getLog(ModulesView.class);
32
33 private TreeViewer viewer;
34
35 private PackageAdmin packageAdmin;
36
37 private Comparator<ExportedPackage> exportedPackageComparator = new Comparator<ExportedPackage>() {
38
39 public int compare(ExportedPackage o1, ExportedPackage o2) {
40 if (!o1.getName().equals(o2.getName()))
41 return o1.getName().compareTo(o2.getName());
42 else
43 return o1.getVersion().compareTo(o2.getVersion());
44 }
45 };
46
47 @Override
48 public void createPartControl(Composite parent) {
49 viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
50 viewer.setContentProvider(new ModulesContentProvider());
51 viewer.setLabelProvider(new ModulesLabelProvider());
52 viewer.setInput(OsgiExplorerPlugin.getDefault().getBundle()
53 .getBundleContext());
54 }
55
56 @Override
57 public void setFocus() {
58 viewer.getTree().setFocus();
59 }
60
61 private class ModulesContentProvider implements ITreeContentProvider {
62
63 public Object[] getElements(Object inputElement) {
64 return getChildren(inputElement);
65 }
66
67 public Object[] getChildren(Object parentElement) {
68 if (parentElement instanceof BundleContext) {
69 BundleContext bundleContext = (BundleContext) parentElement;
70 Bundle[] bundles = bundleContext.getBundles();
71
72 TreeParent bundlesNode = new TreeParent("Bundles");
73 for (Bundle bundle : bundles) {
74 if (bundle.getState() == Bundle.ACTIVE)
75 bundlesNode.addChild(new BundleNode(bundle));
76 }
77
78 // scan packages
79 ServiceReference paSr = bundleContext
80 .getServiceReference(PackageAdmin.class.getName());
81 // TODO: make a cleaner referencing
82 packageAdmin = (PackageAdmin) bundleContext.getService(paSr);
83
84 Bundle bundle1 = null;
85 Bundle bundle2 = null;
86
87 Map<Bundle, Set<ExportedPackage>> importedPackages = new HashMap<Bundle, Set<ExportedPackage>>();
88 Map<String, Set<ExportedPackage>> packages = new TreeMap<String, Set<ExportedPackage>>();
89 for (Bundle bundle : bundles) {
90 if (bundle.getSymbolicName()
91 .equals("org.argeo.security.ui"))
92 bundle1 = bundle;
93 if (bundle.getSymbolicName().equals(
94 "org.argeo.security.equinox"))
95 bundle2 = bundle;
96
97 ExportedPackage[] pkgs = packageAdmin
98 .getExportedPackages(bundle);
99 if (pkgs != null)
100 for (ExportedPackage pkg : pkgs) {
101 if (!packages.containsKey(pkg.getName()))
102 packages.put(pkg.getName(),
103 new TreeSet<ExportedPackage>(
104 exportedPackageComparator));
105 Set<ExportedPackage> expPackages = (Set<ExportedPackage>) packages
106 .get(pkg.getName());
107 expPackages.add(pkg);
108
109 // imported
110 for (Bundle b : pkg.getImportingBundles()) {
111 if (bundle.getBundleId() != b.getBundleId()) {
112 if (!importedPackages.containsKey(b))
113 importedPackages
114 .put(b,
115 new TreeSet<ExportedPackage>(
116 exportedPackageComparator));
117 Set<ExportedPackage> impPackages = (Set<ExportedPackage>) importedPackages
118 .get(b);
119 impPackages.add(pkg);
120 }
121 }
122 }
123 }
124
125 TreeParent mPackageNode = new TreeParent("Multiple Packages");
126 // TreeParent aPackageNode = new TreeParent("All Packages");
127 for (String packageName : packages.keySet()) {
128 Set<ExportedPackage> pkgs = packages.get(packageName);
129 if (pkgs.size() > 1) {
130 MultiplePackagesNode mpn = new MultiplePackagesNode(
131 packageName, pkgs);
132 mPackageNode.addChild(mpn);
133 // aPackageNode.addChild(mpn);
134 } else {
135 // aPackageNode.addChild(new ExportedPackageNode(pkgs
136 // .iterator().next()));
137 }
138 }
139
140 return new Object[] { bundlesNode, mPackageNode };// ,
141 // aPackageNode
142 // };
143 } else if (parentElement instanceof TreeParent) {
144 return ((TreeParent) parentElement).getChildren();
145 } else {
146 return null;
147 }
148 }
149
150 public Object getParent(Object element) {
151 // TODO Auto-generated method stub
152 return null;
153 }
154
155 public boolean hasChildren(Object element) {
156 if (element instanceof TreeParent) {
157 return ((TreeParent) element).hasChildren();
158 }
159 return false;
160 }
161
162 public void dispose() {
163 // TODO Auto-generated method stub
164
165 }
166
167 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
168 // TODO Auto-generated method stub
169
170 }
171
172 }
173
174 protected Map<String, ExportedPackage> dependencySpace(Bundle bundle,
175 Map<Bundle, Set<ExportedPackage>> importedPackages,
176 Map<String, Set<String>> traces) {
177 log.debug("Dependency space for " + bundle.getSymbolicName());
178 Map<String, ExportedPackage> space = new TreeMap<String, ExportedPackage>();
179 fillDependencySpace(space, bundle, importedPackages,
180 bundle.getSymbolicName(), traces);
181 return space;
182 }
183
184 /** Recursive */
185 protected void fillDependencySpace(Map<String, ExportedPackage> space,
186 Bundle bundle, Map<Bundle, Set<ExportedPackage>> importedPackages,
187 String currTrace, Map<String, Set<String>> traces) {
188 if (importedPackages.containsKey(bundle)) {
189 Set<ExportedPackage> imports = importedPackages.get(bundle);
190 // log.debug("## Fill dependency space for " + bundle + " : ");
191 for (ExportedPackage pkg : imports) {
192 if (!traces.containsKey(pkg.getName()))
193 traces.put(pkg.getName(), new TreeSet<String>());
194 traces.get(pkg.getName()).add(currTrace);
195 if (!space.containsKey(pkg.getName())) {
196 space.put(pkg.getName(), pkg);
197 Bundle exportingBundle = pkg.getExportingBundle();
198 // if (bundle.getBundleId() !=
199 // exportingBundle.getBundleId())
200 fillDependencySpace(space, exportingBundle,
201 importedPackages, currTrace + " > "
202 + exportingBundle.getSymbolicName(), traces);
203 }
204 }
205 }
206 }
207
208 private class ModulesLabelProvider extends LabelProvider implements
209 ITableLabelProvider {
210
211 public Image getColumnImage(Object element, int columnIndex) {
212 // TODO Auto-generated method stub
213 return null;
214 }
215
216 public String getColumnText(Object element, int columnIndex) {
217 return getText(element);
218 }
219
220 }
221
222 class BundleNode extends TreeParent {
223 private final Bundle bundle;
224
225 public BundleNode(Bundle bundle) {
226 super(bundle.getSymbolicName());
227 this.bundle = bundle;
228
229 // Registered services
230 ServiceReference[] registeredServices = bundle
231 .getRegisteredServices();
232 if (registeredServices != null) {
233 TreeParent registeredServicesNode = new TreeParent(
234 "Registered Services");
235 addChild(registeredServicesNode);
236 for (ServiceReference sr : registeredServices) {
237 if (sr != null)
238 registeredServicesNode
239 .addChild(new ServiceReferenceNode(sr));
240 }
241 }
242
243 // Used services
244 ServiceReference[] usedServices = bundle.getRegisteredServices();
245 if (usedServices != null) {
246 TreeParent usedServicesNode = new TreeParent("Used Services");
247 addChild(usedServicesNode);
248 for (ServiceReference sr : usedServices) {
249 if (sr != null)
250 usedServicesNode.addChild(new ServiceReferenceNode(sr));
251 }
252 }
253 }
254
255 public Bundle getBundle() {
256 return bundle;
257 }
258
259 }
260
261 class ServiceReferenceNode extends TreeParent {
262 private final ServiceReference serviceReference;
263
264 public ServiceReferenceNode(ServiceReference serviceReference) {
265 super(serviceReference.toString());
266 this.serviceReference = serviceReference;
267
268 Bundle[] usedBundles = serviceReference.getUsingBundles();
269 if (usedBundles != null) {
270 TreeParent usingBundles = new TreeParent("Using Bundles");
271 addChild(usingBundles);
272 for (Bundle b : usedBundles) {
273 if (b != null)
274 usingBundles.addChild(new TreeParent(b
275 .getSymbolicName()));
276 }
277 }
278
279 TreeParent properties = new TreeParent("Properties");
280 addChild(properties);
281 for (String key : serviceReference.getPropertyKeys()) {
282 properties.addChild(new TreeParent(key + "="
283 + serviceReference.getProperty(key)));
284 }
285
286 }
287
288 public ServiceReference getServiceReference() {
289 return serviceReference;
290 }
291
292 }
293
294 class MultiplePackagesNode extends TreeParent {
295 private String packageName;
296 private Set<ExportedPackage> exportedPackages;
297
298 public MultiplePackagesNode(String packageName,
299 Set<ExportedPackage> exportedPackages) {
300 super(packageName);
301 this.packageName = packageName;
302 this.exportedPackages = exportedPackages;
303 for (ExportedPackage pkg : exportedPackages) {
304 addChild(new ExportedPackageNode(pkg));
305 }
306 }
307
308 }
309
310 class ConflictingPackageNode extends TreeParent {
311 private ExportedPackage exportedPackage;
312
313 public ConflictingPackageNode(ExportedPackage exportedPackage) {
314 super(exportedPackage.getName() + " - "
315 + exportedPackage.getVersion() + " ("
316 + exportedPackage.getExportingBundle() + ")");
317 this.exportedPackage = exportedPackage;
318
319 TreeParent bundlesNode = new TreeParent("Dependent Bundles");
320 this.addChild(bundlesNode);
321 Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
322 for (Bundle b : exportedPackage.getImportingBundles()) {
323 bundles.put(b.getSymbolicName(), b);
324 }
325 for (String key : bundles.keySet()) {
326 addDependentBundles(bundlesNode, bundles.get(key));
327 }
328 }
329 }
330
331 protected void addDependentBundles(TreeParent parent, Bundle bundle) {
332 TreeParent bundleNode = new TreeParent(bundle.toString());
333 parent.addChild(bundleNode);
334 Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
335 ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle);
336 if (pkgs != null)
337 for (ExportedPackage pkg : pkgs) {
338 for (Bundle b : pkg.getImportingBundles()) {
339 if (!bundles.containsKey(b.getSymbolicName())
340 && b.getBundleId() != bundle.getBundleId()) {
341 bundles.put(b.getSymbolicName(), b);
342 }
343 }
344 }
345
346 for (String key : bundles.keySet()) {
347 addDependentBundles(bundleNode, bundles.get(key));
348 }
349 }
350
351 class ExportedPackageNode extends TreeParent {
352 private ExportedPackage exportedPackage;
353
354 public ExportedPackageNode(ExportedPackage exportedPackage) {
355 super(exportedPackage.getName() + " - "
356 + exportedPackage.getVersion() + " ("
357 + exportedPackage.getExportingBundle() + ")");
358 this.exportedPackage = exportedPackage;
359 for (Bundle bundle : exportedPackage.getImportingBundles()) {
360 addChild(new BundleNode(bundle));
361 }
362 }
363 }
364 }