1 |
package net.oni2.aeinstaller.backend.packages.unpack; |
2 |
|
3 |
import java.io.File; |
4 |
import java.io.FileOutputStream; |
5 |
import java.io.IOException; |
6 |
import java.io.InputStream; |
7 |
import java.util.Enumeration; |
8 |
import java.util.zip.ZipEntry; |
9 |
import java.util.zip.ZipException; |
10 |
import java.util.zip.ZipFile; |
11 |
|
12 |
import org.apache.commons.io.FileUtils; |
13 |
|
14 |
/** |
15 |
* @author Christian Illy |
16 |
*/ |
17 |
public class Unpacker implements Runnable { |
18 |
/** |
19 |
* @author Christian Illy |
20 |
*/ |
21 |
public enum EState { |
22 |
/** |
23 |
* Unpacker initialized but not started |
24 |
*/ |
25 |
INIT, |
26 |
/** |
27 |
* Unpack running |
28 |
*/ |
29 |
RUNNING, |
30 |
/** |
31 |
* Unpack interrupted |
32 |
*/ |
33 |
INTERRUPTED, |
34 |
/** |
35 |
* Unpack finished successfully |
36 |
*/ |
37 |
FINISHED, |
38 |
}; |
39 |
|
40 |
private UnpackListener listener; |
41 |
|
42 |
private File zip; |
43 |
private File target; |
44 |
|
45 |
private Thread t = null; |
46 |
|
47 |
private EState state = EState.INIT; |
48 |
|
49 |
/** |
50 |
* Initialize a new AE package unpacker |
51 |
* |
52 |
* @param zipFile |
53 |
* AE zip package |
54 |
* @param targetFolder |
55 |
* Target folder |
56 |
* @param listener |
57 |
* Listener for progress updates |
58 |
*/ |
59 |
public Unpacker(File zipFile, File targetFolder, UnpackListener listener) { |
60 |
this.listener = listener; |
61 |
zip = zipFile; |
62 |
target = targetFolder; |
63 |
} |
64 |
|
65 |
/** |
66 |
* Start the unpack process |
67 |
*/ |
68 |
public synchronized void start() { |
69 |
if (t == null) { |
70 |
t = new Thread(this); |
71 |
t.start(); |
72 |
state = EState.RUNNING; |
73 |
updateStatus(); |
74 |
} |
75 |
} |
76 |
|
77 |
/** |
78 |
* Stop (abort) the process |
79 |
*/ |
80 |
public synchronized void stop() { |
81 |
if (state != EState.FINISHED) { |
82 |
state = EState.INTERRUPTED; |
83 |
if (t != null) { |
84 |
try { |
85 |
t.join(); |
86 |
} catch (InterruptedException e) { |
87 |
e.printStackTrace(); |
88 |
} |
89 |
t = null; |
90 |
} |
91 |
updateStatus(); |
92 |
if (state != EState.FINISHED) { |
93 |
if (target.exists()) { |
94 |
try { |
95 |
FileUtils.deleteDirectory(target); |
96 |
} catch (IOException e) { |
97 |
e.printStackTrace(); |
98 |
} |
99 |
} |
100 |
} |
101 |
} |
102 |
} |
103 |
|
104 |
private synchronized void updateStatus() { |
105 |
listener.statusUpdate(this, state); |
106 |
} |
107 |
|
108 |
@Override |
109 |
public void run() { |
110 |
try { |
111 |
switch (state) { |
112 |
case INTERRUPTED: |
113 |
return; |
114 |
case RUNNING: |
115 |
ZipFile zf = null; |
116 |
try { |
117 |
int pathStart = 0; |
118 |
String pathStartName = ""; |
119 |
|
120 |
zf = new ZipFile(zip); |
121 |
|
122 |
if (target.exists()) |
123 |
FileUtils.deleteDirectory(target); |
124 |
target.mkdirs(); |
125 |
|
126 |
for (Enumeration<? extends ZipEntry> e = zf.entries(); e |
127 |
.hasMoreElements();) { |
128 |
ZipEntry ze = e.nextElement(); |
129 |
if (ze.getName().toLowerCase() |
130 |
.endsWith("/mod_info.cfg") |
131 |
|| ze.getName().toLowerCase() |
132 |
.equals("mod_info.cfg")) { |
133 |
pathStart = ze.getName().toLowerCase() |
134 |
.indexOf("mod_info.cfg"); |
135 |
pathStartName = ze.getName().substring(0, |
136 |
pathStart); |
137 |
} |
138 |
} |
139 |
|
140 |
for (Enumeration<? extends ZipEntry> e = zf.entries(); e |
141 |
.hasMoreElements();) { |
142 |
if (state == EState.INTERRUPTED) |
143 |
return; |
144 |
ZipEntry ze = e.nextElement(); |
145 |
if (!ze.isDirectory()) { |
146 |
if (ze.getName().startsWith(pathStartName)) { |
147 |
if (!(ze.getName().endsWith("aei.cfg") || ze |
148 |
.getName().endsWith(".DS_Store"))) { |
149 |
File targetFile = new File(target, ze |
150 |
.getName().substring(pathStart)); |
151 |
File parent = targetFile |
152 |
.getParentFile(); |
153 |
parent.mkdirs(); |
154 |
|
155 |
InputStream in = zf.getInputStream(ze); |
156 |
|
157 |
int read = 0; |
158 |
byte[] data = new byte[1024]; |
159 |
FileOutputStream fileOut = new FileOutputStream( |
160 |
targetFile); |
161 |
while ((read = in.read(data, 0, 1024)) != -1) { |
162 |
fileOut.write(data, 0, read); |
163 |
} |
164 |
fileOut.close(); |
165 |
} |
166 |
} |
167 |
} |
168 |
} |
169 |
} catch (ZipException e) { |
170 |
// TODO Auto-generated catch block |
171 |
e.printStackTrace(); |
172 |
} catch (IOException e) { |
173 |
// TODO Auto-generated catch block |
174 |
e.printStackTrace(); |
175 |
} finally { |
176 |
try { |
177 |
if (zf != null) |
178 |
zf.close(); |
179 |
} catch (IOException e) { |
180 |
e.printStackTrace(); |
181 |
} |
182 |
} |
183 |
break; |
184 |
default: |
185 |
break; |
186 |
} |
187 |
} finally { |
188 |
} |
189 |
|
190 |
state = EState.FINISHED; |
191 |
updateStatus(); |
192 |
} |
193 |
} |