001/*
002 * Copyright 2011-2012 Stephen Connolly.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.jszip.maven;
018
019import org.apache.maven.artifact.Artifact;
020import org.apache.maven.model.Plugin;
021import org.apache.maven.model.PluginExecution;
022import org.apache.maven.plugin.AbstractMojo;
023import org.apache.maven.plugin.Mojo;
024import org.apache.maven.plugin.MojoExecution;
025import org.apache.maven.plugin.MojoExecutionException;
026import org.apache.maven.plugin.descriptor.MojoDescriptor;
027import org.apache.maven.plugin.descriptor.PluginDescriptor;
028import org.apache.maven.plugins.annotations.Parameter;
029import org.apache.maven.project.MavenProject;
030import org.codehaus.plexus.configuration.PlexusConfiguration;
031import org.codehaus.plexus.util.StringUtils;
032import org.codehaus.plexus.util.xml.Xpp3Dom;
033import org.codehaus.plexus.util.xml.Xpp3DomUtils;
034
035import java.lang.reflect.InvocationTargetException;
036import java.lang.reflect.Method;
037import java.util.ArrayList;
038import java.util.Collections;
039import java.util.List;
040
041/**
042 * Common base class for all the JSZip goals.
043 */
044public abstract class AbstractJSZipMojo extends AbstractMojo {
045    /**
046     * The type of packaging.
047     */
048    public static final String JSZIP_TYPE = "jszip";
049
050    /**
051     * The maven project.
052     */
053    @Parameter(property = "project", readonly = true, required = true)
054    protected MavenProject project;
055    /**
056     * The current plugin.
057     */
058    @Parameter(property = "plugin.groupId", readonly = true, required = true)
059    private String pluginGroupId;
060    /**
061     * The current plugin.
062     */
063    @Parameter(property = "plugin.artifactId", readonly = true, required = true)
064    private String pluginArtifactId;
065    /**
066     * The current plugin.
067     */
068    @Parameter(property = "plugin.version", readonly = true, required = true)
069    private String pluginVersion;
070
071    protected static <T> T invokeMethod(Object object, Class<T> rvClass, String method, Object... args)
072            throws MojoExecutionException {
073        Class[] argClasses = new Class[args.length];
074        for (int i = 0; i < args.length; i++) {
075            argClasses[i] = args.getClass();
076        }
077        try {
078            Method m = object.getClass().getMethod(method, argClasses);
079            return rvClass.cast(m.invoke(object, args));
080        } catch (InvocationTargetException e) {
081            throw new MojoExecutionException(e.getMessage(), e);
082        } catch (NoSuchMethodException e) {
083            throw new MojoExecutionException(e.getMessage(), e);
084        } catch (IllegalAccessException e) {
085            throw new MojoExecutionException(e.getMessage(), e);
086        }
087    }
088
089
090    protected MojoExecution createMojoExecution(Plugin plugin, PluginExecution pluginExecution,
091                                                MojoDescriptor mojoDescriptor) {
092        MojoExecution mojoExecution = new MojoExecution(plugin, mojoDescriptor.getGoal(), pluginExecution.getId());
093        mojoExecution.setConfiguration(convert(mojoDescriptor));
094        if (plugin.getConfiguration() != null || pluginExecution.getConfiguration() != null) {
095            Xpp3Dom pluginConfiguration =
096                    plugin.getConfiguration() == null ? new Xpp3Dom("fake")
097                            : (Xpp3Dom) plugin.getConfiguration();
098
099            Xpp3Dom mergedConfigurationWithExecution =
100                    Xpp3DomUtils.mergeXpp3Dom(
101                            (Xpp3Dom) pluginExecution.getConfiguration(),
102                            pluginConfiguration);
103
104            Xpp3Dom mergedConfiguration =
105                    Xpp3DomUtils.mergeXpp3Dom(mergedConfigurationWithExecution,
106                            convert(mojoDescriptor));
107
108            Xpp3Dom cleanedConfiguration = new Xpp3Dom("configuration");
109            if (mergedConfiguration.getChildren() != null) {
110                for (Xpp3Dom parameter : mergedConfiguration.getChildren()) {
111                    if (mojoDescriptor.getParameterMap().containsKey(parameter.getName())) {
112                        cleanedConfiguration.addChild(parameter);
113                    }
114                }
115            }
116            if (getLog().isDebugEnabled()) {
117                getLog().debug("mojoExecution mergedConfiguration: " + mergedConfiguration);
118                getLog().debug("mojoExecution cleanedConfiguration: " + cleanedConfiguration);
119            }
120
121            mojoExecution.setConfiguration(cleanedConfiguration);
122
123        }
124        mojoExecution.setMojoDescriptor(mojoDescriptor);
125        return mojoExecution;
126    }
127
128    protected MojoDescriptor findMojoDescriptor(PluginDescriptor pluginDescriptor, Class<? extends Mojo> mojoClass) {
129        MojoDescriptor mojoDescriptor = null;
130        for (MojoDescriptor d : pluginDescriptor.getMojos()) {
131            if (mojoClass.getName().equals(d.getImplementation())) {
132                mojoDescriptor = pluginDescriptor.getMojo(d.getGoal());
133                break;
134            }
135        }
136
137        if (mojoDescriptor == null) {
138            getLog().error("Cannot find goal that corresponds to " + mojoClass);
139            throw new IllegalStateException("This plugin should always have the " + mojoClass.getName() + " goal");
140        }
141        return mojoDescriptor;
142    }
143
144    protected Plugin findThisPluginInProject(MavenProject project) {
145        Plugin plugin = null;
146        for (Plugin b : project.getBuild().getPlugins()) {
147            if (pluginGroupId.equals(b.getGroupId()) && pluginArtifactId.equals(b.getArtifactId())) {
148                plugin = b.clone();
149                plugin.setVersion(pluginVersion); // we want to use our version
150                break;
151            }
152        }
153        if (plugin == null) {
154            getLog().debug("Falling back to our own plugin");
155            plugin = new Plugin();
156            plugin.setGroupId(pluginGroupId);
157            plugin.setArtifactId(pluginArtifactId);
158            plugin.setVersion(pluginVersion);
159        }
160        return plugin;
161    }
162
163    private Xpp3Dom convert(MojoDescriptor mojoDescriptor) {
164        PlexusConfiguration config = mojoDescriptor.getMojoConfiguration();
165        return (config != null) ? convert(config) : new Xpp3Dom("configuration");
166    }
167
168    private Xpp3Dom convert(PlexusConfiguration config) {
169        if (config == null) {
170            return null;
171        }
172
173        Xpp3Dom dom = new Xpp3Dom(config.getName());
174        dom.setValue(config.getValue(null));
175
176        for (String attrib : config.getAttributeNames()) {
177            dom.setAttribute(attrib, config.getAttribute(attrib, null));
178        }
179
180        for (int n = config.getChildCount(), i = 0; i < n; i++) {
181            dom.addChild(convert(config.getChild(i)));
182        }
183
184        return dom;
185    }
186
187    protected MavenProject findProject(List<MavenProject> projects, Artifact artifact) {
188        for (MavenProject project : projects) {
189            if (StringUtils.equals(artifact.getGroupId(), project.getGroupId())
190                    && StringUtils.equals(artifact.getArtifactId(), project.getArtifactId())
191                    && StringUtils.equals(artifact.getVersion(), project.getVersion())) {
192                return project;
193            }
194        }
195        return null;
196    }
197
198    protected static String[] processIncludesExcludes(List<String> list) {
199        List<String> result = new ArrayList<String>();
200        for (String entry : list) {
201            String[] entries = entry.split(",");
202            Collections.addAll(result, entries);
203        }
204        return result.toArray(new String[result.size()]);
205    }
206
207}