package info.ephyra.util; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; /** * <p>The <code>FileCache</code> is a simple implementation of a permanent * cache. The entries of the cache are accessed by keys. Both keys and entries * are strings, and there may be an arbitrary number of entries for a key.</p> * * <p>The entries are stored in files in a directory which is specified when the * cache handler is created. There is one file for each key and the MD5 checksum * of the key is used as the filename.</p> * * @author Nico Schlaefer * @version 2006-11-27 */ public class FileCache { /** The directory where the files are stored. */ private String cacheDir; /** * Creates a new cache handler and sets the directory of the cache. * * @param cacheDir cache directory */ public FileCache(String cacheDir) { this.cacheDir = cacheDir; } /** * Computes the MD5 checksum of a string. * * @param s the string * @return checksum, or <code>null</code> if the MD5 algorithm is not * available */ private String getMD5(String s) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) {return null;} digest.update(s.getBytes()); byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); return bigInt.toString(16); } /** * Read the entries for the given key from the cache. * * @param key the key * @return the entries, or <code>null</code> if the key is not in the cache */ public String[] read(String key) { // compute checksum for the key String checksum = getMD5(key); if (checksum == null) return null; // read cache entries from a file, using the checksum as the filename File file = new File(cacheDir, new String(checksum)); try { ArrayList<String> entries = new ArrayList<String>(); BufferedReader in = new BufferedReader(new FileReader(file)); while (in.ready()) entries.add(in.readLine()); in.close(); return entries.toArray(new String[entries.size()]); } catch (IOException e) {return null;} // key is not in the cache } /** * Writes new entries to the cache. Existing entries with the given key are * overwritten. * * @param key the key * @param entries the entries * @return <code>true<code> iff the entries could be written to the cache */ public boolean write(String key, String[] entries) { // compute checksum for the key String checksum = getMD5(key); if (checksum == null) return false; // write new cache entries to a file, using the checksum as the filename File file = new File(cacheDir, new String(checksum)); try { PrintWriter out = new PrintWriter(file); for (String entry : entries) out.println(entry); out.close(); return true; } catch (IOException e) {return false;} // entries could not be written } }