Gentoo Archives: gentoo-commits

From: "Petteri Raty (betelgeuse)" <betelgeuse@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-java/java-dep-check/files: Main-0.2.java
Date: Sun, 05 Oct 2008 10:36:23
Message-Id: E1KmQyK-0000Vn-5r@stork.gentoo.org
1 betelgeuse 08/10/05 10:36:20
2
3 Added: Main-0.2.java
4 Log:
5 Fully asm based, doesn't report virtuals with VM providers and handles directory entries in package.env CLASSPATHs.
6 (Portage version: 2.2_rc11/cvs/Linux 2.6.26-gentoo-r1 i686)
7
8 Revision Changes Path
9 1.1 dev-java/java-dep-check/files/Main-0.2.java
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-java/java-dep-check/files/Main-0.2.java?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/dev-java/java-dep-check/files/Main-0.2.java?rev=1.1&content-type=text/plain
13
14 Index: Main-0.2.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.util.HashSet;
43 import java.util.logging.Level;
44 import java.util.logging.Logger;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.InputStreamReader;
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.Enumeration;
51 import java.util.Set;
52 import java.util.jar.JarEntry;
53 import java.util.jar.JarFile;
54 import java.util.regex.Matcher;
55 import java.util.regex.Pattern;
56 import org.apache.commons.cli.CommandLine;
57 import org.apache.commons.cli.CommandLineParser;
58 import org.apache.commons.cli.HelpFormatter;
59 import org.apache.commons.cli.Options;
60 import org.apache.commons.cli.ParseException;
61 import org.apache.commons.cli.PosixParser;
62 import org.objectweb.asm.AnnotationVisitor;
63 import org.objectweb.asm.ClassReader;
64 import org.objectweb.asm.FieldVisitor;
65 import org.objectweb.asm.Label;
66 import org.objectweb.asm.MethodVisitor;
67 import org.objectweb.asm.Type;
68 import org.objectweb.asm.commons.EmptyVisitor;
69
70 /**
71 *
72 * @author betelgeuse
73 */
74 public final class Main extends EmptyVisitor {
75
76 static private String image = "";
77 private Set<String> deps = new HashSet<String>();
78 private Set<String> current = new HashSet<String>();
79
80 /** Creates a new instance of Main */
81 public Main() {
82 }
83
84 private static Collection<String> getPackageJars(String pkg) {
85 ArrayList<String> jars = new ArrayList<String>();
86 try {
87 Process p = Runtime.getRuntime().exec("java-config -p " + pkg);
88 p.waitFor();
89 BufferedReader in;
90 in = new BufferedReader(new InputStreamReader(p.getInputStream()));
91 String output = in.readLine();
92 if (!output.trim().equals("")) {
93 for (String jar : output.split(":")) {
94 jars.add(jar);
95 }
96 }
97 } catch (InterruptedException ex) {
98 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
99 } catch (IOException ex) {
100 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
101 }
102 return jars;
103 }
104
105 public void processJar(JarFile jar) throws IOException {
106 for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
107 JarEntry entry = e.nextElement();
108 String name = entry.getName();
109 if (!entry.isDirectory() && name.endsWith(".class")) {
110 this.current.add(name);
111 InputStream stream = jar.getInputStream(entry);
112 new ClassReader(stream).accept(this, 0);
113 }
114 }
115 }
116
117 private static boolean depNeeded(String pkg, Collection<String> deps) throws IOException {
118 Collection<String> jars = getPackageJars(pkg);
119 // We have a virtual with VM provider here
120 if(jars.size() == 0)
121 return true;
122 for (String jarName : jars) {
123 JarFile jar = new JarFile(jarName);
124 for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements();) {
125 String name = e.nextElement().getName();
126 if (deps.contains(name)) {
127 return true;
128 }
129 }
130 }
131 return false;
132 }
133
134 private static boolean checkPkg(File env) {
135 boolean needed = true;
136 HashSet<String> pkgs = new HashSet<String>();
137 Collection<String> deps = null;
138
139 BufferedReader in = null;
140 try {
141 Pattern dep_re = Pattern.compile("^DEPEND=\"([^\"]*)\"$");
142 Pattern cp_re = Pattern.compile("^CLASSPATH=\"([^\"]*)\"$");
143
144 String line;
145 in = new BufferedReader(new FileReader(env));
146 while ((line = in.readLine()) != null) {
147 Matcher m = dep_re.matcher(line);
148 if (m.matches()) {
149 String atoms = m.group(1);
150 for (String atom : atoms.split(":")) {
151 String pkg = atom;
152 if (atom.contains("@")) {
153 pkg = atom.split("@")[1];
154 }
155 pkgs.add(pkg);
156 }
157 continue;
158 }
159 m = cp_re.matcher(line);
160 if (m.matches()) {
161 Main classParser = new Main();
162 for (String jar : m.group(1).split(":")) {
163 if(jar.endsWith(".jar")) {
164 classParser.processJar(new JarFile(image + jar));
165 }
166 }
167 deps = classParser.getDeps();
168 }
169 }
170
171 for (String pkg : pkgs) {
172 if (!depNeeded(pkg, deps)) {
173 System.out.println(pkg);
174 needed = false;
175 }
176 }
177 } catch (IOException ex) {
178 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
179 } finally {
180 try {
181 in.close();
182 } catch (IOException ex) {
183 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
184 }
185 }
186 return needed;
187 }
188
189 /**
190 * @param args the command line arguments
191 */
192 public static void main(String[] args) throws IOException {
193 int exit = 0;
194 try {
195 CommandLineParser parser = new PosixParser();
196 Options options = new Options();
197 options.addOption("h", "help", false, "print help");
198 options.addOption("i", "image", true, "image directory");
199 options.addOption("v", "verbose", false, "print verbose output");
200 CommandLine line = parser.parse(options, args);
201 String[] files = line.getArgs();
202 if (line.hasOption("h") || files.length == 0) {
203 HelpFormatter h = new HelpFormatter();
204 h.printHelp("java-dep-check [-i <image] <package.env>+", options);
205 } else {
206 image = line.getOptionValue("i", "");
207
208 for (String arg : files) {
209 if (line.hasOption('v')) {
210 System.out.println("Checking " + arg);
211 }
212 if (!checkPkg(new File(arg))) {
213 exit = 1;
214 }
215 }
216 }
217 } catch (ParseException ex) {
218 Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
219 }
220 System.exit(exit);
221 }
222
223 private void addDep(String dep) {
224 deps.add(dep + ".class");
225 }
226
227 private void addDep(Type dep) {
228 if (dep.getSort() == Type.OBJECT) {
229 addDep(dep.getInternalName());
230 }
231 }
232
233 private Collection<String> getDeps() {
234 ArrayList<String> result = new ArrayList<String>();
235 for (String s : deps) {
236 if (!current.contains(s)) {
237 result.add(s);
238 }
239 }
240 return result;
241 }
242
243 @Override
244 public void visit(int version, int access, String name, String signature,
245 String superName, String[] interfaces) {
246 addDep(superName);
247 for(String iface : interfaces) {
248 addDep(iface);
249 }
250 }
251
252 @Override
253 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
254 addDep(Type.getType(desc));
255 return null;
256 }
257
258 @Override
259 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
260 for (Type param : Type.getArgumentTypes(desc)) {
261 addDep(param);
262 }
263 addDep(Type.getReturnType(desc));
264 return new EmptyVisitor() {
265 @Override
266 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
267 addDep(Type.getType(desc));
268 }
269 @Override
270 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
271 addDep(owner);
272 }
273 @Override
274 public void visitMethodInsn(int opcode, String owner, String name, String desc) {
275 addDep(owner);
276 }
277 @Override
278 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
279 return Main.this.visitAnnotation(desc, visible);
280 }
281
282
283 };
284 }
285
286 @Override
287 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
288 addDep(Type.getType(desc));
289 return null;
290 }
291 }