All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.diirt.datasource.file.FileWatcherPollingService Maven / Gradle / Ivy

There is a newer version: 3.1.7
Show newest version
/**
 * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
 * All rights reserved. Use is subject to license terms. See LICENSE.TXT
 */
package org.diirt.datasource.file;

import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author carcassi
 */
public class FileWatcherPollingService implements FileWatcherService {
    
    private static final Logger log = Logger.getLogger(FileWatcherService.class.getName());

    private final Object lock = new Object();
    private final ScheduledExecutorService exec;
    private final Runnable scanTask = new Runnable() {

        @Override
        public void run() {
            scan();
        }
    };
    private final List registrations = new ArrayList<>();

    public FileWatcherPollingService(ScheduledExecutorService exec, Duration scanRate) {
        this.exec = exec;
        exec.scheduleWithFixedDelay(scanTask, 0, scanRate.toNanos(), TimeUnit.NANOSECONDS);
    }

    @Override
    public void addWatcher(File file, Runnable callback) {
        synchronized(lock) {
            try {
                registrations.add(new Registration(file, callback));
            } catch (IOException ex) {
                log.log(Level.WARNING, "Notifications won't be enable for file " + file, ex);
            }
        }
    }

    @Override
    public void removeWatcher(File file, Runnable callback) {
        synchronized(lock) {
            Registration toClose = null;
            for (Registration registration : registrations) {
                if (registration.file.equals(file) && registration.callback.equals(callback)) {
                    toClose = registration;
                }
            }
            registrations.remove(toClose);
        }
    }
    
    public void scan() {
        synchronized(lock) {
            for (Registration registration : registrations) {
                registration.notifyChanges();
            }
        }
    }
    
    private class Registration {
        final File file;
        final Runnable callback;
        Long previousTime;

        Registration(File file, Runnable callback) throws IOException {
            this.file = file;
            this.callback = callback;
        }
        
        void notifyChanges() {
            long latestTime = file.lastModified();
            if ((previousTime == null) || (latestTime != previousTime)) {
                previousTime = latestTime;
                try {
                    callback.run();
                } catch(RuntimeException ex) {
                    // Protecting from callback errors
                    log.log(Level.WARNING, "Exception on the file watcher callback", ex);
                }
            }
        }
        
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy