1 package com.puppycrawl.tools.checkstyle; 20 21 import java.io.FileInputStream ; 22 import java.io.FileNotFoundException ; 23 import java.io.FileOutputStream ; 24 import java.io.IOException ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.ObjectOutputStream ; 27 import java.io.Serializable ; 28 import java.util.Properties ; 29 import java.security.MessageDigest ; 30 31 import com.puppycrawl.tools.checkstyle.api.Configuration; 32 import com.puppycrawl.tools.checkstyle.api.Utils; 33 34 43 final class PropertyCacheFile 44 { 45 51 private static final String CONFIG_HASH_KEY = "configuration*?"; 52 53 54 private final String mDetailsFile; 55 56 private final Properties mDetails = new Properties (); 57 58 64 PropertyCacheFile(Configuration aCurrentConfig, String aFileName) 65 { 66 boolean setInActive = true; 67 if (aFileName != null) { 68 FileInputStream inStream = null; 69 final String currentConfigHash = getConfigHashCode(aCurrentConfig); 72 try { 73 inStream = new FileInputStream (aFileName); 74 mDetails.load(inStream); 75 final String cachedConfigHash = 76 mDetails.getProperty(CONFIG_HASH_KEY); 77 setInActive = false; 78 if ((cachedConfigHash == null) 79 || !cachedConfigHash.equals(currentConfigHash)) 80 { 81 mDetails.clear(); 83 mDetails.put(CONFIG_HASH_KEY, currentConfigHash); 84 } 85 } 86 catch (final FileNotFoundException e) { 87 setInActive = false; 89 mDetails.put(CONFIG_HASH_KEY, currentConfigHash); 91 } 92 catch (final IOException e) { 93 Utils.getExceptionLogger() 94 .debug("Unable to open cache file, ignoring.", e); 95 } 96 finally { 97 if (inStream != null) { 98 try { 99 inStream.close(); 100 } 101 catch (final IOException ex) { 102 Utils.getExceptionLogger() 103 .debug("Unable to close cache file.", ex); 104 } 105 } 106 } 107 } 108 mDetailsFile = (setInActive) ? null : aFileName; 109 } 110 111 112 void destroy() 113 { 114 if (mDetailsFile != null) { 115 FileOutputStream out = null; 116 try { 117 out = new FileOutputStream (mDetailsFile); 118 mDetails.store(out, null); 119 } 120 catch (final IOException e) { 121 Utils.getExceptionLogger() 122 .debug("Unable to save cache file.", e); 123 } 124 finally { 125 if (out != null) { 126 try { 127 out.flush(); 128 out.close(); 129 } 130 catch (final IOException ex) { 131 Utils.getExceptionLogger() 132 .debug("Unable to close cache file.", ex); 133 } 134 } 135 } 136 } 137 } 138 139 144 boolean alreadyChecked(String aFileName, long aTimestamp) 145 { 146 final String lastChecked = mDetails.getProperty(aFileName); 147 return (lastChecked != null) 148 && (lastChecked.equals(Long.toString(aTimestamp))); 149 } 150 151 156 void checkedOk(String aFileName, long aTimestamp) 157 { 158 mDetails.put(aFileName, Long.toString(aTimestamp)); 159 } 160 161 167 private String getConfigHashCode(Serializable aConfiguration) 168 { 169 try { 170 172 final ByteArrayOutputStream baos = new ByteArrayOutputStream (); 173 final ObjectOutputStream oos = new ObjectOutputStream (baos); 174 oos.writeObject(aConfiguration); 175 oos.flush(); 176 oos.close(); 177 178 182 final MessageDigest md = MessageDigest.getInstance("SHA"); 183 md.update(baos.toByteArray()); 184 185 return hexEncode(md.digest()); 186 } 187 catch (final Exception ex) { Utils.getExceptionLogger() 189 .debug("Unable to calculate hashcode.", ex); 190 return "ALWAYS FRESH: " + System.currentTimeMillis(); 191 } 192 } 193 194 195 private static final char[] HEX_CHARS = { 196 '0', '1', '2', '3', '4', '5', '6', '7', 197 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 198 }; 199 200 201 private static final int MASK_0X0F = 0x0F; 202 203 204 private static final int SHIFT_4 = 4; 205 206 211 private static String hexEncode(byte[] aByteArray) 212 { 213 final StringBuffer buf = new StringBuffer (2 * aByteArray.length); 214 for (int i = 0; i < aByteArray.length; i++) { 215 final int b = aByteArray[i]; 216 final int low = b & MASK_0X0F; 217 final int high = (b >> SHIFT_4) & MASK_0X0F; 218 buf.append(HEX_CHARS[high]); 219 buf.append(HEX_CHARS[low]); 220 } 221 return buf.toString(); 222 } 223 } 224 | Popular Tags |