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

Last change on this file since 16438 was 16438, checked in by simon04, 4 years ago

see #19251 - Java 8: use Stream

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