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

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

fix #9778, fix #9806 - access OSM API and JOSM website in HTTPS by default + other HTTPS links where applicable + update CONTRIBUTION

  • Property svn:eol-style set to native
File size: 9.4 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.Main;
17import org.openstreetmap.josm.gui.PleaseWaitRunnable;
18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
19import org.openstreetmap.josm.io.OsmTransferException;
20import org.openstreetmap.josm.tools.ImageProvider;
21import org.openstreetmap.josm.tools.Utils;
22import org.xml.sax.SAXException;
23
24/**
25 * This is an asynchronous task for reading plugin information from the files
26 * in the local plugin repositories.
27 *
28 * It scans the files in the local plugins repository (see {@link org.openstreetmap.josm.data.Preferences#getPluginsDirectory()}
29 * and extracts plugin information from three kind of files:
30 * <ul>
31 * <li>.jar files, assuming that they represent plugin jars</li>
32 * <li>.jar.new files, assuming that these are downloaded but not yet installed plugins</li>
33 * <li>cached lists of available plugins, downloaded for instance from
34 * <a href="https://josm.openstreetmap.de/plugin">https://josm.openstreetmap.de/plugin</a></li>
35 * </ul>
36 *
37 */
38public class ReadLocalPluginInformationTask extends PleaseWaitRunnable {
39 private Map<String, PluginInformation> availablePlugins;
40 private boolean canceled;
41
42 /**
43 * Constructs a new {@code ReadLocalPluginInformationTask}.
44 */
45 public ReadLocalPluginInformationTask() {
46 super(tr("Reading local plugin information.."), false);
47 availablePlugins = new HashMap<String, PluginInformation>();
48 }
49
50 public ReadLocalPluginInformationTask(ProgressMonitor monitor) {
51 super(tr("Reading local plugin information.."),monitor, false);
52 availablePlugins = new HashMap<String, PluginInformation>();
53 }
54
55 @Override
56 protected void cancel() {
57 canceled = true;
58 }
59
60 @Override
61 protected void finish() {}
62
63 protected void processJarFile(File f, String pluginName) throws PluginException{
64 PluginInformation info = new PluginInformation(
65 f,
66 pluginName
67 );
68 if (!availablePlugins.containsKey(info.getName())) {
69 info.updateLocalInfo(info);
70 availablePlugins.put(info.getName(), info);
71 } else {
72 PluginInformation current = availablePlugins.get(info.getName());
73 current.updateFromJar(info);
74 }
75 }
76
77 private File[] listFiles(File pluginsDirectory, final String regex) {
78 return pluginsDirectory.listFiles(
79 new FilenameFilter() {
80 @Override
81 public boolean accept(File dir, String name) {
82 return name.matches(regex);
83 }
84 }
85 );
86 }
87
88 protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
89 File[] siteCacheFiles = listFiles(pluginsDirectory, "^([0-9]+-)?site.*\\.txt$");
90 if (siteCacheFiles == null || siteCacheFiles.length == 0)
91 return;
92 monitor.subTask(tr("Processing plugin site cache files..."));
93 monitor.setTicksCount(siteCacheFiles.length);
94 for (File f: siteCacheFiles) {
95 String fname = f.getName();
96 monitor.setCustomText(tr("Processing file ''{0}''", fname));
97 try {
98 processLocalPluginInformationFile(f);
99 } catch(PluginListParseException e) {
100 Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
101 Main.error(e);
102 }
103 monitor.worked(1);
104 }
105 }
106 protected void scanIconCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
107 File[] siteCacheFiles = listFiles(pluginsDirectory, "^([0-9]+-)?site.*plugin-icons\\.zip$");
108 if (siteCacheFiles == null || siteCacheFiles.length == 0)
109 return;
110 monitor.subTask(tr("Processing plugin site cache icon files..."));
111 monitor.setTicksCount(siteCacheFiles.length);
112 for (File f: siteCacheFiles) {
113 String fname = f.getName();
114 monitor.setCustomText(tr("Processing file ''{0}''", fname));
115 for (PluginInformation pi : availablePlugins.values()) {
116 if (pi.icon == null && pi.iconPath != null) {
117 pi.icon = new ImageProvider(pi.name+".jar/"+pi.iconPath)
118 .setArchive(f)
119 .setMaxWidth(24)
120 .setMaxHeight(24)
121 .setOptional(true).get();
122 }
123 }
124 monitor.worked(1);
125 }
126 }
127
128 protected void scanPluginFiles(ProgressMonitor monitor, File pluginsDirectory) {
129 File[] pluginFiles = pluginsDirectory.listFiles(
130 new FilenameFilter() {
131 @Override
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 Main.warn("PluginException: "+e.getMessage());
154 Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
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 Utils.close(fin);
189 }
190 }
191
192 protected void analyseInProcessPlugins() {
193 for (PluginProxy proxy : PluginHandler.pluginList) {
194 PluginInformation info = proxy.getPluginInformation();
195 if (canceled)return;
196 if (!availablePlugins.containsKey(info.name)) {
197 availablePlugins.put(info.name, info);
198 } else {
199 availablePlugins.get(info.name).localversion = info.localversion;
200 }
201 }
202 }
203
204 protected void filterOldPlugins() {
205 for (PluginHandler.DeprecatedPlugin p : PluginHandler.DEPRECATED_PLUGINS) {
206 if (canceled)return;
207 if (availablePlugins.containsKey(p.name)) {
208 availablePlugins.remove(p.name);
209 }
210 }
211 }
212
213 @Override
214 protected void realRun() throws SAXException, IOException, OsmTransferException {
215 Collection<String> pluginLocations = PluginInformation.getPluginLocations();
216 getProgressMonitor().setTicksCount(pluginLocations.size() + 2);
217 if (canceled) return;
218 for (String location : pluginLocations) {
219 scanLocalPluginRepository(
220 getProgressMonitor().createSubTaskMonitor(1, false),
221 new File(location)
222 );
223 getProgressMonitor().worked(1);
224 if (canceled)return;
225 }
226 analyseInProcessPlugins();
227 getProgressMonitor().worked(1);
228 if (canceled)return;
229 filterOldPlugins();
230 getProgressMonitor().worked(1);
231 }
232
233 /**
234 * Replies information about available plugins detected by this task.
235 *
236 * @return information about available plugins detected by this task.
237 */
238 public List<PluginInformation> getAvailablePlugins() {
239 return new ArrayList<PluginInformation>(availablePlugins.values());
240 }
241
242 /**
243 * Replies true if the task was canceled by the user
244 *
245 * @return true if the task was canceled by the user
246 */
247 public boolean isCanceled() {
248 return canceled;
249 }
250}
Note: See TracBrowser for help on using the repository browser.