/jEdit/tags/jedit-4-0-pre5/org/gjt/sp/jedit/pluginmgr/Roster.java
Java | 319 lines | 239 code | 53 blank | 27 comment | 32 complexity | 5052103d4ffa52e1da42b6b4b5b50b4f MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
1/*
2 * Roster.java - A list of things to do, used in various places
3 * Copyright (C) 2001 Slava Pestov
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20package org.gjt.sp.jedit.pluginmgr;
21
22import javax.swing.JOptionPane;
23import java.awt.Component;
24import java.io.*;
25import java.net.*;
26import java.util.zip.*;
27import java.util.*;
28import org.gjt.sp.jedit.io.VFSManager; // we use VFSManager.error() method
29import org.gjt.sp.jedit.*;
30import org.gjt.sp.util.Log;
31
32class Roster
33{
34 Roster()
35 {
36 operations = new Vector();
37 }
38
39 void addOperation(Operation op)
40 {
41 for(int i = 0; i < operations.size(); i++)
42 {
43 if(operations.elementAt(i).equals(op))
44 return;
45 }
46
47 operations.addElement(op);
48 }
49
50 int getOperationCount()
51 {
52 return operations.size();
53 }
54
55 boolean isEmpty()
56 {
57 return operations.size() == 0;
58 }
59
60 boolean performOperations(PluginManagerProgress progress)
61 {
62 for(int i = 0; i < operations.size(); i++)
63 {
64 Operation op = (Operation)operations.elementAt(i);
65 if(op.perform(progress))
66 progress.done(true);
67 else
68 {
69 progress.done(false);
70 return false;
71 }
72
73 if(Thread.interrupted())
74 return false;
75 }
76
77 return true;
78 }
79
80 // private members
81 private Vector operations;
82
83 static interface Operation
84 {
85 boolean perform(PluginManagerProgress progress);
86 boolean equals(Object o);
87 }
88
89 static class Remove implements Operation
90 {
91 Remove(String plugin)
92 {
93 this.plugin = plugin;
94 }
95
96 public boolean perform(PluginManagerProgress progress)
97 {
98 progress.removing(MiscUtilities.getFileName(plugin));
99
100 // close JAR file
101 EditPlugin.JAR jar = jEdit.getPluginJAR(plugin);
102 if(jar != null)
103 jar.getClassLoader().closeZipFile();
104
105 // move JAR first
106 File jarFile = new File(plugin);
107 File srcFile = new File(plugin.substring(0,plugin.length() - 4));
108
109 boolean ok = true;
110 ok &= deleteRecursively(jarFile);
111
112 if(srcFile.exists())
113 ok &= deleteRecursively(srcFile);
114
115 String[] args = { plugin };
116 if(!ok)
117 GUIUtilities.error(progress,"plugin-manager.remove-failed",args);
118 return ok;
119 }
120
121 public boolean equals(Object o)
122 {
123 if(o instanceof Remove
124 && ((Remove)o).plugin.equals(plugin))
125 return true;
126 else
127 return false;
128 }
129
130 // private members
131 private String plugin;
132
133 private boolean deleteRecursively(File file)
134 {
135 Log.log(Log.NOTICE,this,"Deleting " + file + " recursively");
136
137 boolean ok = true;
138
139 if(file.isDirectory())
140 {
141 String path = file.getPath();
142 String[] children = file.list();
143 for(int i = 0; i < children.length; i++)
144 {
145 ok &= deleteRecursively(new File(path,children[i]));
146 }
147 }
148
149 ok &= file.delete();
150
151 return ok;
152 }
153 }
154
155 static class Install implements Operation
156 {
157 Install(String url, String installDirectory)
158 {
159 // catch those hooligans passing null urls
160 if(url == null)
161 throw new NullPointerException();
162
163 this.url = url;
164 this.installDirectory = installDirectory;
165 }
166
167 public boolean perform(PluginManagerProgress progress)
168 {
169 try
170 {
171 String fileName = MiscUtilities.getFileName(url);
172 progress.downloading(fileName);
173 String path = download(progress,fileName,url);
174 if(path == null)
175 {
176 // interrupted download
177 return false;
178 }
179
180 progress.installing(fileName);
181 install(progress,path,installDirectory);
182
183 return true;
184 }
185 catch(InterruptedIOException iio)
186 {
187 // do nothing, user clicked 'Stop'
188 return false;
189 }
190 catch(IOException io)
191 {
192 Log.log(Log.ERROR,this,io);
193
194 String[] args = { io.getMessage() };
195 VFSManager.error(progress,"ioerror",args);
196
197 return false;
198 }
199 catch(Exception e)
200 {
201 Log.log(Log.ERROR,this,e);
202
203 return false;
204 }
205 }
206
207 public boolean equals(Object o)
208 {
209 if(o instanceof Install
210 && ((Install)o).url.equals(url))
211 {
212 /* even if installDirectory is different */
213 return true;
214 }
215 else
216 return false;
217 }
218
219 // private members
220 private String url;
221 private String installDirectory;
222
223 private String download(PluginManagerProgress progress,
224 String fileName, String url) throws Exception
225 {
226 URLConnection conn = new URL(url).openConnection();
227 progress.setMaximum(Math.max(0,conn.getContentLength()));
228
229 String path = MiscUtilities.constructPath(getDownloadDir(),fileName);
230
231 if(!copy(progress,conn.getInputStream(),
232 new FileOutputStream(path),true,true))
233 return null;
234
235 return path;
236 }
237
238 private boolean install(PluginManagerProgress progress,
239 String path, String dir) throws Exception
240 {
241 progress.setMaximum(1);
242
243 ZipFile zipFile = new ZipFile(path);
244 Enumeration enum = zipFile.entries();
245 while(enum.hasMoreElements())
246 {
247 ZipEntry entry = (ZipEntry)enum.nextElement();
248 String name = entry.getName().replace('/',File.separatorChar);
249 File file = new File(dir,name);
250 if(entry.isDirectory())
251 file.mkdirs();
252 else
253 {
254 new File(file.getParent()).mkdirs();
255 copy(progress,zipFile.getInputStream(entry),
256 new FileOutputStream(file),false,false);
257 }
258 }
259
260 new File(path).delete();
261
262 progress.setValue(1);
263
264 return true;
265 }
266
267 private boolean copy(PluginManagerProgress progress,
268 InputStream in, OutputStream out, boolean canStop,
269 boolean doProgress) throws Exception
270 {
271 in = new BufferedInputStream(in);
272 out = new BufferedOutputStream(out);
273
274 byte[] buf = new byte[4096];
275 int copied = 0;
276loop: for(;;)
277 {
278 int count = in.read(buf,0,buf.length);
279 if(count == -1)
280 break loop;
281
282 if(doProgress)
283 {
284 copied += count;
285 progress.setValue(copied);
286 }
287
288 out.write(buf,0,count);
289 if(canStop && Thread.interrupted())
290 {
291 in.close();
292 out.close();
293 return false;
294 }
295 }
296
297 in.close();
298 out.close();
299 return true;
300 }
301
302 static File downloadDir;
303
304 static String getDownloadDir()
305 {
306 if(downloadDir == null)
307 {
308 String settings = jEdit.getSettingsDirectory();
309 if(settings == null)
310 settings = System.getProperty("user.home");
311 downloadDir = new File(MiscUtilities.constructPath(
312 settings,"PluginManager.download"));
313 downloadDir.mkdirs();
314 }
315
316 return downloadDir.getPath();
317 }
318 }
319}