source: josm/trunk/src/org/openstreetmap/josm/plugins/PluginSelection.java@ 1814

Last change on this file since 1814 was 1769, checked in by stoecker, 15 years ago

fix #2902 - patch by jttt - plugin update

File size: 14.3 KB
Line 
1//License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.plugins;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.GridBagConstraints;
8import java.awt.Insets;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.io.BufferedReader;
12import java.io.ByteArrayInputStream;
13import java.io.File;
14import java.io.FileInputStream;
15import java.io.InputStreamReader;
16import java.util.Arrays;
17import java.util.Collection;
18import java.util.Collections;
19import java.util.Comparator;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.LinkedList;
23import java.util.Map;
24import java.util.Set;
25import java.util.TreeMap;
26import java.util.Map.Entry;
27
28import javax.swing.BorderFactory;
29import javax.swing.JCheckBox;
30import javax.swing.JEditorPane;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.UIManager;
34import javax.swing.event.HyperlinkEvent;
35import javax.swing.event.HyperlinkListener;
36import javax.swing.event.HyperlinkEvent.EventType;
37
38import org.openstreetmap.josm.Main;
39import org.openstreetmap.josm.gui.ExtendedDialog;
40import org.openstreetmap.josm.tools.OpenBrowser;
41
42public class PluginSelection {
43
44 private Map<String, Boolean> pluginMap;
45 private Map<String, PluginInformation> availablePlugins;
46 private Map<String, PluginInformation> localPlugins;
47
48 public void updateDescription(JPanel pluginPanel) {
49 int count = PluginDownloader.downloadDescription();
50 if (count > 0)
51 JOptionPane.showMessageDialog(Main.parent,
52 trn("Downloaded plugin information from {0} site",
53 "Downloaded plugin information from {0} sites", count, count));
54 else
55 JOptionPane.showMessageDialog(Main.parent, tr("No plugin information found."));
56 drawPanel(pluginPanel);
57 }
58
59 public void update(JPanel pluginPanel) {
60 // refresh description
61 int num = PluginDownloader.downloadDescription();
62 Boolean done = false;
63 drawPanel(pluginPanel);
64
65 Set<PluginInformation> toUpdate = new HashSet<PluginInformation>();
66 StringBuilder toUpdateStr = new StringBuilder();
67 for (String pluginName : Main.pref.getCollection("plugins", Collections.<String>emptySet())) {
68 PluginInformation local = localPlugins.get(pluginName);
69 PluginInformation description = availablePlugins.get(local.name);
70
71 if (description.version != null && !description.version.equals(local.version)) {
72 toUpdate.add(description);
73 toUpdateStr.append(description.name+"\n");
74 }
75 }
76 if (toUpdate.isEmpty()) {
77 JOptionPane.showMessageDialog(Main.parent, tr("All installed plugins are up to date."));
78 done = true;
79 } else {
80 int answer = new ExtendedDialog(Main.parent,
81 tr("Update"),
82 tr("Update the following plugins:\n\n{0}", toUpdateStr.toString()),
83 new String[] {tr("Update Plugins"), tr("Cancel")},
84 new String[] {"dialogs/refresh.png", "cancel.png"}).getValue();
85 if (answer == 1) {
86 PluginDownloader.update(toUpdate);
87 done = true;
88 }
89 }
90 if (done && num >= 1)
91 Main.pref.put("pluginmanager.lastupdate", Long.toString(System.currentTimeMillis()));
92 drawPanel(pluginPanel);
93 }
94
95 public boolean finish() {
96 Collection<PluginInformation> toDownload = new LinkedList<PluginInformation>();
97 Collection<String> installedPlugins = Main.pref.getCollection("plugins", Collections.<String>emptySet());
98
99 String msg = "";
100 for (Entry<String, Boolean> entry : pluginMap.entrySet()) {
101 if(entry.getValue() && !installedPlugins.contains(entry.getKey()))
102 {
103 String name = entry.getKey();
104 PluginInformation ap = availablePlugins.get(name);
105 PluginInformation pi = localPlugins.get(name);
106 if(pi == null || (pi.version == null && ap.version != null)
107 || (pi.version != null && !pi.version.equals(ap.version)))
108 {
109 toDownload.add(ap);
110 msg += name + "\n";
111 }
112 }
113 }
114 if (!toDownload.isEmpty()) {
115 int answer = new ExtendedDialog(Main.parent,
116 tr("Download missing plugins"),
117 tr("Download the following plugins?\n\n{0}", msg),
118 new String[] {tr("Download Plugins"), tr("Cancel")},
119 new String[] {"download.png", "cancel.png"}).getValue();
120 Collection<PluginInformation> error =
121 (answer != 1 ? toDownload : new PluginDownloader().download(toDownload));
122 for (PluginInformation pd : error)
123 pluginMap.put(pd.name, false);
124
125 }
126 LinkedList<String> plugins = new LinkedList<String>();
127 for (Map.Entry<String, Boolean> d : pluginMap.entrySet()) {
128 if (d.getValue())
129 plugins.add(d.getKey());
130 }
131
132 Collections.sort(plugins);
133 return Main.pref.putCollection("plugins", plugins);
134 }
135
136 /* return true when plugin list changed */
137 public void drawPanel(JPanel pluginPanel) {
138 loadPlugins();
139 Collection<String> enabledPlugins = Main.pref.getCollection("plugins", null);
140
141 if (pluginMap == null)
142 pluginMap = new HashMap<String, Boolean>();
143 else {
144 // Keep the map in bounds; possibly slightly pointless.
145 Set<String> pluginsToRemove = new HashSet<String>();
146 for (final String pname : pluginMap.keySet()) {
147 if (availablePlugins.get(pname) == null) pluginsToRemove.add(pname);
148 }
149
150 for (String pname : pluginsToRemove) {
151 pluginMap.remove(pname);
152 }
153 }
154
155 pluginPanel.removeAll();
156
157 GridBagConstraints gbc = new GridBagConstraints();
158 gbc.gridx = 0;
159 gbc.anchor = GridBagConstraints.NORTHWEST;
160
161 int row = 0;
162 for (final PluginInformation plugin : availablePlugins.values()) {
163 boolean enabled = (enabledPlugins != null) && enabledPlugins.contains(plugin.name);
164 if (pluginMap.get(plugin.name) == null)
165 pluginMap.put(plugin.name, enabled);
166
167 String remoteversion = plugin.version;
168 if ((remoteversion == null) || remoteversion.equals(""))
169 remoteversion = tr("unknown");
170 else if(plugin.oldmode)
171 remoteversion += "*";
172
173 String localversion = "";
174 PluginInformation p = localPlugins.get(plugin.name);
175 if(p != null)
176 {
177 if (p.version != null && !p.version.equals(""))
178 localversion = p.version;
179 else
180 localversion = tr("unknown");
181 localversion = " (" + localversion + ")";
182 }
183
184 final JCheckBox pluginCheck = new JCheckBox(
185 tr("{0}: Version {1}{2}", plugin.name, remoteversion, localversion),
186 pluginMap.get(plugin.name));
187 gbc.gridy = row++;
188 gbc.insets = new Insets(5,5,0,5);
189 gbc.weighty = 0.1;
190 gbc.fill = GridBagConstraints.NONE;
191 pluginPanel.add(pluginCheck, gbc);
192
193 pluginCheck.setToolTipText(plugin.downloadlink != null ? ""+plugin.downloadlink : tr("Plugin bundled with JOSM"));
194
195 JEditorPane description = new JEditorPane();
196 description.setContentType("text/html");
197 description.setEditable(false);
198 description.setText("<html><body bgcolor=\"#" + Integer.toHexString( UIManager.getColor("Panel.background").getRGB() & 0x00ffffff ) +"\"><i>"+plugin.getLinkDescription()+"</i></body></html>");
199 description.setBorder(BorderFactory.createEmptyBorder());
200 description.setBackground(UIManager.getColor("Panel.background"));
201 description.addHyperlinkListener(new HyperlinkListener() {
202 public void hyperlinkUpdate(HyperlinkEvent e) {
203 if(e.getEventType() == EventType.ACTIVATED) {
204 OpenBrowser.displayUrl(e.getURL().toString());
205 }
206 }
207 });
208
209 gbc.gridy = row++;
210 gbc.insets = new Insets(3,25,5,5);
211 gbc.weighty = 0.9;
212 gbc.weightx = 1.0;
213 gbc.anchor = GridBagConstraints.WEST;
214 gbc.fill = GridBagConstraints.HORIZONTAL;
215 pluginPanel.add(description, gbc);
216
217 pluginCheck.addActionListener(new ActionListener(){
218 public void actionPerformed(ActionEvent e) {
219 pluginMap.put(plugin.name, pluginCheck.isSelected());
220 }
221 });
222 }
223 pluginPanel.updateUI();
224 }
225
226 private void loadPlugins() {
227 availablePlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
228 public int compare(String o1, String o2) {
229 return o1.compareToIgnoreCase(o2);
230 }
231 });
232 localPlugins = new TreeMap<String, PluginInformation>(new Comparator<String>(){
233 public int compare(String o1, String o2) {
234 return o1.compareToIgnoreCase(o2);
235 }
236 });
237 for (String location : PluginInformation.getPluginLocations()) {
238 File[] pluginFiles = new File(location).listFiles();
239 if (pluginFiles != null) {
240 Arrays.sort(pluginFiles);
241 for (File f : pluginFiles) {
242 if (!f.isFile())
243 continue;
244 String fname = f.getName();
245 if (fname.endsWith(".jar")) {
246 try {
247 PluginInformation info = new PluginInformation(f,fname.substring(0,fname.length()-4));
248 if (!availablePlugins.containsKey(info.name))
249 availablePlugins.put(info.name, info);
250 if (!localPlugins.containsKey(info.name))
251 localPlugins.put(info.name, info);
252 } catch (PluginException x) {
253 }
254 } else if (fname.endsWith(".jar.new")) {
255 try {
256 PluginInformation info = new PluginInformation(f,fname.substring(0,fname.length()-8));
257 availablePlugins.put(info.name, info);
258 localPlugins.put(info.name, info);
259 } catch (PluginException x) {
260 }
261 } else if (fname.matches("^[0-9]+-site.*\\.txt$")) {
262 int err = 0;
263 try {
264 BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(f), "utf-8"));
265 String name = null;
266 String url = null;
267 String manifest = null;
268 for (String line = r.readLine(); line != null; line = r.readLine())
269 {
270 if(line.startsWith("\t"))
271 {
272 line = line.substring(1);
273 if(line.length() > 70)
274 {
275 manifest += line.substring(0,70)+"\n";
276 line = " " + line.substring(70);
277 }
278 manifest += line+"\n";
279 }
280 else
281 {
282 if(name != null)
283 {
284 try
285 {
286 PluginInformation info = new PluginInformation(
287 new ByteArrayInputStream(manifest.getBytes("utf-8")),
288 name.substring(0,name.length()-4), url);
289 if(!availablePlugins.containsKey(info.name))
290 availablePlugins.put(info.name, info);
291 }
292 catch (Exception e)
293 {
294 e.printStackTrace();
295 ++err;
296 }
297 }
298 String x[] = line.split(";");
299 name = x[0];
300 url = x[1];
301 manifest = null;
302 }
303 }
304 if(name != null)
305 {
306 PluginInformation info = new PluginInformation(
307 new ByteArrayInputStream(manifest.getBytes("utf-8")),
308 name.substring(0,name.length()-4), url);
309 if(!availablePlugins.containsKey(info.name))
310 availablePlugins.put(info.name, info);
311 }
312 r.close();
313 } catch (Exception e) {
314 e.printStackTrace();
315 ++err;
316 }
317 if(err > 0)
318 {
319 JOptionPane.showMessageDialog(Main.parent, tr("Error reading plugin information file: {0}", f.getName()));
320 }
321 }
322 }
323 }
324 }
325 for (PluginProxy proxy : PluginHandler.pluginList)
326 {
327 if (!availablePlugins.containsKey(proxy.info.name))
328 availablePlugins.put(proxy.info.name, proxy.info);
329 if (!localPlugins.containsKey(proxy.info.name))
330 localPlugins.put(proxy.info.name, proxy.info);
331 }
332 }
333}
Note: See TracBrowser for help on using the repository browser.