1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package com.qulice.maven;
32
33 import com.jcabi.log.Logger;
34 import com.qulice.spi.ValidationException;
35 import java.util.Collection;
36 import java.util.LinkedList;
37 import java.util.Map;
38 import java.util.Properties;
39 import org.apache.maven.execution.MavenSession;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.plugin.InvalidPluginDescriptorException;
42 import org.apache.maven.plugin.MavenPluginManager;
43 import org.apache.maven.plugin.Mojo;
44 import org.apache.maven.plugin.MojoExecution;
45 import org.apache.maven.plugin.MojoExecutionException;
46 import org.apache.maven.plugin.MojoFailureException;
47 import org.apache.maven.plugin.PluginConfigurationException;
48 import org.apache.maven.plugin.PluginContainerException;
49 import org.apache.maven.plugin.PluginDescriptorParsingException;
50 import org.apache.maven.plugin.PluginResolutionException;
51 import org.apache.maven.plugin.descriptor.MojoDescriptor;
52 import org.apache.maven.reporting.exec.DefaultMavenPluginManagerHelper;
53 import org.codehaus.plexus.configuration.PlexusConfiguration;
54 import org.codehaus.plexus.configuration.PlexusConfigurationException;
55 import org.codehaus.plexus.util.xml.Xpp3Dom;
56
57
58
59
60
61
62 public final class MojoExecutor {
63
64
65
66
67 private final MavenPluginManager manager;
68
69
70
71
72 private final MavenSession session;
73
74
75
76
77 private final DefaultMavenPluginManagerHelper helper;
78
79
80
81
82
83
84 @SuppressWarnings({"PMD.NonStaticInitializer", "PMD.DoubleBraceInitialization"})
85 public MojoExecutor(final MavenPluginManager mngr,
86 final MavenSession sesn) {
87 this.manager = mngr;
88 this.session = sesn;
89 this.helper = new DefaultMavenPluginManagerHelper() {
90 {
91 this.mavenPluginManager = MojoExecutor.this.manager;
92 }
93 };
94 }
95
96
97
98
99
100
101
102
103
104 public void execute(final String coords, final String goal,
105 final Properties config) throws ValidationException {
106 final Plugin plugin = new Plugin();
107 final String[] sectors = coords.split(":");
108 plugin.setGroupId(sectors[0]);
109 plugin.setArtifactId(sectors[1]);
110 plugin.setVersion(sectors[2]);
111 final MojoDescriptor descriptor = this.descriptor(plugin, goal);
112 try {
113 this.helper.setupPluginRealm(
114 descriptor.getPluginDescriptor(),
115 this.session,
116 Thread.currentThread().getContextClassLoader(),
117 new LinkedList<String>(),
118 new LinkedList<String>()
119 );
120 } catch (final PluginResolutionException ex) {
121 throw new IllegalStateException("Plugin resolution problem", ex);
122 } catch (final PluginContainerException ex) {
123 throw new IllegalStateException("Can't setup realm", ex);
124 }
125 final Xpp3Dom xpp = Xpp3Dom.mergeXpp3Dom(
126 this.toXppDom(config, "configuration"),
127 this.toXppDom(descriptor.getMojoConfiguration())
128 );
129 final MojoExecution execution = new MojoExecution(descriptor, xpp);
130 final Mojo mojo = this.mojo(execution);
131 try {
132 Logger.info(this, "Calling %s:%s...", coords, goal);
133 mojo.execute();
134 } catch (final MojoExecutionException ex) {
135 throw new IllegalArgumentException(ex);
136 } catch (final MojoFailureException ex) {
137 throw new ValidationException(ex);
138 } finally {
139 this.manager.releaseMojo(mojo, execution);
140 }
141 }
142
143
144
145
146
147
148
149 private MojoDescriptor descriptor(final Plugin plugin, final String goal) {
150 try {
151 return this.helper.getPluginDescriptor(
152 plugin,
153 this.session
154 ).getMojo(goal);
155 } catch (final PluginResolutionException ex) {
156 throw new IllegalStateException("Can't resolve plugin", ex);
157 } catch (final PluginDescriptorParsingException ex) {
158 throw new IllegalStateException("Can't parse descriptor", ex);
159 } catch (final InvalidPluginDescriptorException ex) {
160 throw new IllegalStateException("Invalid plugin descriptor", ex);
161 }
162 }
163
164
165
166
167
168
169 private Mojo mojo(final MojoExecution execution) {
170 final Mojo mojo;
171 try {
172 mojo = this.manager.getConfiguredMojo(
173 Mojo.class, this.session, execution
174 );
175 } catch (final PluginConfigurationException ex) {
176 throw new IllegalStateException("Can't configure MOJO", ex);
177 } catch (final PluginContainerException ex) {
178 throw new IllegalStateException("Plugin container failure", ex);
179 }
180 return mojo;
181 }
182
183
184
185
186
187
188
189
190
191 @SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.CognitiveComplexity"})
192 private Xpp3Dom toXppDom(final Properties config, final String name) {
193 final Xpp3Dom xpp = new Xpp3Dom(name);
194 for (final Map.Entry<?, ?> entry : config.entrySet()) {
195 if (entry.getValue() instanceof String) {
196 final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
197 child.setValue(config.getProperty(entry.getKey().toString()));
198 xpp.addChild(child);
199 } else if (entry.getValue() instanceof String[]) {
200 final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
201 for (final String val : String[].class.cast(entry.getValue())) {
202 final Xpp3Dom row = new Xpp3Dom(entry.getKey().toString());
203 row.setValue(val);
204 child.addChild(row);
205 }
206 xpp.addChild(child);
207 } else if (entry.getValue() instanceof Collection) {
208 final Xpp3Dom child = new Xpp3Dom(entry.getKey().toString());
209 for (final Object val : Collection.class.cast(entry.getValue())) {
210 if (val instanceof Properties) {
211 child.addChild(
212 this.toXppDom(
213 Properties.class.cast(val),
214 entry.getKey().toString()
215 ).getChild(0)
216 );
217 } else if (val != null) {
218 final Xpp3Dom row = new Xpp3Dom(entry.getKey().toString());
219 row.setValue(val.toString());
220 child.addChild(row);
221 }
222 }
223 xpp.addChild(child);
224 } else if (entry.getValue() instanceof Properties) {
225 xpp.addChild(
226 this.toXppDom(
227 Properties.class.cast(entry.getValue()),
228 entry.getKey().toString()
229 )
230 );
231 } else {
232 throw new IllegalArgumentException(
233 String.format(
234 "Invalid properties value at '%s'",
235 entry.getKey().toString()
236 )
237 );
238 }
239 }
240 return xpp;
241 }
242
243
244
245
246
247
248
249 private Xpp3Dom toXppDom(final PlexusConfiguration config) {
250 final Xpp3Dom result = new Xpp3Dom(config.getName());
251 result.setValue(config.getValue(null));
252 for (final String name : config.getAttributeNames()) {
253 try {
254 result.setAttribute(name, config.getAttribute(name));
255 } catch (final PlexusConfigurationException ex) {
256 throw new IllegalArgumentException(ex);
257 }
258 }
259 for (final PlexusConfiguration child : config.getChildren()) {
260 result.addChild(this.toXppDom(child));
261 }
262 return result;
263 }
264
265 }