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     * @since 1.10
036     */
037    public class MavenPlugin {
038    
039      private Plugin plugin;
040      private Xpp3Dom configuration;
041    
042      public MavenPlugin(Plugin plugin) {
043        this.plugin = plugin;
044        this.configuration = (Xpp3Dom) plugin.getConfiguration();
045        if (this.configuration == null) {
046          configuration = new Xpp3Dom("configuration");
047          plugin.setConfiguration(this.configuration);
048        }
049      }
050    
051      public MavenPlugin(String groupId, String artifactId, String version) {
052        this.plugin = new Plugin();
053        plugin.setGroupId(groupId);
054        plugin.setArtifactId(artifactId);
055        plugin.setVersion(version);
056        configuration = new Xpp3Dom("configuration");
057        plugin.setConfiguration(this.configuration);
058      }
059    
060      public MavenPlugin setVersion(String version) {
061        this.plugin.setVersion(version);
062        return this;
063      }
064    
065      public Plugin getPlugin() {
066        return plugin;
067      }
068    
069      public MavenPlugin addDependency(String groupId, String artifactId, String version, String dependencyType) {
070        Dependency dependency = new Dependency();
071        dependency.setGroupId(groupId);
072        dependency.setArtifactId(artifactId);
073        dependency.setVersion(version);
074        dependency.setType(dependencyType);
075        plugin.addDependency(dependency);
076        return this;
077      }
078    
079      public String getParameter(String key) {
080        Xpp3Dom node = findNodeWith(key);
081        return node == null ? null : node.getValue();
082      }
083    
084      public String[] getParameters(String key) {
085        String[] keyParts = StringUtils.split(key, "/");
086        Xpp3Dom node = configuration;
087        for (int i = 0; i < keyParts.length - 1; i++) {
088          node = getOrCreateChild(node, keyParts[i]);
089        }
090        Xpp3Dom[] children = node.getChildren(keyParts[keyParts.length - 1]);
091        String[] result = new String[children.length];
092        for (int i = 0; i < children.length; i++) {
093          result[i] = children[i].getValue();
094        }
095        return result;
096      }
097    
098      public MavenPlugin setParameter(String key, String value) {
099        checkKeyArgument(key);
100        String[] keyParts = StringUtils.split(key, "/");
101        Xpp3Dom node = configuration;
102        for (String keyPart : keyParts) {
103          node = getOrCreateChild(node, keyPart);
104        }
105        node.setValue(value);
106        return this;
107      }
108    
109      public void setParameter(String key, String value, boolean override) {
110        if (getParameter(key) == null || override) {
111          setParameter(key, value);
112        }
113      }
114    
115      public void removeParameters() {
116        configuration = new Xpp3Dom("configuration");
117        plugin.setConfiguration(this.configuration);
118      }
119    
120    
121      public MavenPlugin addParameter(String key, String value) {
122        String[] keyParts = StringUtils.split(key, "/");
123        Xpp3Dom node = configuration;
124        for (int i = 0; i < keyParts.length - 1; i++) {
125          node = getOrCreateChild(node, keyParts[i]);
126        }
127        Xpp3Dom leaf = new Xpp3Dom(keyParts[keyParts.length - 1]);
128        leaf.setValue(value);
129        node.addChild(leaf);
130        return this;
131      }
132    
133      private static Xpp3Dom getOrCreateChild(Xpp3Dom node, String key) {
134        Xpp3Dom child = node.getChild(key);
135        if (child == null) {
136          child = new Xpp3Dom(key);
137          node.addChild(child);
138        }
139        return child;
140      }
141    
142      public void removeParameter(String key) {
143        Xpp3Dom node = findNodeWith(key);
144        if (node != null) {
145          remove(node);
146        }
147      }
148    
149      private Xpp3Dom findNodeWith(String key) {
150        checkKeyArgument(key);
151        String[] keyParts = key.split("/");
152        Xpp3Dom node = configuration;
153        for (String keyPart : keyParts) {
154          node = node.getChild(keyPart);
155          if (node == null) {
156            return null;
157          }
158        }
159        return node;
160      }
161    
162      private static void remove(Xpp3Dom node) {
163        Xpp3Dom parent = node.getParent();
164        for (int i = 0; i < parent.getChildCount(); i++) {
165          Xpp3Dom child = parent.getChild(i);
166          if (child.equals(node)) {
167            parent.removeChild(i);
168            break;
169          }
170        }
171      }
172    
173      public boolean hasConfiguration() {
174        return configuration.getChildCount() == 0;
175      }
176    
177      private static void checkKeyArgument(String key) {
178        if (key == null) {
179          throw new IllegalArgumentException("Parameter 'key' should not be null.");
180        }
181      }
182    
183      public static MavenPlugin registerPlugin(MavenProject pom, String groupId, String artifactId, String version, boolean overrideVersion) {
184        MavenPlugin plugin = getPlugin(pom, groupId, artifactId);
185        if (plugin == null) {
186          plugin = new MavenPlugin(groupId, artifactId, version);
187    
188        } else if (overrideVersion) {
189          plugin.setVersion(version);
190        }
191    
192        // remove from pom
193        unregisterPlugin(pom, groupId, artifactId);
194    
195        // register
196        pom.addPlugin(plugin.getPlugin());
197    
198        return plugin;
199      }
200    
201      public static MavenPlugin getPlugin(MavenProject pom, String groupId, String artifactId) {
202        if (pom == null) {
203          return null;
204        }
205        // look for plugin in <build> section
206        Plugin plugin = null;
207        if (pom.getBuildPlugins() != null) {
208          plugin = getPlugin(pom.getBuildPlugins(), groupId, artifactId);
209        }
210    
211        // look for plugin in <report> section
212        if (plugin == null && pom.getReportPlugins() != null) {
213          plugin = getReportPlugin(pom.getReportPlugins(), groupId, artifactId);
214        }
215    
216        // look for plugin in <pluginManagement> section
217        if (pom.getPluginManagement() != null) {
218          Plugin pluginManagement = getPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId);
219          if (plugin == null) {
220            plugin = pluginManagement;
221    
222          } else if (pluginManagement != null) {
223            if (pluginManagement.getConfiguration() != null) {
224              if (plugin.getConfiguration() == null) {
225                plugin.setConfiguration(pluginManagement.getConfiguration());
226              } else {
227                Xpp3Dom.mergeXpp3Dom((Xpp3Dom) plugin.getConfiguration(), (Xpp3Dom) pluginManagement.getConfiguration());
228              }
229            }
230            if (plugin.getDependencies() == null && pluginManagement.getDependencies() != null) {
231              plugin.setDependencies(pluginManagement.getDependencies());
232            }
233            if (plugin.getVersion() == null) {
234              plugin.setVersion(pluginManagement.getVersion());
235            }
236          }
237        }
238    
239        if (plugin != null) {
240          return new MavenPlugin(plugin);
241        }
242        return null;
243      }
244    
245      private static Plugin getPlugin(Collection<Plugin> plugins, String groupId, String artifactId) {
246        if (plugins == null) {
247          return null;
248        }
249    
250        for (Plugin plugin : plugins) {
251          if (MavenUtils.equals(plugin, groupId, artifactId)) {
252            return plugin;
253          }
254        }
255        return null;
256      }
257    
258      private static Plugin getReportPlugin(Collection<ReportPlugin> plugins, String groupId, String artifactId) {
259        if (plugins == null) {
260          return null;
261        }
262    
263        for (ReportPlugin plugin : plugins) {
264          if (MavenUtils.equals(plugin, groupId, artifactId)) {
265            return cloneReportPluginToPlugin(plugin);
266          }
267        }
268        return null;
269      }
270    
271      private static Plugin cloneReportPluginToPlugin(ReportPlugin reportPlugin) {
272        Plugin plugin = new Plugin();
273        plugin.setGroupId(reportPlugin.getGroupId());
274        plugin.setArtifactId(reportPlugin.getArtifactId());
275        plugin.setVersion(reportPlugin.getVersion());
276        plugin.setConfiguration(reportPlugin.getConfiguration());
277        return plugin;
278      }
279    
280      private static void unregisterPlugin(MavenProject pom, String groupId, String artifactId) {
281        if (pom.getPluginManagement() != null && pom.getPluginManagement().getPlugins() != null) {
282          unregisterPlugin(pom.getPluginManagement().getPlugins(), groupId, artifactId);
283        }
284        if (pom.getBuildPlugins() != null && pom.getBuildPlugins() != null) {
285          unregisterPlugin(pom.getBuildPlugins(), groupId, artifactId);
286        }
287        if (pom.getReportPlugins() != null) {
288          unregisterReportPlugin(pom.getReportPlugins(), groupId, artifactId);
289        }
290      }
291    
292      private static void unregisterPlugin(List<Plugin> plugins, String groupId, String artifactId) {
293        for (Iterator<Plugin> iterator = plugins.iterator(); iterator.hasNext();) {
294          Plugin p = iterator.next();
295          if (MavenUtils.equals(p, groupId, artifactId)) {
296            iterator.remove();
297          }
298        }
299      }
300    
301      private static void unregisterReportPlugin(List<ReportPlugin> plugins, String groupId, String artifactId) {
302        for (Iterator<ReportPlugin> iterator = plugins.iterator(); iterator.hasNext();) {
303          ReportPlugin p = iterator.next();
304          if (MavenUtils.equals(p, groupId, artifactId)) {
305            iterator.remove();
306          }
307        }
308      }
309    
310    
311      @Override
312      public String toString() {
313        return new ToStringBuilder(this)
314            .append("groupId", plugin.getGroupId())
315            .append("artifactId", plugin.getArtifactId())
316            .append("version", plugin.getVersion())
317            .toString();
318      }
319    }