1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.codehaus.plexus.metadata;
16
17 import java.io.File;
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.net.URLClassLoader;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.maven.plugin.MojoExecutionException;
27 import org.codehaus.plexus.component.annotations.Component;
28 import org.codehaus.plexus.component.repository.ComponentDescriptor;
29 import org.codehaus.plexus.metadata.gleaner.AnnotationComponentGleaner;
30 import org.codehaus.plexus.metadata.gleaner.ClassComponentGleaner;
31 import org.codehaus.plexus.util.DirectoryScanner;
32
33
34
35
36
37 @Component(role = ComponentDescriptorExtractor.class, hint = "class")
38 public class ClassComponentDescriptorExtractor extends ComponentDescriptorExtractorSupport {
39 private ClassComponentGleaner gleaner;
40
41 public ClassComponentDescriptorExtractor(final ClassComponentGleaner gleaner) {
42 this.gleaner = gleaner;
43 }
44
45 public ClassComponentDescriptorExtractor() {
46 this.gleaner = new AnnotationComponentGleaner();
47 }
48
49 public List<ComponentDescriptor<?>> extract(
50 MetadataGenerationRequest configuration, final ComponentDescriptor<?>[] roleDefaults) throws Exception {
51
52 if (gleaner == null) {
53 throw new IllegalStateException("Gleaner is not bound");
54 }
55
56 if (!configuration.classesDirectory.exists()) {
57 return Collections.emptyList();
58 }
59
60 if (configuration.useContextClassLoader) {
61 return extract(
62 configuration.classesDirectory,
63 Thread.currentThread().getContextClassLoader(),
64 getDefaultsByRole(roleDefaults));
65 } else {
66 ClassLoader prev = Thread.currentThread().getContextClassLoader();
67 ClassLoader cl = createClassLoader(configuration.classpath);
68
69 Thread.currentThread().setContextClassLoader(cl);
70
71 try {
72 return extract(configuration.classesDirectory, cl, getDefaultsByRole(roleDefaults));
73 } finally {
74 Thread.currentThread().setContextClassLoader(prev);
75 }
76 }
77 }
78
79 private ClassLoader createClassLoader(final List<String> elements) throws Exception {
80 List<URL> list = new ArrayList<URL>();
81
82
83 for (String filename : elements) {
84 try {
85 list.add(new File(filename).toURI().toURL());
86 } catch (MalformedURLException e) {
87 throw new MojoExecutionException("Invalid classpath entry: " + filename, e);
88 }
89 }
90
91 URL[] urls = list.toArray(new URL[list.size()]);
92
93
94 for (URL url : urls) {
95
96 }
97
98 return new URLClassLoader(urls, null);
99 }
100
101 private List<ComponentDescriptor<?>> extract(
102 File classesDir, ClassLoader cl, Map<String, ComponentDescriptor<?>> defaultsByRole) throws Exception {
103 assert classesDir != null;
104 assert cl != null;
105 assert defaultsByRole != null;
106
107 List<ComponentDescriptor<?>> descriptors = new ArrayList<ComponentDescriptor<?>>();
108
109 DirectoryScanner scanner = new DirectoryScanner();
110 scanner.setBasedir(classesDir);
111 scanner.addDefaultExcludes();
112 scanner.setIncludes(new String[] {"**/*.class"});
113
114 scanner.setExcludes(new String[] {"**/*-*.class"});
115
116
117
118 scanner.scan();
119
120 String[] includes = scanner.getIncludedFiles();
121
122 for (String include : includes) {
123 String className = include.substring(0, include.lastIndexOf(".class"))
124 .replace('\\', '.')
125 .replace('/', '.');
126
127 try {
128
129
130 ComponentDescriptor<?> descriptor = gleaner.glean(className, cl);
131
132 if (descriptor != null) {
133 applyDefaults(descriptor, defaultsByRole);
134
135 descriptors.add(descriptor);
136 }
137 } catch (VerifyError e) {
138
139 }
140 }
141
142 return descriptors;
143 }
144 }