001package Torello.JavaDoc.SyntaxHiLite; 002 003import Torello.Java.FileNode; 004import Torello.Java.StrPrint; 005import Torello.Java.FileRW; 006import Torello.Java.StorageWriter; 007 008import Torello.Java.Function.QuadFunction; 009 010// Needed for a JavaDoc Comment 011import Torello.Java.FileTransfer; 012 013import Torello.JavaDoc.LinkJavaSource; 014 015import java.util.TreeSet; 016 017import java.io.File; 018 019/** 020 * A caching-system class that allows this tool to efficiently bypass calls to the server when 021 * an exact-copy of the hilited source-code already exists inside the cache. 022 */ 023public abstract class AbstractHashCodeHLC<NUMBER extends Number> implements HiLiteCache 024{ 025 static final short NUM_DIRS = 5000; 026 027 static 028 { 029 if ((NUM_DIRS < 1000) || (NUM_DIRS > 9999)) 030 throw new InternalError("Wrong Number of NUM_DIRS"); 031 } 032 033 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 // Instance Fields 037 // ******************************************************************************************** 038 // ******************************************************************************************** 039 040 041 /** This is nothing more than a "reified" Generic Type Parameter. No more, no less. */ 042 public final Class<NUMBER> NUMBER_CLASS; 043 044 /** This is, as the name clearly says, the Cache's Storae-Directory */ 045 public final String cacheSaveDirectory; 046 047 048 // This is the list of Hash-Codes for all Code/HTML pairs stored in the cache. This is the 049 // exact data-structure that is referred to as the "Master Hash File" 050 // 051 // This has also been recently converted to "Package-Private", instead of "Private" 052 // See Above Note for Details. 053 054 final TreeSet<NUMBER> hashCodes; 055 056 057 // ******************************************************************************************** 058 // ******************************************************************************************** 059 // Constructor 060 // ******************************************************************************************** 061 // ******************************************************************************************** 062 063 064 /** 065 * This will load the hashCodes table to memory from the file-system directory identified 066 * by {@code String}-Parameter {@code 'cacheSaveDirectory'}. An exception shall be thrown 067 * if this file is not found. 068 * 069 * @param cacheSaveDirectory This constructor presumes that this cache has been used and 070 * visited before. This directory name should point to your local-cache of the 071 * {@code HiLite.ME} Server Code hilite past-operations. 072 * 073 * @throws CacheError This error will throw if the cache has not been instantiated, or 074 * is corrupted. If the specified directory does not exist, then this {@code Error} shall 075 * also throw. The chain-cause {@code Throwable} should be visible, and is included as the 076 * {@code Throwable.getCause()}. 077 */ 078 @LinkJavaSource(handle="TreeSetMethods", name="checkCSD") 079 @LinkJavaSource(handle="TreeSetMethods", name="checkTS") 080 public AbstractHashCodeHLC( 081 final String cacheSaveDirectory, 082 final Class<NUMBER> NUMBER_CLASS 083 ) 084 { 085 this.cacheSaveDirectory = TreeSetMethods.checkCSD(cacheSaveDirectory); 086 this.hashCodes = TreeSetMethods.checkTS(this.cacheSaveDirectory, NUMBER_CLASS); 087 this.NUMBER_CLASS = NUMBER_CLASS; 088 } 089 090 091 // ******************************************************************************************** 092 // ******************************************************************************************** 093 // Static Builder Method 094 // ******************************************************************************************** 095 // ******************************************************************************************** 096 097 098 /** 099 * This will initialize a cache-file in the file-system directory identified by parameter 100 * {@code String cacheSaveDirectory}. If the directory specified does not exist, a 101 * {@code CacheError} is thrown. Any old cache files will be removed. To attempt to 102 * preserve old cache-files, call method {@code initializeOrRepair(String, StorageWriter)} 103 * 104 * <BR /><BR /><B><I>OrClear:</I></B> If the directory structure provided to this 105 * initialize method is not empty, the <SPAN STYLE="color: red;"><B><I>its entire contents 106 * shall be erased by a call to </I></B></SPAN> (Below) 107 * 108 * <DIV CLASS=LOC>{@code 109 * FileTransfer.deleteFilesRecursive 110 * (FileNode.createRoot(cacheSaveDirectory).loadTree(), sw); 111 * }</DIV> 112 * 113 * @param cacheSaveDirectory This constructor presumes that this cache has been used and 114 * visited before. This directory name should point to your local-cache of 115 * {@code HiLite.ME} Server Code hilite past-operations. 116 * 117 * @param sw This receives log-writes from the call to 118 * {@link FileTransfer#deleteFilesRecursive} which clears the files currently in the cache. 119 * This parameter may be null, and if it is, output-text will be shunted. 120 * 121 * @throws CacheError This exception will be throw if there are errors deleting any 122 * old-cache files currently in the directory; or if there is any error creating the new 123 * master hash-cache file. The chain-cause {@code Throwable} should be visible, and is 124 * included as the {@code Throwable.getCause()}. 125 */ 126 @LinkJavaSource(handle="TreeSetMethods", name="initializeOrClear") 127 public static String initializeOrClear(String cacheSaveDirectory, StorageWriter sw) 128 { return TreeSetMethods.initializeOrClear(cacheSaveDirectory, sw); } 129 130 131 // ******************************************************************************************** 132 // ******************************************************************************************** 133 // Implemented Interface Methods 134 // ******************************************************************************************** 135 // ******************************************************************************************** 136 137 138 public long totalSize() 139 { 140 return FileNode 141 .createRoot(this.cacheSaveDirectory) 142 .loadTree() 143 .getDirTotalContentsSize(); 144 } 145 146 public int totalNumber() 147 { 148 return FileNode 149 .createRoot(this.cacheSaveDirectory) 150 .loadTree() 151 .count(); 152 } 153 154 @LinkJavaSource(handle="TreeSetMethods", name="persistMasterHashToDisk") 155 public void persistMasterHashToDisk() throws CacheError 156 { TreeSetMethods.persistMasterHashToDisk(this.hashCodes, this.cacheSaveDirectory); } 157 158 159 // ******************************************************************************************** 160 // ******************************************************************************************** 161 // Implemented Interface Methods: Check In and Out 162 // ******************************************************************************************** 163 // ******************************************************************************************** 164 165 166 @LinkJavaSource(handle="CheckInOut", name="get") 167 public String get( 168 final String sourceCodeAsString, 169 final String codeTypeParam, 170 final boolean includeLineNumbers, 171 final byte styleNum 172 ) 173 { 174 return CheckInOut.get( 175 sourceCodeAsString, 176 this.computeCacheKey 177 (codeTypeParam, includeLineNumbers, styleNum, sourceCodeAsString), 178 this 179 ); 180 } 181 182 @LinkJavaSource(handle="CheckInOut", name="checkIn") 183 public void checkIn( 184 final String sourceCodeAsString, 185 final String hilitedCodeAsString, 186 final String codeTypeParam, 187 final boolean includeLineNumbers, 188 final byte styleNum 189 ) 190 { 191 CheckInOut.checkIn( 192 sourceCodeAsString, 193 hilitedCodeAsString, 194 this.computeCacheKey 195 (codeTypeParam, includeLineNumbers, styleNum, sourceCodeAsString), 196 this 197 ); 198 } 199 200 201 // ******************************************************************************************** 202 // ******************************************************************************************** 203 // Abstract Methods 204 // ******************************************************************************************** 205 // ******************************************************************************************** 206 207 208 /** 209 * Compute a Hash-Code 210 * @param codeTypeParam <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_CODE_TP> 211 * @param includeLineNumbers <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_INC_LINEN> 212 * @param styleNum <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_STYLE_N> 213 * @param sourceCodeAsString <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_SRC_ASSTR> 214 * @return A key which may be used for saving a file to disk. 215 */ 216 public abstract NUMBER computeCacheKey( 217 final String codeTypeParam, 218 final boolean includeLineNumbers, 219 final byte styleNum, 220 final String sourceCodeAsString 221 ); 222 223 abstract String getSubDirName(NUMBER hashCode); 224 225 226 // ******************************************************************************************** 227 // ******************************************************************************************** 228 // I forgot ... 229 // ******************************************************************************************** 230 // ******************************************************************************************** 231 232 233 public static void main(String[] argv) 234 { 235 if (argv.length != 1) 236 { 237 System.out.println( 238 "argv.length != 1\n" + 239 "argv[0] must contain the Cache-Directory Name.\n" 240 ); 241 242 System.exit(1); 243 } 244 245 java.io.File f = new java.io.File(argv[0]); 246 247 if ((! f.exists()) || (! f.isDirectory())) 248 { 249 System.out.println( 250 "argv[0] must contain the Cache-Directory Name.\n" + 251 "Unfortunately: ((! f.exists()) || (! f.isDirectory()))\n" 252 ); 253 254 System.exit(1); 255 } 256 257 initializeOrClear(argv[0], new StorageWriter()); 258 } 259}