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