PageRenderTime 503ms CodeModel.GetById 272ms app.highlight 21ms RepoModel.GetById 19ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/org/gjt/sp/jedit/pluginmgr/Roster.java

#
Java | 319 lines | 239 code | 53 blank | 27 comment | 32 complexity | 5052103d4ffa52e1da42b6b4b5b50b4f MD5 | raw file
  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}