1 package org.apache.maven.shared.dependency.analyzer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.codehaus.plexus.util.DirectoryScanner;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.net.URL;
31 import java.util.jar.JarEntry;
32 import java.util.jar.JarInputStream;
33
34
35
36
37
38
39
40
41 public final class ClassFileVisitorUtils
42 {
43
44
45 private static final String[] CLASS_INCLUDES = { "**/*.class" };
46
47
48
49 private ClassFileVisitorUtils()
50 {
51
52 }
53
54
55
56 public static void accept( URL url, ClassFileVisitor visitor )
57 throws IOException
58 {
59 if ( url.getPath().endsWith( ".jar" ) )
60 {
61 acceptJar( url, visitor );
62 }
63 else if ( url.getProtocol().equalsIgnoreCase( "file" ) )
64 {
65 try
66 {
67 File file = new File( new URI( url.toString() ) );
68
69 if ( file.isDirectory() )
70 {
71 acceptDirectory( file, visitor );
72 }
73 else if ( file.exists() )
74 {
75 throw new IllegalArgumentException( "Cannot accept visitor on URL: " + url );
76 }
77 }
78 catch ( URISyntaxException exception )
79 {
80 IllegalArgumentException e = new IllegalArgumentException( "Cannot accept visitor on URL: " + url );
81 e.initCause( exception );
82 throw e;
83 }
84 }
85 else
86 {
87 throw new IllegalArgumentException( "Cannot accept visitor on URL: " + url );
88 }
89 }
90
91
92
93 private static void acceptJar( URL url, ClassFileVisitor visitor )
94 throws IOException
95 {
96 JarInputStream in = new JarInputStream( url.openStream() );
97 try
98 {
99 JarEntry entry = null;
100
101 while ( ( entry = in.getNextJarEntry() ) != null )
102 {
103 String name = entry.getName();
104
105
106 if ( name.endsWith( ".class" ) && name.indexOf( '-' ) == -1 )
107 {
108 visitClass( name, in, visitor );
109 }
110 }
111 }
112 finally
113 {
114 in.close();
115 }
116 }
117
118 private static void acceptDirectory( File directory, ClassFileVisitor visitor )
119 throws IOException
120 {
121 if ( !directory.isDirectory() )
122 {
123 throw new IllegalArgumentException( "File is not a directory" );
124 }
125
126 DirectoryScanner scanner = new DirectoryScanner();
127
128 scanner.setBasedir( directory );
129 scanner.setIncludes( CLASS_INCLUDES );
130
131 scanner.scan();
132
133 String[] paths = scanner.getIncludedFiles();
134
135 for ( String path : paths )
136 {
137 path = path.replace( File.separatorChar, '/' );
138
139 File file = new File( directory, path );
140 FileInputStream in = new FileInputStream( file );
141
142 try
143 {
144 visitClass( path, in, visitor );
145 }
146 finally
147 {
148 in.close();
149 }
150 }
151 }
152
153 private static void visitClass( String path, InputStream in, ClassFileVisitor visitor )
154 {
155 if ( !path.endsWith( ".class" ) )
156 {
157 throw new IllegalArgumentException( "Path is not a class" );
158 }
159
160 String className = path.substring( 0, path.length() - 6 );
161
162 className = className.replace( '/', '.' );
163
164 visitor.visitClass( className, in );
165 }
166 }