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

org.grails.io.watch.PollingDirectoryWatcher Maven / Gradle / Ivy

package org.grails.io.watch;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * Implementation of a {@link AbstractDirectoryWatcher} that uses polling.
 * This implementation is used where {@link java.nio.WatchService} isn't available (pre Java 7).
 * @author Craig Andrews
 * @since 2.4
 * @see WatchServiceDirectoryWatcher
 * @see DirectoryWatcher
 */
class PollingDirectoryWatcher extends AbstractDirectoryWatcher {

    private Collection extensions = new ConcurrentLinkedQueue();

    private Map lastModifiedMap = new ConcurrentHashMap();
    private Map> directoryToExtensionsMap = new ConcurrentHashMap>();
    private Map directoryWatch = new ConcurrentHashMap();

	@Override
	public void run() {
        int count = 0;
        while (active) {
            Set files = lastModifiedMap.keySet();
            for (File file : files) {
                long currentLastModified = file.lastModified();
                Long cachedTime = lastModifiedMap.get(file);
                if (currentLastModified > cachedTime) {
                    lastModifiedMap.put(file, currentLastModified);
                    fireOnChange(file);
                }
            }
            try {
                count++;
                if (count > 2) {
                    count = 0;
                    checkForNewFiles();
                }
                Thread.sleep(sleepTime);
            } catch (InterruptedException e) {
                // ignore
            }
        }
	}

	@Override
	public void addWatchFile(File fileToWatch) {
        lastModifiedMap.put(fileToWatch, fileToWatch.lastModified());
	}

	@Override
	public void addWatchDirectory(File dir, List fileExtensions) {
		if(!isValidDirectoryToMonitor(dir)){
			return;
		}
        trackDirectoryExtensions(dir, fileExtensions);
        cacheFilesForDirectory(dir, fileExtensions, false);
	}

    private void trackDirectoryExtensions(File dir, List fileExtensions) {
        Collection existingExtensions = directoryToExtensionsMap.get(dir);
        if(existingExtensions == null) {
            directoryToExtensionsMap.put(dir, new ArrayList(fileExtensions));
        }
        else {
            existingExtensions.addAll(fileExtensions);
        }
    }

    private void checkForNewFiles() {
        for (File directory : directoryWatch.keySet()) {
            final Long currentTimestamp = directoryWatch.get(directory);

            if (currentTimestamp < directory.lastModified()) {
                Collection extensions = directoryToExtensionsMap.get(directory);
                if(extensions == null) {
                    extensions = this.extensions;
                }
                cacheFilesForDirectory(directory, extensions, true);
            }
        }
    }

    private void cacheFilesForDirectory(File directory, Collection fileExtensions, boolean fireEvent) {
        addExtensions(fileExtensions);

        directoryWatch.put(directory, directory.lastModified());
        File[] files = directory.listFiles();
        if (files == null) {
            return;
        }

        for (File file : files) {
        	if(isValidDirectoryToMonitor(file)) {
                cacheFilesForDirectory(file, fileExtensions, fireEvent);
        	}
            else if (isValidFileToMonitor(file, fileExtensions)) {
                if (!lastModifiedMap.containsKey(file) && fireEvent) {
                    fireOnNew(file);
                }
                lastModifiedMap.put(file, file.lastModified());
            }
        }
    }

    private void addExtensions(Collection toAdd) {
        for (String extension : toAdd) {
            extension = removeStartingDotIfPresent(extension);
            if (!extensions.contains(extension)) {
                extensions.add(extension);
            }
        }
    }

    private String removeStartingDotIfPresent(String extension) {
        if (extension.startsWith(".")) {
            extension = extension.substring(1);
        }
        return extension;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy