1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.tonicsystems.jarjar;
18
19 import java.io.File;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.apache.maven.artifact.Artifact;
24 import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
25 import org.apache.maven.plugin.AbstractMojo;
26 import org.apache.maven.plugin.MojoExecutionException;
27 import org.apache.maven.project.MavenProject;
28 import org.apache.maven.shared.artifact.filter.StrictPatternExcludesArtifactFilter;
29 import org.apache.maven.shared.artifact.filter.StrictPatternIncludesArtifactFilter;
30 import org.codehaus.plexus.archiver.Archiver;
31 import org.codehaus.plexus.archiver.UnArchiver;
32 import org.codehaus.plexus.archiver.manager.ArchiverManager;
33 import org.codehaus.plexus.util.FileUtils;
34
35 import com.tonicsystems.jarjar.util.StandaloneJarProcessor;
36
37
38
39
40
41
42
43
44 public class JarJarMojo
45 extends AbstractMojo
46 {
47
48
49
50 private static final String[] META_INF_EXCLUDES = { "META-INF/MANIFEST.MF",
51 "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA" };
52
53
54
55
56
57
58 private MavenProject project;
59
60
61
62
63
64 private File workingDirectory;
65
66
67
68
69
70
71
72 private List<PatternElement> rules;
73
74
75
76
77
78
79 private String input;
80
81
82
83
84
85
86 private String output;
87
88
89
90
91
92
93 private List<String> includes;
94
95
96
97
98
99
100 private List<String> excludes;
101
102
103
104
105
106
107 private boolean skipManifest;
108
109
110
111
112
113
114 private boolean overwrite;
115
116
117
118
119 private ArchiverManager archiverManager;
120
121 @SuppressWarnings( "unchecked" )
122 public void execute()
123 throws MojoExecutionException
124 {
125 try
126 {
127
128
129 if ( null == input && null != project.getArtifact() )
130 {
131 input = project.getArtifact().getFile().getAbsolutePath();
132 }
133 if ( "{classes}".equals( input ) )
134 {
135 input = project.getBuild().getOutputDirectory();
136 }
137 if ( "{test-classes}".equals( input ) )
138 {
139 input = project.getBuild().getTestOutputDirectory();
140 }
141 if ( null == input || !new File( input ).exists() )
142 {
143 getLog().info( "Nothing to process" );
144 return;
145 }
146
147 if ( null == output )
148 {
149 output = input;
150 }
151
152 final File inputFile = new File( input );
153 final File outputFile = new File( output );
154
155 final boolean inPlaceJarJar = inputFile.equals( outputFile );
156
157 final File backupFile = new File( outputFile.getParentFile(), "original-" + outputFile.getName() );
158 if ( backupFile.isDirectory() && backupFile.list().length == 0 )
159 {
160 backupFile.delete();
161 }
162 if ( !overwrite && ( inPlaceJarJar && backupFile.exists() || !inPlaceJarJar && outputFile.exists() ) )
163 {
164 getLog().info( "Already processed" );
165 return;
166 }
167
168
169
170 final MainProcessor processor = new MainProcessor( rules, getLog().isDebugEnabled(), skipManifest );
171 final AndArtifactFilter filter = new AndArtifactFilter();
172 if ( null != includes )
173 {
174 filter.add( new StrictPatternIncludesArtifactFilter( includes ) );
175 }
176 if ( null != excludes )
177 {
178 filter.add( new StrictPatternExcludesArtifactFilter( excludes ) );
179 }
180
181
182
183 getLog().info( "Processing: " + inputFile );
184
185 final File uberZip = new File( workingDirectory, "uber-" + inputFile.getName() );
186 final Archiver archiver = archiverManager.getArchiver( "zip" );
187
188 archiver.setDestFile( uberZip );
189
190 if ( inputFile.isDirectory() )
191 {
192 archiver.addDirectory( inputFile );
193 }
194 else
195 {
196 archiver.addArchivedFileSet( inputFile );
197 }
198
199 for ( final Artifact a : (Set<Artifact>) project.getArtifacts() )
200 {
201 if ( filter.include( a ) )
202 {
203 try
204 {
205 archiver.addArchivedFileSet( a.getFile(), null, META_INF_EXCLUDES );
206 }
207 catch ( final Throwable e )
208 {
209 getLog().info( "Ignoring: " + a );
210 getLog().debug( e );
211 }
212 }
213 }
214
215 if ( !archiver.getResources().hasNext() )
216 {
217 getLog().info( "Nothing to JarJar" );
218 return;
219 }
220
221 archiver.createArchive();
222
223
224
225 getLog().info( "JarJar'ing to: " + outputFile );
226
227 final File hullZip = new File( workingDirectory, "hull-" + inputFile.getName() );
228
229 StandaloneJarProcessor.run( uberZip, hullZip, processor, true );
230 processor.strip( hullZip );
231
232 final boolean toDirectory = outputFile.isDirectory() || !outputFile.exists() && inputFile.isDirectory();
233
234 if ( inPlaceJarJar )
235 {
236 try
237 {
238 getLog().info( "Original: " + backupFile );
239 FileUtils.rename( outputFile, backupFile );
240 }
241 catch ( final Throwable e )
242 {
243 getLog().warn( e.toString() );
244 }
245 }
246
247 if ( toDirectory )
248 {
249 outputFile.mkdirs();
250 final UnArchiver unarchiver = archiverManager.getUnArchiver( "zip" );
251 unarchiver.setDestDirectory( outputFile );
252 unarchiver.setSourceFile( hullZip );
253 unarchiver.extract();
254 }
255 else
256 {
257 FileUtils.copyFile( hullZip, outputFile );
258 }
259 }
260 catch ( final Throwable e )
261 {
262 throw new MojoExecutionException( "Unable to JarJar: " + input + " cause: " + e.getMessage(), e );
263 }
264 }
265 }