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 * Gets a parameter of the plugin based on its key 094 * 095 * @param key the param key 096 * @return the parameter if exist, null otherwise 097 */ 098 public String getParameter(String key) { 099 Xpp3Dom node = findNodeWith(key); 100 return node == null ? null : node.getValue(); 101 } 102 103 /** 104 * Gets a list of parameters of the plugin from a param key 105 * 106 * @param key the param key 107 * @return an array of parameters if any, an empty array otherwise 108 */ 109 public String[] getParameters(String key) { 110 String[] keyParts = StringUtils.split(key, "/"); 111 Xpp3Dom node = configuration; 112 for (int i = 0; i < keyParts.length - 1; i++) { 113 node = getOrCreateChild(node, keyParts[i]); 114 } 115 Xpp3Dom[] children = node.getChildren(keyParts[keyParts.length - 1]); 116 String[] result = new String[children.length]; 117 for (int i = 0; i < children.length; i++) { 118 result[i] = children[i].getValue(); 119 } 120 return result; 121 } 122 123 /** 124 * Sets a parameter for the maven plugin. This will overrides an existing parameter. 125 * 126 * @param key the param key 127 * @param value the param value 128 * @return this 129 */ 130 public MavenPlugin setParameter(String key, String value) { 131 checkKeyArgument(key); 132 String[] keyParts = StringUtils.split(key, "/"); 133 Xpp3Dom node = configuration; 134 for (String keyPart : keyParts) { 135 node = getOrCreateChild(node, keyPart); 136 } 137 node.setValue(value); 138 return this; 139 } 140 141 /** 142 * Sets a parameter to the maven plugin. Overrides existing parameter only id specified. 143 * 144 * @param key the param key 145 * @param value the param value 146 * @param override whether to override existing parameter 147 */ 148 public void setParameter(String key, String value, boolean override) { 149 if (getParameter(key) == null || override) { 150 setParameter(key, value); 151 } 152 } 153 154 /** 155 * Removes all parameters from the maven plugin 156 */ 157 public void removeParameters() { 158 configuration = new Xpp3Dom("configuration"); 159 plugin.setConfiguration(this.configuration); 160 } 161 162 /** 163 * Adds a parameter to the maven plugin 164 * 165 * @param key the param key 166 * @param value the param value 167 * @return this 168 */ 169 public MavenPlugin addParameter(String key, String value) { 170 String[] keyParts = StringUtils.split(key, "/"); 171 Xpp3Dom node = configuration; 172 for (int i = 0; i < keyParts.length - 1; i++) { 173 node = getOrCreateChild(node, keyParts[i]); 174 } 175 Xpp3Dom leaf = new Xpp3Dom(keyParts[keyParts.length - 1]); 176 leaf.setValue(value); 177 node.addChild(leaf); 178 return this; 179 } 180 181 private static Xpp3Dom getOrCreateChild(Xpp3Dom node, String key) { 182 Xpp3Dom child = node.getChild(key); 183 if (child == null) { 184 child = new Xpp3Dom(key); 185 node.addChild(child); 186 } 187 return child; 188 } 189 190 /** 191 * Remove a parameter from the maven plugin based on its key 192 * 193 * @param key the param key 194 */ 195 public void removeParameter(String key) { 196 Xpp3Dom node = findNodeWith(key); 197 if (node != null) { 198 remove(node); 199 } 200 } 201 202 private Xpp3Dom findNodeWith(String key) { 203 checkKeyArgument(key); 204 String[] keyParts = key.split("/"); 205 Xpp3Dom node = configuration; 206 for (String keyPart : keyParts) { 207 node = node.getChild(keyPart); 208 if (node == null) { 209 return null; 210 } 211 } 212 return node; 213 } 214 215 private static void remove(Xpp3Dom node) { 216 Xpp3Dom parent = node.getParent(); 217 for (int i = 0; i < parent.getChildCount(); i++) { 218 Xpp3Dom child = parent.getChild(i); 219 if (child.equals(node)) { 220 parent.removeChild(i); 221 break; 222 } 223 } 224 } 225 226 /** 227 * @return whether the maven plugin has got configuration 228 */ 229 public boolean hasConfiguration() { 230 return configuration.getChildCount()>0; 231 } 232 233 private static void checkKeyArgument(String key) { 234 if (key == null) { 235 throw new IllegalArgumentException("Parameter 'key' should not be null."); 236 } 237 } 238 239 /** 240 * Registers a plugin in a project pom 241 * <p/> 242 * <p>Adds the plugin if it does not exist or amend its version if it does exist and specified</p> 243 * 244 * @param pom the project pom 245 * @param groupId the plugin group id 246 * @param artifactId the plugin artifact id 247 * @param version the plugin version 248 * @param overrideVersion whether to override the version if the plugin is already registered 249 * @return the registered plugin 250 */ 251 public static MavenPlugin registerPlugin(MavenProject pom, String groupId, String artifactId, String version, boolean overrideVersion) { 252 MavenPlugin plugin = getPlugin(pom, groupId, artifactId); 253 if (plugin == null) { 254 plugin = new MavenPlugin(groupId, artifactId, version); 255 256 } else if (overrideVersion) { 257 plugin.setVersion(version); 258 } 259 260 // remove from pom 261 unregisterPlugin(pom, groupId, artifactId); 262 263 // register 264 pom.getBuild().addPlugin(plugin.getPlugin()); 265 266 return plugin; 267 } 268 269 /** 270 * Returns a plugin from a pom based on its group id and artifact id 271 * <p/> 272 * <p>It searches in the build section, then the reporting section and finally the pluginManagement section</p> 273 * 274 * @param pom the project pom 275 * @param groupId the plugin group id 276 * @param artifactId the plugin artifact id 277 * @return the plugin if it exists, null otherwise 278 */ 279 public static MavenPlugin getPlugin(MavenProject pom, String groupId, String artifactId) { 280 if (pom == null) { 281 return null; 282 } 283 // look for plugin in <build> section 284 Plugin plugin = null; 285 if (pom.getBuildPlugins() != null) { 286 plugin = getPlugin(pom.getBuildPlugins(), groupId, artifactId); 287 } 288 289 // look for plugin in <report> section 290 if (plugin == null && pom.getReportPlugins() != null) { 291 plugin = getReportPlugin(pom.getReportPlugins(), groupId, artifactId); 292 } 293 294 // look for plugin in <pluginManagement> section 295 if (pom.getPluginManagement() != null) { 296 Plugin pluginManagement = getPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId); 297 if (plugin == null) { 298 plugin = pluginManagement; 299 300 } else if (pluginManagement != null) { 301 if (pluginManagement.getConfiguration() != null) { 302 if (plugin.getConfiguration() == null) { 303 plugin.setConfiguration(pluginManagement.getConfiguration()); 304 } else { 305 Xpp3Dom.mergeXpp3Dom((Xpp3Dom) plugin.getConfiguration(), (Xpp3Dom) pluginManagement.getConfiguration()); 306 } 307 } 308 if (plugin.getDependencies() == null && pluginManagement.getDependencies() != null) { 309 plugin.setDependencies(pluginManagement.getDependencies()); 310 } 311 if (plugin.getVersion() == null) { 312 plugin.setVersion(pluginManagement.getVersion()); 313 } 314 } 315 } 316 317 if (plugin != null) { 318 return new MavenPlugin(plugin); 319 } 320 return null; 321 } 322 323 private static Plugin getPlugin(Collection<Plugin> plugins, String groupId, String artifactId) { 324 if (plugins == null) { 325 return null; 326 } 327 328 for (Plugin plugin : plugins) { 329 if (MavenUtils.equals(plugin, groupId, artifactId)) { 330 return plugin; 331 } 332 } 333 return null; 334 } 335 336 private static Plugin getReportPlugin(Collection<ReportPlugin> plugins, String groupId, String artifactId) { 337 if (plugins == null) { 338 return null; 339 } 340 341 for (ReportPlugin plugin : plugins) { 342 if (MavenUtils.equals(plugin, groupId, artifactId)) { 343 return cloneReportPluginToPlugin(plugin); 344 } 345 } 346 return null; 347 } 348 349 private static Plugin cloneReportPluginToPlugin(ReportPlugin reportPlugin) { 350 Plugin plugin = new Plugin(); 351 plugin.setGroupId(reportPlugin.getGroupId()); 352 plugin.setArtifactId(reportPlugin.getArtifactId()); 353 plugin.setVersion(reportPlugin.getVersion()); 354 plugin.setConfiguration(reportPlugin.getConfiguration()); 355 return plugin; 356 } 357 358 private static void unregisterPlugin(MavenProject pom, String groupId, String artifactId) { 359 if (pom.getPluginManagement() != null && pom.getPluginManagement().getPlugins() != null) { 360 unregisterPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId); 361 } 362 if (pom.getBuildPlugins() != null && pom.getBuildPlugins() != null) { 363 unregisterPlugin(pom.getBuildPlugins(), groupId, artifactId); 364 } 365 if (pom.getReportPlugins() != null) { 366 unregisterReportPlugin(pom.getReportPlugins(), groupId, artifactId); 367 } 368 } 369 370 private static void unregisterPlugin(List<Plugin> plugins, String groupId, String artifactId) { 371 for (Iterator<Plugin> iterator = plugins.iterator(); iterator.hasNext();) { 372 Plugin p = iterator.next(); 373 if (MavenUtils.equals(p, groupId, artifactId)) { 374 iterator.remove(); 375 } 376 } 377 } 378 379 private static void unregisterReportPlugin(List<ReportPlugin> plugins, String groupId, String artifactId) { 380 for (Iterator<ReportPlugin> iterator = plugins.iterator(); iterator.hasNext();) { 381 ReportPlugin p = iterator.next(); 382 if (MavenUtils.equals(p, groupId, artifactId)) { 383 iterator.remove(); 384 } 385 } 386 } 387 388 389 @Override 390 public String toString() { 391 return new ToStringBuilder(this) 392 .append("groupId", plugin.getGroupId()) 393 .append("artifactId", plugin.getArtifactId()) 394 .append("version", plugin.getVersion()) 395 .toString(); 396 } 397 }