1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.codehaus.plexus.maven.plugin;
18
19 import java.io.File;
20 import java.net.MalformedURLException;
21 import java.net.URL;
22 import java.net.URLClassLoader;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.maven.plugin.MojoExecutionException;
30 import org.apache.maven.project.MavenProject;
31 import org.codehaus.plexus.cdc.gleaner.ClassComponentGleaner;
32 import org.codehaus.plexus.component.repository.cdc.ComponentDescriptor;
33 import org.codehaus.plexus.util.DirectoryScanner;
34
35
36
37
38
39
40 public class ClassComponentDescriptorExtractor
41 extends ComponentDescriptorExtractorSupport
42 {
43 private ClassComponentGleaner gleaner;
44
45 public ClassComponentDescriptorExtractor(final ClassComponentGleaner gleaner) {
46 this.gleaner = gleaner;
47 }
48
49 public ClassComponentDescriptorExtractor() {}
50
51 public List extract(final MavenProject project, final String scope, final ComponentDescriptor[] roleDefaults) throws Exception {
52 assert project != null;
53 assert scope != null;
54 assert roleDefaults != null;
55
56
57 if (gleaner == null) {
58 throw new IllegalStateException("Gleaner is not bound");
59 }
60
61 log.debug("Gleaner: " + gleaner + ", scope: " + scope);
62
63 List classpath;
64 File classesDir;
65
66 if (COMPILE_SCOPE.equals(scope)) {
67 classpath = project.getCompileClasspathElements();
68 classesDir = new File(project.getBuild().getOutputDirectory());
69 }
70 else if (TEST_SCOPE.equals(scope)) {
71 classpath = project.getTestClasspathElements();
72 classesDir = new File(project.getBuild().getTestOutputDirectory());
73 }
74 else {
75 throw new IllegalArgumentException("Invalid scope: " + scope);
76 }
77
78 if (!classesDir.exists()) {
79 log.warn("Missing classes directory: {}", classesDir);
80 return Collections.EMPTY_LIST;
81 }
82
83 final ClassLoader prev = Thread.currentThread().getContextClassLoader();
84 final ClassLoader cl = createClassLoader(classpath);
85
86 Thread.currentThread().setContextClassLoader(cl);
87
88 try {
89 return extract(classesDir, cl, getDefaultsByRole(roleDefaults));
90 }
91 finally {
92 Thread.currentThread().setContextClassLoader(prev);
93 }
94 }
95
96 private ClassLoader createClassLoader(final List elements) throws Exception {
97 List list = new ArrayList();
98
99
100 for (Iterator iter = elements.iterator(); iter.hasNext();) {
101 String filename = (String) iter.next();
102
103 try {
104 list.add(new File(filename).toURI().toURL());
105 }
106 catch (MalformedURLException e) {
107 throw new MojoExecutionException("Invalid classpath entry: " + filename, e);
108 }
109 }
110
111 URL[] urls = (URL[]) list.toArray(new URL[list.size()]);
112
113 log.debug("Classpath:");
114 for (int i=0; i<urls.length; i++) {
115 log.debug(" " + urls[i]);
116 }
117
118 return new URLClassLoader(urls, getClass().getClassLoader());
119 }
120
121 private List extract(final File classesDir, final ClassLoader cl, final Map defaultsByRole) throws Exception {
122 assert classesDir != null;
123 assert cl != null;
124 assert defaultsByRole != null;
125
126 List descriptors = new ArrayList();
127
128 DirectoryScanner scanner = new DirectoryScanner();
129 scanner.setBasedir(classesDir);
130 scanner.addDefaultExcludes();
131 scanner.setIncludes(new String[]{ "**/*.class" });
132
133 log.debug("Scanning for classes in: " + classesDir);
134
135 scanner.scan();
136
137 String[] includes = scanner.getIncludedFiles();
138
139 for (int i=0; i<includes.length; i++) {
140 String className = includes[i].substring(0, includes[i].lastIndexOf(".class")).replace('\\', '.').replace('/', '.');
141
142 log.debug("Loading class: " + className);
143
144 try {
145 Class type = cl.loadClass(className);
146
147 log.debug("Gleaning from: " + type);
148
149 ComponentDescriptor descriptor = gleaner.glean(type);
150
151 if (descriptor != null) {
152 applyDefaults(descriptor, defaultsByRole);
153
154 descriptors.add(descriptor);
155 }
156 }
157 catch (VerifyError e) {
158 log.error("Failed to load class: " + className + "; cause: " + e);
159 }
160 }
161
162 log.debug("Extracted " + descriptors.size() + " descriptor(s)");
163
164 return descriptors;
165 }
166 }