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.Annotations.LinkJavaSource; 014 015import java.util.TreeSet; 016 017import java.io.File; 018 019 020/** 021 * An {@code abstract} Parent-Class for both {@link HLC32} and {@link HLC64}. The bulkwork of 022 * methods and fields needed to run both of these classes can be placed in the abstract parent. 023 * In fact, there are only two {@code abstract} implementatio methods that subclasses need to 024 * implement in order to properly fullfill this {@code abstract} Parent-Class, 025 */ 026public abstract class AbstractHashCodeHLC<NUMBER extends Number> implements HiLiteCache 027{ 028 static final short NUM_DIRS = 5000; 029 030 static 031 { 032 if ((NUM_DIRS < 1000) || (NUM_DIRS > 9999)) 033 throw new InternalError("Wrong Number of NUM_DIRS"); 034 } 035 036 037 // ******************************************************************************************** 038 // ******************************************************************************************** 039 // Instance Fields 040 // ******************************************************************************************** 041 // ******************************************************************************************** 042 043 044 /** This is nothing more than a "reified" Generic Type Parameter. No more, no less. */ 045 public final Class<NUMBER> NUMBER_CLASS; 046 047 /** This is, as the name clearly says, the Cache's Storae-Directory */ 048 public final String cacheSaveDirectory; 049 050 051 // This is the list of Hash-Codes for all Code/HTML pairs stored in the cache. This is the 052 // exact data-structure that is referred to as the "Master Hash File" 053 // 054 // This has also been recently converted to "Package-Private", instead of "Private" 055 // See Above Note for Details. 056 057 final TreeSet<NUMBER> hashCodes; 058 059 060 // ******************************************************************************************** 061 // ******************************************************************************************** 062 // Constructor 063 // ******************************************************************************************** 064 // ******************************************************************************************** 065 066 067 /** 068 * This will load the hashCodes table to memory from the file-system directory identified 069 * by {@code String}-Parameter {@code 'cacheSaveDirectory'}. An exception shall be thrown 070 * if this file is not found, or the specified directory doesn't exist. 071 * 072 * @param cacheSaveDirectory This constructor presumes that this cache has been used and 073 * visited before. This directory name should point to your local-cache of the 074 * {@code HiLite.ME} Server Code hilite past-operations. 075 * 076 * @throws CacheError This error will throw if the cache has not been instantiated, or 077 * is corrupted. If the specified directory does not exist, then this {@code Error} shall 078 * also throw. The chain-cause {@code Throwable} should be visible, and is included as the 079 * {@code Throwable.getCause()}. 080 */ 081 @LinkJavaSource(handle="TreeSetMethods", name="checkCSD") 082 @LinkJavaSource(handle="TreeSetMethods", name="checkTS") 083 public AbstractHashCodeHLC( 084 final String cacheSaveDirectory, 085 final Class<NUMBER> NUMBER_CLASS 086 ) 087 { 088 this.cacheSaveDirectory = TreeSetMethods.checkCSD(cacheSaveDirectory); 089 this.hashCodes = TreeSetMethods.checkTS(this.cacheSaveDirectory, NUMBER_CLASS); 090 this.NUMBER_CLASS = NUMBER_CLASS; 091 } 092 093 094 // ******************************************************************************************** 095 // ******************************************************************************************** 096 // Initialize a Directory for Cachine - Create if need be, Erase its contents, if non-empty 097 // ******************************************************************************************** 098 // ******************************************************************************************** 099 100 101 /** 102 * This will initialize a cache-file in the file-system directory identified by parameter 103 * {@code String cacheSaveDirectory}. If the directory specified does not exist, 104 * {@code File.mkdirs()} will be invoked, thereby creating that directory. If the specified 105 * directory already exists - it's contents shall be fully wiped, meaning all files deleted. 106 * 107 * <BR /><BR /><DIV CLASS=JDHint> 108 * <B>Erasing Contents:</B> If the directory structure provided to this method is non-empty, 109 * the <B STYLE="color: red;"><I>its entire contents shall be erased by a call to</I></B> 110 * <B>{@link FileTransfer#deleteFilesRecursive(FileNode, FileNodeFilter, FileNodeFilter, 111 * Appendable) FileTransfer#deleteFilesRecursive}.</B>, as per the statement below 112 * </DIV> 113 * 114 * <BR /><DIV CLASS=SNIP>{@code 115 * FileTransfer.deleteFilesRecursive 116 * (FileNode.createRoot(cacheSaveDirectory).loadTree(), sw); 117 * }</DIV> 118 * 119 * <BR />This method saves a brand-new (empty) Hash-Code List (a java.util.TreeSet) to disk, 120 * using Java Object Serialization. It is not actually important to know whether this Cache 121 * is going to be a 32-Bit or a 64-Bit Cache. The {@code TreeSet} which is written to disk is 122 * empty. Therefore, in all actuality, what is written to disk is a "Raw-Types" TreeSet 123 * (precisely because of Java's Generic Erasure). Thus it is perfectly irrelevant what is 124 * written to disk. 125 * 126 * @param cacheSaveDirectory This constructor presumes that this cache has been used and 127 * visited before. This directory name should point to your local-cache of 128 * {@code HiLite.ME} Server Code hilite past-operations. 129 * 130 * @param sw This receives log-writes from the call to 131 * {@link FileTransfer#deleteFilesRecursive} which clears the files currently in the cache. 132 * This parameter may be null, and if it is, output-text will be shunted. 133 * 134 * @throws CacheError This exception will be throw if there are errors deleting any 135 * old-cache files currently in the directory; or if there is any error creating the new 136 * master hash-cache file. The chain-cause {@code Throwable} should be visible, and is 137 * included as the {@code Throwable.getCause()}. 138 */ 139 @LinkJavaSource(handle="TreeSetMethods", name="initializeDirectory") 140 public static String initializeDirectory(String cacheSaveDirectory, StorageWriter sw) 141 { return TreeSetMethods.initializeDirectory(cacheSaveDirectory, sw); } 142 143 144 // ******************************************************************************************** 145 // ******************************************************************************************** 146 // Implemented Interface Methods 147 // ******************************************************************************************** 148 // ******************************************************************************************** 149 150 151 public long totalSize() 152 { 153 return FileNode 154 .createRoot(this.cacheSaveDirectory) 155 .loadTree() 156 .getDirTotalContentsSize(); 157 } 158 159 public int totalNumber() 160 { 161 return FileNode 162 .createRoot(this.cacheSaveDirectory) 163 .loadTree() 164 .count(); 165 } 166 167 @LinkJavaSource(handle="TreeSetMethods", name="persistMasterHashToDisk") 168 public void persistMasterHashToDisk() throws CacheError 169 { TreeSetMethods.persistMasterHashToDisk(this.hashCodes, this.cacheSaveDirectory); } 170 171 172 // ******************************************************************************************** 173 // ******************************************************************************************** 174 // Implemented Interface Methods: Check In and Out 175 // ******************************************************************************************** 176 // ******************************************************************************************** 177 178 179 @LinkJavaSource(handle="CheckInOut", name="get") 180 public String get( 181 final String sourceCodeAsString, 182 final String codeTypeParam, 183 final boolean includeLineNumbers, 184 final byte styleNum 185 ) 186 { 187 return CheckInOut.get( 188 sourceCodeAsString, 189 this.computeCacheKey 190 (codeTypeParam, includeLineNumbers, styleNum, sourceCodeAsString), 191 this 192 ); 193 } 194 195 @LinkJavaSource(handle="CheckInOut", name="checkIn") 196 public void checkIn( 197 final String sourceCodeAsString, 198 final String hilitedCodeAsString, 199 final String codeTypeParam, 200 final boolean includeLineNumbers, 201 final byte styleNum 202 ) 203 { 204 CheckInOut.checkIn( 205 sourceCodeAsString, 206 hilitedCodeAsString, 207 this.computeCacheKey 208 (codeTypeParam, includeLineNumbers, styleNum, sourceCodeAsString), 209 this 210 ); 211 } 212 213 214 // ******************************************************************************************** 215 // ******************************************************************************************** 216 // Abstract Methods 217 // ******************************************************************************************** 218 // ******************************************************************************************** 219 220 221 /** 222 * Compute a Hash-Code for a given Source-File, and it's HiLiting Parameters 223 * @param codeTypeParam <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_CODE_TP> 224 * @param includeLineNumbers <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_INC_LINEN> 225 * @param styleNum <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_STYLE_N> 226 * @param sourceCodeAsString <EMBED CLASS='external-html' DATA-FILE-ID=HLC_PARAM_SRC_ASSTR> 227 * @return A key which may be used for saving a file to disk. 228 */ 229 public abstract NUMBER computeCacheKey( 230 final String codeTypeParam, 231 final boolean includeLineNumbers, 232 final byte styleNum, 233 final String sourceCodeAsString 234 ); 235 236 abstract String getSubDirName(NUMBER hashCode); 237 238 239 // ******************************************************************************************** 240 // ******************************************************************************************** 241 // Main Method for invoking '' ... 242 // ******************************************************************************************** 243 // ******************************************************************************************** 244 245 246 /** 247 * A Main-Method which invokes {@link #initializeDirectory(String, StorageWriter)} 248 */ 249 public static void main(String[] argv) 250 { 251 if (argv.length != 1) 252 { 253 System.out.println( 254 "argv.length != 1\n" + 255 "argv[0] must contain the Cache-Directory Name.\n" 256 ); 257 258 System.exit(1); 259 } 260 261 initializeDirectory(argv[0], new StorageWriter()); 262 } 263}