Ignore:
Timestamp:
2017-09-11T20:43:41+02:00 (2 years ago)
Author:
Don-vip
Message:

see #15229 - see #15182 - make FileWatcher generic so it has no more dependence on MapCSS

File:
1 edited

Legend:

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

    r12814 r12825  
    1212import java.nio.file.WatchKey;
    1313import java.nio.file.WatchService;
    14 import java.util.Collections;
     14import java.util.EnumMap;
    1515import java.util.HashMap;
    1616import java.util.Map;
    17 import java.util.concurrent.Executors;
     17import java.util.Objects;
     18import java.util.function.Consumer;
    1819
    1920import org.openstreetmap.josm.data.preferences.sources.SourceEntry;
    20 import org.openstreetmap.josm.data.validation.OsmValidator;
    21 import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker;
     21import org.openstreetmap.josm.data.preferences.sources.SourceType;
    2222import org.openstreetmap.josm.gui.mappaint.StyleSource;
    23 import org.openstreetmap.josm.gui.mappaint.loader.MapPaintStyleLoader;
    24 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
    2523import org.openstreetmap.josm.tools.CheckParameterUtil;
    2624import org.openstreetmap.josm.tools.Logging;
    27 import org.openstreetmap.josm.tools.Utils;
    2825
    2926/**
     
    3633    private Thread thread;
    3734
    38     private final Map<Path, StyleSource> styleMap = new HashMap<>();
    39     private final Map<Path, SourceEntry> ruleMap = new HashMap<>();
     35    private static final Map<SourceType, Consumer<SourceEntry>> loaderMap = new EnumMap<>(SourceType.class);
     36    private final Map<Path, SourceEntry> sourceMap = new HashMap<>();
    4037
    4138    /**
     
    6663     * @throws IllegalStateException if the watcher service failed to start
    6764     * @throws IOException if an I/O error occurs
     65     * @deprecated To be removed end of 2017. Use {@link #registerSource} instead
    6866     */
     67    @Deprecated
    6968    public void registerStyleSource(StyleSource style) throws IOException {
    70         register(style, styleMap);
     69        registerSource(style);
    7170    }
    7271
     
    7877     * @throws IOException if an I/O error occurs
    7978     * @since 7276
     79     * @deprecated To be removed end of 2017. Use {@link #registerSource} instead
    8080     */
     81    @Deprecated
    8182    public void registerValidatorRule(SourceEntry rule) throws IOException {
    82         register(rule, ruleMap);
     83        registerSource(rule);
    8384    }
    8485
    85     private <T extends SourceEntry> void register(T obj, Map<Path, T> map) throws IOException {
    86         CheckParameterUtil.ensureParameterNotNull(obj, "obj");
     86    /**
     87     * Registers a source for local file changes, allowing dynamic reloading.
     88     * @param src The source to watch
     89     * @throws IllegalArgumentException if {@code rule} is null or if it does not provide a local file
     90     * @throws IllegalStateException if the watcher service failed to start
     91     * @throws IOException if an I/O error occurs
     92     * @since 12825
     93     */
     94    public void registerSource(SourceEntry src) throws IOException {
     95        CheckParameterUtil.ensureParameterNotNull(src, "src");
    8796        if (watcher == null) {
    8897            throw new IllegalStateException("File watcher is not available");
    8998        }
    9099        // Get local file, as this method is only called for local style sources
    91         File file = new File(obj.url);
     100        File file = new File(src.url);
    92101        // Get parent directory as WatchService allows only to monitor directories, not single files
    93102        File dir = file.getParentFile();
    94103        if (dir == null) {
    95             throw new IllegalArgumentException("Resource "+obj+" does not have a parent directory");
     104            throw new IllegalArgumentException("Resource "+src+" does not have a parent directory");
    96105        }
    97106        synchronized (this) {
     
    99108            // (it returns the same key so it should not send events several times)
    100109            dir.toPath().register(watcher, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
    101             map.put(file.toPath(), obj);
     110            sourceMap.put(file.toPath(), src);
    102111        }
     112    }
     113
     114    /**
     115     * Registers a source loader, allowing dynamic reloading when an entry changes.
     116     * @param type the source type for which the loader operates
     117     * @param loader the loader in charge of reloading any source of given type when it changes
     118     * @return the previous loader registered for this source type, if any
     119     * @since 12825
     120     */
     121    public static Consumer<SourceEntry> registerLoader(SourceType type, Consumer<SourceEntry> loader) {
     122        return loaderMap.put(Objects.requireNonNull(type, "type"), Objects.requireNonNull(loader, "loader"));
    103123    }
    104124
     
    148168
    149169                synchronized (this) {
    150                     StyleSource style = styleMap.get(fullPath);
    151                     SourceEntry rule = ruleMap.get(fullPath);
    152                     if (style != null) {
    153                         Logging.info("Map style "+style.getDisplayString()+" has been modified. Reloading style...");
    154                         Executors.newSingleThreadExecutor(Utils.newThreadFactory("mapstyle-reload-%d", Thread.NORM_PRIORITY)).submit(
    155                                 new MapPaintStyleLoader(Collections.singleton(style)));
    156                     } else if (rule != null) {
    157                         Logging.info("Validator rule "+rule.getDisplayString()+" has been modified. Reloading rule...");
    158                         MapCSSTagChecker tagChecker = OsmValidator.getTest(MapCSSTagChecker.class);
    159                         if (tagChecker != null) {
    160                             try {
    161                                 tagChecker.addMapCSS(rule.url);
    162                             } catch (IOException | ParseException e) {
    163                                 Logging.warn(e);
    164                             }
     170                    SourceEntry source = sourceMap.get(fullPath);
     171                    if (source != null) {
     172                        Consumer<SourceEntry> loader = loaderMap.get(source.type);
     173                        if (loader != null) {
     174                            Logging.info("Source "+source.getDisplayString()+" has been modified. Reloading it...");
     175                            loader.accept(source);
     176                        } else {
     177                            Logging.warn("Received {0} event for unregistered source type: {1}", kind.name(), source.type);
    165178                        }
    166179                    } else if (Logging.isDebugEnabled()) {
Note: See TracChangeset for help on using the changeset viewer.