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

Last change on this file since 4067 was 3874, checked in by bastiK, 13 years ago

use classloader to find projections from plugins

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