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

Last change on this file since 2876 was 2830, checked in by Gubaer, 14 years ago

fixed an ugly hack in the plugin bootstrap procedure

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