geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r1161696 - in /geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose: DiagnoseCommand.java PackageUsesHelper.java Utils.java
Date Thu, 25 Aug 2011 18:56:07 GMT
Author: gawor
Date: Thu Aug 25 18:56:06 2011
New Revision: 1161696

URL: http://svn.apache.org/viewvc?rev=1161696&view=rev
Log:
GERONIMO-5779: Improved diagnose command that considers direct and indirect package uses dependencies
to analyze 'package uses conflict' problems

Added:
    geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
  (with props)
    geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
  (with props)
Modified:
    geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/DiagnoseCommand.java

Modified: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/DiagnoseCommand.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/DiagnoseCommand.java?rev=1161696&r1=1161695&r2=1161696&view=diff
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/DiagnoseCommand.java
(original)
+++ geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/DiagnoseCommand.java
Thu Aug 25 18:56:06 2011
@@ -23,9 +23,6 @@ import static org.eclipse.osgi.service.r
 import static org.eclipse.osgi.service.resolver.ResolverError.MISSING_REQUIRE_BUNDLE;
 import static org.eclipse.osgi.service.resolver.ResolverError.REQUIRE_BUNDLE_USES_CONFLICT;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -45,9 +42,6 @@ import org.eclipse.osgi.service.resolver
 import org.eclipse.osgi.service.resolver.State;
 import org.eclipse.osgi.service.resolver.StateHelper;
 import org.eclipse.osgi.service.resolver.VersionConstraint;
-import org.eclipse.osgi.service.resolver.VersionRange;
-import org.fusesource.jansi.Ansi;
-import org.fusesource.jansi.Ansi.Color;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
@@ -102,20 +96,19 @@ public class DiagnoseCommand extends Osg
     }
     
     private void diagnose(BundleDescription bundle, PlatformAdmin platformAdmin) {
-        System.out.println(bundleInfo(bundle));
+        System.out.println(Utils.bundleToString(bundle));
 
         StateHelper stateHelper = platformAdmin.getStateHelper();
         VersionConstraint[] unsatisfied = stateHelper.getUnsatisfiedConstraints(bundle);
       
         ResolverError[] resolverErrors = analyzeErrors(bundle, platformAdmin.getState(false));
         
         if (unsatisfied.length == 0 && resolverErrors.length == 0) {
-            System.out.println("  No unresolved constraints.");
+            System.out.println(Utils.formatMessage(2, "No unresolved constraints."));
         }
         if (unsatisfied.length > 0) {
-            System.out.println("  Unresolved constraints:");        
+            System.out.println(Utils.formatMessage(2, "Unresolved constraints:"));      
 
             for (int i = 0; i < unsatisfied.length; i++) {
-                System.out.print("    ");
-                System.out.println(getResolutionFailureMessage(unsatisfied[i]));
+                System.out.println(Utils.formatMessage(3, getResolutionFailureMessage(unsatisfied[i])));
             }
         }
     }
@@ -126,32 +119,24 @@ public class DiagnoseCommand extends Osg
         if (unsatisfied instanceof ImportPackageSpecification) {
             String resolution = (String) ((ImportPackageSpecification) unsatisfied).getDirective(Constants.RESOLUTION_DIRECTIVE);
             if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(resolution)) {
-                return warning("Missing optionally imported package " + toString(unsatisfied));
+                return Utils.warning("Missing optionally imported package " + Utils.versionToString(unsatisfied));
             } else if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(resolution))
{
-                return warning("Missing dynamically imported package " + toString(unsatisfied));
+                return Utils.warning("Missing dynamically imported package " + Utils.versionToString(unsatisfied));
             } else {
-                return error("Missing imported package " + toString(unsatisfied));
+                return Utils.error("Missing imported package " + Utils.versionToString(unsatisfied));
             }
         } else if (unsatisfied instanceof BundleSpecification) {
             if (((BundleSpecification) unsatisfied).isOptional()) { 
-                return warning("Missing optionally required bundle " + toString(unsatisfied));
+                return Utils.warning("Missing optionally required bundle " + Utils.versionToString(unsatisfied));
             } else {
-                return error("Missing required bundle " + toString(unsatisfied));
+                return Utils.error("Missing required bundle " + Utils.versionToString(unsatisfied));
             }
         } else if (unsatisfied instanceof HostSpecification) {
-            return error("Missing host bundle " + toString(unsatisfied));
+            return Utils.error("Missing host bundle " + Utils.versionToString(unsatisfied));
         } else {
-            return error("Unknown problem");
+            return Utils.error("Unknown problem");
         }
     }
