Gentoo Archives: gentoo-commits

From: "Serkan Kaba (serkan)" <serkan@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-java/java-dep-check/files: Main-0.3.java
Date: Wed, 28 Jan 2009 20:06:42
Message-Id: E1LSGgJ-0006aT-I9@stork.gentoo.org
1 serkan 09/01/28 20:06:39
2
3 Added: Main-0.3.java
4 Log:
5 Version bump to report classes not found via DEPEND in package.env
6 (Portage version: 2.2_rc23/cvs/Linux x86_64)
7
8 Revision Changes Path
9 1.1 dev-java/java-dep-check/files/Main-0.3.java
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-java/java-dep-check/files/Main-0.3.java?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-java/java-dep-check/files/Main-0.3.java?rev=1.1&content-type=text/plain
13
14 Index: Main-0.3.java
15 ===================================================================
16 /*
17 * Main.java The main application class.
18 *
19 * Created on May 1, 2007, 6:32 PM
20 *
21 * Copyright (C) 2007,2008 Petteri Räty <betelgeuse@g.o>
22 *
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation; either version 2
26 * of the License, or (at your option) any later version.
27
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
36 */
37 package javadepchecker;
38
39 import java.io.BufferedReader;
40 import java.io.File;
41 import java.io.FileReader;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.io.InputStreamReader;
45 import java.util.ArrayList;
46 import java.util.Collection;
47 import java.util.Enumeration;
48 import java.util.HashSet;
49 import java.util.Iterator;
50 import java.util.Set;
51 import java.util.jar.JarEntry;
52 import java.util.jar.JarFile;
53 import java.util.logging.Level;
54 import java.util.logging.Logger;
55 import java.util.regex.Matcher;
56 import java.util.regex.Pattern;
57
58 import org.apache.commons.cli.CommandLine;
59 import org.apache.commons.cli.CommandLineParser;
60 import org.apache.commons.cli.HelpFormatter;
61 import org.apache.commons.cli.Options;
62 import org.apache.commons.cli.ParseException;
63 import org.apache.commons.cli.PosixParser;
64 import org.objectweb.asm.AnnotationVisitor;
65 import org.objectweb.asm.ClassReader;
66 import org.objectweb.asm.FieldVisitor;
67 import org.objectweb.asm.Label;
68 import org.objectweb.asm.MethodVisitor;
69 import org.objectweb.asm.Type;
70 import org.objectweb.asm.commons.EmptyVisitor;
71
72 /**
73 *
74 * @author betelgeuse
75 * @author serkan
76 */
77 public final class Main extends EmptyVisitor {
78
79 static private String image = "";
80 private Set<String> deps = new HashSet<String>();
81 private Set<String> current = new HashSet<String>();
82
83 /** Creates a new instance of Main */
84 public Main() {
85 }
86
87 private static Collection<String> getPackageJars(String pkg) {
88 ArrayList<String> jars = new ArrayList<String>();
89 try {
90 Process p = Runtime.getRuntime().exec("java-config -p " + pkg);
91 p.waitFor();
92 BufferedReader in;
93 in = new BufferedReader(new InputStreamReader(p.getInputStream()));
94 String output = in.readLine();
95 if (output!=null/* package somehow missing*/ && !output.trim().equals("")) {
96 for (String jar : output.split(":")) {
97 jars.add(jar);
98 }
99 }
100 } catch (InterruptedException ex) {
101 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
102 } catch (IOException ex) {
103 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
104 }
105 return jars;
106 }
107
108 public void processJar(JarFile jar) throws IOException {
109 for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
110 JarEntry entry = e.nextElement();
111 String name = entry.getName();
112 if (!entry.isDirectory() && name.endsWith(".class")) {
113 this.current.add(name);
114 InputStream stream = jar.getInputStream(entry);
115 new ClassReader(stream).accept(this, 0);
116 }
117 }
118 }
119
120 private static boolean depNeeded(String pkg, Collection<String> deps) throws IOException {
121 Collection<String> jars = getPackageJars(pkg);
122 // We have a virtual with VM provider here
123 if (jars.size() == 0) {
124 return true;
125 }
126 for (String jarName : jars) {
127 JarFile jar = new JarFile(jarName);
128 for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
129 String name = e.nextElement().getName();
130 if (deps.contains(name)) {
131 return true;
132 }
133 }
134 }
135 return false;
136 }
137
138 private static boolean depsFound(Collection<String> pkgs, Collection<String> deps) throws IOException {
139 boolean found = true;
140 Collection<String> jars = new ArrayList<String>();
141 String[] bootClassPathJars = System.getProperty("sun.boot.class.path").split(":");
142 // Do we need "java-config -r" here?
143 for (String jar : bootClassPathJars) {
144 File jarFile = new File(jar);
145 if (jarFile.exists()) {
146 jars.add(jar);
147 }
148 }
149 for (Iterator<String> pkg = pkgs.iterator(); pkg.hasNext();) {
150 jars.addAll(getPackageJars(pkg.next()));
151 }
152
153 if (jars.size() == 0) {
154 return false;
155 }
156 ArrayList<String> jarClasses = new ArrayList<String>();
157 for (String jarName : jars) {
158 JarFile jar = new JarFile(jarName);
159 for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
160 jarClasses.add(e.nextElement().getName());
161 }
162 }
163 for (String dep : deps) {
164 if (!jarClasses.contains(dep)) {
165 if (found) {
166 System.out.println("Class files not found via DEPEND in package.env");
167 }
168 System.out.println("\t" + dep);
169 found = false;
170 }
171 }
172 return found;
173 }
174
175 private static boolean checkPkg(File env) {
176 boolean needed = true;
177 boolean found = true;
178 HashSet<String> pkgs = new HashSet<String>();
179 Collection<String> deps = null;
180
181 BufferedReader in = null;
182 try {
183 Pattern dep_re = Pattern.compile("^DEPEND=\"([^\"]*)\"$");
184 Pattern cp_re = Pattern.compile("^CLASSPATH=\"([^\"]*)\"$");
185
186 String line;
187 in = new BufferedReader(new FileReader(env));
188 while ((line = in.readLine()) != null) {
189 Matcher m = dep_re.matcher(line);
190 if (m.matches()) {
191 String atoms = m.group(1);
192 for (String atom : atoms.split(":")) {
193 String pkg = atom;
194 if (atom.contains("@")) {
195 pkg = atom.split("@")[1];
196 }
197 pkgs.add(pkg);
198 }
199 continue;
200 }
201 m = cp_re.matcher(line);
202 if (m.matches()) {
203 Main classParser = new Main();
204 for (String jar : m.group(1).split(":")) {
205 if (jar.endsWith(".jar")) {
206 classParser.processJar(new JarFile(image + jar));
207 }
208 }
209 deps = classParser.getDeps();
210 }
211 }
212
213 for (String pkg : pkgs) {
214 if (!depNeeded(pkg, deps)) {
215 if (needed) {
216 System.out.println("Possibly unneeded dependencies found");
217 }
218 System.out.println("\t" + pkg);
219 needed = false;
220 }
221 }
222 found = depsFound(pkgs, deps);
223
224 } catch (IOException ex) {
225 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
226 } finally {
227 try {
228 in.close();
229 } catch (IOException ex) {
230 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
231 }
232 }
233 return needed && found;
234 }
235
236 /**
237 * @param args the command line arguments
238 */
239 public static void main(String[] args) throws IOException {
240 int exit = 0;
241 try {
242 CommandLineParser parser = new PosixParser();
243 Options options = new Options();
244 options.addOption("h", "help", false, "print help");
245 options.addOption("i", "image", true, "image directory");
246 options.addOption("v", "verbose", false, "print verbose output");
247 CommandLine line = parser.parse(options, args);
248 String[] files = line.getArgs();
249 if (line.hasOption("h") || files.length == 0) {
250 HelpFormatter h = new HelpFormatter();
251 h.printHelp("java-dep-check [-i <image>] <package.env>+", options);
252 } else {
253 image = line.getOptionValue("i", "");
254
255 for (String arg : files) {
256 if (line.hasOption('v')) {
257 System.out.println("Checking " + arg);
258 }
259 if (!checkPkg(new File(arg))) {
260 exit = 1;
261 }
262 }
263 }
264 } catch (ParseException ex) {
265 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
266 }
267 System.exit(exit);
268 }
269
270 private void addDep(String dep) {
271 deps.add(dep + ".class");
272 }
273
274 private void addDep(Type dep) {
275 if (dep.getSort() == Type.ARRAY) {
276 addDep(dep.getElementType());
277 }
278 if (dep.getSort() == Type.OBJECT) {
279 addDep(dep.getInternalName());
280 }
281 }
282
283 private Collection<String> getDeps() {
284 ArrayList<String> result = new ArrayList<String>();
285 for (String s : deps) {
286 if (!current.contains(s)) {
287 result.add(s);
288 }
289 }
290 return result;
291 }
292
293 @Override
294 public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
295 if(superName != null) {
296 addDep(superName);
297 }
298 for (String iface : interfaces) {
299 addDep(iface);
300 }
301 }
302
303 @Override
304 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
305 addDep(Type.getType(desc));
306 return null;
307 }
308
309 @Override
310 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
311 for (Type param : Type.getArgumentTypes(desc)) {
312 addDep(param);
313 }
314
315 if (exceptions != null) {
316 for (String exception : exceptions) {
317 addDep(exception);
318 }
319 }
320 addDep(Type.getReturnType(desc));
321 return new EmptyVisitor() {
322 @Override
323 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
324 addDep(Type.getType(desc));
325 }
326
327 @Override
328 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
329 addDep(Type.getObjectType(owner));
330 addDep(Type.getType(desc));
331 }
332
333 @Override
334 public void visitMethodInsn(int opcode, String owner, String name, String desc) {
335 addDep(Type.getObjectType(owner));
336 }
337
338 @Override
339 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
340 return Main.this.visitAnnotation(desc, visible);
341 }
342 };
343 }
344
345 @Override
346 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
347 addDep(Type.getType(desc));
348 return null;
349 }
350 }