1 package org.codehaus.mojo.webstart.pack200;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.shared.utils.io.IOUtil;
23 import org.codehaus.plexus.component.annotations.Component;
24
25 import java.io.BufferedInputStream;
26 import java.io.BufferedOutputStream;
27 import java.io.DataInputStream;
28 import java.io.File;
29 import java.io.FileFilter;
30 import java.io.FileInputStream;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.jar.JarFile;
40 import java.util.jar.JarOutputStream;
41 import java.util.jar.Pack200;
42 import java.util.jar.Pack200.Packer;
43 import java.util.zip.Deflater;
44 import java.util.zip.GZIPInputStream;
45 import java.util.zip.GZIPOutputStream;
46
47
48
49
50
51
52
53 @Component( role = Pack200Tool.class, hint = "default" )
54 public class DefaultPack200Tool
55 implements Pack200Tool
56 {
57
58 public static final String PACK_GZ_EXTENSION = ".pack.gz";
59
60 public static final String PACK_EXTENSION = ".pack";
61
62
63
64
65 public void pack( File source, File destination, Map<String, String> props, boolean gzip )
66 throws IOException
67 {
68 JarFile jar = null;
69 OutputStream out = null;
70 try
71 {
72 out = new FileOutputStream( destination );
73 if ( gzip )
74 {
75 out = new GZIPOutputStream( out )
76 {
77 {
78 def.setLevel( Deflater.BEST_COMPRESSION );
79 }
80 };
81 }
82 out = new BufferedOutputStream( out );
83
84 jar = new JarFile( source, false );
85
86 Pack200.Packer packer = Pack200.newPacker();
87 packer.properties().putAll( props );
88 packer.pack( jar, out );
89 }
90 finally
91 {
92 IOUtil.close( out );
93 if ( jar != null )
94 {
95 jar.close();
96 }
97 }
98 }
99
100
101
102
103 public void repack( File source, File destination, Map<String, String> props )
104 throws IOException
105 {
106 File tempFile = new File( source.toString() + ".tmp" );
107
108 try
109 {
110 pack( source, tempFile, props, false );
111 unpack( tempFile, destination, props );
112 }
113 finally
114 {
115 deleteFile( tempFile );
116 }
117 }
118
119
120
121
122 public void unpack( File source, File destination, Map<String, String> props )
123 throws IOException
124 {
125 InputStream in = null;
126 JarOutputStream out = null;
127 try
128 {
129 in = new FileInputStream( source );
130 if ( isGzipped( source ) )
131 {
132 in = new GZIPInputStream( in );
133 }
134 in = new BufferedInputStream( in );
135
136 out = new JarOutputStream( new BufferedOutputStream( new FileOutputStream( destination ) ) );
137
138 Pack200.Unpacker unpacker = Pack200.newUnpacker();
139 unpacker.properties().putAll( props );
140 unpacker.unpack( in, out );
141 }
142 finally
143 {
144 IOUtil.close( in );
145 IOUtil.close( out );
146 }
147 }
148
149
150
151
152 public void packJars( File directory, FileFilter jarFileFilter, boolean gzip, List<String> passFiles )
153 throws IOException
154 {
155
156 File[] jarFiles = directory.listFiles( jarFileFilter );
157 for ( File jarFile1 : jarFiles )
158 {
159
160
161 final String extension = gzip ? PACK_GZ_EXTENSION : PACK_EXTENSION;
162
163 File jarFile = jarFile1;
164
165 File pack200Jar = new File( jarFile.getParentFile(), jarFile.getName() + extension );
166
167 deleteFile( pack200Jar );
168
169 Map<String, String> propMap = new HashMap<String, String>();
170
171 propMap.put( Pack200.Packer.SEGMENT_LIMIT, String.valueOf( -1 ) );
172
173
174 if ( passFiles != null && !passFiles.isEmpty() )
175 {
176 for ( int j = 0; j < passFiles.size(); j++ )
177 {
178 propMap.put( Packer.PASS_FILE_PFX + j, passFiles.get( j ) );
179 }
180 }
181
182 pack( jarFile, pack200Jar, propMap, gzip );
183 setLastModified( pack200Jar, jarFile.lastModified() );
184 }
185 }
186
187
188
189
190 public File packJar( File jarFile, boolean gzip, List<String> passFiles )
191 throws IOException
192 {
193 final String extension = gzip ? PACK_GZ_EXTENSION : PACK_EXTENSION;
194
195 File pack200Jar = new File( jarFile.getParentFile(), jarFile.getName() + extension );
196
197 deleteFile( pack200Jar );
198
199 Map<String, String> propMap = new HashMap<String, String>();
200
201 propMap.put( Pack200.Packer.SEGMENT_LIMIT, String.valueOf( -1 ) );
202
203
204 if ( passFiles != null && !passFiles.isEmpty() )
205 {
206 for ( int j = 0; j < passFiles.size(); j++ )
207 {
208 propMap.put( Packer.PASS_FILE_PFX + j, passFiles.get( j ) );
209 }
210 }
211
212 pack( jarFile, pack200Jar, propMap, gzip );
213 setLastModified( pack200Jar, jarFile.lastModified() );
214 return pack200Jar;
215 }
216
217
218
219
220
221 public void unpackJars( File directory, FileFilter pack200FileFilter )
222 throws IOException
223 {
224
225 File[] packFiles = directory.listFiles( pack200FileFilter );
226 for ( File packFile : packFiles )
227 {
228 final String packedJarPath = packFile.getAbsolutePath();
229 int extensionLength = packedJarPath.endsWith( PACK_GZ_EXTENSION ) ? 8 : 5;
230 String jarFileName = packedJarPath.substring( 0, packedJarPath.length() - extensionLength );
231 File jarFile = new File( jarFileName );
232
233 deleteFile( jarFile );
234
235 unpack( packFile, jarFile, Collections.<String, String>emptyMap() );
236 setLastModified( jarFile, packFile.lastModified() );
237 }
238 }
239
240
241
242
243 public File unpackJar( File packFile )
244 throws IOException
245 {
246 final String packedJarPath = packFile.getAbsolutePath();
247 int extensionLength = packedJarPath.endsWith( PACK_GZ_EXTENSION ) ? 8 : 5;
248 String jarFileName = packedJarPath.substring( 0, packedJarPath.length() - extensionLength );
249 File jarFile = new File( jarFileName );
250
251 deleteFile( jarFile );
252
253 unpack( packFile, jarFile, Collections.<String, String>emptyMap() );
254 setLastModified( jarFile, packFile.lastModified() );
255 return jarFile;
256 }
257
258 private void deleteFile( File file )
259 throws IOException
260 {
261 if ( file.exists() )
262 {
263 boolean delete = file.delete();
264 if ( !delete )
265 {
266 throw new IOException( "Could not delete file " + file );
267 }
268 }
269 }
270
271 private void setLastModified( File file, long modifi )
272 throws IOException
273 {
274 boolean b = file.setLastModified( modifi );
275 if ( !b )
276 {
277 throw new IOException( "Could not change last modifified on file: " + file );
278 }
279 }
280
281
282
283
284
285
286 private static boolean isGzipped( File file )
287 throws IOException
288 {
289 DataInputStream is = new DataInputStream( new FileInputStream( file ) );
290 int i = is.readInt();
291 is.close();
292 return ( i & 0xffffff00 ) == 0x1f8b0800;
293 }
294 }