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 }