001package Torello.Java; 002 003import java.io.IOException; 004import java.util.*; 005 006/** 007 * A utility that attempts to mimic the UNIX command <CODE>'grep'</CODE>. 008 * <EMBED CLASS='external-html' DATA-FILE-ID=GREP> 009 */ 010@Torello.JavaDoc.StaticFunctional 011public class GREP 012{ 013 private GREP() { } 014 015 /** 016 * Convenience Method. 017 * <BR />Automatically Selects: {@link RTC#VECTOR()} 018 * <BR />Invokes: {@link #search(RTC, Iterator, SearchAndPrint, IOExceptionHandler)} 019 */ 020 public static Vector<FileNode> search 021 (Iterable<FileNode> iterable, SearchAndPrint sp, IOExceptionHandler ioeh) 022 { return search(RTC.VECTOR(), iterable.iterator(), sp, ioeh); } 023 024 /** 025 * Convenience Method. 026 * <BR />Automatically Selects: {@link RTC#VECTOR()} 027 * <BR />Invokes: {@link #search(RTC, Iterator, SearchAndPrint, IOExceptionHandler)}. 028 */ 029 public static Vector<FileNode> search 030 (Iterator<FileNode> iter, SearchAndPrint sp, IOExceptionHandler ioeh) 031 { return search(RTC.VECTOR(), iter, sp, ioeh); } 032 033 /** 034 * This version of GREP shall search every file in a java {@code Iterator<FileNode>} 035 * data-structure. Any 'directories' (which are not files) returned by this {@code Iterator} 036 * shall be skipped / ignored. 037 * 038 * @param dataStructureChoice <EMBED CLASS='external-html' DATA-FILE-ID=FN_RTC_PARAM> 039 * 040 * @param iter Any Iterator of type {@code Iterator<FileNode>}. Each file that is returned in 041 * the return set shall be searched for the described matches using {@code 'SearchAndPrint'} 042 * parameter {@code 'sp'} 043 * 044 * @param sp The {@code 'sp'} parameter is the implementation of the file-grep operation that 045 * the user is requesting. The actions that this SearchAndPrint method-pointer should perform 046 * include: 047 * 048 * <BR /><BR /><UL CLASS=JDUL> 049 * <LI> Test if the file contains a match - using whatever string-testing procedure required. 050 * Usually either a simple {@code String} token is being searched, or an entire 051 * {@code String} regular-expression is used. 052 * </LI> 053 * 054 * <LI> Do some kind of output printing to a writable printing parameter to report these 055 * {@code String}-match results 056 * </LI> 057 * 058 * <LI> return either {@code TRUE} or {@code FALSE} to indicate whether or not a particular file 059 * contained matches. 060 * </LI> 061 * </UL> 062 * 063 * <BR /><BR /><B><SPAN STYLE="color: red;">IMPORTANT:</B></SPAN> This parameter cannot be 064 * null. It is the core of the grep-search algorithm. If the programmer wishes to rely on the 065 * standard 'token-search' or 'regular-expression-search' methods defined in 066 * {@code class 'SearchAndPrint'} - <I>then the programmer should simply use one of the 067 * standard factory methods provided in {@code 'SearchAndPrint'} to build an instance of 068 * this class.</I> 069 * 070 * @param ioeh When performing these UNIX-GREP styled text-file searches, it becomes imperative 071 * to catch any potential {@code IOException's} so that if one file is failing to load to Java, 072 * the rest of the entire search will not be sacrificed or ceased. Using this parameter allows 073 * a programmer to log exceptions, or take any user-defined action when any potential 074 * {@code IOException's} occur while reading the files in a directory tree. Using this 075 * exception-handler allows the GREP-Search to continue, even if reading one particular file 076 * fails. 077 * 078 * <BR /><BR /><B>NOTE:</B> This parameter may be null, and if it is, it will be ignored - 079 * <I>and all exceptions shall suppressed</I>. This means that no exception information will 080 * be reported back to the user. If this parameter is null, and if an {@code IOException} is 081 * generated while traversing a particular file for GREP-search, that file will merely be 082 * skipped (gracefully), and its contents will not be searched. 083 * 084 * @return The return-list shall contain a reference of every instance of 085 * {@code FileNode} for which whose contents on the file-system contained a match - as 086 * determined by the {@code SearchAndPrint} instance that is passed to parameter {@code 'sp'}. 087 * 088 * <EMBED CLASS='external-html' DATA-FILE-ID=FN_RTC_RET> 089 * 090 * @see SearchAndPrint 091 * @see FileRW#loadFileToString(String) 092 * @see FileNode#isDirectory 093 * @see FileNode#toString() 094 * @see SearchAndPrint#test(String, String) 095 * @see IOExceptionHandler#accept(FileNode, IOException) 096 */ 097 public static <T> T search( 098 RTC<T> dataStructureChoice, Iterator<FileNode> iter, SearchAndPrint sp, 099 IOExceptionHandler ioeh 100 ) 101 { 102 while (iter.hasNext()) 103 { 104 FileNode fn = iter.next(); 105 106 if (fn.isDirectory) continue; 107 108 try 109 { 110 String fileContents = FileRW.loadFileToString(fn.toString()); 111 boolean wasMatch = sp.test(fn.toString(), fileContents); 112 113 if (wasMatch) dataStructureChoice.inserter.accept(fn); 114 } 115 116 catch (IOException e) 117 { if (ioeh != null) ioeh.accept(fn, e); } 118 } 119 120 return dataStructureChoice.finisher.get(); 121 } 122 123 /** 124 * This version of GREP shall search a single file only. The passed parameter 'file' must be 125 * a {@code FileNode} instance that represents a UNIX or MS-DOS file, not a directory. 126 * 127 * @param file This is the file to be searched or "GREPPED." 128 * 129 * @param sp The {@code 'sp'} parameter is the implementation of the file-grep operation 130 * that the user is requesting. The actions that this SearchAndPrint method-pointer should 131 * perform include: 132 * 133 * <BR /><BR /><UL CLASS=JDUL> 134 * <LI> Test if the file contains a match - using whatever string-testing procedure required. 135 * Usually either a simple {@code String} token is being searched, or an entire 136 * {@code String} regular-expression is used. 137 * </LI> 138 * 139 * <LI> Do some kind of output printing to a writable printing parameter to report these 140 * {@code String}-match results 141 * </LI> 142 * 143 * <LI> return either {@code TRUE} or {@code FALSE} to indicate whether or not a particular file 144 * contained matches. 145 * </LI> 146 * </UL> 147 * 148 * <BR /><B><SPAN STYLE="color: red;">IMPORTANT:</B></SPAN> This parameter cannot be null. 149 * It is the core of the grep-search algorithm. If the programmer wishes to rely on the 150 * standard 'token-search' or 'regular-expression-search' methods defined in class 151 * {@code 'SearchAndPrint'} - <I>then the programmer should simply use one of the standard 152 * factory methods provided in {@code 'SearchAndPrint'} to build an instance of this class.</I> 153 * 154 * @param ioeh This parameter may be used, or it may be left null. It is less emphasized here, 155 * because only a single file is being searched. That file is specified in the parameters to 156 * this method. Since there is only one file to search, catching the {@code IOException's} 157 * makes little difference because GREP-search on other files will not be hindered, since there 158 * are no other files being searched. 159 * 160 * @return A value of {@code TRUE} shall indicate that there was a match found. 161 * 162 * @throws FileExpectedException The parameter {@code 'file'} must actually be a 'file' instance 163 * of {@code FileNode}. If {@code 'file'} is not actually a file, but rather a directory, then 164 * this exception shall throw. 165 * 166 * @see FileExpectedException#check(FileNode) 167 * @see FileRW#loadFileToString(String) 168 * @see FileNode#toString() 169 * @see SearchAndPrint#test(String, String) 170 * @see IOExceptionHandler#accept(FileNode, IOException) 171 */ 172 public static boolean searchFile(FileNode file, SearchAndPrint sp, IOExceptionHandler ioeh) 173 { 174 // Can only test files, not directories... 175 FileExpectedException.check(file); 176 177 // Test to see if there is a match 178 try 179 { return sp.test(file.toString(), FileRW.loadFileToString(file.toString())); } 180 181 catch (IOException e) 182 { if (ioeh != null) ioeh.accept(file, e); return false; } 183 } 184}