-        
-    private static String error(String msg) {
-        return Ansi.ansi().fg(Color.RED).a(msg).reset().toString();
-    }
-    
-    private static String warning(String msg) {
-        return Ansi.ansi().fg(Color.YELLOW).a(msg).reset().toString();
-    }
     
     public ResolverError[] analyzeErrors(BundleDescription bundle, State state) {
         return analyzeErrors(bundle, state, new HashSet<BundleDescription>(), 2);
@@ -161,13 +146,14 @@ public class DiagnoseCommand extends Osg
         if (bundles.contains(bundle)) {
             return null;
         }
+        
         bundles.add(bundle);
         ResolverError[] errors = state.getResolverErrors(bundle);
         if (level == 2 && errors.length > 0) {
-            System.out.println("  Resolver errors:");
+            System.out.println(Utils.formatMessage(level, "Resolver errors:"));
         }
         for (ResolverError error : errors) {
-            displayError(bundle, level, error.toString());
+            Utils.displayError(bundle, level, error.toString());
             VersionConstraint constraint = error.getUnsatisfiedConstraint();
             switch (error.getType()) {
                 case MISSING_IMPORT_PACKAGE:
@@ -177,11 +163,11 @@ public class DiagnoseCommand extends Osg
                             if (pkg.getName().equals(pkgSpec.getName())) {
                                 if (pkgSpec.getVersionRange().isIncluded(pkg.getVersion()))
{
                                     if (!pkg.getExporter().isResolved()) {
-                                        displayError(b, level + 1, "Bundle unresolved: "
+ pkg);
+                                        Utils.displayError(b, level + 1, "Bundle unresolved:
" + pkg);
                                         analyzeErrors(pkg.getExporter(), state, bundles,
level + 1);
                                     }
                                 } else {
-                                    displayError(b, level + 1, "Version mismatch: " + pkgSpec
+ " " + pkg);
+                                    Utils.displayError(b, level + 1, "Version mismatch: "
+ pkgSpec + " " + pkg);
                                 }
                             }
                         }
@@ -194,36 +180,26 @@ public class DiagnoseCommand extends Osg
                             continue;
                         }
                         if (b.getSymbolicName() == null) {
-                            displayError(b, level, "No SymbolicName for " + b.getLocation());
+                            Utils.displayError(b, level, "No SymbolicName for " + b.getLocation());
                             continue;
                         }
                         if (constraint.getName() == null) {
-                            displayError(bundle, level, "No constraint name: " + constraint);
+                            Utils.displayError(bundle, level, "No constraint name: " + constraint);
                         }
                         if (b.getSymbolicName().equals(constraint.getName())) {
                             if (constraint.getVersionRange().isIncluded(b.getVersion()))
{
                                 // There must be something wrong in the bundle
                                 analyzeErrors(b, state, bundles, level + 1);
                             } else {
-                                displayError(bundle, level, "Version mismatch: " + constraint
+ " " + b);
+                                Utils.displayError(bundle, level, "Version mismatch: " +
constraint + " " + b);
                             }
                         }
                     }
                     break;
                 case IMPORT_PACKAGE_USES_CONFLICT:
-                    ImportPackageSpecification importPackage = (ImportPackageSpecification)constraint;
-                    ExportPackageDescription pkg = findExportPackage(importPackage, state.getExportedPackages());
-                    if (pkg != null) {
-                        if (simple) {
-                            displayError(pkg.getExporter(), level + 1, pkg.toString());
-                        } else {
-                            String[] uses = (String[]) pkg.getDirective("uses");
-                            if (uses != null) {
-                                for (String usePackageName : uses) {
-                                    checkPackageConflict(importPackage, pkg, usePackageName,
state, level + 1);
-                                }
-                            }
-                        }
+                    if (!simple) {
+                        PackageUsesHelper helper = new PackageUsesHelper(state);
+                        helper.analyzeConflict(bundle, level);
                     }
                     break;
                 case REQUIRE_BUNDLE_USES_CONFLICT:
@@ -234,127 +210,5 @@ public class DiagnoseCommand extends Osg
         }
         return errors;
     }
