Changeset 15508 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java
r15121 r15508 56 56 import org.openstreetmap.josm.gui.widgets.FilterField; 57 57 import org.openstreetmap.josm.plugins.PluginDownloadTask; 58 import org.openstreetmap.josm.plugins.PluginHandler; 58 59 import org.openstreetmap.josm.plugins.PluginInformation; 59 60 import org.openstreetmap.josm.plugins.ReadLocalPluginInformationTask; … … 325 326 Collections.sort(l); 326 327 Config.getPref().putList("plugins", l); 327 if (!model.getNewlyDeactivatedPlugins().isEmpty()) 328 return true; 328 List<PluginInformation> deactivatedPlugins = model.getNewlyDeactivatedPlugins(); 329 if (!deactivatedPlugins.isEmpty()) { 330 boolean requiresRestart = PluginHandler.removePlugins(deactivatedPlugins); 331 if (requiresRestart) 332 return requiresRestart; 333 } 329 334 for (PluginInformation pi : model.getNewlyActivatedPlugins()) { 330 335 if (!pi.canloadatruntime) -
trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
r15505 r15508 69 69 import org.openstreetmap.josm.io.OnlineResource; 70 70 import org.openstreetmap.josm.spi.preferences.Config; 71 import org.openstreetmap.josm.tools.Destroyable; 71 72 import org.openstreetmap.josm.tools.GBC; 72 73 import org.openstreetmap.josm.tools.I18n; … … 1169 1170 tr("Update plugins") 1170 1171 ); 1171 1172 1172 try { 1173 1173 pluginDownloadTask.run(); … … 1333 1333 pluginsToLoad.stream().filter(x -> x.libraries.contains(oldPluginURL)).forEach( 1334 1334 x -> Collections.replaceAll(x.libraries, oldPluginURL, newPluginURL)); 1335 1336 // Attempt to update loaded plugin (must implement Destroyable) 1337 PluginInformation tInfo = pluginsToLoad.parallelStream() 1338 .filter(x -> x.libraries.contains(newPluginURL)).findAny().orElse(null); 1339 if (tInfo != null) { 1340 Object tUpdatedPlugin = getPlugin(tInfo.name); 1341 if (tUpdatedPlugin instanceof Destroyable) { 1342 ((Destroyable) tUpdatedPlugin).destroy(); 1343 PluginHandler.loadPlugins(getInfoPanel(), Collections.singleton(tInfo), 1344 NullProgressMonitor.INSTANCE); 1345 } 1346 } 1335 1347 } catch (MalformedURLException e) { 1336 1348 Logging.warn(e); … … 1644 1656 } 1645 1657 } 1658 1659 /** 1660 * Remove deactivated plugins, returning true if JOSM should restart 1661 * 1662 * @param deactivatedPlugins The plugins to deactivate 1663 * 1664 * @return true if there was a plugin that requires a restart 1665 * @since 15508 1666 */ 1667 public static boolean removePlugins(List<PluginInformation> deactivatedPlugins) { 1668 List<Destroyable> noRestart = deactivatedPlugins.parallelStream() 1669 .map(info -> PluginHandler.getPlugin(info.name)).filter(Destroyable.class::isInstance) 1670 .map(Destroyable.class::cast).collect(Collectors.toList()); 1671 boolean restartNeeded; 1672 try { 1673 noRestart.forEach(Destroyable::destroy); 1674 new ArrayList<>(pluginList).stream().filter(proxy -> noRestart.contains(proxy.getPlugin())) 1675 .forEach(pluginList::remove); 1676 restartNeeded = deactivatedPlugins.size() != noRestart.size(); 1677 } catch (Exception e) { 1678 Logging.error(e); 1679 restartNeeded = true; 1680 } 1681 return restartNeeded; 1682 } 1646 1683 } -
trunk/test/unit/org/openstreetmap/josm/plugins/PluginHandlerTestIT.java
r15242 r15508 8 8 import java.awt.GraphicsEnvironment; 9 9 import java.awt.HeadlessException; 10 import java.io.IOException; 11 import java.util.ArrayList; 10 12 import java.util.Arrays; 11 13 import java.util.Collection; … … 14 16 import java.util.List; 15 17 import java.util.Map; 18 import java.util.Map.Entry; 16 19 import java.util.Set; 17 20 import java.util.function.Consumer; … … 19 22 20 23 import org.apache.commons.lang3.exception.ExceptionUtils; 21 import org.junit.Rule; 24 import org.junit.BeforeClass; 25 import org.junit.ClassRule; 22 26 import org.junit.Test; 27 import org.openstreetmap.josm.TestUtils; 23 28 import org.openstreetmap.josm.data.Preferences; 24 29 import org.openstreetmap.josm.data.gpx.GpxData; … … 31 36 import org.openstreetmap.josm.spi.preferences.Config; 32 37 import org.openstreetmap.josm.testutils.JOSMTestRules; 38 import org.openstreetmap.josm.tools.Destroyable; 33 39 import org.openstreetmap.josm.tools.Utils; 34 40 … … 40 46 public class PluginHandlerTestIT { 41 47 48 private static List<String> errorsToIgnore = new ArrayList<>(); 42 49 /** 43 50 * Setup test. 44 51 */ 45 @Rule 52 @ClassRule 46 53 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") 47 public JOSMTestRules test = new JOSMTestRules().main().projection().preferences().https().timeout(10*60*1000); 54 public static JOSMTestRules test = new JOSMTestRules().main().projection().preferences().https() 55 .timeout(10 * 60 * 1000); 56 57 /** 58 * Setup test 59 * 60 * @throws IOException in case of I/O error 61 */ 62 @BeforeClass 63 public static void beforeClass() throws IOException { 64 errorsToIgnore.addAll(TestUtils.getIgnoredErrorMessages(PluginHandlerTestIT.class)); 65 } 48 66 49 67 /** … … 75 93 } 76 94 95 Map<String, Throwable> noRestartExceptions = new HashMap<>(); 96 testCompletelyRestartlessPlugins(loadedPlugins, noRestartExceptions); 97 77 98 debugPrint(invalidManifestEntries); 78 99 debugPrint(loadingExceptions); 79 100 debugPrint(layerExceptions); 101 debugPrint(noRestartExceptions); 102 103 invalidManifestEntries = filterKnownErrors(invalidManifestEntries); 104 loadingExceptions = filterKnownErrors(loadingExceptions); 105 layerExceptions = filterKnownErrors(layerExceptions); 106 noRestartExceptions = filterKnownErrors(noRestartExceptions); 107 80 108 String msg = Arrays.toString(invalidManifestEntries.entrySet().toArray()) + '\n' + 81 109 Arrays.toString(loadingExceptions.entrySet().toArray()) + '\n' + 82 Arrays.toString(layerExceptions.entrySet().toArray()); 110 Arrays.toString(layerExceptions.entrySet().toArray()) + '\n' 111 + Arrays.toString(noRestartExceptions.entrySet().toArray()); 83 112 assertTrue(msg, invalidManifestEntries.isEmpty() && loadingExceptions.isEmpty() && layerExceptions.isEmpty()); 113 } 114 115 private static void testCompletelyRestartlessPlugins(List<PluginInformation> loadedPlugins, 116 Map<String, Throwable> noRestartExceptions) { 117 try { 118 List<PluginInformation> restartable = loadedPlugins.parallelStream() 119 .filter(info -> PluginHandler.getPlugin(info.name) instanceof Destroyable) 120 .collect(Collectors.toList()); 121 // ensure good plugin behavior with regards to Destroyable (i.e., they can be 122 // removed and readded) 123 for (int i = 0; i < 2; i++) { 124 assertFalse(PluginHandler.removePlugins(restartable)); 125 assertTrue(restartable.stream().noneMatch(info -> PluginHandler.getPlugins().contains(info))); 126 loadPlugins(restartable); 127 } 128 129 assertTrue(PluginHandler.removePlugins(loadedPlugins)); 130 assertTrue(restartable.parallelStream().noneMatch(info -> PluginHandler.getPlugins().contains(info))); 131 } catch (Exception | LinkageError t) { 132 Throwable root = ExceptionUtils.getRootCause(t); 133 root.printStackTrace(); 134 noRestartExceptions.put(findFaultyPlugin(loadedPlugins, root), root); 135 } 136 } 137 138 private static <T> Map<String, T> filterKnownErrors(Map<String, T> errorMap) { 139 return errorMap.entrySet().parallelStream() 140 .filter(entry -> !errorsToIgnore.contains(convertEntryToString(entry))) 141 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); 84 142 } 85 143 … … 87 145 System.out.println(invalidManifestEntries.entrySet() 88 146 .stream() 89 .map(e -> e.getKey() + "=\"" + e.getValue() + "\"")147 .map(e -> convertEntryToString(e)) 90 148 .collect(Collectors.joining(", "))); 149 } 150 151 private static String convertEntryToString(Entry<String, ?> entry) { 152 return entry.getKey() + "=\"" + entry.getValue() + "\""; 91 153 } 92 154 … … 134 196 downloadPlugins(plugins); 135 197 198 loadPlugins(plugins); 199 } 200 201 static void loadPlugins(List<PluginInformation> plugins) { 136 202 // Load early plugins 137 203 PluginHandler.loadEarlyPlugins(null, plugins, null);
Note:
See TracChangeset
for help on using the changeset viewer.