1 package org.apache.maven.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.Date;
27 import java.util.zip.ZipEntry;
28 import java.util.zip.ZipInputStream;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.tools.ant.util.FileUtils;
33
34 /**
35 * Unzip a file.
36 *
37 * @author costin@dnt.ro
38 * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
39 * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a>
40 * @since Ant 1.1
41 * @ant.task category="packaging" name="unzip" name="unjar" name="unwar"
42 */
43 public class Expand
44 {
45 /** Logger. */
46 private static final Log LOGGER = LogFactory.getLog( Expand.class );
47
48 /** Destination. */
49 private File dest;
50
51 /** Source. */
52 private File source;
53
54 /** Should overwrite flag. */
55 private boolean overwrite = true;
56
57 /** file utility class */
58 private FileUtils fileUtils;
59
60 /**
61 * Do the work.
62 *
63 * @throws IOException If an error occurs.
64 */
65 public void execute()
66 throws IOException
67 {
68 expandFile();
69 }
70
71 /**
72 * Expand a file.
73 */
74 protected void expandFile()
75 throws IOException
76 {
77 ZipInputStream zis = null;
78 FileInputStream fis = null;
79 try
80 {
81
82 fis = new FileInputStream( source );
83 zis = new ZipInputStream( fis );
84 ZipEntry ze = null;
85 setFileUtils( FileUtils.newFileUtils() );
86
87 while ( ( ze = zis.getNextEntry() ) != null )
88 {
89 extractFile( zis, ze.getName(), new Date( ze.getTime() ), ze.isDirectory() );
90 }
91
92 LOGGER.debug( "expand complete" );
93 }
94 finally
95 {
96 if ( fis != null )
97 {
98 try
99 {
100 fis.close();
101 }
102 catch ( IOException e )
103 {
104 LOGGER.debug( "WARNING: Cannot close stream!", e );
105 }
106 }
107 if ( zis != null )
108 {
109 try
110 {
111 zis.close();
112 }
113 catch ( IOException e )
114 {
115 LOGGER.debug( "WARNING: Cannot close stream!", e );
116 }
117 }
118 }
119 }
120
121 /** Extract a file.
122 *
123 * @param compressedInputStream The input stream.
124 * @param entryName The entry name.
125 * @param entryDate The entry date.
126 * @param isDirectory Flag indicating if is directory.
127 *
128 * @throws IOException If an error occurs while attempting to
129 * extract the file.
130 */
131 protected void extractFile( InputStream compressedInputStream, String entryName, Date entryDate, boolean isDirectory )
132 throws IOException
133 {
134 File f = fileUtils.resolveFile( dest, entryName );
135
136 if ( !overwrite && f.exists() && ( f.lastModified() >= entryDate.getTime() ) )
137 {
138 LOGGER.debug( "Skipping " + f + " as it is up-to-date" );
139 return;
140 }
141
142 File dirF = f.getParentFile();
143
144 dirF.mkdirs();
145
146 if ( isDirectory )
147 {
148 f.mkdirs();
149 }
150 else
151 {
152 byte[] buffer = new byte[1024];
153 int length = 0;
154 FileOutputStream fos = null;
155 try
156 {
157 fos = new FileOutputStream( f );
158
159 while ( ( length = compressedInputStream.read( buffer ) ) >= 0 )
160 {
161 fos.write( buffer, 0, length );
162 }
163
164 fos.close();
165 fos = null;
166 }
167 finally
168 {
169 if ( fos != null )
170 {
171 try
172 {
173 fos.close();
174 }
175 catch ( IOException e )
176 {
177 LOGGER.debug( "WARNING: Cannot close stream!", e );
178 }
179 }
180 }
181 }
182
183 fileUtils.setFileLastModified( f, entryDate.getTime() );
184 }
185
186 /**
187 * Set the destination directory. File will be unzipped into the destination
188 * directory.
189 *
190 * @param d Path to the directory.
191 */
192 public void setDest( File d )
193 {
194 dest = d;
195 }
196
197 /**
198 * Set the path to zip-file.
199 *
200 * @param s Path to zip-file.
201 */
202 public void setSrc( File s )
203 {
204 source = s;
205 }
206
207 /**
208 * Should we overwrite files in dest, even if they are newer than the
209 * corresponding entries in the archive?
210 *
211 * @param shouldOverwrite <code>true</code> to indicate that files
212 * should be overwritten, otherwise <code>false</code>.
213 */
214 public void setOverwrite( boolean shouldOverwrite )
215 {
216 overwrite = shouldOverwrite;
217 }
218
219 /**
220 * @param utils
221 */
222 public void setFileUtils( FileUtils utils )
223 {
224 fileUtils = utils;
225 }
226
227 }