001 package org.wdssii.core.fam; 002 003 import java.io.File; 004 import java.io.FilenameFilter; 005 import java.util.ArrayList; 006 import java.util.Arrays; 007 import java.util.List; 008 009 import net.contentobjects.jnotify.JNotify; 010 import net.contentobjects.jnotify.JNotifyException; 011 import net.contentobjects.jnotify.JNotifyListener; 012 013 import org.apache.commons.logging.Log; 014 import org.apache.commons.logging.LogFactory; 015 016 public class FamIndexHelperInotifyImpl implements FamIndexHelper, 017 JNotifyListener { 018 019 private final Log log = LogFactory.getLog(getClass()); 020 private List<File> files = new ArrayList<File>(); 021 private int wd; 022 private final FilenameFilter filenamePattern; 023 024 /** By default look only at files that end with .fml */ 025 public FamIndexHelperInotifyImpl() { 026 this(new FmlFilesOnlyFilter()); 027 } 028 029 public FamIndexHelperInotifyImpl(FilenameFilter pattern) { 030 // this will cause a class-load exception if JNotify is not in classpath 031 try{ 032 JNotify.removeWatch(-1); 033 } catch (JNotifyException e){ 034 // ok 035 } 036 filenamePattern = pattern; 037 } 038 039 @Override 040 public File[] getInitialFiles(String indexDir) { 041 try { 042 // JNotify maps IN_CREATE and IN_MOVED_TO to these constants 043 final int mask = JNotify.FILE_CREATED | JNotify.FILE_RENAMED; 044 this.wd = JNotify.addWatch(indexDir, mask, false, this); 045 if (log.isInfoEnabled()) { 046 log.info("Successfully created inotify watch for " + indexDir 047 + " wd=" + wd); 048 } 049 } catch (JNotifyException e) { 050 log 051 .error("Make sure that the jnotify jar file and .so are in Tomcat's shared/lib"); 052 log 053 .error( 054 "Otherwise, you could try using WebIndexDirectoryListingDAO instead", 055 e); 056 throw new UnsupportedOperationException(e); 057 } 058 // existing files 059 File[] files = new File(indexDir).listFiles(filenamePattern); 060 Arrays.sort(files); 061 return files; 062 } 063 064 @Override 065 public synchronized void fileCreated(int watch, String indexDir, 066 String filename) { 067 if (filename != null && filenamePattern.accept(null, filename)) { 068 File f = new File(indexDir, filename); 069 files.add(f); 070 } 071 } 072 073 @Override 074 public synchronized void fileDeleted(int arg0, String arg1, String arg2) { 075 } 076 077 @Override 078 public synchronized void fileModified(int arg0, String arg1, String arg2) { 079 } 080 081 @Override 082 public synchronized void fileRenamed(int wd, String indexDir, 083 String oldName, String newName) { 084 if (newName != null && filenamePattern.accept(null, newName)) { 085 File f = new File(indexDir, newName); 086 files.add(f); 087 } 088 } 089 090 @Override 091 /** 092 * returns new files in watched directory since previous call to this 093 * method. 094 */ 095 public synchronized File[] getNewFiles() { 096 File[] newfiles = files.toArray(new File[0]); 097 files.clear(); // start accumulating again 098 return newfiles; 099 } 100 101 /** 102 * De-registers from the watch so that the servlet container does not keep 103 * receiving events. 104 */ 105 @Override 106 public void close() { 107 if (wd >= 0) { 108 try { 109 JNotify.removeWatch(wd); 110 if (log.isInfoEnabled()) { 111 log.info("Removed inotify watch wd=" + wd); 112 } 113 } catch (JNotifyException e) { 114 // ok 115 } 116 } 117 } 118 119 @Override 120 public void pruneToMaxSize(long m, long n){ 121 // nothing to do 122 } 123 }