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

Last change on this file since 10294 was 10173, checked in by Don-vip, 8 years ago

sonar - squid:S1186 - Methods should not be empty

  • Property svn:eol-style set to native
File size: 8.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.Main;
17import org.openstreetmap.josm.gui.PleaseWaitRunnable;
18import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
19import org.openstreetmap.josm.gui.progress.ProgressMonitor;
20import org.openstreetmap.josm.io.OsmTransferException;
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 org.openstreetmap.josm.data.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="https://josm.openstreetmap.de/pluginicons">https://josm.openstreetmap.de/pluginicons</a></li>
34 * </ul>
35 *
36 */
37public class ReadLocalPluginInformationTask extends PleaseWaitRunnable {
38 private final Map<String, PluginInformation> availablePlugins;
39 private boolean canceled;
40
41 /**
42 * Constructs a new {@code ReadLocalPluginInformationTask}.
43 */
44 public ReadLocalPluginInformationTask() {
45 super(tr("Reading local plugin information.."), false);
46 availablePlugins = new HashMap<>();
47 }
48
49 public ReadLocalPluginInformationTask(ProgressMonitor monitor) {
50 super(tr("Reading local plugin information.."), monitor, false);
51 availablePlugins = new HashMap<>();
52 }
53
54 @Override
55 protected void cancel() {
56 canceled = true;
57 }
58
59 @Override
60 protected void finish() {
61 // Do nothing
62 }
63
64 protected void processJarFile(File f, String pluginName) throws PluginException {
65 PluginInformation info = new PluginInformation(
66 f,
67 pluginName
68 );
69 if (!availablePlugins.containsKey(info.getName())) {
70 info.updateLocalInfo(info);
71 availablePlugins.put(info.getName(), info);
72 } else {
73 PluginInformation current = availablePlugins.get(info.getName());
74 current.updateFromJar(info);
75 }
76 }
77
78 private static File[] listFiles(File pluginsDirectory, final String regex) {
79 return pluginsDirectory.listFiles(
80 new FilenameFilter() {
81 @Override
82 public boolean accept(File dir, String name) {
83 return name.matches(regex);
84 }
85 }
86 );
87 }
88
89 protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
90 File[] siteCacheFiles = listFiles(pluginsDirectory, "^([0-9]+-)?site.*\\.txt$");
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 Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
102 Main.error(e);
103 }
104 monitor.worked(1);
105 }
106 }
107
108 protected void scanPluginFiles(ProgressMonitor monitor, File pluginsDirectory) {
109 File[] pluginFiles = pluginsDirectory.listFiles(
110 new FilenameFilter() {
111 @Override
112 public boolean accept(File dir, String name) {
113 return name.endsWith(".jar") || name.endsWith(".jar.new");
114 }
115 }
116 );
117 if (pluginFiles == null || pluginFiles.length == 0)
118 return;
119 monitor.subTask(tr("Processing plugin files..."));
120 monitor.setTicksCount(pluginFiles.length);
121 for (File f: pluginFiles) {
122 String fname = f.getName();
123 monitor.setCustomText(tr("Processing file ''{0}''", fname));
124 try {
125 if (fname.endsWith(".jar")) {
126 String pluginName = fname.substring(0, fname.length() - 4);
127 processJarFile(f, pluginName);
128 } else if (fname.endsWith(".jar.new")) {
129 String pluginName = fname.substring(0, fname.length() - 8);
130 processJarFile(f, pluginName);
131 }
132 } catch (PluginException e) {
133 Main.warn("PluginException: "+e.getMessage());
134 Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
135 }
136 monitor.worked(1);
137 }
138 }
139
140 protected void scanLocalPluginRepository(ProgressMonitor monitor, File pluginsDirectory) {
141 if (pluginsDirectory == null)
142 return;
143 if (monitor == null)
144 monitor = NullProgressMonitor.INSTANCE;
145 try {
146 monitor.beginTask("");
147 scanSiteCacheFiles(monitor, pluginsDirectory);
148 scanPluginFiles(monitor, pluginsDirectory);
149 } finally {
150 monitor.setCustomText("");
151 monitor.finishTask();
152 }
153 }
154
155 protected void processLocalPluginInformationFile(File file) throws PluginListParseException {
156 try (FileInputStream fin = new FileInputStream(file)) {
157 List<PluginInformation> pis = new PluginListParser().parse(fin);
158 for (PluginInformation pi : pis) {
159 // we always keep plugin information from a plugin site because it
160 // includes information not available in the plugin jars Manifest, i.e.
161 // the download link or localized descriptions
162 //
163 availablePlugins.put(pi.name, pi);
164 }
165 } catch (IOException e) {
166 throw new PluginListParseException(e);
167 }
168 }
169
170 protected void analyseInProcessPlugins() {
171 for (PluginProxy proxy : PluginHandler.pluginList) {
172 PluginInformation info = proxy.getPluginInformation();
173 if (canceled) return;
174 if (!availablePlugins.containsKey(info.name)) {
175 availablePlugins.put(info.name, info);
176 } else {
177 availablePlugins.get(info.name).localversion = info.localversion;
178 }
179 }
180 }
181
182 protected void filterOldPlugins() {
183 for (PluginHandler.DeprecatedPlugin p : PluginHandler.DEPRECATED_PLUGINS) {
184 if (canceled) return;
185 if (availablePlugins.containsKey(p.name)) {
186 availablePlugins.remove(p.name);
187 }
188 }
189 }
190
191 @Override
192 protected void realRun() throws SAXException, IOException, OsmTransferException {
193 Collection<String> pluginLocations = PluginInformation.getPluginLocations();
194 getProgressMonitor().setTicksCount(pluginLocations.size() + 2);
195 if (canceled) return;
196 for (String location : pluginLocations) {
197 scanLocalPluginRepository(
198 getProgressMonitor().createSubTaskMonitor(1, false),
199 new File(location)
200 );
201 getProgressMonitor().worked(1);
202 if (canceled) return;
203 }
204 analyseInProcessPlugins();
205 getProgressMonitor().worked(1);
206 if (canceled) return;
207 filterOldPlugins();
208 getProgressMonitor().worked(1);
209 }
210
211 /**
212 * Replies information about available plugins detected by this task.
213 *
214 * @return information about available plugins detected by this task.
215 */
216 public List<PluginInformation> getAvailablePlugins() {
217 return new ArrayList<>(availablePlugins.values());
218 }
219
220 /**
221 * Replies true if the task was canceled by the user
222 *
223 * @return true if the task was canceled by the user
224 */
225 public boolean isCanceled() {
226 return canceled;
227 }
228}
Note: See TracBrowser for help on using the repository browser.