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 public final class ClassFileVisitorUtils
40 {
41
42 private ClassFileVisitorUtils()
43 {
44
45 }
46
47
48
49
50
51
52
53
54 public static void accept( URL url, ClassFileVisitor visitor )
55 throws IOException
56 {
57 if ( url.getPath().endsWith( ".jar" ) )
58 {
59 acceptJar( url, visitor );
60 }
61 else if ( url.getProtocol().equalsIgnoreCase( "file" ) )
62 {
63 try
64 {
65 File file = new File( new URI( url.toString() ) );
66
67 if ( file.isDirectory() )
68 {
69 acceptDirectory( file, visitor );
70 }
71 else if ( file.exists() )
72 {
73 throw new IllegalArgumentException( "Cannot accept visitor on URL: " + url );
74 }
75 }
76 catch ( URISyntaxException exception )
77 {
78 throw new IllegalArgumentException( "Cannot accept visitor on URL: " + url,
79 exception );
80 }
81 }
82 else
83 {
84 throw new IllegalArgumentException( "Cannot accept visitor on URL: " + url );
85 }
86 }
87
88
89
90 private static void acceptJar( URL url, ClassFileVisitor visitor )
91 throws IOException
92 {
93 try ( JarInputStream in = new JarInputStream( url.openStream() ) )
94 {
95 JarEntry entry;
96 while ( ( entry = in.getNextJarEntry() ) != null )
97 {
98 String name = entry.getName();
99
100 if ( name.endsWith( ".class" ) && name.indexOf( '-' ) == -1 )
101 {
102 visitClass( name, in, visitor );
103 }
104 }
105 }
106 }
107
108 private static void acceptDirectory( File directory, ClassFileVisitor visitor )
109 throws IOException
110 {
111 if ( !directory.isDirectory() )
112 {
113 throw new IllegalArgumentException( "File is not a directory" );
114 }
115
116 DirectoryScanner scanner = new DirectoryScanner();
117
118 scanner.setBasedir( directory );
119 scanner.setIncludes( new String[] { "**/*.class" } );
120
121 scanner.scan();
122
123 String[] paths = scanner.getIncludedFiles();
124
125 for ( String path : paths )
126 {
127 path = path.replace( File.separatorChar, '/' );
128
129 File file = new File( directory, path );
130
131 try ( InputStream in = new FileInputStream( file ) )
132 {
133 visitClass( path, in, visitor );
134 }
135 }
136 }
137
138 private static void visitClass( String path, InputStream in, ClassFileVisitor visitor )
139 {
140 if ( !path.endsWith( ".class" ) )
141 {
142 throw new IllegalArgumentException( "Path is not a class" );
143 }
144
145 String className = path.substring( 0, path.length() - 6 );
146
147 className = className.replace( '/', '.' );
148
149 visitor.visitClass( className, in );
150 }
151 }