You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by jc...@apache.org on 2009/04/21 23:30:31 UTC

svn commit: r767303 - in /incubator/river/jtsk/trunk/src/com/sun/jini/tool: ClassDep.java classdepend/ClassDepend.java classdepend/ClassDependParameters.java classdepend/ClassDependencyRelationship.java classdepend/ClassDependencyTreeNodes.java

Author: jcosters
Date: Tue Apr 21 21:30:30 2009
New Revision: 767303

URL: http://svn.apache.org/viewvc?rev=767303&view=rev
Log:
RIVER-272: Updates to Classdep replacement ClassDepend, by Peter Firmstone (ClassDep-a6.patch). Added Apache license header to all files.

Added:
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java   (with props)
Removed:
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyTreeNodes.java
Modified:
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/ClassDep.java
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDepend.java
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependParameters.java

Modified: incubator/river/jtsk/trunk/src/com/sun/jini/tool/ClassDep.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/com/sun/jini/tool/ClassDep.java?rev=767303&r1=767302&r2=767303&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/com/sun/jini/tool/ClassDep.java (original)
+++ incubator/river/jtsk/trunk/src/com/sun/jini/tool/ClassDep.java Tue Apr 21 21:30:30 2009
@@ -20,6 +20,7 @@
 import com.sun.jini.tool.classdepend.ClassDepend;
 import com.sun.jini.tool.classdepend.ClassDependParameters;
 import com.sun.jini.tool.classdepend.ClassDependParameters.CDPBuilder;
+import com.sun.jini.tool.classdepend.ClassDependencyRelationship;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -33,6 +34,8 @@
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Tool used to analyze a set of classes and determine on what other classes
@@ -809,38 +812,6 @@
 	}
     }
 
-
-    /*
-     * Depending on the part of the class file
-     * that we are on the class types that we are
-     * looking for can come in several flavors.
-     * This method handles Identifiers and 
-     * Identifiers referenced from other Identifiers.
-     * <p>
-     * Several actions happen here with the goal of 
-     * generating the list of dependencies within the domain
-     * space provided by the user.
-     * These actions are:
-     * <ul>
-     *    <li> printing out "-tell" output if user asks for it.
-     *    <li> extracting class types from the class file.
-     *         <ul>
-     *             <li> either in arrays or by
-     *             <li> themselves
-     *         </ul>
-     *    <li> noting classes we have already seen.
-     *    <li> traversing the remainder of the class file.
-     *    <li> resolving and looking for dependencies in
-     *         inner classes.
-     *    <li> saving found results for later use.
-     * </ul>
-     *
-     * @param from the Identifier referenced from <code>id</code>
-     * @param id   the Identifier being looked at
-	 *
-     * The above was for the old process(Identifier from, Identifier id) method.
-	 */	
-
     private static class Compare implements Comparator {
 	public int compare(Object o1, Object o2) {
 	    if (o1 == null) {
@@ -901,54 +872,67 @@
 		traverse((String)roots.get(i));
 	    }
 	}
-        // Now use ClassDepend to perform dependency computation
-        Iterator itr = classes.iterator();
-        
-        //System.out.println("Classes to include:");
-        while (itr.hasNext()){
-            System.out.println(itr.next());
-        }
-        
-        //Ready the Parameter Builder for ClassDepend
-        CDPBuilder cdpb = new CDPBuilder();
-       
-        cdpb.addOutsidePackagesOrClasses(addClassesRecursively(outside))
-                .addOutsidePackagesOrClasses(skips)
-                .addInsidePackages(addClassesRecursively(inside))
-                .addShowPackages(addClassesRecursively(shows))
-                .addHidePackages(addClassesRecursively(hides));
         
+        // Now use ClassDepend to perform dependency computation
         if (classpath.length() == 0) { classpath = null; }
         try {
-            cd = ClassDepend.newInstance(classpath, "JDK 1.4", true);
+            cd = ClassDepend.newInstance(classpath, null, true);
         } catch (IOException e) {
             e.printStackTrace();
         }
-        ClassDependParameters cdp = cdpb.addRootClasses(classes)
-                .recurse(true)
-                .excludePlatformClasses(false)
-                .build();
-        
+        Map classDependencyRelationMap = null;
         try{
-            results.addAll(cd.compute(cdp));
+            classDependencyRelationMap = cd.getDependencyRelationshipMap(classes, true); // get the reference to Collection<Class>
         }catch (ClassNotFoundException e){
             e.printStackTrace();
         }catch (IOException e) {
             e.printStackTrace();
         }
          
-        /*
-	for (int i = 0; i < classes.size(); i++) {
-	    process(null, (String)classes.get(i));
+        if (tells.isEmpty()){
+            // Here's where we should build the parameter list and call the filter
+            //Ready the Parameter Builder for ClassDepend
+            // .ignoreOuterParentClass(ignoreOuter) isn't implemented in ClassDepend yet.
+            CDPBuilder cdpb = new CDPBuilder();
+            ClassDependParameters cdp = cdpb.addOutsidePackagesOrClasses(addClassesRecursively(outside))
+                    .addOutsidePackagesOrClasses(skips)
+                    .addInsidePackages(addClassesRecursively(inside))
+                    .addShowPackages(addClassesRecursively(shows))
+                    .addHidePackages(addClassesRecursively(hides))
+                    .ignoreOuterParentClass(ignoreOuter)                   
+                    .excludePlatformClasses(false)
+                    .edges(edges)
+                    .build();
+            Set result = cd.filterClassDependencyRelationShipMap
+                    (classDependencyRelationMap, cdp);
+            Iterator itr = result.iterator();
+            while (itr.hasNext()) {
+                results.add(itr.next().toString());
 	}
-        */
+        }else{
         
-        /* the -tells option needs to be handled by ClassDepend somehow
-         */
-        
-	if (!tells.isEmpty()) {
-	    return new String[0];
+            Iterator iter = tells.iterator();
+            while (iter.hasNext()){
+                String name = (String) iter.next();
+                if ( classDependencyRelationMap.containsKey(name)){
+                    ClassDependencyRelationship provider = (ClassDependencyRelationship) classDependencyRelationMap.get(name);
+                    Set dependants = provider.getDependants();
+                    if (!dependants.isEmpty()) {
+                        Iterator it = dependants.iterator();
+                        while (it.hasNext()) {
+                            ClassDependencyRelationship dependant = (ClassDependencyRelationship) it.next();
+                            if (tells.size() > 1) {
+                                print("classdep.cause", provider, dependant);
+        }
+                            else {
+                                print("classdep.cause1", dependant);
+                            }                 
+                        }
+                    }
+                }
+            }
         }
+        // cannot change the return type or we break the API backward compatibility.
 	return (String[])results.toArray(new String[results.size()]);
     }
 
