001package org.jszip.maven;
002
003import org.apache.maven.artifact.Artifact;
004import org.apache.maven.artifact.ArtifactUtils;
005import org.apache.maven.execution.MavenSession;
006import org.apache.maven.model.Plugin;
007import org.apache.maven.model.PluginExecution;
008import org.apache.maven.plugin.MavenPluginManager;
009import org.apache.maven.plugin.MojoExecution;
010import org.apache.maven.plugin.MojoExecutionException;
011import org.apache.maven.plugin.PluginConfigurationException;
012import org.apache.maven.plugin.PluginContainerException;
013import org.apache.maven.plugin.descriptor.MojoDescriptor;
014import org.apache.maven.plugin.descriptor.PluginDescriptor;
015import org.apache.maven.plugins.annotations.Component;
016import org.apache.maven.plugins.annotations.Parameter;
017import org.apache.maven.project.MavenProject;
018import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
019import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
020import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter;
021import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
022import org.apache.maven.shared.artifact.filter.collection.TypeFilter;
023import org.codehaus.plexus.util.StringUtils;
024import org.jszip.pseudo.io.PseudoFileSystem;
025
026import java.io.File;
027import java.io.IOException;
028import java.util.ArrayList;
029import java.util.List;
030import java.util.Set;
031
032/**
033 * @author stephenc
034 * @since 21/12/2012 15:02
035 */
036public abstract class AbstractPseudoFileSystemProcessorMojo extends AbstractJSZipMojo {
037    /**
038     * The directory where the webapp is built.
039     */
040    @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}", required = true)
041    protected File webappDirectory;
042    /**
043     * The reactor projects
044     */
045    @Parameter(property = "reactorProjects", required = true, readonly = true)
046    protected List<MavenProject> reactorProjects;
047    /**
048     * The artifact path mappings for unpacking.
049     */
050    @Parameter(property = "mappings")
051    private Mapping[] mappings;
052    /**
053     * Single directory for extra files to include in the WAR.
054     */
055    @Parameter(defaultValue = "${basedir}/src/main/webapp", required = true)
056    private File warSourceDirectory;
057    /**
058     * The Maven plugin Manager
059     */
060    @Component
061    private MavenPluginManager mavenPluginManager;
062    /**
063     * The current build session instance. This is used for plugin manager API calls.
064     */
065    @Parameter(property = "session", required = true, readonly = true)
066    private MavenSession session;
067    /**
068     * This plugin's descriptor
069     */
070    @Parameter(property = "plugin", readonly = true)
071    private PluginDescriptor pluginDescriptor;
072
073    private String getPath(Artifact artifact) {
074        return Mapping.getArtifactPath(mappings, artifact);
075    }
076
077    protected List<PseudoFileSystem.Layer> buildVirtualFileSystemLayers() throws MojoExecutionException {
078        List<PseudoFileSystem.Layer> layers = new ArrayList<PseudoFileSystem.Layer>();
079        layers.add(new PseudoFileSystem.FileLayer("/target", webappDirectory));
080        layers.add(new PseudoFileSystem.FileLayer("/virtual", warSourceDirectory));
081        FilterArtifacts filter = new FilterArtifacts();
082
083        filter.addFilter(new ProjectTransitivityFilter(project.getDependencyArtifacts(), false));
084
085        filter.addFilter(new ScopeFilter("runtime", ""));
086
087        filter.addFilter(new TypeFilter(JSZIP_TYPE, ""));
088
089        // start with all artifacts.
090        Set<Artifact> artifacts = project.getArtifacts();
091
092        // perform filtering
093        try {
094            artifacts = filter.filter(artifacts);
095        } catch (ArtifactFilterException e) {
096            throw new MojoExecutionException(e.getMessage(), e);
097        }
098
099        for (Artifact artifact : artifacts) {
100            String path = getPath(artifact);
101            getLog().info("Adding " + ArtifactUtils.key(artifact) + " to virtual filesystem");
102            File file = artifact.getFile();
103            if (file.isDirectory()) {
104                MavenProject fromReactor = findProject(reactorProjects, artifact);
105                if (fromReactor != null) {
106                    MavenSession session = this.session.clone();
107                    session.setCurrentProject(fromReactor);
108                    Plugin plugin = findThisPluginInProject(fromReactor);
109                    try {
110                        // we cheat here and use our version of the plugin... but this is less of a cheat than the only
111                        // other way which is via reflection.
112                        MojoDescriptor jszipDescriptor = findMojoDescriptor(this.pluginDescriptor, JSZipMojo.class);
113
114                        for (PluginExecution pluginExecution : plugin.getExecutions()) {
115                            if (!pluginExecution.getGoals().contains(jszipDescriptor.getGoal())) {
116                                continue;
117                            }
118                            MojoExecution mojoExecution =
119                                    createMojoExecution(plugin, pluginExecution, jszipDescriptor);
120                            JSZipMojo mojo = (JSZipMojo) mavenPluginManager
121                                    .getConfiguredMojo(org.apache.maven.plugin.Mojo.class, session, mojoExecution);
122                            try {
123                                File contentDirectory = mojo.getContentDirectory();
124                                if (contentDirectory.isDirectory()) {
125                                    getLog().debug("Merging directory " + contentDirectory + " into " + path);
126                                    layers.add(new PseudoFileSystem.FileLayer(path, contentDirectory));
127                                }
128                                File resourcesDirectory = mojo.getResourcesDirectory();
129                                if (resourcesDirectory.isDirectory()) {
130                                    getLog().debug("Merging directory " + contentDirectory + " into " + path);
131                                    layers.add(new PseudoFileSystem.FileLayer(path, resourcesDirectory));
132                                }
133                            } finally {
134                                mavenPluginManager.releaseMojo(mojo, mojoExecution);
135                            }
136                        }
137                    } catch (PluginConfigurationException e) {
138                        throw new MojoExecutionException(e.getMessage(), e);
139                    } catch (PluginContainerException e) {
140                        throw new MojoExecutionException(e.getMessage(), e);
141                    }
142                } else {
143                    throw new MojoExecutionException("Cannot find jzsip artifact: " + artifact.getId());
144                }
145            } else {
146                try {
147                    getLog().debug("Merging .zip file " + file + " into " + path);
148                    layers.add(new PseudoFileSystem.ZipLayer(path, file));
149                } catch (IOException e) {
150                    throw new MojoExecutionException(e.getMessage(), e);
151                }
152            }
153        }
154        return layers;
155    }
156}