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

Last change on this file was 18801, checked in by taylor.smock, 9 months ago

Fix #22832: Code cleanup and some simplification, documentation fixes (patch by gaben)

There should not be any functional changes in this patch; it is intended to do
the following:

  • Simplify and cleanup code (example: Arrays.asList(item) -> Collections.singletonList(item))
  • Fix typos in documentation (which also corrects the documentation to match what actually happens, in some cases)
  • 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 -> Boolean.TRUE.equals(selectedPluginsMap.get(pi)))
143 .collect(Collectors.toList());
144 }
145
146 /**
147 * Replies the set of selected plugin information objects
148 *
149 * @return the set of selected plugin information objects
150 */
151 public Set<String> getSelectedPluginNames() {
152 return getSelectedPlugins().stream().map(pi -> pi.name).collect(Collectors.toSet());
153 }
154
155 /**
156 * Sorts the list of available plugins
157 */
158 protected void sort() {
159 availablePlugins.sort(Comparator.comparing(
160 o -> o.getName() == null ? "" : o.getName().toLowerCase(Locale.ENGLISH)));
161 }
162
163 /**
164 * Replies the list of plugin information to display.
165 *
166 * @return the list of plugin information to display
167 */
168 public List<PluginInformation> getDisplayedPlugins() {
169 return displayedPlugins;
170 }
171
172 /**
173 * Replies the set of plugins waiting for update or download.
174 *
175 * @return the set of plugins waiting for update or download
176 */
177 public Set<PluginInformation> getPluginsScheduledForUpdateOrDownload() {
178 return pendingDownloads.stream()
179 .map(this::getPluginInformation)
180 .filter(Objects::nonNull)
181 .collect(Collectors.toSet());
182 }
183
184 /**
185 * Sets whether the plugin is selected or not.
186 *
187 * @param name the name of the plugin
188 * @param selected true, if selected; false, otherwise
189 */
190 public void setPluginSelected(String name, boolean selected) {
191 PluginInformation pi = getPluginInformation(name);
192 if (pi != null) {
193 selectedPluginsMap.put(pi, selected);
194 if (pi.isUpdateRequired()) {
195 pendingDownloads.add(pi.name);
196 }
197 }
198 if (!selected) {
199 pendingDownloads.remove(name);
200 }
201 }
202
203 /**
204 * Removes all the plugin in {@code plugins} from the list of plugins
205 * with a pending download
206 *
207 * @param plugins the list of plugins to clear for a pending download
208 */
209 public void clearPendingPlugins(Collection<PluginInformation> plugins) {
210 if (plugins != null) {
211 for (PluginInformation pi: plugins) {
212 pendingDownloads.remove(pi.name);
213 }
214 }
215 }
216
217 /**
218 * Replies the plugin info with the name <code>name</code>. null, if no
219 * such plugin info exists.
220 *
221 * @param name the name. If null, replies null.
222 * @return the plugin info.
223 */
224 public PluginInformation getPluginInformation(String name) {
225 if (name != null) {
226 return availablePlugins.stream()
227 .filter(pi -> name.equals(pi.getName()) || name.equals(pi.provides))
228 .findFirst().orElse(null);
229 }
230 return null;
231 }
232
233 /**
234 * Initializes the model from preferences
235 */
236 public void initFromPreferences() {
237 Collection<String> enabledPlugins = Config.getPref().getList("plugins", null);
238 if (enabledPlugins == null) {
239 this.selectedPluginsMap.clear();
240 return;
241 }
242 for (String name: enabledPlugins) {
243 PluginInformation pi = getPluginInformation(name);
244 if (pi == null) {
245 continue;
246 }
247 setPluginSelected(name, true);
248 }
249 }
250
251 /**
252 * Replies true if the plugin with name <code>name</code> is currently
253 * selected in the plugin model
254 *
255 * @param name the plugin name
256 * @return true if the plugin is selected; false, otherwise
257 */
258 public boolean isSelectedPlugin(String name) {
259 PluginInformation pi = getPluginInformation(name);
260 if (pi == null || selectedPluginsMap.get(pi) == null)
261 return false;
262 return selectedPluginsMap.get(pi);
263 }
264
265 /**
266 * Replies the list of plugins which have been added by the user to
267 * the set of activated plugins.
268 *
269 * @return the list of newly activated plugins
270 */
271 public List<PluginInformation> getNewlyActivatedPlugins() {
272 List<PluginInformation> ret = new LinkedList<>();
273 for (Entry<PluginInformation, Boolean> entry: selectedPluginsMap.entrySet()) {
274 PluginInformation pi = entry.getKey();
275 boolean selected = entry.getValue();
276 if (selected && !currentActivePlugins.contains(pi.name)) {
277 ret.add(pi);
278 }
279 }
280 return ret;
281 }
282
283 /**
284 * Replies the list of plugins which have been removed by the user from
285 * the set of deactivated plugins.
286 *
287 * @return the list of newly deactivated plugins
288 */
289 public List<PluginInformation> getNewlyDeactivatedPlugins() {
290 return availablePlugins.stream()
291 .filter(pi -> currentActivePlugins.contains(pi.name))
292 .filter(pi -> selectedPluginsMap.get(pi) == null || !selectedPluginsMap.get(pi))
293 .collect(Collectors.toList());
294 }
295
296 /**
297 * Replies the list of all available plugins.
298 *
299 * @return the list of all available plugins
300 */
301 public List<PluginInformation> getAvailablePlugins() {
302 return new LinkedList<>(availablePlugins);
303 }
304
305 /**
306 * Replies the set of plugin names which have been added by the user to
307 * the set of activated plugins.
308 *
309 * @return the set of newly activated plugin names
310 */
311 public Set<String> getNewlyActivatedPluginNames() {
312 return getNewlyActivatedPlugins().stream().map(pi -> pi.name).collect(Collectors.toSet());
313 }
314
315 /**
316 * Replies true if the set of active plugins has been changed by the user
317 * in this preference model. He has either added plugins or removed plugins
318 * being active before.
319 *
320 * @return true if the collection of active plugins has changed
321 */
322 public boolean isActivePluginsChanged() {
323 Set<String> newActivePlugins = getSelectedPluginNames();
324 return !newActivePlugins.equals(currentActivePlugins);
325 }
326
327 /**
328 * Refreshes the local version field on the plugins in <code>plugins</code> with
329 * the version in the manifest of the downloaded "jar.new"-file for this plugin.
330 *
331 * @param plugins the collections of plugins to refresh
332 */
333 public void refreshLocalPluginVersion(Collection<PluginInformation> plugins) {
334 if (plugins != null) {
335 for (PluginInformation pi : plugins) {
336 File downloadedPluginFile = PluginHandler.findUpdatedJar(pi.name);
337 if (downloadedPluginFile == null) {
338 continue;
339 }
340 try {
341 PluginInformation newinfo = new PluginInformation(downloadedPluginFile, pi.name);
342 PluginInformation oldinfo = getPluginInformation(pi.name);
343 if (oldinfo != null) {
344 oldinfo.updateFromJar(newinfo);
345 }
346 } catch (PluginException e) {
347 Logging.error(e);
348 }
349 }
350 }
351 }
352}
Note: See TracBrowser for help on using the repository browser.