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

Last change on this file since 5132 was 4737, checked in by stoecker, 12 years ago

fix #7197 - fix plugin version check on load

  • Property svn:eol-style set to native
File size: 9.7 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 {@see 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.localversion = info.version;
66 info.localmainversion = info.mainversion;
67 availablePlugins.put(info.getName(), info);
68 } else {
69 PluginInformation current = availablePlugins.get(info.getName());
70 current.localversion = info.version;
71 current.localmainversion = info.mainversion;
72 if (info.icon != null) {
73 current.icon = info.icon;
74 }
75 current.early = info.early;
76 current.className = info.className;
77 current.libraries = info.libraries;
78 current.stage = info.stage;
79 current.requires = info.requires;
80 }
81 }
82
83 protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
84 File[] siteCacheFiles = pluginsDirectory.listFiles(
85 new FilenameFilter() {
86 public boolean accept(File dir, String name) {
87 return name.matches("^([0-9]+-)?site.*\\.txt$");
88 }
89 }
90 );
91 if (siteCacheFiles == null || siteCacheFiles.length == 0)
92 return;
93 monitor.subTask(tr("Processing plugin site cache files..."));
94 monitor.setTicksCount(siteCacheFiles.length);
95 for (File f: siteCacheFiles) {
96 String fname = f.getName();
97 monitor.setCustomText(tr("Processing file ''{0}''", fname));
98 try {
99 processLocalPluginInformationFile(f);
100 } catch(PluginListParseException e) {
101 System.err.println(tr("Warning: Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
102 e.printStackTrace();
103 }
104 monitor.worked(1);
105 }
106 }
107
108 protected void scanIconCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
109 File[] siteCacheFiles = pluginsDirectory.listFiles(
110 new FilenameFilter() {
111 public boolean accept(File dir, String name) {
112 return name.matches("^([0-9]+-)?site.*plugin-icons\\.zip$");
113 }
114 }
115 );
116 if (siteCacheFiles == null || siteCacheFiles.length == 0)
117 return;
118 monitor.subTask(tr("Processing plugin site cache icon files..."));
119 monitor.setTicksCount(siteCacheFiles.length);
120 for (File f: siteCacheFiles) {
121 String fname = f.getName();
122 monitor.setCustomText(tr("Processing file ''{0}''", fname));
123 for (PluginInformation pi : availablePlugins.values()) {
124 if (pi.icon == null && pi.iconPath != null) {
125 pi.icon = new ImageProvider(pi.name+".jar/"+pi.iconPath)
126 .setArchive(f)
127 .setMaxWidth(24)
128 .setMaxHeight(24)
129 .setOptional(true).get();
130 }
131 }
132 monitor.worked(1);
133 }
134 }
135
136 protected void scanPluginFiles(ProgressMonitor monitor, File pluginsDirectory) {
137 File[] pluginFiles = pluginsDirectory.listFiles(
138 new FilenameFilter() {
139 public boolean accept(File dir, String name) {
140 return name.endsWith(".jar") || name.endsWith(".jar.new");
141 }
142 }
143 );
144 if (pluginFiles == null || pluginFiles.length == 0)
145 return;
146 monitor.subTask(tr("Processing plugin files..."));
147 monitor.setTicksCount(pluginFiles.length);
148 for (File f: pluginFiles) {
149 String fname = f.getName();
150 monitor.setCustomText(tr("Processing file ''{0}''", fname));
151 try {
152 if (fname.endsWith(".jar")) {
153 String pluginName = fname.substring(0, fname.length() - 4);
154 processJarFile(f, pluginName);
155 } else if (fname.endsWith(".jar.new")) {
156 String pluginName = fname.substring(0, fname.length() - 8);
157 processJarFile(f, pluginName);
158 }
159 } catch(PluginException e){
160 System.err.println(tr("Warning: Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
161 e.printStackTrace();
162 }
163 monitor.worked(1);
164 }
165 }
166
167 protected void scanLocalPluginRepository(ProgressMonitor monitor, File pluginsDirectory) {
168 if (pluginsDirectory == null) return;
169 try {
170 monitor.beginTask("");
171 scanSiteCacheFiles(monitor, pluginsDirectory);
172 scanIconCacheFiles(monitor, pluginsDirectory);
173 scanPluginFiles(monitor, pluginsDirectory);
174 } finally {
175 monitor.setCustomText("");
176 monitor.finishTask();
177 }
178 }
179
180 protected void processLocalPluginInformationFile(File file) throws PluginListParseException{
181 FileInputStream fin = null;
182 try {
183 fin = new FileInputStream(file);
184 List<PluginInformation> pis = new PluginListParser().parse(fin);
185 for (PluginInformation pi : pis) {
186 // we always keep plugin information from a plugin site because it
187 // includes information not available in the plugin jars Manifest, i.e.
188 // the download link or localized descriptions
189 //
190 availablePlugins.put(pi.name, pi);
191 }
192 } catch(IOException e) {
193 throw new PluginListParseException(e);
194 } finally {
195 Utils.close(fin);
196 }
197 }
198
199 protected void analyseInProcessPlugins() {
200 for (PluginProxy proxy : PluginHandler.pluginList) {
201 PluginInformation info = proxy.getPluginInformation();
202 if (canceled)return;
203 if (!availablePlugins.containsKey(info.name)) {
204 availablePlugins.put(info.name, info);
205 } else {
206 availablePlugins.get(info.name).localversion = info.localversion;
207 }
208 }
209 }
210
211 protected void filterOldPlugins() {
212 for (PluginHandler.DeprecatedPlugin p : PluginHandler.DEPRECATED_PLUGINS) {
213 if (canceled)return;
214 if (availablePlugins.containsKey(p.name)) {
215 availablePlugins.remove(p.name);
216 }
217 }
218 }
219
220 @Override
221 protected void realRun() throws SAXException, IOException, OsmTransferException {
222 Collection<String> pluginLocations = PluginInformation.getPluginLocations();
223 getProgressMonitor().setTicksCount(pluginLocations.size() + 2);
224 if (canceled) return;
225 for (String location : pluginLocations) {
226 scanLocalPluginRepository(
227 getProgressMonitor().createSubTaskMonitor(1, false),
228 new File(location)
229 );
230 getProgressMonitor().worked(1);
231 if (canceled)return;
232 }
233 analyseInProcessPlugins();
234 getProgressMonitor().worked(1);
235 if (canceled)return;
236 filterOldPlugins();
237 getProgressMonitor().worked(1);
238 }
239
240 /**
241 * Replies information about available plugins detected by this task.
242 *
243 * @return information about available plugins detected by this task.
244 */
245 public List<PluginInformation> getAvailablePlugins() {
246 return new ArrayList<PluginInformation>(availablePlugins.values());
247 }
248
249 /**
250 * Replies true if the task was canceled by the user
251 *
252 * @return true if the task was canceled by the user
253 */
254 public boolean isCanceled() {
255 return canceled;
256 }
257}
Note: See TracBrowser for help on using the repository browser.