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

com.github.henkexbg.gallery.service.impl.GalleryRootDirConfigJob Maven / Gradle / Ivy

Go to download

There is a newer version: 1.1.1
Show newest version
/**
 * Copyright (c) 2016 Henrik Bjerne
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:The above copyright
 * notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 */
package com.github.henkexbg.gallery.service.impl;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;

import static java.nio.file.StandardWatchEventKinds.*;

import java.nio.file.ClosedWatchServiceException;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.henkexbg.gallery.service.GalleryRootDirChangeListener;
import com.github.henkexbg.gallery.bean.GalleryRootDir;

/**
 * Job rather than a service. It listens continuously to changes to the given
 * config file. Any time a change is noticed, the file is parsed, and the new
 * root dirs are loaded. All listeners are then notified.
 * 
 * @author Henrik Bjerne
 *
 */
public class GalleryRootDirConfigJob {

    private final Logger LOG = LoggerFactory.getLogger(getClass());

    private Collection rootDirs = new ArrayList<>();

    private File configFile;

    private WatchService watcher;

    private Collection galleryRootDirChangeListeners;

    @PostConstruct
    public void setUp() throws IOException {
        watcher = FileSystems.getDefault().newWatchService();
        // Initial loading
        updateConfigFromFile();

        // Kick of watcher thread
        Runnable fileWatcher = () -> {
            watchForChanges();
        };
        new Thread(fileWatcher).start();
        ;
    }

    @PreDestroy
    public void shutdown() {
        try {
            watcher.close();
        } catch (IOException ioe) {
            LOG.info("Exception while closing watcher", ioe);
        }
    }

    public void setConfigFile(File configFile) {
        this.configFile = configFile;
    }

    public void setGalleryRootDirChangeListeners(Collection galleryRootDirChangeListeners) {
        this.galleryRootDirChangeListeners = galleryRootDirChangeListeners;
    }

    private void updateConfigFromFile() throws IOException {
        LOG.debug("Entering updateConfigFromFile()");
        Collection newRootDirs = new ArrayList<>();
        Properties prop = new Properties();
        prop.load(new FileReader(configFile));
        prop.forEach((k, v) -> {
            String[] split = ((String) k).split("\\.");
            if (split.length == 2) {
                GalleryRootDir oneRootDir = new GalleryRootDir();
                newRootDirs.add(oneRootDir);
                oneRootDir.setRole(split[0]);
                oneRootDir.setName(split[1]);
                oneRootDir.setDir(new File(v.toString()));
            }
        });
        rootDirs = newRootDirs;
        galleryRootDirChangeListeners.forEach(r -> r.setRootDirs(rootDirs));
    }

    private void watchForChanges() {
        Path dir = configFile.getParentFile().toPath();
        try {
            WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
            for (;;) {
                try {
                    key = watcher.take();
                } catch (InterruptedException | ClosedWatchServiceException e) {
                    LOG.info("Interrupted during watcher.take(). Exiting watch loop.");
                    return;
                }
                for (WatchEvent event : key.pollEvents()) {
                    WatchEvent.Kind kind = event.kind();
                    if (kind == OVERFLOW) {
                        continue;
                    }

                    @SuppressWarnings("unchecked")
                    WatchEvent ev = (WatchEvent) event;
                    Path filename = ev.context();

                    Path child = dir.resolve(filename);
                    if (child.equals(configFile.toPath())) {
                        LOG.debug("File was changed.");
                        updateConfigFromFile();
                    }
                }
                boolean valid = key.reset();
                if (!valid) {
                    break;
                }
            }
        } catch (IOException ioe) {
            LOG.error("Exception in filewatcher loop. Exiting.", ioe);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy