001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.batch.maven;
021
022 import org.apache.commons.lang.StringUtils;
023 import org.apache.commons.lang.builder.ToStringBuilder;
024 import org.apache.maven.model.Dependency;
025 import org.apache.maven.model.Plugin;
026 import org.apache.maven.model.ReportPlugin;
027 import org.apache.maven.project.MavenProject;
028 import org.codehaus.plexus.util.xml.Xpp3Dom;
029
030 import java.util.Collection;
031 import java.util.Iterator;
032 import java.util.List;
033
034 /**
035 * A class to handle maven plugins
036 *
037 * @since 1.10
038 */
039 public class MavenPlugin {
040
041 private Plugin plugin;
042 private Xpp3Dom configuration;
043
044 /**
045 * Creates a MavenPlugin based on a Plugin
046 *
047 * @param plugin the plugin
048 */
049 public MavenPlugin(Plugin plugin) {
050 this.plugin = plugin;
051 this.configuration = (Xpp3Dom) plugin.getConfiguration();
052 if (this.configuration == null) {
053 configuration = new Xpp3Dom("configuration");
054 plugin.setConfiguration(this.configuration);
055 }
056 }
057
058 /**
059 * Creates a Maven plugin based on artifact + group + version
060 *
061 * @param groupId the group id
062 * @param artifactId the artifact id
063 * @param version the version
064 */
065 public MavenPlugin(String groupId, String artifactId, String version) {
066 this.plugin = new Plugin();
067 plugin.setGroupId(groupId);
068 plugin.setArtifactId(artifactId);
069 plugin.setVersion(version);
070 configuration = new Xpp3Dom("configuration");
071 plugin.setConfiguration(this.configuration);
072 }
073
074 /**
075 * Sets the maven plugin version
076 *
077 * @param version the version
078 * @return this
079 */
080 public MavenPlugin setVersion(String version) {
081 this.plugin.setVersion(version);
082 return this;
083 }
084
085 /**
086 * @return the underlying plugin
087 */
088 public Plugin getPlugin() {
089 return plugin;
090 }
091
092 /**
093 * Adds a dependency to the maven plugin
094 *
095 * @param groupId the dependency group id
096 * @param artifactId the dependency artifact id
097 * @param version the dependency version
098 * @param dependencyType the dependency type
099 * @return this
100 */
101 public MavenPlugin addDependency(String groupId, String artifactId, String version, String dependencyType) {
102 Dependency dependency = new Dependency();
103 dependency.setGroupId(groupId);
104 dependency.setArtifactId(artifactId);
105 dependency.setVersion(version);
106 dependency.setType(dependencyType);
107 plugin.addDependency(dependency);
108 return this;
109 }
110
111 /**
112 * Gets a parameter of the plugin based on its key
113 *
114 * @param key the param key
115 * @return the parameter if exist, null otherwise
116 */
117 public String getParameter(String key) {
118 Xpp3Dom node = findNodeWith(key);
119 return node == null ? null : node.getValue();
120 }
121
122 /**
123 * Gets a list of parameters of the plugin from a param key
124 *
125 * @param key the param key
126 * @return an array of parameters if any, an empty array otherwise
127 */
128 public String[] getParameters(String key) {
129 String[] keyParts = StringUtils.split(key, "/");
130 Xpp3Dom node = configuration;
131 for (int i = 0; i < keyParts.length - 1; i++) {
132 node = getOrCreateChild(node, keyParts[i]);
133 }
134 Xpp3Dom[] children = node.getChildren(keyParts[keyParts.length - 1]);
135 String[] result = new String[children.length];
136 for (int i = 0; i < children.length; i++) {
137 result[i] = children[i].getValue();
138 }
139 return result;
140 }
141
142 /**
143 * Sets a parameter for the maven plugin. This will overrides an existing parameter.
144 *
145 * @param key the param key
146 * @param value the param value
147 * @return this
148 */
149 public MavenPlugin setParameter(String key, String value) {
150 checkKeyArgument(key);
151 String[] keyParts = StringUtils.split(key, "/");
152 Xpp3Dom node = configuration;
153 for (String keyPart : keyParts) {
154 node = getOrCreateChild(node, keyPart);
155 }
156 node.setValue(value);
157 return this;
158 }
159
160 /**
161 * Sets a parameter to the maven plugin. Overrides existing parameter only id specified.
162 *
163 * @param key the param key
164 * @param value the param value
165 * @param override whether to override existing parameter
166 */
167 public void setParameter(String key, String value, boolean override) {
168 if (getParameter(key) == null || override) {
169 setParameter(key, value);
170 }
171 }
172
173 /**
174 * Removes all parameters from the maven plugin
175 */
176 public void removeParameters() {
177 configuration = new Xpp3Dom("configuration");
178 plugin.setConfiguration(this.configuration);
179 }
180
181 /**
182 * Adds a parameter to the maven plugin
183 *
184 * @param key the param key
185 * @param value the param value
186 * @return this
187 */
188 public MavenPlugin addParameter(String key, String value) {
189 String[] keyParts = StringUtils.split(key, "/");
190 Xpp3Dom node = configuration;
191 for (int i = 0; i < keyParts.length - 1; i++) {
192 node = getOrCreateChild(node, keyParts[i]);
193 }
194 Xpp3Dom leaf = new Xpp3Dom(keyParts[keyParts.length - 1]);
195 leaf.setValue(value);
196 node.addChild(leaf);
197 return this;
198 }
199
200 private static Xpp3Dom getOrCreateChild(Xpp3Dom node, String key) {
201 Xpp3Dom child = node.getChild(key);
202 if (child == null) {
203 child = new Xpp3Dom(key);
204 node.addChild(child);
205 }
206 return child;
207 }
208
209 /**
210 * Remove a parameter from the maven plugin based on its key
211 *
212 * @param key the param key
213 */
214 public void removeParameter(String key) {
215 Xpp3Dom node = findNodeWith(key);
216 if (node != null) {
217 remove(node);
218 }
219 }
220
221 private Xpp3Dom findNodeWith(String key) {
222 checkKeyArgument(key);
223 String[] keyParts = key.split("/");
224 Xpp3Dom node = configuration;
225 for (String keyPart : keyParts) {
226 node = node.getChild(keyPart);
227 if (node == null) {
228 return null;
229 }
230 }
231 return node;
232 }
233
234 private static void remove(Xpp3Dom node) {
235 Xpp3Dom parent = node.getParent();
236 for (int i = 0; i < parent.getChildCount(); i++) {
237 Xpp3Dom child = parent.getChild(i);
238 if (child.equals(node)) {
239 parent.removeChild(i);
240 break;
241 }
242 }
243 }
244
245 /**
246 * @return whether the maven plugin has got configuration
247 */
248 public boolean hasConfiguration() {
249 return configuration.getChildCount()>0;
250 }
251
252 private static void checkKeyArgument(String key) {
253 if (key == null) {
254 throw new IllegalArgumentException("Parameter 'key' should not be null.");
255 }
256 }
257
258 /**
259 * Registers a plugin in a project pom
260 * <p/>
261 * <p>Adds the plugin if it does not exist or amend its version if it does exist and specified</p>
262 *
263 * @param pom the project pom
264 * @param groupId the plugin group id
265 * @param artifactId the plugin artifact id
266 * @param version the plugin version
267 * @param overrideVersion whether to override the version if the plugin is already registered
268 * @return the registered plugin
269 */
270 public static MavenPlugin registerPlugin(MavenProject pom, String groupId, String artifactId, String version, boolean overrideVersion) {
271 MavenPlugin plugin = getPlugin(pom, groupId, artifactId);
272 if (plugin == null) {
273 plugin = new MavenPlugin(groupId, artifactId, version);
274
275 } else if (overrideVersion) {
276 plugin.setVersion(version);
277 }
278
279 // remove from pom
280 unregisterPlugin(pom, groupId, artifactId);
281
282 // register
283 pom.getBuild().addPlugin(plugin.getPlugin());
284
285 return plugin;
286 }
287
288 /**
289 * Returns a plugin from a pom based on its group id and artifact id
290 * <p/>
291 * <p>It searches in the build section, then the reporting section and finally the pluginManagement section</p>
292 *
293 * @param pom the project pom
294 * @param groupId the plugin group id
295 * @param artifactId the plugin artifact id
296 * @return the plugin if it exists, null otherwise
297 */
298 public static MavenPlugin getPlugin(MavenProject pom, String groupId, String artifactId) {
299 if (pom == null) {
300 return null;
301 }
302 // look for plugin in <build> section
303 Plugin plugin = null;
304 if (pom.getBuildPlugins() != null) {
305 plugin = getPlugin(pom.getBuildPlugins(), groupId, artifactId);
306 }
307
308 // look for plugin in <report> section
309 if (plugin == null && pom.getReportPlugins() != null) {
310 plugin = getReportPlugin(pom.getReportPlugins(), groupId, artifactId);
311 }
312
313 // look for plugin in <pluginManagement> section
314 if (pom.getPluginManagement() != null) {
315 Plugin pluginManagement = getPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId);
316 if (plugin == null) {
317 plugin = pluginManagement;
318
319 } else if (pluginManagement != null) {
320 if (pluginManagement.getConfiguration() != null) {
321 if (plugin.getConfiguration() == null) {
322 plugin.setConfiguration(pluginManagement.getConfiguration());
323 } else {
324 Xpp3Dom.mergeXpp3Dom((Xpp3Dom) plugin.getConfiguration(), (Xpp3Dom) pluginManagement.getConfiguration());
325 }
326 }
327 if (plugin.getDependencies() == null && pluginManagement.getDependencies() != null) {
328 plugin.setDependencies(pluginManagement.getDependencies());
329 }
330 if (plugin.getVersion() == null) {
331 plugin.setVersion(pluginManagement.getVersion());
332 }
333 }
334 }
335
336 if (plugin != null) {
337 return new MavenPlugin(plugin);
338 }
339 return null;
340 }
341
342 private static Plugin getPlugin(Collection<Plugin> plugins, String groupId, String artifactId) {
343 if (plugins == null) {
344 return null;
345 }
346
347 for (Plugin plugin : plugins) {
348 if (MavenUtils.equals(plugin, groupId, artifactId)) {
349 return plugin;
350 }
351 }
352 return null;
353 }
354
355 private static Plugin getReportPlugin(Collection<ReportPlugin> plugins, String groupId, String artifactId) {
356 if (plugins == null) {
357 return null;
358 }
359
360 for (ReportPlugin plugin : plugins) {
361 if (MavenUtils.equals(plugin, groupId, artifactId)) {
362 return cloneReportPluginToPlugin(plugin);
363 }
364 }
365 return null;
366 }
367
368 private static Plugin cloneReportPluginToPlugin(ReportPlugin reportPlugin) {
369 Plugin plugin = new Plugin();
370 plugin.setGroupId(reportPlugin.getGroupId());
371 plugin.setArtifactId(reportPlugin.getArtifactId());
372 plugin.setVersion(reportPlugin.getVersion());
373 plugin.setConfiguration(reportPlugin.getConfiguration());
374 return plugin;
375 }
376
377 private static void unregisterPlugin(MavenProject pom, String groupId, String artifactId) {
378 if (pom.getPluginManagement() != null && pom.getPluginManagement().getPlugins() != null) {
379 unregisterPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId);
380 }
381 if (pom.getBuildPlugins() != null && pom.getBuildPlugins() != null) {
382 unregisterPlugin(pom.getBuildPlugins(), groupId, artifactId);
383 }
384 if (pom.getReportPlugins() != null) {
385 unregisterReportPlugin(pom.getReportPlugins(), groupId, artifactId);
386 }
387 }
388
389 private static void unregisterPlugin(List<Plugin> plugins, String groupId, String artifactId) {
390 for (Iterator<Plugin> iterator = plugins.iterator(); iterator.hasNext();) {
391 Plugin p = iterator.next();
392 if (MavenUtils.equals(p, groupId, artifactId)) {
393 iterator.remove();
394 }
395 }
396 }
397
398 private static void unregisterReportPlugin(List<ReportPlugin> plugins, String groupId, String artifactId) {
399 for (Iterator<ReportPlugin> iterator = plugins.iterator(); iterator.hasNext();) {
400 ReportPlugin p = iterator.next();
401 if (MavenUtils.equals(p, groupId, artifactId)) {
402 iterator.remove();
403 }
404 }
405 }
406
407
408 @Override
409 public String toString() {
410 return new ToStringBuilder(this)
411 .append("groupId", plugin.getGroupId())
412 .append("artifactId", plugin.getArtifactId())
413 .append("version", plugin.getVersion())
414 .toString();
415 }
416 }