source: josm/trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java@ 5601

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

fix #7680, fix #8209 - Better handling of plugin automatic updates (automatic dependencies resolution + version number update)

  • Property svn:eol-style set to native
File size: 12.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.preferences.plugin;
3
4import java.io.File;
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.Collections;
8import java.util.Comparator;
9import java.util.HashMap;
10import java.util.HashSet;
11import java.util.LinkedList;
12import java.util.List;
13import java.util.Observable;
14import java.util.Set;
15import java.util.Map.Entry;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.plugins.PluginException;
19import org.openstreetmap.josm.plugins.PluginHandler;
20import org.openstreetmap.josm.plugins.PluginInformation;
21
22public class PluginPreferencesModel extends Observable{
23 private final ArrayList<PluginInformation> availablePlugins = new ArrayList<PluginInformation>();
24 private final ArrayList<PluginInformation> displayedPlugins = new ArrayList<PluginInformation>();
25 private final HashMap<PluginInformation, Boolean> selectedPluginsMap = new HashMap<PluginInformation, Boolean>();
26 private Set<String> pendingDownloads = new HashSet<String>();
27 private String filterExpression;
28 private Set<String> currentActivePlugins;
29
30 public PluginPreferencesModel() {
31 currentActivePlugins = new HashSet<String>();
32 currentActivePlugins.addAll(Main.pref.getCollection("plugins", currentActivePlugins));
33 }
34
35 public void filterDisplayedPlugins(String filter) {
36 if (filter == null) {
37 displayedPlugins.clear();
38 displayedPlugins.addAll(availablePlugins);
39 this.filterExpression = null;
40 return;
41 }
42 displayedPlugins.clear();
43 for (PluginInformation pi: availablePlugins) {
44 if (pi.matches(filter)) {
45 displayedPlugins.add(pi);
46 }
47 }
48 filterExpression = filter;
49 clearChanged();
50 notifyObservers();
51 }
52
53 public void setAvailablePlugins(Collection<PluginInformation> available) {
54 availablePlugins.clear();
55 if (available != null) {
56 availablePlugins.addAll(available);
57 }
58 sort();
59 filterDisplayedPlugins(filterExpression);
60 Set<String> activePlugins = new HashSet<String>();
61 activePlugins.addAll(Main.pref.getCollection("plugins", activePlugins));
62 for (PluginInformation pi: availablePlugins) {
63 if (selectedPluginsMap.get(pi) == null) {
64 if (activePlugins.contains(pi.name)) {
65 selectedPluginsMap.put(pi, true);
66 }
67 }
68 }
69 clearChanged();
70 notifyObservers();
71 }
72
73 protected void updateAvailablePlugin(PluginInformation other) {
74 if (other == null) return;
75 PluginInformation pi = getPluginInformation(other.name);
76 if (pi == null) {
77 availablePlugins.add(other);
78 return;
79 }
80 pi.updateFromPluginSite(other);
81 }
82
83 /**
84 * Updates the list of plugin information objects with new information from
85 * plugin update sites.
86 *
87 * @param fromPluginSite plugin information read from plugin update sites
88 */
89 public void updateAvailablePlugins(Collection<PluginInformation> fromPluginSite) {
90 for (PluginInformation other: fromPluginSite) {
91 updateAvailablePlugin(other);
92 }
93 sort();
94 filterDisplayedPlugins(filterExpression);
95 Set<String> activePlugins = new HashSet<String>();
96 activePlugins.addAll(Main.pref.getCollection("plugins", activePlugins));
97 for (PluginInformation pi: availablePlugins) {
98 if (selectedPluginsMap.get(pi) == null) {
99 if (activePlugins.contains(pi.name)) {
100 selectedPluginsMap.put(pi, true);
101 }
102 }
103 }
104 clearChanged();
105 notifyObservers();
106 }
107
108 /**
109 * Replies the list of selected plugin information objects
110 *
111 * @return the list of selected plugin information objects
112 */
113 public List<PluginInformation> getSelectedPlugins() {
114 List<PluginInformation> ret = new LinkedList<PluginInformation>();
115 for (PluginInformation pi: availablePlugins) {
116 if (selectedPluginsMap.get(pi) == null) {
117 continue;
118 }
119 if (selectedPluginsMap.get(pi)) {
120 ret.add(pi);
121 }
122 }
123 return ret;
124 }
125
126 /**
127 * Replies the list of selected plugin information objects
128 *
129 * @return the list of selected plugin information objects
130 */
131 public Set<String> getSelectedPluginNames() {
132 Set<String> ret = new HashSet<String>();
133 for (PluginInformation pi: getSelectedPlugins()) {
134 ret.add(pi.name);
135 }
136 return ret;
137 }
138
139 /**
140 * Sorts the list of available plugins
141 */
142 protected void sort() {
143 Collections.sort(
144 availablePlugins,
145 new Comparator<PluginInformation>() {
146 public int compare(PluginInformation o1, PluginInformation o2) {
147 String n1 = o1.getName() == null ? "" : o1.getName().toLowerCase();
148 String n2 = o2.getName() == null ? "" : o2.getName().toLowerCase();
149 return n1.compareTo(n2);
150 }
151 }
152 );
153 }
154
155 /**
156 * Replies the list of plugin informations to display
157 *
158 * @return the list of plugin informations to display
159 */
160 public List<PluginInformation> getDisplayedPlugins() {
161 return displayedPlugins;
162 }
163
164
165 /**
166 * Replies the list of plugins waiting for update or download
167 *
168 * @return the list of plugins waiting for update or download
169 */
170 public List<PluginInformation> getPluginsScheduledForUpdateOrDownload() {
171 List<PluginInformation> ret = new ArrayList<PluginInformation>();
172 for (String plugin: pendingDownloads) {
173 PluginInformation pi = getPluginInformation(plugin);
174 if (pi == null) {
175 continue;
176 }
177 ret.add(pi);
178 }
179 return ret;
180 }
181
182 /**
183 * Sets whether the plugin is selected or not.
184 *
185 * @param name the name of the plugin
186 * @param selected true, if selected; false, otherwise
187 */
188 public void setPluginSelected(String name, boolean selected) {
189 PluginInformation pi = getPluginInformation(name);
190 if (pi != null) {
191 selectedPluginsMap.put(pi,selected);
192 if (pi.isUpdateRequired()) {
193 pendingDownloads.add(pi.name);
194 }
195 }
196 if (!selected) {
197 pendingDownloads.remove(name);
198 }
199 }
200
201 /**
202 * Removes all the plugin in {@code plugins} from the list of plugins
203 * with a pending download
204 *
205 * @param plugins the list of plugins to clear for a pending download
206 */
207 public void clearPendingPlugins(Collection<PluginInformation> plugins){
208 if (plugins == null || plugins.isEmpty()) return;
209 for(PluginInformation pi: plugins) {
210 pendingDownloads.remove(pi.name);
211 }
212 }
213
214 /**
215 * Replies the plugin info with the name <code>name</code>. null, if no
216 * such plugin info exists.
217 *
218 * @param name the name. If null, replies null.
219 * @return the plugin info.
220 */
221 public PluginInformation getPluginInformation(String name) {
222 for (PluginInformation pi: availablePlugins) {
223 if (pi.getName() != null && pi.getName().equals(name))
224 return pi;
225 }
226 return null;
227 }
228
229 /**
230 * Initializes the model from preferences
231 */
232 public void initFromPreferences() {
233 Collection<String> enabledPlugins = Main.pref.getCollection("plugins", null);
234 if (enabledPlugins == null) {
235 this.selectedPluginsMap.clear();
236 return;
237 }
238 for (String name: enabledPlugins) {
239 PluginInformation pi = getPluginInformation(name);
240 if (pi == null) {
241 continue;
242 }
243 setPluginSelected(name, true);
244 }
245 }
246
247 /**
248 * Replies true if the plugin with name <code>name</code> is currently
249 * selected in the plugin model
250 *
251 * @param name the plugin name
252 * @return true if the plugin is selected; false, otherwise
253 */
254 public boolean isSelectedPlugin(String name) {
255 PluginInformation pi = getPluginInformation(name);
256 if (pi == null) return false;
257 if (selectedPluginsMap.get(pi) == null) return false;
258 return selectedPluginsMap.get(pi);
259 }
260
261 /**
262 * Replies the set of plugins which have been added by the user to
263 * the set of activated plugins.
264 *
265 * @return the set of newly deactivated plugins
266 */
267 public List<PluginInformation> getNewlyActivatedPlugins() {
268 List<PluginInformation> ret = new LinkedList<PluginInformation>();
269 for (Entry<PluginInformation, Boolean> entry: selectedPluginsMap.entrySet()) {
270 PluginInformation pi = entry.getKey();
271 boolean selected = entry.getValue();
272 if (selected && ! currentActivePlugins.contains(pi.name)) {
273 ret.add(pi);
274 }
275 }
276 return ret;
277 }
278
279 /**
280 * Replies the set of plugins which have been removed by the user from
281 * the set of activated plugins.
282 *
283 * @return the set of newly deactivated plugins
284 */
285 public List<PluginInformation> getNewlyDeactivatedPlugins() {
286 List<PluginInformation> ret = new LinkedList<PluginInformation>();
287 for (PluginInformation pi: availablePlugins) {
288 if (!currentActivePlugins.contains(pi.name)) {
289 continue;
290 }
291 if (selectedPluginsMap.get(pi) == null || ! selectedPluginsMap.get(pi)) {
292 ret.add(pi);
293 }
294 }
295 return ret;
296 }
297
298 /**
299 * Replies the set of all available plugins.
300 *
301 * @return the set of all available plugins
302 */
303 public List<PluginInformation> getAvailablePlugins() {
304 return new LinkedList<PluginInformation>(availablePlugins);
305 }
306
307 /**
308 * Replies the set of plugin names which have been added by the user to
309 * the set of activated plugins.
310 *
311 * @return the set of newly activated plugin names
312 */
313 public Set<String> getNewlyActivatedPluginNames() {
314 Set<String> ret = new HashSet<String>();
315 List<PluginInformation> plugins = getNewlyActivatedPlugins();
316 for (PluginInformation pi: plugins) {
317 ret.add(pi.name);
318 }
319 return ret;
320 }
321
322 /**
323 * Replies true if the set of active plugins has been changed by the user
324 * in this preference model. He has either added plugins or removed plugins
325 * being active before.
326 *
327 * @return true if the collection of active plugins has changed
328 */
329 public boolean isActivePluginsChanged() {
330 Set<String> newActivePlugins = getSelectedPluginNames();
331 return ! newActivePlugins.equals(currentActivePlugins);
332 }
333
334 /**
335 * Refreshes the local version field on the plugins in <code>plugins</code> with
336 * the version in the manifest of the downloaded "jar.new"-file for this plugin.
337 *
338 * @param plugins the collections of plugins to refresh
339 */
340 public void refreshLocalPluginVersion(Collection<PluginInformation> plugins) {
341 if (plugins == null) return;
342 for (PluginInformation pi : plugins) {
343 File downloadedPluginFile = PluginHandler.findUpdatedJar(pi.name);
344 if (downloadedPluginFile == null) {
345 continue;
346 }
347 try {
348 PluginInformation newinfo = new PluginInformation(downloadedPluginFile, pi.name);
349 PluginInformation oldinfo = getPluginInformation(pi.name);
350 if (oldinfo == null) {
351 // should not happen
352 continue;
353 }
354 oldinfo.updateLocalInfo(newinfo);
355 } catch(PluginException e) {
356 e.printStackTrace();
357 }
358 }
359 }
360}
Note: See TracBrowser for help on using the repository browser.