1 package org.apache.maven.plugin.compiler.module;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedHashMap;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.jar.JarFile;
32 import java.util.jar.Manifest;
33
34 import org.apache.maven.plugin.compiler.module.ProjectAnalyzerResult.ModuleNameSource;
35 import org.codehaus.plexus.component.annotations.Component;
36 import org.codehaus.plexus.component.annotations.Requirement;
37 import org.codehaus.plexus.logging.AbstractLogEnabled;
38
39
40
41
42
43
44
45 @Component( role = ProjectAnalyzer.class )
46 public class ProjectAnalyzer extends AbstractLogEnabled
47 {
48 @Requirement( hint = "asm" )
49 private ModuleInfoParser asmParser;
50
51 @Requirement( hint = "reflect" )
52 private ModuleInfoParser reflectParser;
53
54 public ProjectAnalyzerResult analyze( ProjectAnalyzerRequest request )
55 throws IOException
56 {
57 ProjectAnalyzerResult result = new ProjectAnalyzerResult();
58
59 Map<File, JavaModuleDescriptor> pathElements =
60 new LinkedHashMap<File, JavaModuleDescriptor>( request.getDependencyArtifacts().size() );
61
62 JavaModuleDescriptor baseModuleDescriptor = request.getBaseModuleDescriptor();
63
64 Map<String, JavaModuleDescriptor> availableNamedModules = new HashMap<String, JavaModuleDescriptor>();
65
66 Map<String, ModuleNameSource> moduleNameSources = new HashMap<String, ModuleNameSource>();
67
68
69 result.setBaseModuleDescriptor( baseModuleDescriptor );
70
71
72 for ( File file : request.getDependencyArtifacts() )
73 {
74 JavaModuleDescriptor descriptor = extractDescriptor( file );
75
76 if ( descriptor != null )
77 {
78 availableNamedModules.put( descriptor.name(), descriptor );
79 }
80
81 if ( descriptor == null || descriptor.isAutomatic() )
82 {
83 Manifest manifest = extractManifest( file );
84
85 String modulename = null;
86
87 if ( manifest != null )
88 {
89 modulename = manifest.getMainAttributes().getValue( "Automatic-Module-Name" );
90 }
91
92 if ( modulename != null )
93 {
94 moduleNameSources.put( modulename, ModuleNameSource.MANIFEST );
95 }
96 else if ( descriptor != null )
97 {
98 moduleNameSources.put( descriptor.name(), ModuleNameSource.FILENAME );
99 }
100 }
101 else
102 {
103 moduleNameSources.put( descriptor.name(), ModuleNameSource.MODULEDESCRIPTOR );
104 }
105
106 pathElements.put( file, descriptor );
107 }
108 result.setPathElements( pathElements );
109
110 result.setModuleNameSources( moduleNameSources );
111
112 if ( baseModuleDescriptor != null )
113 {
114 Set<String> requiredNamedModules = new HashSet<String>();
115 Set<String> requiredUnnamedModules = new HashSet<String>();
116
117 select( baseModuleDescriptor, Collections.unmodifiableMap( availableNamedModules ), requiredNamedModules,
118 requiredUnnamedModules );
119
120 result.setRequiredNormalModules( requiredNamedModules );
121 result.setRequiredAutomaticModules( requiredUnnamedModules );
122 }
123
124 return result;
125 }
126
127 private JavaModuleDescriptor extractDescriptor( File file )
128 throws IOException
129 {
130 JavaModuleDescriptor moduleDescriptor;
131 if ( file.isFile() || new File( file, "module-info.class" ).exists() )
132 {
133 moduleDescriptor = reflectParser.getModuleDescriptor( file );
134
135 if ( moduleDescriptor == null )
136 {
137 moduleDescriptor = asmParser.getModuleDescriptor( file );
138 }
139 }
140 else
141 {
142 moduleDescriptor = null;
143 }
144 return moduleDescriptor;
145 }
146
147 private Manifest extractManifest( File file )
148 throws IOException
149 {
150 Manifest manifest;
151 if ( file.isFile() )
152 {
153 JarFile jarFile = null;
154 try
155 {
156 jarFile = new JarFile( file );
157 manifest = jarFile.getManifest();
158 }
159 finally
160 {
161 jarFile.close();
162 }
163 }
164 else if ( new File( file, "META-INF/MANIFEST.MF" ).exists() )
165 {
166 manifest = new Manifest( new FileInputStream( new File( file, "META-INF/MANIFEST.MF" ) ) );
167 }
168 else
169 {
170 manifest = null;
171 }
172
173 return manifest;
174 }
175
176
177 private void select( JavaModuleDescriptor module, Map<String, JavaModuleDescriptor> availableModules,
178 Set<String> namedModules, Set<String> unnamedModules )
179 {
180 for ( JavaModuleDescriptor.JavaRequires requires : module.requires() )
181 {
182 String requiresName = requires.name();
183 JavaModuleDescriptor requiredModule = availableModules.get( requiresName );
184
185 if ( requiredModule != null && !requiredModule.isAutomatic() )
186 {
187 if ( namedModules.add( requiresName ) )
188 {
189 select( requiredModule, availableModules, namedModules, unnamedModules );
190 }
191 }
192 else
193 {
194 unnamedModules.add( requiresName );
195 }
196 }
197 }
198 }