001 /** 002 * 003 */ 004 package org.wdssii.core.fam; 005 006 import java.io.File; 007 import java.io.FilenameFilter; 008 import java.util.Arrays; 009 import java.util.Date; 010 import java.util.HashSet; 011 import java.util.Set; 012 013 import org.apache.commons.logging.Log; 014 import org.apache.commons.logging.LogFactory; 015 016 /** 017 * @author lakshman 018 * 019 */ 020 public class FamIndexHelperLsImpl implements FamIndexHelper { 021 private String indexDir; 022 private Set<String> knownFiles; 023 private long timeOfLastUpdate; 024 private final FilenameFilter filenamePattern; 025 private NewFilesOnly newFilesOnly; 026 027 private long updateIntervalInMilliSeconds = 60 * 1000; // milliseconds 028 private final File[] emptyList = new File[0]; 029 private final Log log = LogFactory.getLog(FamIndexHelperLsImpl.class); 030 031 public FamIndexHelperLsImpl(FilenameFilter pattern){ 032 this.filenamePattern = pattern; 033 } 034 035 /** By default look only at files that end with .fml */ 036 public FamIndexHelperLsImpl(){ 037 this(new FmlFilesOnlyFilter()); 038 } 039 040 @Override 041 public File[] getInitialFiles(String indexDir) { 042 this.close(); // resets 043 this.indexDir = indexDir; 044 File[] files = new File(indexDir).listFiles(filenamePattern); 045 return processFileListAndReturn(files); 046 } 047 048 @Override 049 public void close(){ 050 knownFiles = new HashSet<String>(); 051 timeOfLastUpdate = 0; 052 newFilesOnly = new NewFilesOnly(); 053 } 054 055 private File[] processFileListAndReturn(File[] files) { 056 if (files == null) { 057 log.warn("Problem listing files in " + indexDir); 058 return emptyList; 059 } 060 061 if (log.isDebugEnabled()) { 062 log.debug("Found " + files.length + " files in " + indexDir); 063 } 064 065 Arrays.sort(files); // alphabetical 066 for (File f : files) { 067 knownFiles.add(f.getAbsolutePath()); 068 } 069 return files; 070 } 071 072 /** Accepts only new FML files */ 073 public class NewFilesOnly implements FilenameFilter { 074 @Override 075 public boolean accept(File dir, String baseName) { 076 boolean isFml = filenamePattern.accept(dir, baseName); 077 if (isFml) { 078 File f = new File(dir, baseName); 079 if (isNew(f)) { 080 return true; 081 } 082 } 083 return false; 084 } 085 086 protected boolean isNew(File f) { 087 String absPath = f.getAbsolutePath(); 088 089 // Has this file been aged off in memory? 090 if (!knownFiles.isEmpty()) { 091 String firstFile = knownFiles.iterator().next(); 092 if (absPath.compareTo(firstFile) < 0) { 093 // older than oldest file in map 094 return false; 095 } 096 } 097 return (!knownFiles.contains(absPath)); 098 } 099 } 100 101 @Override 102 public File[] getNewFiles() { 103 // don't update if we just did 104 long now = new Date().getTime(); 105 if ((now - timeOfLastUpdate) < updateIntervalInMilliSeconds) { 106 return emptyList; 107 } 108 timeOfLastUpdate = now; 109 110 // get all files 111 File[] files = new File(indexDir).listFiles(newFilesOnly); 112 return processFileListAndReturn(files); 113 } 114 115 @Override 116 public void pruneToMaxSize(long maxNumRecords, long targetNumRecords){ 117 // prune 118 if (knownFiles.size() > maxNumRecords){ 119 String[] temp = knownFiles.toArray(new String[0]); 120 knownFiles.clear(); 121 for (int i=1; i <= targetNumRecords; ++i){ 122 knownFiles.add(temp[temp.length-i]); 123 } 124 } 125 } 126 }