PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-2-pre4/org/gjt/sp/jedit/pluginmgr/Roster.java

#
Java | 487 lines | 351 code | 70 blank | 66 comment | 53 complexity | 0884161cba8172c2af895ab47fa0569f 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. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2001, 2003 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. package org.gjt.sp.jedit.pluginmgr;
  23. //{{{ Imports
  24. import javax.swing.SwingUtilities;
  25. import java.awt.Component;
  26. import java.io.*;
  27. import java.net.*;
  28. import java.util.zip.*;
  29. import java.util.*;
  30. import org.gjt.sp.jedit.*;
  31. import org.gjt.sp.util.Log;
  32. //}}}
  33. class Roster
  34. {
  35. //{{{ Roster constructor
  36. Roster()
  37. {
  38. operations = new ArrayList();
  39. toLoad = new ArrayList();
  40. } //}}}
  41. //{{{ addRemove() method
  42. void addRemove(String plugin)
  43. {
  44. addOperation(new Remove(plugin));
  45. } //}}}
  46. //{{{ addInstall() method
  47. void addInstall(String installed, String url, String installDirectory,
  48. int size)
  49. {
  50. addOperation(new Install(installed,url,installDirectory,size));
  51. } //}}}
  52. //{{{ getOperation() method
  53. public Operation getOperation(int i)
  54. {
  55. return (Operation)operations.get(i);
  56. } //}}}
  57. //{{{ getOperationCount() method
  58. int getOperationCount()
  59. {
  60. return operations.size();
  61. } //}}}
  62. //{{{ isEmpty() method
  63. boolean isEmpty()
  64. {
  65. return operations.size() == 0;
  66. } //}}}
  67. //{{{ performOperationsInWorkThread() method
  68. void performOperationsInWorkThread(PluginManagerProgress progress)
  69. {
  70. for(int i = 0; i < operations.size(); i++)
  71. {
  72. Operation op = (Operation)operations.get(i);
  73. op.runInWorkThread(progress);
  74. progress.done();
  75. if(Thread.interrupted())
  76. return;
  77. }
  78. } //}}}
  79. //{{{ performOperationsInAWTThread() method
  80. void performOperationsInAWTThread(Component comp)
  81. {
  82. for(int i = 0; i < operations.size(); i++)
  83. {
  84. Operation op = (Operation)operations.get(i);
  85. op.runInAWTThread(comp);
  86. }
  87. // add the JARs before checking deps since dep check might
  88. // require all JARs to be present
  89. for(int i = 0; i < toLoad.size(); i++)
  90. {
  91. String pluginName = (String)toLoad.get(i);
  92. if(jEdit.getPluginJAR(pluginName) != null)
  93. {
  94. Log.log(Log.WARNING,this,"Already loaded: "
  95. + pluginName);
  96. }
  97. else
  98. jEdit.addPluginJAR(pluginName);
  99. }
  100. for(int i = 0; i < toLoad.size(); i++)
  101. {
  102. String pluginName = (String)toLoad.get(i);
  103. PluginJAR plugin = jEdit.getPluginJAR(pluginName);
  104. if(plugin != null)
  105. plugin.checkDependencies();
  106. }
  107. // now activate the plugins
  108. for(int i = 0; i < toLoad.size(); i++)
  109. {
  110. String pluginName = (String)toLoad.get(i);
  111. PluginJAR plugin = jEdit.getPluginJAR(pluginName);
  112. if(plugin != null)
  113. plugin.activatePluginIfNecessary();
  114. }
  115. } //}}}
  116. //{{{ Private members
  117. private static File downloadDir;
  118. private List operations;
  119. private List toLoad;
  120. //{{{ addOperation() method
  121. private void addOperation(Operation op)
  122. {
  123. for(int i = 0; i < operations.size(); i++)
  124. {
  125. if(operations.get(i).equals(op))
  126. return;
  127. }
  128. operations.add(op);
  129. } //}}}
  130. //{{{ getDownloadDir() method
  131. private static String getDownloadDir()
  132. {
  133. if(downloadDir == null)
  134. {
  135. String settings = jEdit.getSettingsDirectory();
  136. if(settings == null)
  137. settings = System.getProperty("user.home");
  138. downloadDir = new File(MiscUtilities.constructPath(
  139. settings,"PluginManager.download"));
  140. downloadDir.mkdirs();
  141. }
  142. return downloadDir.getPath();
  143. } //}}}
  144. //}}}
  145. //{{{ Operation interface
  146. static abstract class Operation
  147. {
  148. public void runInWorkThread(PluginManagerProgress progress)
  149. {
  150. }
  151. public void runInAWTThread(Component comp)
  152. {
  153. }
  154. public int getMaximum()
  155. {
  156. return 0;
  157. }
  158. } //}}}
  159. //{{{ Remove class
  160. class Remove extends Operation
  161. {
  162. //{{{ Remove constructor
  163. Remove(String plugin)
  164. {
  165. this.plugin = plugin;
  166. } //}}}
  167. //{{{ runInAWTThread() method
  168. public void runInAWTThread(Component comp)
  169. {
  170. // close JAR file and all JARs that depend on this
  171. PluginJAR jar = jEdit.getPluginJAR(plugin);
  172. if(jar != null)
  173. {
  174. unloadPluginJAR(jar);
  175. String cachePath = jar.getCachePath();
  176. if(cachePath != null)
  177. new File(cachePath).delete();
  178. }
  179. toLoad.remove(plugin);
  180. // remove cache file
  181. // move JAR first
  182. File jarFile = new File(plugin);
  183. File srcFile = new File(plugin.substring(0,plugin.length() - 4));
  184. Log.log(Log.NOTICE,this,"Deleting " + jarFile);
  185. boolean ok = jarFile.delete();
  186. if(srcFile.exists())
  187. ok &= deleteRecursively(srcFile);
  188. if(!ok)
  189. {
  190. String[] args = { plugin };
  191. GUIUtilities.error(comp,"plugin-manager.remove-failed",args);
  192. }
  193. } //}}}
  194. //{{{ unloadPluginJAR() method
  195. /**
  196. * This should go into a public method somewhere.
  197. */
  198. private void unloadPluginJAR(PluginJAR jar)
  199. {
  200. String[] dependents = jar.getDependentPlugins();
  201. for(int i = 0; i < dependents.length; i++)
  202. {
  203. PluginJAR _jar = jEdit.getPluginJAR(
  204. dependents[i]);
  205. if(_jar != null)
  206. {
  207. toLoad.add(dependents[i]);
  208. unloadPluginJAR(_jar);
  209. }
  210. }
  211. jEdit.removePluginJAR(jar,false);
  212. } //}}}
  213. //{{{ equals() method
  214. public boolean equals(Object o)
  215. {
  216. if(o instanceof Remove
  217. && ((Remove)o).plugin.equals(plugin))
  218. return true;
  219. else
  220. return false;
  221. } //}}}
  222. //{{{ Private members
  223. private String plugin;
  224. private boolean deleteRecursively(File file)
  225. {
  226. Log.log(Log.NOTICE,this,"Deleting " + file + " recursively");
  227. boolean ok = true;
  228. if(file.isDirectory())
  229. {
  230. String path = file.getPath();
  231. String[] children = file.list();
  232. for(int i = 0; i < children.length; i++)
  233. {
  234. ok &= deleteRecursively(new File(path,children[i]));
  235. }
  236. }
  237. ok &= file.delete();
  238. return ok;
  239. } //}}}
  240. } //}}}
  241. //{{{ Install class
  242. class Install extends Operation
  243. {
  244. int size;
  245. //{{{ Install constructor
  246. Install(String installed, String url, String installDirectory,
  247. int size)
  248. {
  249. // catch those hooligans passing null urls
  250. if(url == null)
  251. throw new NullPointerException();
  252. this.installed = installed;
  253. this.url = url;
  254. this.installDirectory = installDirectory;
  255. this.size = size;
  256. } //}}}
  257. //{{{ getMaximum() method
  258. public int getMaximum()
  259. {
  260. return size;
  261. } //}}}
  262. //{{{ runInWorkThread() method
  263. public void runInWorkThread(PluginManagerProgress progress)
  264. {
  265. String fileName = MiscUtilities.getFileName(url);
  266. path = download(progress,fileName,url);
  267. } //}}}
  268. //{{{ runInAWTThread() method
  269. public void runInAWTThread(Component comp)
  270. {
  271. // check if download failed
  272. if(path == null)
  273. return;
  274. // if download OK, remove existing version
  275. if(installed != null)
  276. new Remove(installed).runInAWTThread(comp);
  277. ZipFile zipFile = null;
  278. try
  279. {
  280. zipFile = new ZipFile(path);
  281. Enumeration enum = zipFile.entries();
  282. while(enum.hasMoreElements())
  283. {
  284. ZipEntry entry = (ZipEntry)enum.nextElement();
  285. String name = entry.getName().replace('/',File.separatorChar);
  286. File file = new File(installDirectory,name);
  287. if(entry.isDirectory())
  288. file.mkdirs();
  289. else
  290. {
  291. new File(file.getParent()).mkdirs();
  292. copy(null,
  293. zipFile.getInputStream(entry),
  294. new FileOutputStream(
  295. file),false);
  296. if(file.getName().toLowerCase().endsWith(".jar"))
  297. toLoad.add(file.getPath());
  298. }
  299. }
  300. }
  301. catch(InterruptedIOException iio)
  302. {
  303. }
  304. catch(final IOException io)
  305. {
  306. Log.log(Log.ERROR,this,io);
  307. String[] args = { io.getMessage() };
  308. GUIUtilities.error(null,"ioerror",args);
  309. }
  310. catch(Exception e)
  311. {
  312. Log.log(Log.ERROR,this,e);
  313. }
  314. finally
  315. {
  316. try
  317. {
  318. if(zipFile != null)
  319. zipFile.close();
  320. }
  321. catch(IOException io)
  322. {
  323. Log.log(Log.ERROR,this,io);
  324. }
  325. if(jEdit.getBooleanProperty(
  326. "plugin-manager.deleteDownloads"))
  327. {
  328. new File(path).delete();
  329. }
  330. }
  331. } //}}}
  332. //{{{ equals() method
  333. public boolean equals(Object o)
  334. {
  335. if(o instanceof Install
  336. && ((Install)o).url.equals(url))
  337. {
  338. /* even if installDirectory is different */
  339. return true;
  340. }
  341. else
  342. return false;
  343. } //}}}
  344. //{{{ Private members
  345. private String installed;
  346. private String url;
  347. private String installDirectory;
  348. private String path;
  349. //{{{ download() method
  350. private String download(PluginManagerProgress progress,
  351. String fileName, String url)
  352. {
  353. try
  354. {
  355. URLConnection conn = new URL(url).openConnection();
  356. String path = MiscUtilities.constructPath(getDownloadDir(),fileName);
  357. if(!copy(progress,conn.getInputStream(),
  358. new FileOutputStream(path),true))
  359. return null;
  360. return path;
  361. }
  362. catch(InterruptedIOException iio)
  363. {
  364. // do nothing, user clicked 'Stop'
  365. return null;
  366. }
  367. catch(final IOException io)
  368. {
  369. Log.log(Log.ERROR,this,io);
  370. SwingUtilities.invokeLater(new Runnable()
  371. {
  372. public void run()
  373. {
  374. String[] args = { io.getMessage() };
  375. GUIUtilities.error(null,"ioerror",args);
  376. }
  377. });
  378. return null;
  379. }
  380. catch(Exception e)
  381. {
  382. Log.log(Log.ERROR,this,e);
  383. return null;
  384. }
  385. } //}}}
  386. //{{{ copy() method
  387. private boolean copy(PluginManagerProgress progress,
  388. InputStream in, OutputStream out, boolean canStop)
  389. throws Exception
  390. {
  391. in = new BufferedInputStream(in);
  392. out = new BufferedOutputStream(out);
  393. byte[] buf = new byte[4096];
  394. int copied = 0;
  395. loop: for(;;)
  396. {
  397. int count = in.read(buf,0,buf.length);
  398. if(count == -1)
  399. break loop;
  400. copied += count;
  401. if(progress != null)
  402. progress.setValue(copied);
  403. out.write(buf,0,count);
  404. if(canStop && Thread.interrupted())
  405. {
  406. in.close();
  407. out.close();
  408. return false;
  409. }
  410. }
  411. in.close();
  412. out.close();
  413. return true;
  414. } //}}}
  415. //}}}
  416. } //}}}
  417. }