/** * Construct an observer for the specified directory, file filter and * file comparator. * * @param directory the directory to observe * @param fileFilter The file filter or null if none * @param caseSensitivity what case sensitivity to use comparing file names, null means system sensitive */ public FileAlterationObserver(final File directory, final FileFilter fileFilter, final IOCase caseSensitivity) { this(new FileEntry(directory), fileFilter, caseSensitivity); }
/** * Initialize the observer. * * @throws Exception if an error occurs */ public void initialize() throws Exception { rootEntry.refresh(rootEntry.getFile()); final FileEntry[] children = doListFiles(rootEntry.getFile(), rootEntry); rootEntry.setChildren(children); }
/** * Fire directory/file created events to the registered listeners. * * @param entry The file entry */ private void doCreate(final FileEntry entry) { for (final FileAlterationListener listener : listeners) { if (entry.isDirectory()) { listener.onDirectoryCreate(entry.getFile()); } else { listener.onFileCreate(entry.getFile()); } } final FileEntry[] children = entry.getChildren(); for (final FileEntry aChildren : children) { doCreate(aChildren); } }
/** * Create a new file entry for the specified file. * * @param parent The parent file entry * @param file The file to create an entry for * @return A new file entry */ private FileEntry createFileEntry(final FileEntry parent, final File file) { final FileEntry entry = parent.newChildInstance(file); entry.refresh(file); final FileEntry[] children = doListFiles(file, entry); entry.setChildren(children); return entry; }
/** * Fire directory/file delete events to the registered listeners. * * @param entry The file entry */ private void doDelete(final FileEntry entry) { for (final FileAlterationListener listener : listeners) { if (entry.isDirectory()) { listener.onDirectoryDelete(entry.getFile()); } else { listener.onFileDelete(entry.getFile()); } } }
/** * Check whether the file and its children have been created, modified or deleted. */ public void checkAndNotify() { /* fire onStart() */ for (final FileAlterationListener listener : listeners) { listener.onStart(this); } /* fire directory/file events */ final File rootFile = rootEntry.getFile(); if (rootFile.exists()) { checkAndNotify(rootEntry, rootEntry.getChildren(), listFiles(rootFile)); } else if (rootEntry.isExists()) { checkAndNotify(rootEntry, rootEntry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); } else { // Didn't exist and still doesn't } /* fire onStop() */ for (final FileAlterationListener listener : listeners) { listener.onStop(this); } }
final FileEntry[] current = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_ENTRIES; for (final FileEntry entry : previous) { while (c < files.length && comparator.compare(entry.getFile(), files[c]) > 0) { current[c] = createFileEntry(parent, files[c]); doCreate(current[c]); c++; if (c < files.length && comparator.compare(entry.getFile(), files[c]) == 0) { doMatch(entry, files[c]); checkAndNotify(entry, entry.getChildren(), listFiles(files[c])); current[c] = entry; c++; } else { checkAndNotify(entry, entry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); doDelete(entry); doCreate(current[c]); parent.setChildren(current);
/** * Fire directory/file change events to the registered listeners. * * @param entry The previous file system entry * @param file The current file */ private void doMatch(final FileEntry entry, final File file) { if (entry.refresh(file)) { for (final FileAlterationListener listener : listeners) { if (entry.isDirectory()) { listener.onDirectoryChange(file); } else { listener.onFileChange(file); } } } }
/** * Return the directory being observed. * * @return the directory being observed */ public File getDirectory() { return rootEntry.getFile(); }
@Override public void initialize() throws Exception { log.debug("Initialize the observer."); configFileEntry = new FileEntry(configFile); configFileEntry.refresh(configFile); prepareSassAndCssPaths(); sassWatchable = new WatchableDirectory(sassPath, new SassFileFilter()); sassWatchable.initialize(); }
/** * Return the level * * @return the level */ public int getLevel() { return parent == null ? 0 : parent.getLevel() + 1; }
@Override public void check() throws Exception { if (configFileEntry.refresh(configFile)) { log.debug("Compass config file changed, need compile."); buildInternal(); return; } Result result = sassWatchable.check(); if (!result.isEmpty()) { log.debug("File(s) changed:\n{}", result.toString()); buildInternal(); } else { log.debug("Nothing to compile - all css files are up to date"); } }
/** * Create a new file entry for the specified file. * * @param parent The parent file entry * @param file The file to create an entry for * @return A new file entry */ private FileEntry createFileEntry(final FileEntry parent, final File file) { final FileEntry entry = parent.newChildInstance(file); entry.refresh(file); final FileEntry[] children = doListFiles(file, entry); entry.setChildren(children); return entry; }
/** * Check whether the file and its children have been created, modified or deleted. */ public void checkAndNotify() { /* fire onStart() */ for (final FileAlterationListener listener : listeners) { listener.onStart(this); } /* fire directory/file events */ final File rootFile = rootEntry.getFile(); if (rootFile.exists()) { checkAndNotify(rootEntry, rootEntry.getChildren(), listFiles(rootFile)); } else if (rootEntry.isExists()) { checkAndNotify(rootEntry, rootEntry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); } else { // Didn't exist and still doesn't } /* fire onStop() */ for (final FileAlterationListener listener : listeners) { listener.onStop(this); } }
FileEntry[] current = files.length > 0 ? new FileEntry[files.length] : FileEntry.EMPTY_ENTRIES; for (FileEntry entry : previous) { while (c < files.length && comparator.compare(entry.getFile(), files[c]) > 0) { current[c] = createFileEntry(parent, files[c]); doCreate(current[c]); c++; if (c < files.length && comparator.compare(entry.getFile(), files[c]) == 0) { doMatch(entry, files[c]); checkAndNotify(entry, entry.getChildren(), listFiles(files[c])); current[c] = entry; c++; } else { checkAndNotify(entry, entry.getChildren(), FileUtils.EMPTY_FILE_ARRAY); doDelete(entry); doCreate(current[c]); parent.setChildren(current);
/** * Fire directory/file delete events to the registered listeners. * * @param entry The file entry */ private void doDelete(FileEntry entry) { for (FileAlterationListener listener : listeners) { if (entry.isDirectory()) { listener.onDirectoryDelete(entry.getFile()); } else { listener.onFileDelete(entry.getFile()); } } }
/** * Fire directory/file change events to the registered listeners. * * @param entry The previous file system entry * @param file The current file */ private void doMatch(final FileEntry entry, final File file) { if (entry.refresh(file)) { for (final FileAlterationListener listener : listeners) { if (entry.isDirectory()) { listener.onDirectoryChange(file); } else { listener.onFileChange(file); } } } }
/** * Construct an observer for the specified directory, file filter and * file comparator. * * @param rootEntry the root directory to observe * @param fileFilter The file filter or null if none * @param caseSensitivity what case sensitivity to use comparing file names, null means system sensitive */ protected FileAlterationObserver(final FileEntry rootEntry, final FileFilter fileFilter, final IOCase caseSensitivity) { if (rootEntry == null) { throw new IllegalArgumentException("Root entry is missing"); } if (rootEntry.getFile() == null) { throw new IllegalArgumentException("Root directory is missing"); } this.rootEntry = rootEntry; this.fileFilter = fileFilter; if (caseSensitivity == null || caseSensitivity.equals(IOCase.SYSTEM)) { this.comparator = NameFileComparator.NAME_SYSTEM_COMPARATOR; } else if (caseSensitivity.equals(IOCase.INSENSITIVE)) { this.comparator = NameFileComparator.NAME_INSENSITIVE_COMPARATOR; } else { this.comparator = NameFileComparator.NAME_COMPARATOR; } }