2 * Copyright (C) 2007-2012 Mathieu Baudier
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.osgi
.ui
.explorer
.views
;
18 import java
.util
.Comparator
;
19 import java
.util
.HashMap
;
22 import java
.util
.TreeMap
;
23 import java
.util
.TreeSet
;
25 import org
.apache
.commons
.logging
.Log
;
26 import org
.apache
.commons
.logging
.LogFactory
;
27 import org
.argeo
.eclipse
.ui
.TreeParent
;
28 import org
.argeo
.osgi
.ui
.explorer
.OsgiExplorerPlugin
;
29 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
30 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
31 import org
.eclipse
.jface
.viewers
.LabelProvider
;
32 import org
.eclipse
.jface
.viewers
.TreeViewer
;
33 import org
.eclipse
.jface
.viewers
.Viewer
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.graphics
.Image
;
36 import org
.eclipse
.swt
.widgets
.Composite
;
37 import org
.eclipse
.ui
.part
.ViewPart
;
38 import org
.osgi
.framework
.Bundle
;
39 import org
.osgi
.framework
.BundleContext
;
40 import org
.osgi
.framework
.ServiceReference
;
41 import org
.osgi
.service
.packageadmin
.ExportedPackage
;
42 import org
.osgi
.service
.packageadmin
.PackageAdmin
;
44 /** <b>Experimental</b> The OSGi runtime from a module perspective. */
45 public class ModulesView
extends ViewPart
{
46 private final static Log log
= LogFactory
.getLog(ModulesView
.class);
48 private TreeViewer viewer
;
50 private PackageAdmin packageAdmin
;
52 private Comparator
<ExportedPackage
> exportedPackageComparator
= new Comparator
<ExportedPackage
>() {
54 public int compare(ExportedPackage o1
, ExportedPackage o2
) {
55 if (!o1
.getName().equals(o2
.getName()))
56 return o1
.getName().compareTo(o2
.getName());
58 return o1
.getVersion().compareTo(o2
.getVersion());
63 public void createPartControl(Composite parent
) {
64 viewer
= new TreeViewer(parent
, SWT
.MULTI
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
65 viewer
.setContentProvider(new ModulesContentProvider());
66 viewer
.setLabelProvider(new ModulesLabelProvider());
67 viewer
.setInput(OsgiExplorerPlugin
.getDefault().getBundle()
72 public void setFocus() {
73 viewer
.getTree().setFocus();
76 private class ModulesContentProvider
implements ITreeContentProvider
{
78 public Object
[] getElements(Object inputElement
) {
79 return getChildren(inputElement
);
82 public Object
[] getChildren(Object parentElement
) {
83 if (parentElement
instanceof BundleContext
) {
84 BundleContext bundleContext
= (BundleContext
) parentElement
;
85 Bundle
[] bundles
= bundleContext
.getBundles();
87 TreeParent bundlesNode
= new TreeParent("Bundles");
88 for (Bundle bundle
: bundles
) {
89 if (bundle
.getState() == Bundle
.ACTIVE
)
90 bundlesNode
.addChild(new BundleNode(bundle
));
94 ServiceReference paSr
= bundleContext
95 .getServiceReference(PackageAdmin
.class.getName());
96 // TODO: make a cleaner referencing
97 packageAdmin
= (PackageAdmin
) bundleContext
.getService(paSr
);
99 Bundle bundle1
= null;
100 Bundle bundle2
= null;
102 Map
<Bundle
, Set
<ExportedPackage
>> importedPackages
= new HashMap
<Bundle
, Set
<ExportedPackage
>>();
103 Map
<String
, Set
<ExportedPackage
>> packages
= new TreeMap
<String
, Set
<ExportedPackage
>>();
104 for (Bundle bundle
: bundles
) {
105 if (bundle
.getSymbolicName()
106 .equals("org.argeo.security.ui"))
108 if (bundle
.getSymbolicName().equals(
109 "org.argeo.security.equinox"))
112 ExportedPackage
[] pkgs
= packageAdmin
113 .getExportedPackages(bundle
);
115 for (ExportedPackage pkg
: pkgs
) {
116 if (!packages
.containsKey(pkg
.getName()))
117 packages
.put(pkg
.getName(),
118 new TreeSet
<ExportedPackage
>(
119 exportedPackageComparator
));
120 Set
<ExportedPackage
> expPackages
= (Set
<ExportedPackage
>) packages
122 expPackages
.add(pkg
);
125 for (Bundle b
: pkg
.getImportingBundles()) {
126 if (bundle
.getBundleId() != b
.getBundleId()) {
127 if (!importedPackages
.containsKey(b
))
130 new TreeSet
<ExportedPackage
>(
131 exportedPackageComparator
));
132 Set
<ExportedPackage
> impPackages
= (Set
<ExportedPackage
>) importedPackages
134 impPackages
.add(pkg
);
140 TreeParent mPackageNode
= new TreeParent("Multiple Packages");
141 // TreeParent aPackageNode = new TreeParent("All Packages");
142 for (String packageName
: packages
.keySet()) {
143 Set
<ExportedPackage
> pkgs
= packages
.get(packageName
);
144 if (pkgs
.size() > 1) {
145 MultiplePackagesNode mpn
= new MultiplePackagesNode(
147 mPackageNode
.addChild(mpn
);
148 // aPackageNode.addChild(mpn);
150 // aPackageNode.addChild(new ExportedPackageNode(pkgs
151 // .iterator().next()));
155 return new Object
[] { bundlesNode
, mPackageNode
};// ,
158 } else if (parentElement
instanceof TreeParent
) {
159 return ((TreeParent
) parentElement
).getChildren();
165 public Object
getParent(Object element
) {
166 // TODO Auto-generated method stub
170 public boolean hasChildren(Object element
) {
171 if (element
instanceof TreeParent
) {
172 return ((TreeParent
) element
).hasChildren();
177 public void dispose() {
178 // TODO Auto-generated method stub
182 public void inputChanged(Viewer viewer
, Object oldInput
, Object newInput
) {
183 // TODO Auto-generated method stub
189 protected Map
<String
, ExportedPackage
> dependencySpace(Bundle bundle
,
190 Map
<Bundle
, Set
<ExportedPackage
>> importedPackages
,
191 Map
<String
, Set
<String
>> traces
) {
192 log
.debug("Dependency space for " + bundle
.getSymbolicName());
193 Map
<String
, ExportedPackage
> space
= new TreeMap
<String
, ExportedPackage
>();
194 fillDependencySpace(space
, bundle
, importedPackages
,
195 bundle
.getSymbolicName(), traces
);
200 protected void fillDependencySpace(Map
<String
, ExportedPackage
> space
,
201 Bundle bundle
, Map
<Bundle
, Set
<ExportedPackage
>> importedPackages
,
202 String currTrace
, Map
<String
, Set
<String
>> traces
) {
203 if (importedPackages
.containsKey(bundle
)) {
204 Set
<ExportedPackage
> imports
= importedPackages
.get(bundle
);
205 // log.debug("## Fill dependency space for " + bundle + " : ");
206 for (ExportedPackage pkg
: imports
) {
207 if (!traces
.containsKey(pkg
.getName()))
208 traces
.put(pkg
.getName(), new TreeSet
<String
>());
209 traces
.get(pkg
.getName()).add(currTrace
);
210 if (!space
.containsKey(pkg
.getName())) {
211 space
.put(pkg
.getName(), pkg
);
212 Bundle exportingBundle
= pkg
.getExportingBundle();
213 // if (bundle.getBundleId() !=
214 // exportingBundle.getBundleId())
215 fillDependencySpace(space
, exportingBundle
,
216 importedPackages
, currTrace
+ " > "
217 + exportingBundle
.getSymbolicName(), traces
);
223 private class ModulesLabelProvider
extends LabelProvider
implements
224 ITableLabelProvider
{
226 public Image
getColumnImage(Object element
, int columnIndex
) {
227 // TODO Auto-generated method stub
231 public String
getColumnText(Object element
, int columnIndex
) {
232 return getText(element
);
237 class BundleNode
extends TreeParent
{
238 private final Bundle bundle
;
240 public BundleNode(Bundle bundle
) {
241 super(bundle
.getSymbolicName());
242 this.bundle
= bundle
;
244 // Registered services
245 ServiceReference
[] registeredServices
= bundle
246 .getRegisteredServices();
247 if (registeredServices
!= null) {
248 TreeParent registeredServicesNode
= new TreeParent(
249 "Registered Services");
250 addChild(registeredServicesNode
);
251 for (ServiceReference sr
: registeredServices
) {
253 registeredServicesNode
254 .addChild(new ServiceReferenceNode(sr
));
259 ServiceReference
[] usedServices
= bundle
.getRegisteredServices();
260 if (usedServices
!= null) {
261 TreeParent usedServicesNode
= new TreeParent("Used Services");
262 addChild(usedServicesNode
);
263 for (ServiceReference sr
: usedServices
) {
265 usedServicesNode
.addChild(new ServiceReferenceNode(sr
));
270 public Bundle
getBundle() {
276 class ServiceReferenceNode
extends TreeParent
{
277 private final ServiceReference serviceReference
;
279 public ServiceReferenceNode(ServiceReference serviceReference
) {
280 super(serviceReference
.toString());
281 this.serviceReference
= serviceReference
;
283 Bundle
[] usedBundles
= serviceReference
.getUsingBundles();
284 if (usedBundles
!= null) {
285 TreeParent usingBundles
= new TreeParent("Using Bundles");
286 addChild(usingBundles
);
287 for (Bundle b
: usedBundles
) {
289 usingBundles
.addChild(new TreeParent(b
290 .getSymbolicName()));
294 TreeParent properties
= new TreeParent("Properties");
295 addChild(properties
);
296 for (String key
: serviceReference
.getPropertyKeys()) {
297 properties
.addChild(new TreeParent(key
+ "="
298 + serviceReference
.getProperty(key
)));
303 public ServiceReference
getServiceReference() {
304 return serviceReference
;
309 class MultiplePackagesNode
extends TreeParent
{
310 private String packageName
;
311 private Set
<ExportedPackage
> exportedPackages
;
313 public MultiplePackagesNode(String packageName
,
314 Set
<ExportedPackage
> exportedPackages
) {
316 this.packageName
= packageName
;
317 this.exportedPackages
= exportedPackages
;
318 for (ExportedPackage pkg
: exportedPackages
) {
319 addChild(new ExportedPackageNode(pkg
));
325 class ConflictingPackageNode
extends TreeParent
{
326 private ExportedPackage exportedPackage
;
328 public ConflictingPackageNode(ExportedPackage exportedPackage
) {
329 super(exportedPackage
.getName() + " - "
330 + exportedPackage
.getVersion() + " ("
331 + exportedPackage
.getExportingBundle() + ")");
332 this.exportedPackage
= exportedPackage
;
334 TreeParent bundlesNode
= new TreeParent("Dependent Bundles");
335 this.addChild(bundlesNode
);
336 Map
<String
, Bundle
> bundles
= new TreeMap
<String
, Bundle
>();
337 for (Bundle b
: exportedPackage
.getImportingBundles()) {
338 bundles
.put(b
.getSymbolicName(), b
);
340 for (String key
: bundles
.keySet()) {
341 addDependentBundles(bundlesNode
, bundles
.get(key
));
346 protected void addDependentBundles(TreeParent parent
, Bundle bundle
) {
347 TreeParent bundleNode
= new TreeParent(bundle
.toString());
348 parent
.addChild(bundleNode
);
349 Map
<String
, Bundle
> bundles
= new TreeMap
<String
, Bundle
>();
350 ExportedPackage
[] pkgs
= packageAdmin
.getExportedPackages(bundle
);
352 for (ExportedPackage pkg
: pkgs
) {
353 for (Bundle b
: pkg
.getImportingBundles()) {
354 if (!bundles
.containsKey(b
.getSymbolicName())
355 && b
.getBundleId() != bundle
.getBundleId()) {
356 bundles
.put(b
.getSymbolicName(), b
);
361 for (String key
: bundles
.keySet()) {
362 addDependentBundles(bundleNode
, bundles
.get(key
));
366 class ExportedPackageNode
extends TreeParent
{
367 private ExportedPackage exportedPackage
;
369 public ExportedPackageNode(ExportedPackage exportedPackage
) {
370 super(exportedPackage
.getName() + " - "
371 + exportedPackage
.getVersion() + " ("
372 + exportedPackage
.getExportingBundle() + ")");
373 this.exportedPackage
= exportedPackage
;
374 for (Bundle bundle
: exportedPackage
.getImportingBundles()) {
375 addChild(new BundleNode(bundle
));