PageRenderTime 293ms CodeModel.GetById 274ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/pluginmgr/Roster.java

#
Java | 483 lines | 346 code | 63 blank | 74 comment | 44 complexity | f7c4796f33004ba6aefdaba54064f179 MD5 | raw file
  1/*
  2 * Roster.java - A list of things to do, used in various places
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001, 2004 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.pluginmgr;
 24
 25//{{{ Imports
 26import javax.swing.SwingUtilities;
 27import java.awt.Component;
 28import java.io.*;
 29import java.net.*;
 30import java.util.zip.*;
 31import java.util.*;
 32import org.gjt.sp.jedit.*;
 33import org.gjt.sp.util.Log;
 34import org.gjt.sp.util.IOUtilities;
 35
 36import static org.gjt.sp.jedit.io.FileVFS.recursiveDelete;
 37//}}}
 38
 39/**
 40 * @author $Id: Roster.java 16348 2009-10-14 10:40:15Z kpouer $
 41 */
 42class Roster
 43{
 44	//{{{ Roster constructor
 45	Roster()
 46	{
 47		operations = new ArrayList<Operation>();
 48		toLoad = new ArrayList<String>();
 49	} //}}}
 50
 51	//{{{ addRemove() method
 52	/**
 53	 * Add a remove operation for the given jar
 54	 * @param jar the jar name
 55	 */
 56	void addRemove(String jar)
 57	{
 58		addOperation(new Remove(jar));
 59	} //}}}
 60
 61	//{{{ addInstall() method
 62	void addInstall(String installed, String url, String installDirectory,
 63		int size)
 64	{
 65		addOperation(new Install(installed,url,installDirectory,size));
 66	} //}}}
 67
 68	//{{{ getOperation() method
 69	public Operation getOperation(int i)
 70	{
 71		return operations.get(i);
 72	} //}}}
 73
 74	//{{{ getOperationCount() method
 75	int getOperationCount()
 76	{
 77		return operations.size();
 78	} //}}}
 79
 80	//{{{ isEmpty() method
 81	boolean isEmpty()
 82	{
 83		return operations.isEmpty();
 84	} //}}}
 85
 86	//{{{ performOperationsInWorkThread() method
 87	void performOperationsInWorkThread(PluginManagerProgress progress)
 88	{
 89		for(int i = 0; i < operations.size(); i++)
 90		{
 91			Operation op = operations.get(i);
 92			op.runInWorkThread(progress);
 93			progress.done();
 94
 95			if(Thread.interrupted())
 96				return;
 97		}
 98	} //}}}
 99
100	//{{{ performOperationsInAWTThread() method
101	void performOperationsInAWTThread(Component comp)
102	{
103		for(int i = 0; i < operations.size(); i++)
104		{
105			Operation op = operations.get(i);
106			op.runInAWTThread(comp);
107		}
108
109		// add the JARs before checking deps since dep check might
110		// require all JARs to be present
111		for(int i = 0; i < toLoad.size(); i++)
112		{
113			String pluginName = toLoad.get(i);
114			if(jEdit.getPluginJAR(pluginName) != null)
115			{
116				Log.log(Log.WARNING,this,"Already loaded: "
117					+ pluginName);
118			}
119			else
120				jEdit.addPluginJAR(pluginName);
121		}
122
123		for(int i = 0; i < toLoad.size(); i++)
124		{
125			String pluginName = toLoad.get(i);
126			PluginJAR plugin = jEdit.getPluginJAR(pluginName);
127			if(plugin != null)
128				plugin.checkDependencies();
129		}
130
131		// now activate the plugins
132		for(int i = 0; i < toLoad.size(); i++)
133		{
134			String pluginName = toLoad.get(i);
135			PluginJAR plugin = jEdit.getPluginJAR(pluginName);
136			if(plugin != null)
137				plugin.activatePluginIfNecessary();
138		}
139	} //}}}
140
141	//{{{ Private members
142	private static File downloadDir;
143
144	private List<Operation> operations;
145	private List<String> toLoad;
146
147	//{{{ addOperation() method
148	private void addOperation(Operation op)
149	{
150		for(int i = 0; i < operations.size(); i++)
151		{
152			if(operations.get(i).equals(op))
153				return;
154		}
155
156		operations.add(op);
157	} //}}}
158
159	//{{{ getDownloadDir() method
160	private static String getDownloadDir()
161	{
162		if(downloadDir == null)
163		{
164			String settings = jEdit.getSettingsDirectory();
165			if(settings == null)
166				settings = System.getProperty("user.home");
167			downloadDir = new File(MiscUtilities.constructPath(
168				settings,"PluginManager.download"));
169			downloadDir.mkdirs();
170		}
171
172		return downloadDir.getPath();
173	} //}}}
174
175	//}}}
176
177	//{{{ Operation interface
178	abstract static class Operation
179	{
180		public void runInWorkThread(PluginManagerProgress progress)
181		{
182		}
183
184		public void runInAWTThread(Component comp)
185		{
186		}
187
188		public int getMaximum()
189		{
190			return 0;
191		}
192	} //}}}
193
194	//{{{ Remove class
195	class Remove extends Operation
196	{
197		//{{{ Remove constructor
198		Remove(String jar)
199		{
200			this.jar = jar;
201		} //}}}
202
203		//{{{ runInAWTThread() method
204		public void runInAWTThread(Component comp)
205		{
206			// close JAR file and all JARs that depend on this
207			PluginJAR jar = jEdit.getPluginJAR(this.jar);
208			if(jar != null)
209			{
210				unloadPluginJAR(jar);
211			}
212
213			toLoad.remove(this.jar);
214
215			// remove cache file
216
217			// move JAR first
218			File jarFile = new File(this.jar);
219			File srcFile = new File(this.jar.substring(0, this.jar.length() - 4));
220
221			Log.log(Log.NOTICE,this,"Deleting " + jarFile);
222
223			boolean ok = jarFile.delete();
224
225			if(srcFile.exists())
226			{
227				ok &= recursiveDelete(srcFile);
228			}
229
230			if(!ok)
231			{
232				String[] args = {this.jar};
233				GUIUtilities.error(comp,"plugin-manager.remove-failed",args);
234			}
235		} //}}}
236
237		//{{{ unloadPluginJAR() method
238		/**
239		 * This should go into a public method somewhere.
240		 * @param jar the jar of the plugin
241		 */
242		private void unloadPluginJAR(PluginJAR jar)
243		{
244			String[] dependents = jar.getDependentPlugins();
245			for (String path: dependents) 
246			{
247				PluginJAR _jar = jEdit.getPluginJAR(path);
248				if(_jar != null)
249				{
250					toLoad.add(path);
251					unloadPluginJAR(_jar);
252					// clear cache file
253					String cachePath = jar.getCachePath();
254					if(cachePath != null)
255						new File(cachePath).delete();
256
257				}
258			}
259			jEdit.removePluginJAR(jar,false);
260			
261		} //}}}
262
263		//{{{ equals() method
264		public boolean equals(Object o)
265		{
266			return o instanceof Remove
267			       && ((Remove) o).jar.equals(jar);
268		} //}}}
269
270		//{{{ Private members
271		private final String jar;
272		//}}}
273	} //}}}
274
275	//{{{ Install class
276	class Install extends Operation
277	{
278		int size;
279
280		//{{{ Install constructor
281		Install(String installed, String url, String installDirectory,
282			int size)
283		{
284			// catch those hooligans passing null urls
285			if(url == null)
286				throw new NullPointerException();
287
288			this.installed = installed;
289			this.url = url;
290			this.installDirectory = installDirectory;
291			this.size = size;
292		} //}}}
293
294		//{{{ getMaximum() method
295		public int getMaximum()
296		{
297			return size;
298		} //}}}
299
300		//{{{ runInWorkThread() method
301		public void runInWorkThread(PluginManagerProgress progress)
302		{
303			String fileName = MiscUtilities.getFileName(url);
304
305			path = download(progress,fileName,url);
306		} //}}}
307
308		//{{{ runInAWTThread() method
309		public void runInAWTThread(Component comp)
310		{
311			// check if download failed
312			if(path == null)
313				return;
314
315			// if download OK, remove existing version
316			if(installed != null)
317				new Remove(installed).runInAWTThread(comp);
318
319			ZipFile zipFile = null;
320
321			try
322			{
323				zipFile = new ZipFile(path);
324
325				Enumeration<? extends ZipEntry> e = zipFile.entries();
326				while(e.hasMoreElements())
327				{
328					ZipEntry entry = e.nextElement();
329					String name = entry.getName().replace('/',File.separatorChar);
330					File file = new File(installDirectory,name);
331					if(entry.isDirectory())
332						file.mkdirs();
333					else
334					{
335						new File(file.getParent()).mkdirs();
336						InputStream in = null;
337						FileOutputStream out = null;
338						try
339						{
340							in = zipFile.getInputStream(entry);
341							out = new FileOutputStream(file);
342							IOUtilities.copyStream(4096,
343								null,
344								in,
345								out,false);
346						}
347						finally
348						{
349							IOUtilities.closeQuietly(in);
350							IOUtilities.closeQuietly(out);
351						}
352						if(file.getName().toLowerCase().endsWith(".jar"))
353							toLoad.add(file.getPath());
354					}
355				}
356			}
357			catch(InterruptedIOException iio)
358			{
359			}
360			catch(ZipException e)
361			{
362				Log.log(Log.ERROR,this,e);
363				GUIUtilities.error(null,"plugin-error-download",new Object[]{""});
364			}
365			catch(IOException io)
366			{
367				Log.log(Log.ERROR,this,io);
368
369				String[] args = { io.getMessage() };
370				GUIUtilities.error(null,"ioerror",args);
371			}
372			catch(Exception e)
373			{
374				Log.log(Log.ERROR,this,e);
375			}
376			finally
377			{
378				try
379				{
380					if(zipFile != null)
381						zipFile.close();
382				}
383				catch(IOException io)
384				{
385					Log.log(Log.ERROR,this,io);
386				}
387
388				if(jEdit.getBooleanProperty(
389					"plugin-manager.deleteDownloads"))
390				{
391					new File(path).delete();
392				}
393			}
394		} //}}}
395
396		//{{{ equals() method
397		public boolean equals(Object o)
398		{
399			return o instanceof Install
400			       && ((Install) o).url.equals(url);
401		} //}}}
402
403		//{{{ Private members
404		private String installed;
405		private final String url;
406		private String installDirectory;
407		private String path;
408
409		//{{{ download() method
410		private String download(PluginManagerProgress progress,
411			String fileName, String url)
412		{
413			try
414			{
415				String host = jEdit.getProperty("plugin-manager.mirror.id");
416				if (host == null || host.equals(MirrorList.Mirror.NONE))
417					host = "default";
418				
419				String path = MiscUtilities.constructPath(getDownloadDir(),fileName);
420				URLConnection conn = new URL(url).openConnection();
421				progress.setStatus(jEdit.getProperty("plugin-manager.progress",new String[] {fileName, host}));
422				InputStream in = null;
423				FileOutputStream out = null;
424				try
425				{
426					in = conn.getInputStream();
427					out = new FileOutputStream(path);
428					if(!IOUtilities.copyStream(progress,in,out,true))
429						return null;
430				}
431				finally
432				{
433					IOUtilities.closeQuietly(in);
434					IOUtilities.closeQuietly(out);
435				}
436				
437				return path;
438			}
439			catch(InterruptedIOException iio)
440			{
441				// do nothing, user clicked 'Stop'
442				return null;
443			}
444			catch(FileNotFoundException e)
445			{
446				Log.log(Log.ERROR,this,e);
447
448				SwingUtilities.invokeLater(new Runnable()
449				{
450					public void run()
451					{
452						GUIUtilities.error(null,"plugin-error-download",new Object[]{""});
453					}
454				});
455
456				return null;
457			}
458			catch(final IOException io)
459			{
460				Log.log(Log.ERROR,this,io);
461
462				SwingUtilities.invokeLater(new Runnable()
463				{
464					public void run()
465					{
466						String[] args = { io.getMessage() };
467						GUIUtilities.error(null,"plugin-error-download",args);
468					}
469				});
470
471				return null;
472			}
473			catch(Exception e)
474			{
475				Log.log(Log.ERROR,this,e);
476
477				return null;
478			}
479		} //}}}
480
481		//}}}
482	} //}}}
483}