source: josm/trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java@ 5723

Last change on this file since 5723 was 5723, checked in by Don-vip, 11 years ago

fix #7754 - plugin management: unable to activate plugin after aborted download + fix EDT violations

  • Property svn:eol-style set to native
File size: 9.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.plugins;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.FilenameFilter;
9import java.io.IOException;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15
16import org.openstreetmap.josm.gui.PleaseWaitRunnable;
17import org.openstreetmap.josm.gui.progress.ProgressMonitor;
18import org.openstreetmap.josm.io.OsmTransferException;
19import org.openstreetmap.josm.tools.ImageProvider;
20import org.openstreetmap.josm.tools.Utils;
21import org.xml.sax.SAXException;
22
23/**
24 * This is an asynchronous task for reading plugin information from the files
25 * in the local plugin repositories.
26 *
27 * It scans the files in the local plugins repository (see {@link Preferences#getPluginsDirectory()}
28 * and extracts plugin information from three kind of files:
29 * <ul>
30 * <li>.jar files, assuming that they represent plugin jars</li>
31 * <li>.jar.new files, assuming that these are downloaded but not yet installed plugins</li>
32 * <li>cached lists of available plugins, downloaded for instance from
33 * <a href="http://josm.openstreetmap.de/plugins">http://josm.openstreetmap.de/plugins</a></li>
34 * </ul>
35 *
36 */
37public class ReadLocalPluginInformationTask extends PleaseWaitRunnable {
38 private Map<String, PluginInformation> availablePlugins;
39 private boolean canceled;
40
41 public ReadLocalPluginInformationTask() {
42 super(tr("Reading local plugin information.."), false);
43 availablePlugins = new HashMap<String, PluginInformation>();
44 }
45
46 public ReadLocalPluginInformationTask(ProgressMonitor monitor) {
47 super(tr("Reading local plugin information.."),monitor, false);
48 availablePlugins = new HashMap<String, PluginInformation>();
49 }
50
51 @Override
52 protected void cancel() {
53 canceled = true;
54 }
55
56 @Override
57 protected void finish() {}
58
59 protected void processJarFile(File f, String pluginName) throws PluginException{
60 PluginInformation info = new PluginInformation(
61 f,
62 pluginName
63 );
64 if (!availablePlugins.containsKey(info.getName())) {
65 info.updateLocalInfo(info);
66 availablePlugins.put(info.getName(), info);
67 } else {
68 PluginInformation current = availablePlugins.get(info.getName());
69 current.updateFromJar(info);
70 }
71 }
72
73 protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
74 File[] siteCacheFiles = pluginsDirectory.listFiles(
75 new FilenameFilter() {
76 public boolean accept(File dir, String name) {
77 return name.matches("^([0-9]+-)?site.*\\.txt$");
78 }
79 }
80 );
81 if (siteCacheFiles == null || siteCacheFiles.length == 0)
82 return;
83 monitor.subTask(tr("Processing plugin site cache files..."));
84 monitor.setTicksCount(siteCacheFiles.length);
85 for (File f: siteCacheFiles) {
86 String fname = f.getName();
87 monitor.setCustomText(tr("Processing file ''{0}''", fname));
88 try {
89 processLocalPluginInformationFile(f);
90 } catch(PluginListParseException e) {
91 System.err.println(tr("Warning: Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
92 e.printStackTrace();
93 }
94 monitor.worked(1);
95 }
96 }
97
98 protected void scanIconCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
99 File[] siteCacheFiles = pluginsDirectory.listFiles(
100 new FilenameFilter() {
101 public boolean accept(File dir, String name) {
102 return name.matches("^([0-9]+-)?site.*plugin-icons\\.zip$");
103 }
104 }
105 );
106 if (siteCacheFiles == null || siteCacheFiles.length == 0)
107 return;
108 monitor.subTask(tr("Processing plugin site cache icon files..."));
109 monitor.setTicksCount(siteCacheFiles.length);
110 for (File f: siteCacheFiles) {
111 String fname = f.getName();
112 monitor.setCustomText(tr("Processing file ''{0}''", fname));
113 for (PluginInformation pi : availablePlugins.values()) {
114 if (pi.icon == null && pi.iconPath != null) {
115 pi.icon = new ImageProvider(pi.name+".jar/"+pi.iconPath)
116 .setArchive(f)
117 .setMaxWidth(24)
118 .setMaxHeight(24)
119 .setOptional(true).get();
120 }
121 }
122 monitor.worked(1);
123 }
124 }
125
126 protected void scanPluginFiles(ProgressMonitor monitor, File pluginsDirectory) {
127 File[] pluginFiles = pluginsDirectory.listFiles(
128 new FilenameFilter() {
129 public boolean accept(File dir, String name) {
130 return name.endsWith(".jar") || name.endsWith(".jar.new");
131 }
132 }
133 );
134 if (pluginFiles == null || pluginFiles.length == 0)
135 return;
136 monitor.subTask(tr("Processing plugin files..."));
137 monitor.setTicksCount(pluginFiles.length);
138 for (File f: pluginFiles) {
139 String fname = f.getName();
140 monitor.setCustomText(tr("Processing file ''{0}''", fname));
141 try {
142 if (fname.endsWith(".jar")) {
143 String pluginName = fname.substring(0, fname.length() - 4);
144 processJarFile(f, pluginName);
145 } else if (fname.endsWith(".jar.new")) {
146 String pluginName = fname.substring(0, fname.length() - 8);
147 processJarFile(f, pluginName);
148 }
149 } catch (PluginException e){
150 System.err.println(e.getMessage());
151 System.err.println(tr("Warning: Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
152 }
153 monitor.worked(1);
154 }
155 }
156
157 protected void scanLocalPluginRepository(ProgressMonitor monitor, File pluginsDirectory) {
158 if (pluginsDirectory == null) return;
159 try {
160 monitor.beginTask("");
161 scanSiteCacheFiles(monitor, pluginsDirectory);
162 scanIconCacheFiles(monitor, pluginsDirectory);
163 scanPluginFiles(monitor, pluginsDirectory);
164 } finally {
165 monitor.setCustomText("");
166 monitor.finishTask();
167 }
168 }
169
170 protected void processLocalPluginInformationFile(File file) throws PluginListParseException{
171 FileInputStream fin = null;
172 try {
173 fin = new FileInputStream(file);
174 List<PluginInformation> pis = new PluginListParser().parse(fin);
175 for (PluginInformation pi : pis) {
176 // we always keep plugin information from a plugin site because it
177 // includes information not available in the plugin jars Manifest, i.e.
178 // the download link or localized descriptions
179 //
180 availablePlugins.put(pi.name, pi);
181 }
182 } catch(IOException e) {
183 throw new PluginListParseException(e);
184 } finally {
185 Utils.close(fin);
186 }
187 }
188
189 protected void analyseInProcessPlugins() {
190 for (PluginProxy proxy : PluginHandler.pluginList) {
191 PluginInformation info = proxy.getPluginInformation();
192 if (canceled)return;
193 if (!availablePlugins.containsKey(info.name)) {
194 availablePlugins.put(info.name, info);
195 } else {
196 availablePlugins.get(info.name).localversion = info.localversion;
197 }
198 }
199 }
200
201 protected void filterOldPlugins() {
202 for (PluginHandler.DeprecatedPlugin p : PluginHandler.DEPRECATED_PLUGINS) {
203 if (canceled)return;
204 if (availablePlugins.containsKey(p.name)) {
205 availablePlugins.remove(p.name);
206 }
207 }
208 }
209
210 @Override
211 protected void realRun() throws SAXException, IOException, OsmTransferException {
212 Collection<String> pluginLocations = PluginInformation.getPluginLocations();
213 getProgressMonitor().setTicksCount(pluginLocations.size() + 2);
214 if (canceled) return;
215 for (String location : pluginLocations) {
216 scanLocalPluginRepository(
217 getProgressMonitor().createSubTaskMonitor(1, false),
218 new File(location)
219 );
220 getProgressMonitor().worked(1);
221 if (canceled)return;
222 }
223 analyseInProcessPlugins();
224 getProgressMonitor().worked(1);
225 if (canceled)return;
226 filterOldPlugins();
227 getProgressMonitor().worked(1);
228 }
229
230 /**
231 * Replies information about available plugins detected by this task.
232 *
233 * @return information about available plugins detected by this task.
234 */
235 public List<PluginInformation> getAvailablePlugins() {
236 return new ArrayList<PluginInformation>(availablePlugins.values());
237 }
238
239 /**
240 * Replies true if the task was canceled by the user
241 *
242 * @return true if the task was canceled by the user
243 */
244 public boolean isCanceled() {
245 return canceled;
246 }
247}
Note: See TracBrowser for help on using the repository browser.