KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > tools > ClassDep


1 /* Copyright (C) 2004 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: ClassDep.java,v 1.1.2.2 2004/07/09 01:42:04 vlad_r Exp $
8  */

9 package com.vladium.tools;
10
11 import java.io.File JavaDoc;
12 import java.io.FileOutputStream JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.net.URL JavaDoc;
16 import java.net.URLClassLoader JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.LinkedList JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Properties JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 import com.vladium.jcd.cls.ClassDef;
27 import com.vladium.jcd.cls.IConstantCollection;
28 import com.vladium.jcd.cls.constant.CONSTANT_Class_info;
29 import com.vladium.jcd.cls.constant.CONSTANT_info;
30 import com.vladium.jcd.parser.ClassDefParser;
31 import com.vladium.util.ByteArrayOStream;
32 import com.vladium.util.Descriptors;
33
34 // ----------------------------------------------------------------------------
35
/**
36  * TODO: doc
37  *
38  * @author Vlad Roubtsov, (C) 2004
39  */

40 public class ClassDep
41 {
42     // public: ................................................................
43

44     public static void main (final String JavaDoc [] args)
45         throws Exception JavaDoc
46     {
47         if (args.length < 2)
48             throw new IllegalArgumentException JavaDoc ("usage: classpath output_file rootset_classname_1 [rootset_classname_2 ...]");
49             
50         final String JavaDoc _classPath = args [0];
51         final URL JavaDoc [] classPath;
52         {
53             final StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc (_classPath, File.pathSeparator);
54             classPath = new URL JavaDoc [tokenizer.countTokens ()];
55             
56             for (int i = 0; tokenizer.hasMoreTokens (); ++ i)
57             {
58                 classPath [i] = new File JavaDoc (tokenizer.nextToken ()).toURL ();
59             }
60         }
61         
62         final File JavaDoc outFile = new File JavaDoc (args [1]);
63         
64         final int offset = 2;
65         final String JavaDoc [] rootSet = args.length > offset
66             ? new String JavaDoc [args.length - offset]
67             : new String JavaDoc [0];
68         {
69             for (int a = 0; a < rootSet.length; ++ a)
70             {
71                 rootSet [a] = args [a + offset];
72             }
73         }
74         
75         final ClassDep _this = new ClassDep (rootSet, classPath);
76         final String JavaDoc [] deps = _this.getDependencies (true);
77         
78         final StringBuffer JavaDoc s = new StringBuffer JavaDoc ();
79         for (int d = deps.length - 1; d >= 0; -- d) // reverse topological order
80
{
81             s.append (deps [d]);
82             if (d > 0) s.append (',');
83         }
84         
85         final File JavaDoc parent = outFile.getParentFile ();
86         if (parent != null) parent.mkdirs ();
87         
88         final FileOutputStream JavaDoc out = new FileOutputStream JavaDoc (outFile);
89         
90         final Properties JavaDoc result = new Properties JavaDoc ();
91         result.setProperty ("closure", s.toString ());
92         
93         result.store (out, "this file is auto-generated, do not edit");
94         
95         out.close ();
96     }
97     
98     
99     public ClassDep (final String JavaDoc [] rootSet, final URL JavaDoc [] classPath)
100     {
101         if (rootSet == null)
102             throw new IllegalArgumentException JavaDoc ("null input: rootSet");
103         
104         if (classPath == null)
105             throw new IllegalArgumentException JavaDoc ("null input: classPath");
106         
107         m_rootSet = rootSet;
108         m_classPath = classPath;
109     }
110     
111     public String JavaDoc [] getDependencies (final boolean includeRootSet)
112         throws IOException JavaDoc
113     {
114         final Set JavaDoc /* class Java name:String */ _result = new HashSet JavaDoc ();
115         final ClassLoader JavaDoc loader = new URLClassLoader JavaDoc (m_classPath, null);
116         
117         if (includeRootSet)
118         {
119             for (int i = 0; i < m_rootSet.length; ++ i)
120             {
121                 _result.add (m_rootSet [i]);
122             }
123         }
124         
125         final LinkedList JavaDoc /* class VM name:String */ queue = new LinkedList JavaDoc ();
126         for (int i = 0; i < m_rootSet.length; ++ i)
127         {
128             queue.add (Descriptors.javaNameToVMName (m_rootSet [i]));
129         }
130         
131         final ByteArrayOStream baos = new ByteArrayOStream (8 * 1024);
132         final byte [] readbuf = new byte [8 * 1024];
133         
134         while (! queue.isEmpty ())
135         {
136             final String JavaDoc classVMName = (String JavaDoc) queue.removeFirst ();
137             
138             // keep at most one file descriptor open:
139

140             InputStream JavaDoc in = null;
141             try
142             {
143                 // NOTE: getResources() not used
144
in = loader.getResourceAsStream (classVMName + ".class");
145                 
146                 if (in == null)
147                 {
148                     throw new IllegalArgumentException JavaDoc ("class [" + Descriptors.vmNameToJavaName (classVMName) + "] not found in the input classpath");
149                 }
150                 else
151                 {
152                     baos.reset ();
153                     for (int read; (read = in.read (readbuf)) >= 0; baos.write (readbuf, 0, read));
154                 }
155             }
156             finally
157             {
158                 if (in != null) try { in.close (); } catch (IOException JavaDoc ignore) { ignore.printStackTrace (); }
159             }
160             in = null;
161
162             final ClassDef cls = ClassDefParser.parseClass (baos.getByteArray (), baos.size ());
163             final List JavaDoc /* class VM name:String */ clsDeps = getCONSTANT_Class_info (cls);
164             
165             for (Iterator JavaDoc i = clsDeps.iterator (); i.hasNext (); )
166             {
167                 final String JavaDoc classDepVMName = (String JavaDoc) i.next ();
168                 
169                 if (classDepVMName.startsWith ("com/vladium/")) // TODO: generic filtering
170
{
171                     if (_result.add (Descriptors.vmNameToJavaName (classDepVMName)))
172                     {
173                         queue.addLast (classDepVMName);
174                     }
175                 }
176             }
177         }
178         
179         final String JavaDoc [] result = new String JavaDoc [_result.size ()];
180         _result.toArray (result);
181         
182         return result;
183     }
184     
185     /**
186      * @return array of class VM names [may contain duplicates]
187      */

188     public static List JavaDoc getCONSTANT_Class_info (final ClassDef cls)
189     {
190         if (cls == null)
191             throw new IllegalArgumentException JavaDoc ("null input: cls");
192         
193         final IConstantCollection constants = cls.getConstants ();
194         final IConstantCollection.IConstantIterator i = constants.iterator ();
195         
196         final List JavaDoc result = new ArrayList JavaDoc ();
197
198         for (CONSTANT_info entry; (entry = i.nextConstant ()) != null; )
199         {
200             if (entry instanceof CONSTANT_Class_info)
201             {
202                 result.add (((CONSTANT_Class_info) entry).getName (cls));
203             }
204         }
205         
206         return result;
207     }
208     
209     // protected: .............................................................
210

211     // package: ...............................................................
212

213     // private: ...............................................................
214

215
216     private final String JavaDoc [] m_rootSet;
217     private final URL JavaDoc [] m_classPath;
218     
219 } // end of class
220
// ----------------------------------------------------------------------------
Popular Tags