-    
-    private void checkPackageConflict(ImportPackageSpecification importPackage, ExportPackageDescription
wiredExportPackage, String usePackageName, State state, int level) {
-        
-        BundleDescription importing = importPackage.getBundle();
-        BundleDescription exporting = wiredExportPackage.getExporter();
-        
-        // find import package the importing bundle has
-        ImportPackageSpecification useImportPackage = findImportPackage(usePackageName, importing.getImportPackages());
-        
-        if (useImportPackage != null) {
-            
-            /* 
-             * Find exported package the exporting bundle is wired to.
-             * A package in "uses" clause can refer to an imported package or exported package
so 
-             * need to check both places.
-             */
-            ExportPackageDescription exportPackage = findExportPackage(usePackageName, exporting.getResolvedImports());
-            if (exportPackage == null) {
-                exportPackage = findExportPackage(usePackageName, exporting.getExportPackages());
-            }
-            
-            ExportPackageDescription highestExportPackage = findExportPackage(useImportPackage,
state.getExportedPackages());
-            
-            if (exportPackage.getExporter().getBundleId() != highestExportPackage.getExporter().getBundleId())
{
-                
-                displayError(null, level, "Found possible conflict for " + usePackageName
+ " package which is used by " + importPackage.getName() + " package:");
-                
-                displayError(importing, level + 1, useImportPackage + " is wiring to " +
bundleInfo(highestExportPackage.getExporter()));
-                displayError(importing, level + 1, importPackage + " is wiring to " + bundleInfo(wiredExportPackage.getExporter()));
-                
-                ImportPackageSpecification eImportPackage = findImportPackage(usePackageName,
exporting.getImportPackages());
-                if (eImportPackage == null) {
-                    displayError(exporting, level + 2, exportPackage.toString());
-                } else {
-                    displayError(exporting, level + 2, eImportPackage + " is wiring to "
+ bundleInfo(exportPackage.getExporter()));
-                }
-
-            }
-        }
-        
-    }
-    
-    private static ExportPackageDescription findExportPackage(String packageName, ExportPackageDescription[]
exports) {
-        for (ExportPackageDescription pkg : exports) {
-            if (pkg.getName().equals(packageName)) {
-                return pkg;
-            }
-        }
-        return null;
-    }
-    
-    private static ImportPackageSpecification findImportPackage(String packageName, ImportPackageSpecification[]
imports) {
-        for (ImportPackageSpecification pkg : imports) {
-            if (pkg.getName().equals(packageName)) {
-                return pkg;
-            }
-        }
-        return null;
-    }
-    
-    private static ExportPackageDescription findExportPackage(ImportPackageSpecification
packageName, ExportPackageDescription[] exports) {
-        List<ExportPackageDescription> matches = new ArrayList<ExportPackageDescription>(2);
-        for (ExportPackageDescription pkg : exports) {
-            if (packageName.getName().equals(pkg.getName()) && packageName.getVersionRange().isIncluded(pkg.getVersion()))
{
-                matches.add(pkg);
-            }
-        }
-        int size = matches.size();
-        if (size == 0) {
-            return null;
-        } else if (size == 1) {
-            return matches.get(0);
-        } else {
-            Collections.sort(matches, ExportPackageComparator.INSTANCE);
-            return matches.get(0);
-        }      
-    }
-    
-    private static class ExportPackageComparator implements Comparator<ExportPackageDescription>
{
-        
-        static final ExportPackageComparator INSTANCE = new ExportPackageComparator();
-        
-        public int compare(ExportPackageDescription object1, ExportPackageDescription object2)
{
-            return object2.getVersion().compareTo(object1.getVersion());
-        }            
-    }
-    
-    private static void displayError(BundleDescription bundle, int level, String object)
{
-        StringBuilder msg = new StringBuilder();
-        for (int i = 0; i < level; i++) {
-            msg.append("  ");
-        }
-        if (bundle != null) {
-            msg.append(error(bundleInfo(bundle)));
-        }
-        if (object != null) {
-            if (bundle != null) {
-                msg.append(" ");
-            }
-            msg.append(error(object));
-        }
-        System.out.println(msg.toString());
-    }
-    
-    private static String bundleInfo(BundleDescription bundle) {
-        return bundle.getSymbolicName() + " [" + bundle.getBundleId() + "]";
-    }
-            
-    private static String toString(VersionConstraint constraint) {
-        VersionRange versionRange = constraint.getVersionRange();
-        if (versionRange == null) {
-            return constraint.getName();
-        } else {
-            String versionAttribute;            
-            if (constraint instanceof ImportPackageSpecification) {
-                versionAttribute = "version=\"" + versionRange + "\"";
-            } else {
-                versionAttribute = "bundle-version=\"" + versionRange + "\"";
-            }
-            return constraint.getName() + "; " + versionAttribute;
-        }
-    }
-    
+   
 }

Added: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java?rev=1161696&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
(added)
+++ geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
Thu Aug 25 18:56:06 2011
@@ -0,0 +1,375 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.geronimo.shell.diagnose;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Constants;
+
+public class PackageUsesHelper {
+            
+    private final State state;
+    
+    public PackageUsesHelper(State state) {
+        this.state = state;
+    }
+    
+    public void analyzeConflict(BundleDescription bundle, int level) {
+        // ignore fragment bundles
+        if (bundle.getHost() != null) {
+            return;
+        }
+        
+        PackageGraph graph = new PackageGraph();
+        
+        List<PackageEdge> edges = new ArrayList<PackageEdge>();
+        ImportPackageSpecification[] importPackages = bundle.getImportPackages();
+        for (ImportPackageSpecification importPackage : importPackages) {
+            PackageEdge edge = processImportPackage(graph, bundle, importPackage);
+            if (edge != null) {
+                edges.add(edge);
+            }
+        }
+
+        for (Map.Entry<String, Set<PackageNode>> entry : graph.packageMap.entrySet())
{
+            Set<PackageNode> versions = entry.getValue();
+            if (hasMultipleDifferentExporters(versions)) {
+                
+                String packageName = entry.getKey();
+                System.out.println();
+                System.out.println(Utils.formatMessage(level, "Found multiple versions of
package " + packageName + " in bundle's dependency graph:"));
+                
+                for (PackageNode version : versions) {
+                    System.out.println(Utils.formatErrorMessage(level + 1, "package " + version.getPackageNameAndVersion()
+ " is exported from " + Utils.bundleToString(version.getPackageExporter())));           
                
+                }
+                
+                System.out.println();
+                System.out.println(Utils.formatMessage(level, "Dependency paths:"));
+                
+                for (PackageEdge edge : edges) {
+                    List<PackagePath> paths = edge.findPathsToPackage(packageName);
+                    if (!paths.isEmpty()) {
+                        for (PackagePath path : paths) {
+                            System.out.println(path.toString(level + 1));
+                        }
+                    }
+                }
+            }
+        }
+        
+    }
+    
+    private boolean hasMultipleDifferentExporters(Set<PackageNode> versions) {
+        if (versions.size() > 1) {
+            BundleDescription exporter = null;
+            for (PackageNode version : versions) {
+                if (exporter == null) {
+                    exporter = version.getExportPackage().getExporter();
+                } else if (exporter != version.getExportPackage().getExporter()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    private PackageEdge processImportPackage(PackageGraph graph, BundleDescription importer,
ImportPackageSpecification importPackage) {
+        ExportPackageDescription exportedPackage = null;
+        if (importer.isResolved()) {
+            exportedPackage = findExportPackage(importPackage.getName(), importer.getResolvedImports());
+        } else {
+            exportedPackage = findExportPackage(importPackage, state.getExportedPackages());
+        }
+        if (exportedPackage == null) {
+            String resolution = (String) importPackage.getDirective(Constants.RESOLUTION_DIRECTIVE);
+            if (ImportPackageSpecification.RESOLUTION_OPTIONAL.equals(resolution) ||
+                ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(resolution)) {
+                return null;
+            } else {
+                throw new RuntimeException(importPackage + " cannot be satisfied for " +
Utils.bundleToString(importer));
+            }
+        }
+        return new PackageEdge(processExportPackage(graph, exportedPackage), importPackage);
+    }
+    
+    private PackageNode processExportPackage(PackageGraph graph, ExportPackageDescription
exportedPackage) {
+        PackageNode node = graph.getNode(exportedPackage);
+        if (node != null) {
+            return node;
+        }
+        node = graph.addNode(exportedPackage);
+        
+        String[] uses = (String[]) exportedPackage.getDirective("uses");
+        if (uses != null) {
+            BundleDescription bundle = exportedPackage.getExporter();
+            for (String usePackageName : uses) {
+                // see uses clause points to import or export package
+                ImportPackageSpecification useImportPackage = findImportPackage(usePackageName,
bundle.getImportPackages());
+                if (useImportPackage == null) {
+                    ExportPackageDescription useExportPackage = findExportPackage(usePackageName,
bundle.getExportPackages());
+                    if (useExportPackage == null) {
+                        throw new RuntimeException("No import or export package for an 'uses'
package " + usePackageName + " in " + Utils.bundleToString(bundle));
+                    } else {
+                        PackageEdge edge = new PackageEdge(processExportPackage(graph, useExportPackage));
+                        node.addEdge(edge);
+                    }
+                } else {
+                    PackageEdge edge = processImportPackage(graph, bundle, useImportPackage);
+                    if (edge != null) {
+                        node.addEdge(edge);
+                    }
+                }
+            }
+        }
+        
+        return node;
+    }
+    
+    private static ExportPackageDescription findExportPackage(String packageName, ExportPackageDescription[]
exports) {
+        for (ExportPackageDescription pkg : exports) {
+            if (pkg.getName().equals(packageName)) {
+                return pkg;
+            }
+        }
+        return null;
+    }
+    
+    private static ImportPackageSpecification findImportPackage(String packageName, ImportPackageSpecification[]
imports) {
+        for (ImportPackageSpecification pkg : imports) {
+            if (pkg.getName().equals(packageName)) {
+                return pkg;
+            }
+        }
+        return null;
+    }
+    
+    private static ExportPackageDescription findExportPackage(ImportPackageSpecification
packageName, ExportPackageDescription[] exports) {
+        List<ExportPackageDescription> matches = new ArrayList<ExportPackageDescription>(2);
+        for (ExportPackageDescription pkg : exports) {
+            if (packageName.getName().equals(pkg.getName()) && packageName.getVersionRange().isIncluded(pkg.getVersion()))
{
+                matches.add(pkg);
+            }
+        }
+        int size = matches.size();
+        if (size == 0) {
+            return null;
+        } else if (size == 1) {
+            return matches.get(0);
+        } else {
+            Collections.sort(matches, ExportPackageComparator.INSTANCE);
+            return matches.get(0);
+        }      
+    }
+    
+    private static class ExportPackageComparator implements Comparator<ExportPackageDescription>
{
+        
+        static final ExportPackageComparator INSTANCE = new ExportPackageComparator();
+        
+        public int compare(ExportPackageDescription object1, ExportPackageDescription object2)
{
+            return object2.getVersion().compareTo(object1.getVersion());
+        }            
+    }
+    
+    private static class PackageGraph {
+    
+        private Map<String, Set<PackageNode>> packageMap = new HashMap<String,
Set<PackageNode>>();
+        private Map<ExportPackageDescription, PackageNode> nodes = new HashMap<ExportPackageDescription,
PackageNode>();
+        
+        public PackageNode getNode(ExportPackageDescription exportPackage) {
+            return nodes.get(exportPackage);
+        }
+        
+        public PackageNode addNode(ExportPackageDescription exportPackage) {
+            PackageNode node = new PackageNode(exportPackage);
+            nodes.put(exportPackage, node);
+            
+            Set<PackageNode> versions = packageMap.get(exportPackage.getName());
+            if (versions == null) {
+                versions = new HashSet<PackageNode>();
+                packageMap.put(exportPackage.getName(), versions);
+            }
+            versions.add(node);
+
+            return node;
+        }
+
+    }
+    
+    private static class PackageEdge {
+        private ImportPackageSpecification importPackage;
+        private PackageNode target;
+        
+        public PackageEdge(PackageNode target) {
+            this(target, null);
+        }
+        
+        public PackageEdge(PackageNode target, ImportPackageSpecification importPackage)
{
+            this.target = target;
+            this.importPackage = importPackage;
+        }
+        
+        public PackageNode getTarget() {
+            return target;
+        }
+        
+        public ImportPackageSpecification getImportPackage() {
+            return importPackage;
+        }
+        
+        public List<PackagePath> findPathsToPackage(String packageName) {
+            List<PackagePath> paths = new ArrayList<PackagePath>();
+            findPathsToPackage(paths, new PackagePath(), packageName);
+            return paths;
+        }
+        
+        public void findPathsToPackage(List<PackagePath> paths, PackagePath path, String
packageName) {
+            if (path.contains(this)) {
+                throw new RuntimeException("Cirucular dependency path detected: " + path);
+            }
+            path.addLast(this);
+            
+            if (packageName.equals(target.getExportPackage().getName())) {
+                PackagePath copy = new PackagePath(path);
+                paths.add(copy);
+            } else {
+                this.target.findPathsToPackage(paths, path, packageName);
+            }
+            
+            path.removeLast();
+        }
+    }
+    
+    private static class PackageNode {
+        
+        private ExportPackageDescription exportPackage;
+        // list of package uses
+        private List<PackageEdge> edges;
+        
+        public PackageNode(ExportPackageDescription exportPackage) {
+            this.exportPackage = exportPackage;
+            this.edges = new ArrayList<PackageEdge>();
+        }
+        
+        public ExportPackageDescription getExportPackage() {
+            return exportPackage;
+        }
+        
+        public void addEdge(PackageEdge usedPackage) {
+            edges.add(usedPackage);
+        }
+        
+        private void findPathsToPackage(List<PackagePath> paths, PackagePath path,
String packageName) {
+            for (PackageEdge edge : edges) {
+                edge.findPathsToPackage(paths, path, packageName);
+            }
+        }
+                
+        public String toString() {
+            return getPackageNameAndVersion();
+        }
+        
+        public String getPackageNameAndVersion() {
+            return exportPackage.getName() + "; version=\"" + exportPackage.getVersion()
+ "\"";
+        }
+        
+        public BundleDescription getPackageExporter() {
+            return exportPackage.getExporter();
+        }
+    }
+    
+    private static class PackagePath extends LinkedList<PackageEdge> {
+        
+        public PackagePath() {            
+        }
+        
+        public PackagePath(PackagePath path) {
+            super(path);
+        }
+
+        public String toString() {
+            return toString(0);
+        }
+        
+        public String toString(int level) {
+            StringBuilder builder = new StringBuilder();
+            Iterator<PackageEdge> iterator = iterator();
+            if (iterator.hasNext()) {
+                PackageEdge edge = iterator.next();
+                PackageNode node = edge.getTarget();
+                
+                builder.append(importToString(level, edge, iterator.hasNext()));
+                builder.append(Utils.LINE_SEPARATOR);
+
+                while (iterator.hasNext()) {
+                    PackageEdge nextEdge = iterator.next(); 
+                    PackageNode nextNode = nextEdge.getTarget();
+                    
+                    builder.append(usesToString(level + 1, node, nextNode));
+                    builder.append(Utils.LINE_SEPARATOR);
+                    
+                    if (nextEdge.getImportPackage() != null) {                          
      
+                        builder.append(importToString(level + 1, nextEdge, iterator.hasNext()));
+                        builder.append(Utils.LINE_SEPARATOR);
+                        level++;
+                    }
+                    
+                    edge = nextEdge;
+                    node = nextNode;
+                }
+            }
+            return builder.toString();
+        }
+        
+        private static String importToString(int level, PackageEdge edge, boolean hasMore)
{
+            StringBuilder builder = new StringBuilder();            
+            builder.append(Utils.bundleToString(edge.getImportPackage().getBundle())).append("
imports package ").append(Utils.importPackageToString(edge.getImportPackage()));
+            if (edge.getImportPackage().isResolved()) {
+                builder.append(" and is wired to ");
+            } else {
+                builder.append(" wants to wire to ");
+            }
+            builder.append(Utils.bundleToString(edge.getTarget().getPackageExporter()));
+            if (hasMore) {
+                return Utils.formatMessage(level, builder.toString());
+            } else {
+                return Utils.formatErrorMessage(level, builder.toString());
+            }
+        }
+        
+        private static String usesToString(int level, PackageNode source, PackageNode target)
{
+            StringBuilder builder = new StringBuilder();  
+            builder.append("package ").append(source.getExportPackage().getName());
+            builder.append(" uses package ").append(target.getExportPackage().getName());
+            return Utils.formatMessage(level, builder.toString());
+        }
+
+    }
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/PackageUsesHelper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java?rev=1161696&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
(added)
+++ geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
Thu Aug 25 18:56:06 2011
@@ -0,0 +1,110 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.apache.geronimo.shell.diagnose;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.VersionConstraint;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.Ansi.Color;
+
+public class Utils {
+
+    public static final String PADDING = "  ";
+    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
+    
+    public static String error(String msg) {
+        return Ansi.ansi().fg(Color.RED).a(msg).reset().toString();
+    }
+    
+    public static String warning(String msg) {
+        return Ansi.ansi().fg(Color.YELLOW).a(msg).reset().toString();
+    }
+    
+    public static String formatMessage(int level, String message) {
+        return formatMessage(level, message, null);
+    }
+    
+    public static String formatErrorMessage(int level, String message) {
+        return formatMessage(level, message, Color.RED);
+    }
+    
+    public static String formatWarningMessage(int level, String message) {
+        return formatMessage(level, message, Color.YELLOW);
+    }
+       
+    private static String formatMessage(int level, String message, Color color) {
+        StringBuilder msg = new StringBuilder();
+        for (int i = 0; i < level; i++) {
+            msg.append(PADDING);
+        }
+        if (color != null) {
+            msg.append(Ansi.ansi().fg(color).a(message).reset().toString());
+        } else {
+            msg.append(message);
+        }
+        return msg.toString();
+    }
+    
+    public static void displayError(BundleDescription bundle, int level, String object) {
+        StringBuilder msg = new StringBuilder();
+        for (int i = 0; i < level; i++) {
+            msg.append(PADDING);
+        }
+        if (bundle != null) {
+            msg.append(error(bundleToString(bundle)));
+        }
+        if (object != null) {
+            if (bundle != null) {
+                msg.append(" ");
+            }
+            msg.append(error(object));
+        }
+        System.out.println(msg.toString());
+    }
+    
+    public static String bundleToString(BundleDescription bundle) {
+        return bundle.getSymbolicName() + " [" + bundle.getBundleId() + "]";            
+    }
+    
+    public static String importPackageToString(ImportPackageSpecification importPackage)
{
+        return importPackage.getName() + "; version=\"" + importPackage.getVersionRange()
+ "\"";
+    }
+    
+    public static String exportPackageToString(ExportPackageDescription exportPackage) {
+        return exportPackage.getName() + "; version=\"" + exportPackage.getVersion() + "\"";
+    }
+            
+    public static String versionToString(VersionConstraint constraint) {
+        VersionRange versionRange = constraint.getVersionRange();
+        if (versionRange == null) {
+            return constraint.getName();
+        } else {
+            String versionAttribute;            
+            if (constraint instanceof ImportPackageSpecification) {
+                versionAttribute = "version=\"" + versionRange + "\"";
+            } else {
+                versionAttribute = "bundle-version=\"" + versionRange + "\"";
+            }
+            return constraint.getName() + "; " + versionAttribute;
+        }
+    }
+ 
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-shell-diagnose/src/main/java/org/apache/geronimo/shell/diagnose/Utils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message