22
22
import javax .inject .Named ;
23
23
import javax .inject .Singleton ;
24
24
25
+ import java .util .ArrayList ;
26
+ import java .util .HashMap ;
27
+ import java .util .List ;
25
28
import java .util .Map ;
26
29
import java .util .Optional ;
30
+ import java .util .Set ;
31
+ import java .util .stream .Collectors ;
27
32
28
33
import org .apache .maven .api .Packaging ;
29
34
import org .apache .maven .api .Type ;
35
+ import org .apache .maven .api .model .Dependency ;
36
+ import org .apache .maven .api .model .InputLocation ;
37
+ import org .apache .maven .api .model .InputSource ;
38
+ import org .apache .maven .api .model .Plugin ;
39
+ import org .apache .maven .api .model .PluginContainer ;
40
+ import org .apache .maven .api .model .PluginExecution ;
30
41
import org .apache .maven .api .services .PackagingRegistry ;
31
42
import org .apache .maven .api .services .TypeRegistry ;
43
+ import org .apache .maven .api .spi .PackagingProvider ;
44
+ import org .apache .maven .lifecycle .internal .DefaultLifecyclePluginAnalyzer ;
32
45
import org .apache .maven .lifecycle .mapping .LifecycleMapping ;
46
+ import org .apache .maven .lifecycle .mapping .LifecycleMojo ;
47
+ import org .apache .maven .lifecycle .mapping .LifecyclePhase ;
48
+ import org .slf4j .Logger ;
49
+ import org .slf4j .LoggerFactory ;
33
50
34
51
/**
35
52
* TODO: this is session scoped as SPI can contribute.
36
53
*/
37
54
@ Named
38
55
@ Singleton
39
- public class DefaultPackagingRegistry implements PackagingRegistry {
56
+ public class DefaultPackagingRegistry
57
+ extends ExtensibleEnumRegistries .DefaultExtensibleEnumRegistry <Packaging , PackagingProvider >
58
+ implements PackagingRegistry {
59
+
60
+ private static final Logger LOGGER = LoggerFactory .getLogger (DefaultPackagingRegistry .class );
61
+
40
62
private final Map <String , LifecycleMapping > lifecycleMappings ;
41
63
42
64
private final TypeRegistry typeRegistry ;
43
65
44
66
@ Inject
45
- public DefaultPackagingRegistry (Map <String , LifecycleMapping > lifecycleMappings , TypeRegistry typeRegistry ) {
67
+ public DefaultPackagingRegistry (
68
+ Map <String , LifecycleMapping > lifecycleMappings ,
69
+ TypeRegistry typeRegistry ,
70
+ List <PackagingProvider > providers ) {
71
+ super (providers );
46
72
this .lifecycleMappings = lifecycleMappings ;
47
73
this .typeRegistry = typeRegistry ;
48
74
}
@@ -57,17 +83,111 @@ public Optional<Packaging> lookup(String id) {
57
83
if (type == null ) {
58
84
return Optional .empty ();
59
85
}
86
+ return Optional .of (new DefaultPackaging (id , type , getPlugins (lifecycleMapping )));
87
+ }
60
88
61
- return Optional .of (new Packaging () {
62
- @ Override
63
- public String id () {
64
- return id ;
65
- }
89
+ private PluginContainer getPlugins (LifecycleMapping lifecycleMapping ) {
90
+ Map <String , Plugin > plugins = new HashMap <>();
91
+ lifecycleMapping .getLifecycles ().forEach ((id , lifecycle ) -> lifecycle
92
+ .getLifecyclePhases ()
93
+ .forEach ((phase , lifecyclePhase ) -> parseLifecyclePhaseDefinitions (plugins , phase , lifecyclePhase )));
94
+ return PluginContainer .newBuilder ().plugins (plugins .values ()).build ();
95
+ }
96
+
97
+ private void parseLifecyclePhaseDefinitions (Map <String , Plugin > plugins , String phase , LifecyclePhase goals ) {
98
+ InputSource inputSource =
99
+ new InputSource (DefaultLifecyclePluginAnalyzer .DEFAULTLIFECYCLEBINDINGS_MODELID , null );
100
+ InputLocation location = new InputLocation (-1 , -1 , inputSource , 0 );
101
+
102
+ List <LifecycleMojo > mojos = goals .getMojos ();
103
+ if (mojos != null ) {
104
+ for (int i = 0 ; i < mojos .size (); i ++) {
105
+ LifecycleMojo mojo = mojos .get (i );
106
+
107
+ // Compute goal coordinates
108
+ String groupId , artifactId , version , goal ;
109
+ String [] p = mojo .getGoal ().trim ().split (":" );
110
+ if (p .length == 3 ) {
111
+ // <groupId>:<artifactId>:<goal>
112
+ groupId = p [0 ];
113
+ artifactId = p [1 ];
114
+ version = null ;
115
+ goal = p [2 ];
116
+ } else if (p .length == 4 ) {
117
+ // <groupId>:<artifactId>:<version>:<goal>
118
+ groupId = p [0 ];
119
+ artifactId = p [1 ];
120
+ version = p [2 ];
121
+ goal = p [3 ];
122
+ } else {
123
+ // invalid
124
+ LOGGER .warn (
125
+ "Ignored invalid goal specification '{}' from lifecycle mapping for phase {}" ,
126
+ mojo .getGoal (),
127
+ phase );
128
+ continue ;
129
+ }
130
+
131
+ String key = groupId + ":" + artifactId ;
132
+
133
+ // Build plugin
134
+ List <PluginExecution > execs = new ArrayList <>();
135
+ List <Dependency > deps = new ArrayList <>();
66
136
67
- @ Override
68
- public Type getType () {
69
- return type ;
137
+ Plugin existing = plugins .get (key );
138
+ if (existing != null ) {
139
+ if (version == null ) {
140
+ version = existing .getVersion ();
141
+ }
142
+ execs .addAll (existing .getExecutions ());
143
+ deps .addAll (existing .getDependencies ());
144
+ }
145
+
146
+ PluginExecution execution = PluginExecution .newBuilder ()
147
+ .id (getExecutionId (existing , goal ))
148
+ .priority (i - mojos .size ())
149
+ .phase (phase )
150
+ .goals (List .of (goal ))
151
+ .configuration (mojo .getConfiguration ())
152
+ .location ("" , location )
153
+ .location ("id" , location )
154
+ .location ("phase" , location )
155
+ .location ("goals" , location )
156
+ .build ();
157
+ execs .add (execution );
158
+
159
+ if (mojo .getDependencies () != null ) {
160
+ mojo .getDependencies ().forEach (d -> deps .add (d .getDelegate ()));
161
+ }
162
+
163
+ Plugin plugin = Plugin .newBuilder ()
164
+ .groupId (groupId )
165
+ .artifactId (artifactId )
166
+ .version (version )
167
+ .location ("" , location )
168
+ .location ("groupId" , location )
169
+ .location ("artifactId" , location )
170
+ .location ("version" , location )
171
+ .executions (execs )
172
+ .dependencies (deps )
173
+ .build ();
174
+
175
+ plugins .put (key , plugin );
70
176
}
71
- });
177
+ }
72
178
}
179
+
180
+ private static String getExecutionId (Plugin plugin , String goal ) {
181
+ Set <String > existingIds = plugin != null
182
+ ? plugin .getExecutions ().stream ().map (PluginExecution ::getId ).collect (Collectors .toSet ())
183
+ : Set .of ();
184
+ String base = "default-" + goal ;
185
+ String id = base ;
186
+ for (int index = 1 ; existingIds .contains (id ); index ++) {
187
+ id = base + '-' + index ;
188
+ }
189
+ return id ;
190
+ }
191
+
192
+ private record DefaultPackaging (String id , Type type , PluginContainer plugins ) implements Packaging {}
73
193
}
0 commit comments