@@ -1353,5 +1337,4 @@
 	}
     }
 		    }
-
 	}

Modified: incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDepend.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDepend.java?rev=767303&r1=767302&r2=767303&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDepend.java (original)
+++ incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDepend.java Tue Apr 21 21:30:30 2009
@@ -1,3 +1,20 @@
+/*
+ * 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 com.sun.jini.tool.classdepend;
 
 import com.sun.jini.tool.classdepend.ClassDependParameters.CDPBuilder;
@@ -10,8 +27,10 @@
 import java.net.URLClassLoader;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;
@@ -109,6 +128,8 @@
             CDPBuilder cdpb = new CDPBuilder();
 	    String classpath = null;
 	    String platform = null;
+            Set rootClasses = new HashSet();
+            boolean recurse = true;
 	    boolean warn = false; //supress exceptions, print to error, warn instead
 	    boolean files = false; //print class with file path separator
 	    for (int i = 0; i < args.length; i++) {
@@ -120,7 +141,7 @@
 		} else if (arg.equals("-exclude")) {
 		    cdpb.addOutsidePackageOrClass(args[++i]);
 		} else if (arg.equals("-norecurse")) {
-		    cdpb.recurse(false);
+		    recurse = false;
 		} else if (arg.equals("-warn")) {
 		    warn = true;
 		} else if (arg.equals("-files")) {
@@ -128,12 +149,18 @@
 		} else if (arg.startsWith("-")) {
 		    throw new IllegalArgumentException("Bad option: " + arg);
 		} else {
-		    cdpb.addRootClass(arg);
+		    rootClasses.add(arg);
 		}
 	    }
             ClassDependParameters cdp = cdpb.build();          
 	    ClassDepend classDepend = ClassDepend.newInstance(classpath, platform, warn);
-	    String[] dependencies = (String[]) classDepend.compute(cdp).toArray(new String[0]);
+            
+            
+	    String[] dependencies = (String[]) classDepend
+                    .filterClassDependencyRelationShipMap(
+                    classDepend.getDependencyRelationshipMap(rootClasses, recurse),
+                    cdp)
+                    .toArray(new String[0]);
 	    Arrays.sort(dependencies);
             int l = dependencies.length;
 	    for ( int i = 0 ; i < l ; i++) {
@@ -193,72 +220,54 @@
     }
 
     /**
+     * This method builds the entire DependencyRelationShipMap that can be
+     * used to analyse class dependencies.
+     * 
      * Computes information about class dependencies.  The computation of
      * dependencies starts with the classes that match the names in
-     * <code>roots</code>.  Classes are found in a URL class loader by the
-     * <code>classpath</code> specified in the constructor.  Classes that can
-     * be found in the class loader specified by the <code>platform</code>
-     * argument to the constructor are excluded from the computation.  Classes
-     * that match names in <code>excludes</code> are excluded from the
-     * computation.  Dependencies will be computed recursively if
-     * <code>recurse</code> is <code>true</code>; otherwise, only classes
-     * directly referenced by classes named in <code>roots</code> will be
-     * included.
+     * <code>rootClasses</code>.  Classes are found in a URL class loader by the
+     * <code>classpath</code> specified in the constructor. 
      *
-     * @param   cdp The immutable parameter class.
-     * @see ClassDependParameters, CDPBuilder
-     * @return	a set of the dependent classes
-     * @throws	ClassNotFoundException if a class is not found and this
-     *		exception is thrown by {@link #noteClassNotFound
-     *		noteClassNotFound}
-     * @throws	IOException if an I/O error occurs while reading class
-     *		bytecodes and this exception is thrown by {@link
-     *		#noteClassLoadingFailed noteClassLoadingFailed}
+     * @param rootClasses 
+     * @param recurse If true, this option causes ClassDepend to inspect class 
+     * files for dependencies.
+     * If false, ClassDepend doesn't inspect class files, it simply
+     * gathers the names of class files from within Package directories and 
+     * JAR files.
+     * @return result
+     * @throws java.io.IOException
+     * @throws java.lang.ClassNotFoundException
+     * @see ClassDependencyRelationship
      */
