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

net.contextfw.web.application.internal.service.DirectoryWatcher Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010 Marko Lavikainen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.contextfw.web.application.internal.service;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import net.contextfw.web.application.WebApplicationException;
import net.contextfw.web.application.internal.util.ResourceScanner;

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

import com.google.inject.Singleton;

@Singleton
public class DirectoryWatcher {

    private Logger logger = LoggerFactory.getLogger(DirectoryWatcher.class);

    private Pattern matcher;

    public DirectoryWatcher(Collection paths, Pattern matcher) {
        if (paths != null) {
            this.matcher = matcher;
            logger.info("Tracking resources for changes");
            List uris = ResourceScanner.toURIs(paths);
            for (URI uri : uris) {
                Enumeration resources;
                try {
                    resources = Thread.currentThread().getContextClassLoader()
                            .getResources(uri.getSchemeSpecificPart());
                    while (resources.hasMoreElements()) {
                        URL url = resources.nextElement();
                        File dir = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
                        if (dir.exists() && dir.isDirectory()) {
                            logger.info("Tracking directory:" + dir.getAbsolutePath());
                            rootDirs.add(dir);
                            update(dir);
                        }
                    }
                } catch (IOException e1) {
                    throw new WebApplicationException(e1);
                }
            }
        }
    }

    private static class FileEntry {

        long lastModified;
        long fileCount;

        FileEntry(File file) {
            lastModified = file.lastModified();
            if (file.isDirectory()) {
                fileCount = file.list().length;
            }
        }

        boolean hasChanged(File file) {
            if (file.isFile() && file.lastModified() != lastModified) {
                return true;
            } else if (file.isDirectory() && fileCount != file.list().length) {
                return true;
            } else {
                return false;
            }
        }
    }

    private final Set rootDirs = new HashSet();
    private final Map entries = new HashMap();

    public void registerDirectory(File file) {

        if (file == null) {
            throw new IllegalArgumentException("Cannot register null directory");
        }
        if (!file.isDirectory()) {
            throw new IllegalArgumentException("File " + file.getAbsolutePath()
                    + " is not a directory");
        }

    }

    private void update(File file) {
        if (file != null && file.exists()) {
            entries.put(file, new FileEntry(file));
            if (file.isDirectory()) {
                for (File child : file.listFiles()) {
                    update(child);
                }
            }
        }
    }

    private boolean hasChanged(File file) {
        if (file.isFile() && !matcher.matcher(file.getName()).matches()) {
            return false;
        } else if (!file.exists()) {
            return true;
        }
        FileEntry entry = entries.get(file);
        if (entry == null) {
            return true;
        } else if (entry.hasChanged(file)) {
            return true;
        } else if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                if (hasChanged(child)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean hasChanged() {
        for (File root : rootDirs) {
            if (hasChanged(root)) {
                reload();
                return true;
            }
        }
        return false;
    }

    private void reload() {
        entries.clear();
        for (File root1 : rootDirs) {
            update(root1);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy