1 9 package com.vladium.tools; 10 11 import java.io.File ; 12 import java.io.FileOutputStream ; 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.net.URL ; 16 import java.net.URLClassLoader ; 17 import java.util.ArrayList ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.LinkedList ; 21 import java.util.List ; 22 import java.util.Properties ; 23 import java.util.Set ; 24 import java.util.StringTokenizer ; 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 40 public class ClassDep 41 { 42 44 public static void main (final String [] args) 45 throws Exception 46 { 47 if (args.length < 2) 48 throw new IllegalArgumentException ("usage: classpath output_file rootset_classname_1 [rootset_classname_2 ...]"); 49 50 final String _classPath = args [0]; 51 final URL [] classPath; 52 { 53 final StringTokenizer tokenizer = new StringTokenizer (_classPath, File.pathSeparator); 54 classPath = new URL [tokenizer.countTokens ()]; 55 56 for (int i = 0; tokenizer.hasMoreTokens (); ++ i) 57 { 58 classPath [i] = new File (tokenizer.nextToken ()).toURL (); 59 } 60 } 61 62 final File outFile = new File (args [1]); 63 64 final int offset = 2; 65 final String [] rootSet = args.length > offset 66 ? new String [args.length - offset] 67 : new String [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 [] deps = _this.getDependencies (true); 77 78 final StringBuffer s = new StringBuffer (); 79 for (int d = deps.length - 1; d >= 0; -- d) { 81 s.append (deps [d]); 82 if (d > 0) s.append (','); 83 } 84 85 final File parent = outFile.getParentFile (); 86 if (parent != null) parent.mkdirs (); 87 88 final FileOutputStream out = new FileOutputStream (outFile); 89 90 final Properties result = new Properties (); 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 [] rootSet, final URL [] classPath) 100 { 101 if (rootSet == null) 102 throw new IllegalArgumentException ("null input: rootSet"); 103 104 if (classPath == null) 105 throw new IllegalArgumentException ("null input: classPath"); 106 107 m_rootSet = rootSet; 108 m_classPath = classPath; 109 } 110 111 public String [] getDependencies (final boolean includeRootSet) 112 throws IOException 113 { 114 final Set _result = new HashSet (); 115 final ClassLoader loader = new URLClassLoader (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 queue = new LinkedList (); 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 classVMName = (String ) queue.removeFirst (); 137 138 140 InputStream in = null; 141 try 142 { 143 in = loader.getResourceAsStream (classVMName + ".class"); 145 146 if (in == null) 147 { 148 throw new IllegalArgumentException ("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 ignore) { ignore.printStackTrace (); } 159 } 160 in = null; 161 162 final ClassDef cls = ClassDefParser.parseClass (baos.getByteArray (), baos.size ()); 163 final List clsDeps = getCONSTANT_Class_info (cls); 164 165 for (Iterator i = clsDeps.iterator (); i.hasNext (); ) 166 { 167 final String classDepVMName = (String ) i.next (); 168 169 if (classDepVMName.startsWith ("com/vladium/")) { 171 if (_result.add (Descriptors.vmNameToJavaName (classDepVMName))) 172 { 173 queue.addLast (classDepVMName); 174 } 175 } 176 } 177 } 178 179 final String [] result = new String [_result.size ()]; 180 _result.toArray (result); 181 182 return result; 183 } 184 185 188 public static List getCONSTANT_Class_info (final ClassDef cls) 189 { 190 if (cls == null) 191 throw new IllegalArgumentException ("null input: cls"); 192 193 final IConstantCollection constants = cls.getConstants (); 194 final IConstantCollection.IConstantIterator i = constants.iterator (); 195 196 final List result = new ArrayList (); 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 211 213 215 216 private final String [] m_rootSet; 217 private final URL [] m_classPath; 218 219 } | Popular Tags |