-    public Set compute(ClassDependParameters cdp)
-	throws ClassNotFoundException, IOException
-    {
-	// Collection roots, Collection excludes, boolean recurse
-        Set compute = computeClasses(cdp.rootClasses()); // Discovers all root classes including those in packages
-	Pattern excludePattern = createPattern(cdp.outsidePackagesOrClasses());     
-        Pattern includePattern = createPattern(cdp.insidePackages());
-        Pattern hidePattern = createPattern(cdp.hidePackages());
-        Pattern showPattern = createPattern(cdp.showPackages());
-	Set result = new HashSet();
+    public Map getDependencyRelationshipMap(Collection rootClasses, boolean recurse) 
+            throws IOException, ClassNotFoundException {
+        Map result = new HashMap(); // May be changed to ConcurrentHashMap for Java 5
         Set seen = new HashSet();
-        
+        Set compute = computeClasses(rootClasses);      
 	while (!compute.isEmpty()) {
-	    Set computeNext = new HashSet(); //built from 
+            Set computeNext = new HashSet(); //built from discovered dependencies
             Iterator computeIterator = compute.iterator();            
 	    while (computeIterator.hasNext()) {
                 String name = (String) computeIterator.next();
-                // filter out the crap
-                if (!seen.contains(name) &&
-		    ( !cdp.excludePlatformClasses() || !classPresent(name, platformLoader) ) &&
-		    !matches(name, excludePattern) && 
-                    ( cdp.insidePackages().size() == 0 || matches(name, includePattern)))
-		{
-		     /* If we have shows or hides, we don't want to add these to
-                     * the result, however we don't want to drop out of the
-                     * dependency search either
-                     */
+                if ( !seen.contains(name)){
                     seen.add(name);
-                    if(( cdp.hidePackages().size() == 0 || !matches(name,hidePattern) )
-                            && ( cdp.showPackages().size() == 0 || matches(name, showPattern)))
-                    {
-                        result.add(name); //Add the result after filtering
+                    if (rootClasses.contains(name)){
+                        // Put all root classes into ClassDependencyRelationship containers
+                        ClassDependencyRelationship rootClass = new ClassDependencyRelationship(name, true);
+                        result.put(name, rootClass);
                     }
+                    Set providerClassNames = new HashSet();
 		    String resource = getResourceName(name);
-		    if (cdp.recurse()) {
+                    if (recurse) {
 			InputStream in = loader.getResourceAsStream(resource);
 			if (in == null) {
 			    noteClassNotFound(name);
 			} else {
 			    try {
                                 // Discover the referenced classes by loading classfile and inspecting
-				computeNext.addAll(
-				    ReferencedClasses.compute(
-					new BufferedInputStream(in)));
+                                providerClassNames = ReferencedClasses.compute(
+                                        new BufferedInputStream(in));
+                                computeNext.addAll(providerClassNames);
 			    } catch (IOException e) {
 				noteClassLoadingFailed(name, e);
 			    } finally {
@@ -271,14 +280,115 @@
 		    } else if (loader.getResource(resource) == null) {
 			noteClassNotFound(name);
 		    }
+                    /* Now we add all the provider classes to the dependant
+                     * this is useful for edges or classes of interest where 
+                     * we my want to pick points to recurse through dependents 
+                     * instead of providers.
+                     */
+                   Iterator iter = providerClassNames.iterator();
+                    while (iter.hasNext()){
+                        String provider = (String) iter.next();
+                        ClassDependencyRelationship providerClass;
+                        if (!result.containsKey(provider)){
+                            providerClass = new ClassDependencyRelationship(provider);
+                            result.put(provider, providerClass);
+                        }else{
+                            providerClass = (ClassDependencyRelationship) result.get(provider);
 		}
+                        ((ClassDependencyRelationship) result.get(name)).addProvider(providerClass);
 	    }
+                }
+            }
+            /* The old list is exhausted, lets iterate through our newly
+             * discovered collection.
+             */
 	    compute = computeNext;
 	}
 	return result;
     }
 
     /**
+     * This method applies optional filters to provide methods to support the
+     * original API of ClassDep.
+     * @param dependencyRelationShipMap The initial map before filtering.
+     * @param cdp The parameters for filtration.
+     * @see ClassDependParameters, ClassDependencyRelationship
+     * @return Set<ClassDependencyRelationShip> result The result after filtration.
+     */
+    public Set filterClassDependencyRelationShipMap(Map dependencyRelationShipMap, ClassDependParameters cdp){
+        Set result = new HashSet(); // final result
+        Set preliminaryResult = new HashSet();
+        
+        Pattern excludePattern = createPattern(cdp.outsidePackagesOrClasses());     
+        Pattern includePattern = createPattern(cdp.insidePackages());
+        Pattern hidePattern = createPattern(cdp.hidePackages());
+        Pattern showPattern = createPattern(cdp.showPackages());      
+        Collection classRelations = dependencyRelationShipMap.values();
+        // get the root class set.
+        Set rootClasses = new HashSet();
+        {
+            Iterator itr = classRelations.iterator();
+            while (itr.hasNext()){
+                ClassDependencyRelationship cdr = (ClassDependencyRelationship) itr.next();
+                if (cdr.isRootClass()){
+                    rootClasses.add(cdr);
+                }
+            }
+        }
+        // traverse the tree from root dependant to providers
+        while ( !rootClasses.isEmpty() ){
+            Set computeNext = new HashSet();
+            Iterator computeIterator = rootClasses.iterator();
+            while (computeIterator.hasNext()){
+                ClassDependencyRelationship cdr = (ClassDependencyRelationship) computeIterator.next();
+                String name = cdr.toString();
+                    // filter out the classes as requested
+                    if ( !preliminaryResult.contains(cdr) && 
+                        ( !cdp.excludePlatformClasses() || !classPresent(name, platformLoader) ) &&
+                        !matches(name, excludePattern) && 
+                        ( cdp.insidePackages().size() == 0 || matches(name, includePattern)))
+                    {
+                        // TODO remove the outer parent class if requested
+                        preliminaryResult.add(cdr);
+                        computeNext.addAll(cdr.getProviders());
+                    }
+            }
+            rootClasses = computeNext;
+        }
+        // populate the result with the edge classes if requested
+        if (cdp.edges()){
+            Iterator itr = preliminaryResult.iterator();
+            while (itr.hasNext()) {
+                ClassDependencyRelationship cdr = (ClassDependencyRelationship) itr.next();
+                result.addAll(cdr.getProviders());
+            }
+            /* edge classes aren't in the filtered preliminary result set ;), 
+             * so remove it just in case some classes from the preliminary
+             * result set snuck back in via the provider Sets;
+             */
+            result.removeAll(preliminaryResult); 
+        }else{
+            result = preliminaryResult;
+        }
+        
+        /* If we have shows or hides, we want to remove these from
+         * the result Collection, under certain conditions.
+         */
+        Set remove = new HashSet();
+        Iterator itr = result.iterator();
+        while (itr.hasNext()){
+            ClassDependencyRelationship cdr = (ClassDependencyRelationship) itr.next();
+            String name = cdr.toString();
+            if(( matches(name,hidePattern)|| ( showPattern != null && !matches(name, showPattern))))
+            {
+                remove.add(cdr);
+            }
+        }
+        result.removeAll(remove);
+        return result;
+    }
+
+    /**
      * Called when the specified class is not found. <p>
      *
      * This implementation throws a <code>ClassNotFoundException</code>.
@@ -364,8 +474,10 @@
      * argument.  Returns null if the argument is empty.  xNames that end in
      * '.*' match classes in the package, names that end in '.**' match classes
      * in the package and it's subpackage.  Other names match the class.
+     * @param names
+     * @return 
      */
-    private Pattern createPattern(Collection names) {
+    public Pattern createPattern(Collection names) {
 	if (names.isEmpty()) {
 	    return null;
 	}
@@ -397,8 +509,11 @@
     /**
      * Checks if the string matches the pattern, returning false if the pattern
      * is null.
+     * @param string
+     * @param pattern
+     * @return 
      */
-    private boolean matches(String string, Pattern pattern) {
+    public boolean matches(String string, Pattern pattern) {
 	return pattern != null && pattern.matcher(string).matches();
     }
     

Modified: incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependParameters.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependParameters.java?rev=767303&r1=767302&r2=767303&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependParameters.java (original)
+++ incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependParameters.java Tue Apr 21 21:30:30 2009
@@ -1,6 +1,19 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * 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 com.sun.jini.tool.classdepend;
 
@@ -24,32 +37,17 @@
      * or package patterns, that should be excluded from the computation */
 
     private final String[] outsidePackagesOrClasses;
-    private final String[] rootClasses; // classes were interested in finding dependencies for.
     private final String[] insidePackages; // package scope to search for dependencies in.
     private final String[] showPackages; //Show only the dependencies found in these Packages.
     private final String[] hidePackages; //Hide these packages from output, the dependencies are still calculated.
-    /*
-     * Specifies the fully qualified name of a class for which dependency
-     * information is desired. This option causes the tool to display
-     * information about every class in the dependency graph that references
-     * the specified class. This information is sent to the error stream of
-     * the tool, not to the normal output stream. This option can be specified
-     * zero or more times. If this option is used, all other output options
-     * are ignored, and the normal class output is not produced. 
-     * This option is useful for debugging.  
-     * Originally concieved in the original ClassDep as the -tells option.
-     */
-    private final String[] printErrStreamInfoOfClassesDependantOn;
-    private final boolean ignoreOuterParentClass; // For internal classes
-    private final boolean recurse;
+    private final boolean ignoreOuterParentClass; // For internal classes to ignore their parent class.
     private final boolean excludePlatformClasses;
+    private final boolean edges;
 
     private ClassDependParameters(CDPBuilder builder) {
 
         outsidePackagesOrClasses = (String[]) builder.outsidePackagesOrClasses.toArray(
                 new String[builder.outsidePackagesOrClasses.size()]);
-        rootClasses = (String[]) builder.rootClasses.toArray(
-                new String[builder.rootClasses.size()]);
         insidePackages = (String[]) builder.insidePackages.toArray(
                 new String[builder.insidePackages.size()]);
         showPackages = (String[]) builder.showPackages.toArray(
@@ -57,11 +55,8 @@
         hidePackages = (String[]) builder.hidePackages.toArray(
                 new String[builder.hidePackages.size()]);
         ignoreOuterParentClass = builder.ignoreOuterParentClass;
-        recurse = builder.recurse;
         excludePlatformClasses = builder.excludePlatformClasses;
-        printErrStreamInfoOfClassesDependantOn = (String[]) 
-                builder.printErrStreamInfoOfClassesDependantOn.toArray(
-                new String[builder.printErrStreamInfoOfClassesDependantOn.size()]);
+        edges = builder.edges;
 
     }
 
@@ -87,10 +82,6 @@
         return cloneArraytoList(outsidePackagesOrClasses);
     }
 
-    public List rootClasses() {
-        return cloneArraytoList(rootClasses);
-    }
-
     public List insidePackages() {
         return cloneArraytoList(insidePackages);
     }
@@ -103,28 +94,16 @@
         return cloneArraytoList(hidePackages);
     }
     
-    public List printErrStreamInfoOfClassesDependantOn() {
-        return cloneArraytoList(printErrStreamInfoOfClassesDependantOn);
-    }
-
     public boolean ignoreOuterParentClass() {
         return ignoreOuterParentClass;
     }
-    /* recurse if <code>true</code>, compute dependencies recursively;
-     * if <code>false</code>, only include classes directly referenced
-     * by classes in <code>roots</code>
-     */
-
-    public boolean recurse() {
-        return recurse;
-    }
 
     public boolean excludePlatformClasses() {
         return excludePlatformClasses;
     }
 
-    public String[] getPrintErrStreamInfoOfClassesDependantOn() {
-        return printErrStreamInfoOfClassesDependantOn;
+    public boolean edges() {
+        return edges;
     }
 
     /**
@@ -145,14 +124,12 @@
          */
 
         private List outsidePackagesOrClasses = new ArrayList();
-        private List rootClasses = new ArrayList();
         private List insidePackages = new ArrayList();
         private List showPackages = new ArrayList();
         private List hidePackages = new ArrayList();
-        private List printErrStreamInfoOfClassesDependantOn = new ArrayList();
         private boolean ignoreOuterParentClass = false;
-        private boolean recurse = true;
         private boolean excludePlatformClasses = false;
+        private boolean edges = false;
 
         public CDPBuilder() {
         }
@@ -188,23 +165,7 @@
             return this;
         }
 
-        public CDPBuilder addRootClass(String rootClass) {
-            rootClasses.add(rootClass);
-            return this;
-        }
-
-        public CDPBuilder addRootClasses(String[] rootClasses) {
-            int l = rootClasses.length;
-            for (int i = 0; i < l; i++) {
-                this.rootClasses.add(rootClasses[i]);
-            }
-            return this;
-        }
 
-        public CDPBuilder addRootClasses(List classes) {
-            rootClasses.addAll(classes);
-            return this;
-        }
 
         /**
          * Inside packages limit the scope of the dependency search to
@@ -272,73 +233,12 @@
             return this;
         }
         
-        /**
-         * Specifies the fully qualified name of a class for which dependency
-         * information is desired. This option causes the tool to display
-         * information about every class in the dependency graph that references
-         * the specified class. This information is sent to the error stream of
-         * the tool, not to the normal output stream. This option can be specified
-         * zero or more times. If this option is used, all other output options
-         * are ignored, and the normal class output is not produced. 
-         * This option is useful for debugging.  
-         * Originally concieved in the original ClassDep as the -tells option.
-         *
-         * @param clas A fully qualified class name for which dependent classes
-         *              will print information to the error stream.
-         * @return this
-         */
-        public CDPBuilder printErrStreamInfoOfClassesDependantOn(String clas) {
-            printErrStreamInfoOfClassesDependantOn.add(clas);
-            return this;
-        }
-        /**
-         * Print information to the error stream for all classes
-         * that depend on those in <code>classes</code>, the normal class
-         * output is not produced.
-         * @param classes
-         * @return
-         */
-        public CDPBuilder printErrStreamInfoOfClassesDependantOn(String [] classes){
-            int l = classes.length;
-            for (int i = 0; i < l; i++){
-                this.printErrStreamInfoOfClassesDependantOn.add(classes[i]);
-            }
-            return this;
-        }
-        /**
-         * Print information to the error stream for all classes
-         * that depend on those in <code>classes</code>, the normal class
-         * output is not produced.
-         * @param classes
-         * @return
-         */
-        public CDPBuilder printErrStreamInfoOfClassesDependantOn(List classes) {
-            printErrStreamInfoOfClassesDependantOn.addAll(classes);
-            return this;
-        }
-        
-        
-
         public CDPBuilder ignoreOuterParentClass(boolean b) {
             ignoreOuterParentClass = b;
             return this;
         }
 
         /**
-         * This option causes ClassDepend to inspect class files for dependencies,
-         * if true.  If false, ClassDepend doesn't inspect class files, it simply
-         * gathers the names of class files from within Package directories and 
-         * JAR files.
-         * 
-         * @param b
-         * @return
-         */
-        public CDPBuilder recurse(boolean b) {
-            recurse = b;
-            return this;
-        }
-
-        /**
          * This optional parameter if true, excludes Java platform classes
          * from the dependency search.
          * If false the platform classes returned will depend on the Java
@@ -352,6 +252,11 @@
             return this;
         }
 
+        public CDPBuilder edges(boolean e){
+            edges = e;
+            return this;
+        }
+
         /**
          * Builds ClassDependParameters immutable object from optional
          * parameters, execute this method last, after setting all optional

Added: incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java?rev=767303&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java (added)
+++ incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java Tue Apr 21 21:30:30 2009
@@ -0,0 +1,117 @@
+/*
+ * 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 com.sun.jini.tool.classdepend;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A container to store class dependency related information for later analysis.
+ * @author Peter Firmstone
+ * @Threadsafe
+ * @see ClassDepend
+ */
+public class ClassDependencyRelationship {
+
+    private final Set dependants;   // classes that depend upon this class.
+    private final Set providers;    // classes that this class depends upon.
+    private final String fullyQualifiedClassName;
+    private final boolean rootClass;
+    private volatile boolean result = false; // never set back to false, once true, true always.
+    private volatile boolean interesting = false;
+    
+    ClassDependencyRelationship (String fullyQualifiedClassName, boolean rootClass){
+        this.fullyQualifiedClassName = fullyQualifiedClassName;
+        dependants = Collections.synchronizedSet(new HashSet());
+        providers = Collections.synchronizedSet(new HashSet());
+        this.rootClass = rootClass;
+    }
+    
+    ClassDependencyRelationship (String fullyQualifiedClassName){
+        this(fullyQualifiedClassName, false);    
+    }
+    
+    // This is private since we tend to recurse the dependency tree from the
+    // dependant end to the provider.
+    private void addDependant(ClassDependencyRelationship dependant) {
+        synchronized (dependants) {
+            dependants.add(dependant);
+        }
+    }
+
+    /**
+     * Add a provider class to this dependant class.
+     * @param provider
+     */
+    public void addProvider(ClassDependencyRelationship provider) {
+        synchronized (providers){
+            providers.add(provider);
+        }
+        provider.addDependant(this);
+    }
+
+    /**
+     * Get the classes dependant on this class.
+     * @return classes dependant on this
+     */
+    public Set getDependants() {
+        Set deps = new HashSet();
+        //defensive copy
+        synchronized (dependants){
+            deps.addAll(dependants);
+        }
+        return deps;
+    }
+
+    public void addProviders(Set providers) {
+        Iterator iter = providers.iterator();
+        synchronized (this.providers){
+            this.providers.addAll(providers);
+        }
+        while (iter.hasNext()){
+            ((ClassDependencyRelationship) iter.next()).addDependant(this);
+        }
+    }
+
+    /**
+     * Get the classes that this class needs to function.
+     * @return
+     */
+    public Set getProviders() {
+        Set prov = new HashSet();
+        //defensive copy
+        synchronized (providers){
+            prov.addAll(providers);
+        }
+        return prov;
+    }
+    
+    public String toString(){
+        return fullyQualifiedClassName;
+    }
+
+    /**
+     * Is this a root dependant, that is no other classes depend on this.
+     * @return true or false
+     */
+    public boolean isRootClass() {
+        return rootClass;
+    }
+}

Propchange: incubator/river/jtsk/trunk/src/com/sun/jini/tool/classdepend/ClassDependencyRelationship.java
------------------------------------------------------------------------------
    svn:eol-style = native