]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - eclipse/plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/views/ModulesView.java
Introduce distribution editor
[gpl/argeo-slc.git] / eclipse / plugins / org.argeo.slc.client.ui.dist / src / main / java / org / argeo / slc / client / ui / dist / views / ModulesView.java
index 6d1190414657b990d2b08add8e0e771491d68905..0c0a679b177029518376266277e40eed8e7c22a0 100644 (file)
@@ -1,8 +1,30 @@
+/*
+ * Copyright (C) 2007-2012 Mathieu Baudier
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package org.argeo.slc.client.ui.dist.views;
 
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.eclipse.ui.TreeParent;
 import org.argeo.slc.client.ui.dist.DistPlugin;
 import org.eclipse.jface.viewers.ITableLabelProvider;
@@ -16,10 +38,27 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.part.ViewPart;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
 
 public class ModulesView extends ViewPart {
+       private final static Log log = LogFactory.getLog(ModulesView.class);
+
        private TreeViewer viewer;
 
+       private PackageAdmin packageAdmin;
+
+       private Comparator<ExportedPackage> exportedPackageComparator = new Comparator<ExportedPackage>() {
+
+               public int compare(ExportedPackage o1, ExportedPackage o2) {
+                       if (!o1.getName().equals(o2.getName()))
+                               return o1.getName().compareTo(o2.getName());
+                       else
+                               return o1.getVersion().compareTo(o2.getVersion());
+               }
+       };
+
        @Override
        public void createPartControl(Composite parent) {
                viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
@@ -43,12 +82,108 @@ public class ModulesView extends ViewPart {
                        if (parentElement instanceof BundleContext) {
                                BundleContext bundleContext = (BundleContext) parentElement;
                                Bundle[] bundles = bundleContext.getBundles();
-                               Set<ModuleNode> moduleNodes = new TreeSet<ModulesView.ModuleNode>();
+
+                               TreeParent bundlesNode = new TreeParent("Bundles");
                                for (Bundle bundle : bundles) {
                                        if (bundle.getState() == Bundle.ACTIVE)
-                                               moduleNodes.add(new ModuleNode(bundle));
+                                               bundlesNode.addChild(new BundleNode(bundle));
                                }
-                               return moduleNodes.toArray();
+
+                               // scan packages
+                               ServiceReference paSr = bundleContext
+                                               .getServiceReference(PackageAdmin.class.getName());
+                               // TODO: make a cleaner referencing
+                               packageAdmin = (PackageAdmin) bundleContext.getService(paSr);
+
+                               Bundle bundle1 = null;
+                               Bundle bundle2 = null;
+
+                               Map<Bundle, Set<ExportedPackage>> importedPackages = new HashMap<Bundle, Set<ExportedPackage>>();
+                               Map<String, Set<ExportedPackage>> packages = new TreeMap<String, Set<ExportedPackage>>();
+                               for (Bundle bundle : bundles) {
+                                       if (bundle.getSymbolicName()
+                                                       .equals("org.argeo.security.ui"))
+                                               bundle1 = bundle;
+                                       if (bundle.getSymbolicName().equals(
+                                                       "org.argeo.security.equinox"))
+                                               bundle2 = bundle;
+
+                                       ExportedPackage[] pkgs = packageAdmin
+                                                       .getExportedPackages(bundle);
+                                       if (pkgs != null)
+                                               for (ExportedPackage pkg : pkgs) {
+                                                       if (!packages.containsKey(pkg.getName()))
+                                                               packages.put(pkg.getName(),
+                                                                               new TreeSet<ExportedPackage>(
+                                                                                               exportedPackageComparator));
+                                                       Set<ExportedPackage> expPackages = (Set<ExportedPackage>) packages
+                                                                       .get(pkg.getName());
+                                                       expPackages.add(pkg);
+
+                                                       // imported
+                                                       for (Bundle b : pkg.getImportingBundles()) {
+                                                               if (bundle.getBundleId() != b.getBundleId()) {
+                                                                       if (!importedPackages.containsKey(b))
+                                                                               importedPackages
+                                                                                               .put(b,
+                                                                                                               new TreeSet<ExportedPackage>(
+                                                                                                                               exportedPackageComparator));
+                                                                       Set<ExportedPackage> impPackages = (Set<ExportedPackage>) importedPackages
+                                                                                       .get(b);
+                                                                       impPackages.add(pkg);
+                                                               }
+                                                       }
+                                               }
+                               }
+
+                               TreeParent mPackageNode = new TreeParent("Multiple Packages");
+                               TreeParent aPackageNode = new TreeParent("All Packages");
+                               for (String packageName : packages.keySet()) {
+                                       Set<ExportedPackage> pkgs = packages.get(packageName);
+                                       if (pkgs.size() > 1) {
+                                               MultiplePackagesNode mpn = new MultiplePackagesNode(
+                                                               packageName, pkgs);
+                                               mPackageNode.addChild(mpn);
+                                               aPackageNode.addChild(mpn);
+                                       } else {
+                                               aPackageNode.addChild(new ExportedPackageNode(pkgs
+                                                               .iterator().next()));
+                                       }
+                               }
+
+                               // Map<String, Set<String>> traces1 = new TreeMap<String,
+                               // Set<String>>();
+                               // Map<String, ExportedPackage> space1 =
+                               // dependencySpace(bundle1,
+                               // importedPackages, traces1);
+                               // Map<String, Set<String>> traces2 = new TreeMap<String,
+                               // Set<String>>();
+                               // Map<String, ExportedPackage> space2 =
+                               // dependencySpace(bundle2,
+                               // importedPackages, traces2);
+                               // for (String key : space1.keySet()) {
+                               // if (space2.containsKey(key)) {
+                               // ExportedPackage pkg1 = space1.get(key);
+                               // ExportedPackage pkg2 = space2.get(key);
+                               // if (!pkg1.getVersion().equals(pkg2.getVersion())) {
+                               // log.debug("\n##" + pkg1 + " <> " + pkg2);
+                               // log.debug("# Traces for "
+                               // + bundle1.getSymbolicName());
+                               // for (String trace : traces1.get(pkg1.getName())) {
+                               // log.debug(trace);
+                               // }
+                               // log.debug("# Traces for "
+                               // + bundle2.getSymbolicName());
+                               // for (String trace : traces2.get(pkg2.getName())) {
+                               // log.debug(trace);
+                               // }
+                               // }
+                               // }
+                               // }
+
+                               return new Object[] { bundlesNode, mPackageNode, aPackageNode };
+                       } else if (parentElement instanceof TreeParent) {
+                               return ((TreeParent) parentElement).getChildren();
                        } else {
                                return null;
                        }
@@ -60,6 +195,9 @@ public class ModulesView extends ViewPart {
                }
 
                public boolean hasChildren(Object element) {
+                       if (element instanceof TreeParent) {
+                               return ((TreeParent) element).hasChildren();
+                       }
                        return false;
                }
 
@@ -75,6 +213,40 @@ public class ModulesView extends ViewPart {
 
        }
 
+       protected Map<String, ExportedPackage> dependencySpace(Bundle bundle,
+                       Map<Bundle, Set<ExportedPackage>> importedPackages,
+                       Map<String, Set<String>> traces) {
+               log.debug("Dependency space for " + bundle.getSymbolicName());
+               Map<String, ExportedPackage> space = new TreeMap<String, ExportedPackage>();
+               fillDependencySpace(space, bundle, importedPackages,
+                               bundle.getSymbolicName(), traces);
+               return space;
+       }
+
+       /** Recursive */
+       protected void fillDependencySpace(Map<String, ExportedPackage> space,
+                       Bundle bundle, Map<Bundle, Set<ExportedPackage>> importedPackages,
+                       String currTrace, Map<String, Set<String>> traces) {
+               if (importedPackages.containsKey(bundle)) {
+                       Set<ExportedPackage> imports = importedPackages.get(bundle);
+                       // log.debug("## Fill dependency space for " + bundle + " : ");
+                       for (ExportedPackage pkg : imports) {
+                               if (!traces.containsKey(pkg.getName()))
+                                       traces.put(pkg.getName(), new TreeSet<String>());
+                               traces.get(pkg.getName()).add(currTrace);
+                               if (!space.containsKey(pkg.getName())) {
+                                       space.put(pkg.getName(), pkg);
+                                       Bundle exportingBundle = pkg.getExportingBundle();
+                                       // if (bundle.getBundleId() !=
+                                       // exportingBundle.getBundleId())
+                                       fillDependencySpace(space, exportingBundle,
+                                                       importedPackages, currTrace + " > "
+                                                                       + exportingBundle.getSymbolicName(), traces);
+                               }
+                       }
+               }
+       }
+
        private class ModulesLabelProvider extends LabelProvider implements
                        ITableLabelProvider {
 
@@ -89,12 +261,37 @@ public class ModulesView extends ViewPart {
 
        }
 
-       private class ModuleNode extends TreeParent {
+       class BundleNode extends TreeParent {
                private final Bundle bundle;
 
-               public ModuleNode(Bundle bundle) {
+               public BundleNode(Bundle bundle) {
                        super(bundle.getSymbolicName());
                        this.bundle = bundle;
+
+                       // Registered services
+                       ServiceReference[] registeredServices = bundle
+                                       .getRegisteredServices();
+                       if (registeredServices != null) {
+                               TreeParent registeredServicesNode = new TreeParent(
+                                               "Registered Services");
+                               addChild(registeredServicesNode);
+                               for (ServiceReference sr : registeredServices) {
+                                       if (sr != null)
+                                               registeredServicesNode
+                                                               .addChild(new ServiceReferenceNode(sr));
+                               }
+                       }
+
+                       // Used services
+                       ServiceReference[] usedServices = bundle.getRegisteredServices();
+                       if (usedServices != null) {
+                               TreeParent usedServicesNode = new TreeParent("Used Services");
+                               addChild(usedServicesNode);
+                               for (ServiceReference sr : usedServices) {
+                                       if (sr != null)
+                                               usedServicesNode.addChild(new ServiceReferenceNode(sr));
+                               }
+                       }
                }
 
                public Bundle getBundle() {
@@ -102,4 +299,108 @@ public class ModulesView extends ViewPart {
                }
 
        }
+
+       class ServiceReferenceNode extends TreeParent {
+               private final ServiceReference serviceReference;
+
+               public ServiceReferenceNode(ServiceReference serviceReference) {
+                       super(serviceReference.toString());
+                       this.serviceReference = serviceReference;
+
+                       Bundle[] usedBundles = serviceReference.getUsingBundles();
+                       if (usedBundles != null) {
+                               TreeParent usingBundles = new TreeParent("Using Bundles");
+                               addChild(usingBundles);
+                               for (Bundle b : usedBundles) {
+                                       if (b != null)
+                                               usingBundles.addChild(new TreeParent(b
+                                                               .getSymbolicName()));
+                               }
+                       }
+
+                       TreeParent properties = new TreeParent("Properties");
+                       addChild(properties);
+                       for (String key : serviceReference.getPropertyKeys()) {
+                               properties.addChild(new TreeParent(key + "="
+                                               + serviceReference.getProperty(key)));
+                       }
+
+               }
+
+               public ServiceReference getServiceReference() {
+                       return serviceReference;
+               }
+
+       }
+
+       class MultiplePackagesNode extends TreeParent {
+               private String packageName;
+               private Set<ExportedPackage> exportedPackages;
+
+               public MultiplePackagesNode(String packageName,
+                               Set<ExportedPackage> exportedPackages) {
+                       super(packageName);
+                       this.packageName = packageName;
+                       this.exportedPackages = exportedPackages;
+                       for (ExportedPackage pkg : exportedPackages) {
+                               addChild(new ExportedPackageNode(pkg));
+                       }
+               }
+
+       }
+
+       class ConflictingPackageNode extends TreeParent {
+               private ExportedPackage exportedPackage;
+
+               public ConflictingPackageNode(ExportedPackage exportedPackage) {
+                       super(exportedPackage.getName() + " - "
+                                       + exportedPackage.getVersion() + " ("
+                                       + exportedPackage.getExportingBundle() + ")");
+                       this.exportedPackage = exportedPackage;
+
+                       TreeParent bundlesNode = new TreeParent("Dependent Bundles");
+                       this.addChild(bundlesNode);
+                       Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
+                       for (Bundle b : exportedPackage.getImportingBundles()) {
+                               bundles.put(b.getSymbolicName(), b);
+                       }
+                       for (String key : bundles.keySet()) {
+                               addDependentBundles(bundlesNode, bundles.get(key));
+                       }
+               }
+       }
+
+       protected void addDependentBundles(TreeParent parent, Bundle bundle) {
+               TreeParent bundleNode = new TreeParent(bundle.toString());
+               parent.addChild(bundleNode);
+               Map<String, Bundle> bundles = new TreeMap<String, Bundle>();
+               ExportedPackage[] pkgs = packageAdmin.getExportedPackages(bundle);
+               if (pkgs != null)
+                       for (ExportedPackage pkg : pkgs) {
+                               for (Bundle b : pkg.getImportingBundles()) {
+                                       if (!bundles.containsKey(b.getSymbolicName())
+                                                       && b.getBundleId() != bundle.getBundleId()) {
+                                               bundles.put(b.getSymbolicName(), b);
+                                       }
+                               }
+                       }
+
+               for (String key : bundles.keySet()) {
+                       addDependentBundles(bundleNode, bundles.get(key));
+               }
+       }
+
+       class ExportedPackageNode extends TreeParent {
+               private ExportedPackage exportedPackage;
+
+               public ExportedPackageNode(ExportedPackage exportedPackage) {
+                       super(exportedPackage.getName() + " - "
+                                       + exportedPackage.getVersion() + " ("
+                                       + exportedPackage.getExportingBundle() + ")");
+                       this.exportedPackage = exportedPackage;
+                       for (Bundle bundle : exportedPackage.getImportingBundles()) {
+                               addChild(new BundleNode(bundle));
+                       }
+               }
+       }
 }