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.artifact.ArtifactUtils; 021import org.apache.maven.execution.MavenSession; 022import org.apache.maven.model.Plugin; 023import org.apache.maven.model.PluginExecution; 024import org.apache.maven.plugin.MavenPluginManager; 025import org.apache.maven.plugin.Mojo; 026import org.apache.maven.plugin.MojoExecution; 027import org.apache.maven.plugin.MojoExecutionException; 028import org.apache.maven.plugin.MojoFailureException; 029import org.apache.maven.plugin.PluginConfigurationException; 030import org.apache.maven.plugin.PluginContainerException; 031import org.apache.maven.plugin.descriptor.MojoDescriptor; 032import org.apache.maven.plugin.descriptor.PluginDescriptor; 033import org.apache.maven.plugins.annotations.Component; 034import org.apache.maven.plugins.annotations.LifecyclePhase; 035import org.apache.maven.plugins.annotations.Parameter; 036import org.apache.maven.plugins.annotations.ResolutionScope; 037import org.apache.maven.project.MavenProject; 038import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; 039import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; 040import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter; 041import org.apache.maven.shared.artifact.filter.collection.ScopeFilter; 042import org.apache.maven.shared.artifact.filter.collection.TypeFilter; 043import org.codehaus.plexus.archiver.ArchiverException; 044import org.codehaus.plexus.archiver.zip.ZipUnArchiver; 045import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector; 046import org.codehaus.plexus.util.FileUtils; 047import org.codehaus.plexus.util.StringUtils; 048 049import java.io.File; 050import java.io.IOException; 051import java.util.List; 052import java.util.Set; 053 054/** 055 * Unpacks all the JSZip dependencies into a web application. 056 */ 057@org.apache.maven.plugins.annotations.Mojo(name = "unpack", 058 defaultPhase = LifecyclePhase.GENERATE_RESOURCES, 059 requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME 060) 061public class UnpackMojo extends AbstractJSZipMojo { 062 063 /** 064 * The artifact path mappings for unpacking. 065 */ 066 @Parameter(property = "mappings") 067 private Mapping[] mappings; 068 069 /** 070 * The directory where the webapp is built. 071 */ 072 @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}", required = true) 073 private File webappDirectory; 074 075 /** 076 * The Zip unarchiver. 077 */ 078 @Component(role = org.codehaus.plexus.archiver.UnArchiver.class, hint = "zip") 079 private ZipUnArchiver zipUnArchiver; 080 081 /** 082 * The reactor projects 083 */ 084 @Parameter(property = "reactorProjects", required = true, readonly = true) 085 protected List<MavenProject> reactorProjects; 086 087 /** 088 * The Maven plugin Manager 089 */ 090 @Component 091 private MavenPluginManager mavenPluginManager; 092 093 /** 094 * The current build session instance. This is used for plugin manager API calls. 095 */ 096 @Parameter(property = "session", required = true, readonly = true) 097 private MavenSession session; 098 099 /** 100 * This plugin's descriptor 101 */ 102 @Parameter(property = "plugin", readonly = true) 103 private PluginDescriptor pluginDescriptor; 104 105 /** 106 * A list of <include> elements specifying the files (by pattern) that should be included in 107 * unpacking. 108 */ 109 @Parameter 110 private List<String> unpackIncludes; 111 112 /** 113 * A list of <exclude> elements specifying the files (by pattern) that should be excluded from 114 * unpacking. The default is 115 * <pre> 116 * <unpackExclude>META-INF/maven/**/pom.*</unpackExclude> 117 * <unpackExclude>package.json</unpackExclude> 118 * <unpackExclude>**/*.less</unpackExclude> 119 * <unpackExclude>**/*.sass</unpackExclude> 120 * <unpackExclude>**/*.scss</unpackExclude> 121 * </pre> 122 */ 123 @Parameter 124 private List<String> unpackExcludes; 125 126 /** 127 * @see org.apache.maven.plugin.Mojo#execute() 128 */ 129 public void execute() 130 throws MojoExecutionException, MojoFailureException { 131 getLog().info("Starting unpack into " + webappDirectory); 132 FilterArtifacts filter = new FilterArtifacts(); 133 134 filter.addFilter(new ProjectTransitivityFilter(project.getDependencyArtifacts(), false)); 135 136 filter.addFilter(new ScopeFilter("runtime", "")); 137 138 filter.addFilter(new TypeFilter(JSZIP_TYPE, "")); 139 140 // start with all artifacts. 141 Set<Artifact> artifacts = project.getArtifacts(); 142 143 // perform filtering 144 try { 145 artifacts = filter.filter(artifacts); 146 } catch (ArtifactFilterException e) { 147 throw new MojoExecutionException(e.getMessage(), e); 148 } 149 150 String includes; 151 String excludes; 152 if (unpackIncludes != null && !unpackIncludes.isEmpty()) { 153 includes = StringUtils.join(unpackIncludes.iterator(), ","); 154 } else { 155 includes = null; 156 } 157 158 if (unpackExcludes != null && !unpackExcludes.isEmpty()) { 159 excludes = StringUtils.join(unpackExcludes.iterator(), ","); 160 } else { 161 excludes="META-INF/maven/**/pom.*,package.json,**/*.less,**/*.sass,**/*.scss"; 162 } 163 164 165 166 for (Artifact artifact : artifacts) { 167 String path = getPath(artifact); 168 File artifactDirectory; 169 if (StringUtils.isBlank(path)) { 170 getLog().info("Unpacking " + ArtifactUtils.key(artifact)); 171 artifactDirectory = webappDirectory; 172 } else { 173 getLog().info("Unpacking " + ArtifactUtils.key(artifact) + " at path " + path); 174 artifactDirectory = new File(webappDirectory, path); 175 } 176 unpack(artifact, artifactDirectory, includes, excludes); 177 } 178 } 179 180 private String getPath(Artifact artifact) { 181 if (mappings == null) return ""; 182 for (Mapping mapping: mappings) { 183 if (mapping.isMatch(artifact)) 184 return StringUtils.clean(mapping.getPath()); 185 } 186 return ""; 187 } 188 189 protected void unpack(Artifact artifact, File location, String includes, String excludes) 190 throws MojoExecutionException { 191 File file = artifact.getFile(); 192 if (file.isDirectory()) { 193 MavenProject fromReactor = findProject(reactorProjects, artifact); 194 if (fromReactor != null) { 195 MavenSession session = this.session.clone(); 196 session.setCurrentProject(fromReactor); 197 Plugin plugin = findThisPluginInProject(fromReactor); 198 try { 199 // we cheat here and use our version of the plugin... but this is less of a cheat than the only 200 // other way which is via reflection. 201 MojoDescriptor jszipDescriptor = findMojoDescriptor(this.pluginDescriptor, JSZipMojo.class); 202 203 for (PluginExecution pluginExecution : plugin.getExecutions()) { 204 if (!pluginExecution.getGoals().contains(jszipDescriptor.getGoal())) { 205 continue; 206 } 207 MojoExecution mojoExecution = 208 createMojoExecution(plugin, pluginExecution, jszipDescriptor); 209 JSZipMojo mojo = (JSZipMojo) mavenPluginManager 210 .getConfiguredMojo(Mojo.class, session, mojoExecution); 211 try { 212 File contentDirectory = mojo.getContentDirectory(); 213 if (contentDirectory.isDirectory()) { 214 FileUtils.copyDirectory(contentDirectory, location); 215 } 216 File resourcesDirectory = mojo.getResourcesDirectory(); 217 if (resourcesDirectory.isDirectory()) { 218 FileUtils.copyDirectory(resourcesDirectory, location); 219 } 220 } finally { 221 mavenPluginManager.releaseMojo(mojo, mojoExecution); 222 } 223 } 224 } catch (PluginConfigurationException e) { 225 throw new MojoExecutionException(e.getMessage(), e); 226 } catch (IOException e) { 227 throw new MojoExecutionException(e.getMessage(), e); 228 } catch (PluginContainerException e) { 229 throw new MojoExecutionException(e.getMessage(), e); 230 } 231 } else { 232 throw new MojoExecutionException("Cannot find jzsip artifact: " + artifact.getId()); 233 } 234 } else { 235 try { 236 location.mkdirs(); 237 238 zipUnArchiver.setSourceFile(file); 239 240 zipUnArchiver.setDestDirectory(location); 241 242 if (StringUtils.isNotEmpty(excludes) || StringUtils.isNotEmpty(includes)) { 243 IncludeExcludeFileSelector[] selectors = 244 new IncludeExcludeFileSelector[]{new IncludeExcludeFileSelector()}; 245 246 if (StringUtils.isNotEmpty(excludes)) { 247 selectors[0].setExcludes(excludes.split(",")); 248 } 249 250 if (StringUtils.isNotEmpty(includes)) { 251 selectors[0].setIncludes(includes.split(",")); 252 } 253 254 zipUnArchiver.setFileSelectors(selectors); 255 } 256 257 zipUnArchiver.extract(); 258 } catch (ArchiverException e) { 259 e.printStackTrace(); 260 throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location + "\r\n" 261 + e.toString(), e); 262 } 263 } 264 } 265 266}