Changeset 14139 in josm


Ignore:
Timestamp:
2018-08-12T02:52:44+02:00 (8 months ago)
Author:
Don-vip
Message:

see #15229 - move Main initialization methods to lifecycle SPI + new class MainInitialization

Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/Main.java

    r14138 r14139  
    1010import java.util.Collection;
    1111import java.util.Collections;
    12 import java.util.List;
    1312import java.util.Map;
    1413import java.util.Set;
    15 import java.util.concurrent.Callable;
    16 import java.util.concurrent.ExecutionException;
    17 import java.util.concurrent.ExecutorService;
    18 import java.util.concurrent.Executors;
    19 import java.util.concurrent.Future;
    2014
    2115import org.openstreetmap.josm.data.Preferences;
     
    3529import org.openstreetmap.josm.io.NetworkManager;
    3630import org.openstreetmap.josm.io.OnlineResource;
    37 import org.openstreetmap.josm.spi.lifecycle.InitializationTask;
    3831import org.openstreetmap.josm.spi.preferences.Config;
    3932import org.openstreetmap.josm.spi.preferences.IUrls;
    4033import org.openstreetmap.josm.tools.ImageProvider;
    41 import org.openstreetmap.josm.tools.JosmRuntimeException;
    4234import org.openstreetmap.josm.tools.Logging;
    4335import org.openstreetmap.josm.tools.PlatformHook;
    4436import org.openstreetmap.josm.tools.PlatformManager;
    45 import org.openstreetmap.josm.tools.Utils;
    46 import org.openstreetmap.josm.tools.bugreport.BugReport;
    4737
    4838/**
     
    9383    /**
    9484     * Constructs new {@code Main} object.
    95      * @see #initialize()
    9685     */
    9786    protected Main() {
     
    10190    private static void setInstance(Main instance) {
    10291        main = instance;
    103     }
    104 
    105     /**
    106      * Initializes the main object. A lot of global variables are initialized here.
    107      * @since 10340
    108      */
    109     public void initialize() {
    110         // Initializes tasks that must be run before parallel tasks
    111         runInitializationTasks(beforeInitializationTasks());
    112 
    113         // Initializes tasks to be executed (in parallel) by a ExecutorService
    114         try {
    115             ExecutorService service = Executors.newFixedThreadPool(
    116                     Runtime.getRuntime().availableProcessors(), Utils.newThreadFactory("main-init-%d", Thread.NORM_PRIORITY));
    117             for (Future<Void> i : service.invokeAll(parallelInitializationTasks())) {
    118                 i.get();
    119             }
    120             // asynchronous initializations to be completed eventually
    121             asynchronousRunnableTasks().forEach(service::submit);
    122             asynchronousCallableTasks().forEach(service::submit);
    123             try {
    124                 service.shutdown();
    125             } catch (SecurityException e) {
    126                 Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown executor service", e);
    127             }
    128         } catch (InterruptedException | ExecutionException ex) {
    129             throw new JosmRuntimeException(ex);
    130         }
    131 
    132         // Initializes tasks that must be run after parallel tasks
    133         runInitializationTasks(afterInitializationTasks());
    134     }
    135 
    136     private static void runInitializationTasks(List<InitializationTask> tasks) {
    137         for (InitializationTask task : tasks) {
    138             try {
    139                 task.call();
    140             } catch (JosmRuntimeException e) {
    141                 // Can happen if the current projection needs NTV2 grid which is not available
    142                 // In this case we want the user be able to change his projection
    143                 BugReport.intercept(e).warn();
    144             }
    145         }
    146     }
    147 
    148     /**
    149      * Returns tasks that must be run before parallel tasks.
    150      * @return tasks that must be run before parallel tasks
    151      * @see #afterInitializationTasks
    152      * @see #parallelInitializationTasks
    153      */
    154     protected List<InitializationTask> beforeInitializationTasks() {
    155         return Collections.emptyList();
    156     }
    157 
    158     /**
    159      * Returns tasks to be executed (in parallel) by a ExecutorService.
    160      * @return tasks to be executed (in parallel) by a ExecutorService
    161      */
    162     protected Collection<InitializationTask> parallelInitializationTasks() {
    163         return Collections.emptyList();
    164     }
    165 
    166     /**
    167      * Returns asynchronous callable initializations to be completed eventually
    168      * @return asynchronous callable initializations to be completed eventually
    169      */
    170     protected List<Callable<?>> asynchronousCallableTasks() {
    171         return Collections.emptyList();
    172     }
    173 
    174     /**
    175      * Returns asynchronous runnable initializations to be completed eventually
    176      * @return asynchronous runnable initializations to be completed eventually
    177      */
    178     protected List<Runnable> asynchronousRunnableTasks() {
    179         return Collections.emptyList();
    180     }
    181 
    182     /**
    183      * Returns tasks that must be run after parallel tasks.
    184      * @return tasks that must be run after parallel tasks
    185      * @see #beforeInitializationTasks
    186      * @see #parallelInitializationTasks
    187      */
    188     protected List<InitializationTask> afterInitializationTasks() {
    189         return Collections.emptyList();
    19092    }
    19193
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r14138 r14139  
    66import static org.openstreetmap.josm.tools.Utils.getSystemProperty;
    77
    8 import java.awt.BorderLayout;
    98import java.awt.Container;
    109import java.awt.Dimension;
     
    1312import java.awt.GridBagLayout;
    1413import java.awt.Toolkit;
    15 import java.awt.event.KeyEvent;
    1614import java.io.File;
    1715import java.io.IOException;
     
    4644import java.util.Set;
    4745import java.util.TreeSet;
    48 import java.util.concurrent.Callable;
    4946import java.util.concurrent.ExecutorService;
    5047import java.util.concurrent.Executors;
     
    6966
    7067import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
    71 import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
    7268import org.openstreetmap.josm.Main;
    7369import org.openstreetmap.josm.actions.DeleteAction;
     
    108104import org.openstreetmap.josm.data.projection.datum.NTV2GridShiftFileWrapper;
    109105import org.openstreetmap.josm.data.projection.datum.NTV2Proj4DirGridShiftFileSource;
    110 import org.openstreetmap.josm.data.validation.OsmValidator;
    111106import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker;
    112107import org.openstreetmap.josm.gui.ProgramArguments.Option;
     
    118113import org.openstreetmap.josm.gui.io.SaveLayersDialog;
    119114import org.openstreetmap.josm.gui.layer.AutosaveTask;
    120 import org.openstreetmap.josm.gui.layer.ImageryLayer;
    121115import org.openstreetmap.josm.gui.layer.Layer;
    122116import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
     
    126120import org.openstreetmap.josm.gui.layer.MainLayerManager;
    127121import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    128 import org.openstreetmap.josm.gui.layer.TMSLayer;
    129122import org.openstreetmap.josm.gui.mappaint.RenderingCLI;
    130123import org.openstreetmap.josm.gui.mappaint.loader.MapPaintStyleLoader;
     
    132125import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
    133126import org.openstreetmap.josm.gui.preferences.display.LafPreference;
    134 import org.openstreetmap.josm.gui.preferences.imagery.ImageryPreference;
    135 import org.openstreetmap.josm.gui.preferences.map.MapPaintPreference;
    136127import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
    137128import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
    138129import org.openstreetmap.josm.gui.progress.swing.ProgressMonitorExecutor;
    139 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
    140130import org.openstreetmap.josm.gui.util.GuiHelper;
    141131import org.openstreetmap.josm.gui.util.RedirectInputMap;
     
    149139import org.openstreetmap.josm.io.NetworkManager;
    150140import org.openstreetmap.josm.io.OnlineResource;
    151 import org.openstreetmap.josm.io.OsmApi;
    152 import org.openstreetmap.josm.io.OsmApiInitializationException;
    153141import org.openstreetmap.josm.io.OsmConnection;
    154 import org.openstreetmap.josm.io.OsmTransferCanceledException;
    155142import org.openstreetmap.josm.io.OsmTransferException;
    156143import org.openstreetmap.josm.io.auth.AbstractCredentialsAgent;
     
    162149import org.openstreetmap.josm.plugins.PluginInformation;
    163150import org.openstreetmap.josm.spi.lifecycle.InitStatusListener;
    164 import org.openstreetmap.josm.spi.lifecycle.InitializationTask;
    165151import org.openstreetmap.josm.spi.lifecycle.Lifecycle;
    166152import org.openstreetmap.josm.spi.preferences.Config;
     
    173159import org.openstreetmap.josm.tools.JosmRuntimeException;
    174160import org.openstreetmap.josm.tools.Logging;
    175 import org.openstreetmap.josm.tools.OpenBrowser;
    176161import org.openstreetmap.josm.tools.OsmUrlToBounds;
    177 import org.openstreetmap.josm.tools.OverpassTurboQueryWizard;
    178162import org.openstreetmap.josm.tools.PlatformHook.NativeOsCallback;
    179163import org.openstreetmap.josm.tools.PlatformHookWindows;
    180164import org.openstreetmap.josm.tools.PlatformManager;
    181 import org.openstreetmap.josm.tools.RightAndLefthandTraffic;
    182165import org.openstreetmap.josm.tools.Shortcut;
    183 import org.openstreetmap.josm.tools.Territories;
    184166import org.openstreetmap.josm.tools.Utils;
    185167import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
     
    312294     * Listener that sets the enabled state of undo/redo menu entries.
    313295     */
    314     private final CommandQueueListener redoUndoListener = (queueSize, redoSize) -> {
     296    final CommandQueueListener redoUndoListener = (queueSize, redoSize) -> {
    315297            menu.undo.setEnabled(queueSize > 0);
    316298            menu.redo.setEnabled(redoSize > 0);
     
    407389            }
    408390        }
    409     }
    410 
    411     @Override
    412     protected List<InitializationTask> beforeInitializationTasks() {
    413         return Arrays.asList(
    414             new InitializationTask(tr("Starting file watcher"), FileWatcher.getDefaultInstance()::start),
    415             new InitializationTask(tr("Executing platform startup hook"),
    416                     () -> PlatformManager.getPlatform().startupHook(MainApplication::askUpdateJava)),
    417             new InitializationTask(tr("Building main menu"), this::initializeMainWindow),
    418             new InitializationTask(tr("Updating user interface"), () -> {
    419                 UndoRedoHandler.getInstance().addCommandQueueListener(redoUndoListener);
    420                 // creating toolbar
    421                 GuiHelper.runInEDTAndWait(() -> contentPanePrivate.add(toolbar.control, BorderLayout.NORTH));
    422                 // help shortcut
    423                 registerActionShortcut(menu.help, Shortcut.registerShortcut("system:help", tr("Help"),
    424                         KeyEvent.VK_F1, Shortcut.DIRECT));
    425             }),
    426             // This needs to be done before RightAndLefthandTraffic::initialize is called
    427             new InitializationTask(tr("Initializing internal boundaries data"), Territories::initialize)
    428         );
    429     }
    430 
    431     @Override
    432     protected Collection<InitializationTask> parallelInitializationTasks() {
    433         return Arrays.asList(
    434             new InitializationTask(tr("Initializing OSM API"), () -> {
    435                     OsmApi.addOsmApiInitializationListener(api -> {
    436                         // This checks if there are any layers currently displayed that are now on the blacklist, and removes them.
    437                         // This is a rare situation - probably only occurs if the user changes the API URL in the preferences menu.
    438                         // Otherwise they would not have been able to load the layers in the first place because they would have been disabled
    439                         if (isDisplayingMapView()) {
    440                             for (Layer l : getLayerManager().getLayersOfType(ImageryLayer.class)) {
    441                                 if (((ImageryLayer) l).getInfo().isBlacklisted()) {
    442                                     Logging.info(tr("Removed layer {0} because it is not allowed by the configured API.", l.getName()));
    443                                     getLayerManager().removeLayer(l);
    444                                 }
    445                             }
    446                         }
    447                     });
    448                     // We try to establish an API connection early, so that any API
    449                     // capabilities are already known to the editor instance. However
    450                     // if it goes wrong that's not critical at this stage.
    451                     try {
    452                         OsmApi.getOsmApi().initialize(null, true);
    453                     } catch (OsmTransferCanceledException | OsmApiInitializationException | SecurityException e) {
    454                         Logging.warn(Logging.getErrorMessage(Utils.getRootCause(e)));
    455                     }
    456                 }),
    457             new InitializationTask(tr("Initializing internal traffic data"), RightAndLefthandTraffic::initialize),
    458             new InitializationTask(tr("Initializing validator"), OsmValidator::initialize),
    459             new InitializationTask(tr("Initializing presets"), TaggingPresets::initialize),
    460             new InitializationTask(tr("Initializing map styles"), MapPaintPreference::initialize),
    461             new InitializationTask(tr("Loading imagery preferences"), ImageryPreference::initialize)
    462         );
    463     }
    464 
    465     @Override
    466     protected List<Callable<?>> asynchronousCallableTasks() {
    467         return Arrays.asList(
    468                 OverpassTurboQueryWizard::getInstance
    469             );
    470     }
    471 
    472     @Override
    473     protected List<Runnable> asynchronousRunnableTasks() {
    474         return Arrays.asList(
    475                 TMSLayer::getCache,
    476                 OsmValidator::initializeTests
    477             );
    478     }
    479 
    480     @Override
    481     protected List<InitializationTask> afterInitializationTasks() {
    482         return Arrays.asList(
    483             new InitializationTask(tr("Updating user interface"), () -> GuiHelper.runInEDTAndWait(() -> {
    484                 // hooks for the jmapviewer component
    485                 FeatureAdapter.registerBrowserAdapter(OpenBrowser::displayUrl);
    486                 FeatureAdapter.registerTranslationAdapter(I18n::tr);
    487                 FeatureAdapter.registerLoggingAdapter(name -> Logging.getLogger());
    488                 // UI update
    489                 toolbar.refreshToolbarControl();
    490                 toolbar.control.updateUI();
    491                 contentPanePrivate.updateUI();
    492             }))
    493         );
    494391    }
    495392
     
    1086983
    1087984        monitor.indeterminateSubTask(tr("Creating main GUI"));
    1088         final Main main = new MainApplication(mainFrame);
    1089         main.initialize();
     985        Lifecycle.initialize(new MainInitialization(new MainApplication(mainFrame)));
    1090986
    1091987        if (!skipLoadingPlugins) {
  • trunk/src/org/openstreetmap/josm/spi/lifecycle/Lifecycle.java

    r14131 r14139  
    22package org.openstreetmap.josm.spi.lifecycle;
    33
     4import java.util.List;
    45import java.util.Objects;
     6import java.util.concurrent.ExecutionException;
     7import java.util.concurrent.ExecutorService;
     8import java.util.concurrent.Executors;
     9import java.util.concurrent.Future;
     10
     11import org.openstreetmap.josm.tools.Logging;
     12import org.openstreetmap.josm.tools.Utils;
     13import org.openstreetmap.josm.tools.bugreport.BugReport;
    514
    615/**
     
    3140        initStatusListener = Objects.requireNonNull(listener);
    3241    }
     42
     43    /**
     44     * Initializes the main object. A lot of global variables are initialized here.
     45     * @param initSequence Initialization sequence
     46     * @since 14139
     47     */
     48    public static void initialize(InitializationSequence initSequence) {
     49        // Initializes tasks that must be run before parallel tasks
     50        runInitializationTasks(initSequence.beforeInitializationTasks());
     51
     52        // Initializes tasks to be executed (in parallel) by a ExecutorService
     53        try {
     54            ExecutorService service = Executors.newFixedThreadPool(
     55                    Runtime.getRuntime().availableProcessors(), Utils.newThreadFactory("main-init-%d", Thread.NORM_PRIORITY));
     56            for (Future<Void> i : service.invokeAll(initSequence.parallelInitializationTasks())) {
     57                i.get();
     58            }
     59            // asynchronous initializations to be completed eventually
     60            initSequence.asynchronousRunnableTasks().forEach(service::submit);
     61            initSequence.asynchronousCallableTasks().forEach(service::submit);
     62            try {
     63                service.shutdown();
     64            } catch (SecurityException e) {
     65                Logging.log(Logging.LEVEL_ERROR, "Unable to shutdown executor service", e);
     66            }
     67        } catch (InterruptedException | ExecutionException ex) {
     68            throw new RuntimeException(ex);
     69        }
     70
     71        // Initializes tasks that must be run after parallel tasks
     72        runInitializationTasks(initSequence.afterInitializationTasks());
     73    }
     74
     75    private static void runInitializationTasks(List<InitializationTask> tasks) {
     76        for (InitializationTask task : tasks) {
     77            try {
     78                task.call();
     79            } catch (RuntimeException e) {
     80                // Can happen if the current projection needs NTV2 grid which is not available
     81                // In this case we want the user be able to change his projection
     82                BugReport.intercept(e).warn();
     83            }
     84        }
     85    }
    3386}
  • trunk/test/unit/org/openstreetmap/josm/JOSMFixture.java

    r14138 r14139  
    2222import org.openstreetmap.josm.gui.MainApplication;
    2323import org.openstreetmap.josm.gui.MainApplicationTest;
     24import org.openstreetmap.josm.gui.MainInitialization;
    2425import org.openstreetmap.josm.gui.layer.LayerManagerTest.TestLayer;
    2526import org.openstreetmap.josm.gui.util.GuiHelper;
    2627import org.openstreetmap.josm.io.CertificateAmendment;
    2728import org.openstreetmap.josm.io.OsmApi;
     29import org.openstreetmap.josm.spi.lifecycle.Lifecycle;
    2830import org.openstreetmap.josm.spi.preferences.Config;
    2931import org.openstreetmap.josm.testutils.JOSMTestRules;
     
    161163        initToolbar();
    162164        if (Main.main == null) {
    163             new MainApplication().initialize();
     165            Lifecycle.initialize(new MainInitialization(new MainApplication()));
    164166        }
    165167        // Add a test layer to the layer manager to get the MapFrame
Note: See TracChangeset for help on using the changeset viewer.