Clover coverage report -
Coverage timestamp: Sat Apr 30 2005 21:58:28 PDT
file stats: LOC: 109   Methods: 3
NCLOC: 59   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
HashDiskPersistenceListener.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  * Copyright (c) 2002-2003 by OpenSymphony
 3   
  * All rights reserved.
 4   
  */
 5   
 package com.opensymphony.oscache.plugins.diskpersistence;
 6   
 
 7   
 import com.opensymphony.oscache.base.Config;
 8   
 import com.opensymphony.oscache.base.persistence.PersistenceListener;
 9   
 
 10   
 import java.security.MessageDigest;
 11   
 import java.security.NoSuchAlgorithmException;
 12   
 
 13   
 /**
 14   
  * Persists cache data to disk. Provides a hash of the standard key name as the file name.
 15   
  *
 16   
  * A configurable hash algorithm is used to create a digest of the cache key for the
 17   
  * disk filename. This is to allow for more sane filenames for objects which dont generate
 18   
  * friendly cache keys.
 19   
  *
 20   
  * @author <a href="mailto:jparrott@soe.sony.com">Jason Parrott</a>
 21   
  */
 22   
 public class HashDiskPersistenceListener extends AbstractDiskPersistenceListener {
 23   
     public final static String HASH_ALGORITHM_KEY = "cache.persistence.disk.hash.algorithm";
 24   
     public final static String DEFAULT_HASH_ALGORITHM = "MD5";
 25   
     protected MessageDigest md = null;
 26   
 
 27   
     /**
 28   
      * Initializes the <tt>HashDiskPersistenceListener</tt>. Namely this involves only setting up the
 29   
      * message digester to hash the key values.
 30   
      * @see com.opensymphony.oscache.base.persistence.PersistenceListener#configure(com.opensymphony.oscache.base.Config)
 31   
      */
 32  0
     public PersistenceListener configure(Config config) {
 33  0
         try {
 34  0
             if (config.getProperty(HashDiskPersistenceListener.HASH_ALGORITHM_KEY) != null) {
 35  0
                 try {
 36  0
                     md = MessageDigest.getInstance(config.getProperty(HashDiskPersistenceListener.HASH_ALGORITHM_KEY));
 37   
                 } catch (NoSuchAlgorithmException e) {
 38  0
                     md = MessageDigest.getInstance(HashDiskPersistenceListener.DEFAULT_HASH_ALGORITHM);
 39   
                 }
 40   
             } else {
 41  0
                 md = MessageDigest.getInstance(HashDiskPersistenceListener.DEFAULT_HASH_ALGORITHM);
 42   
             }
 43   
         } catch (NoSuchAlgorithmException e) {
 44  0
             e.printStackTrace();
 45  0
             throw new RuntimeException("No hash algorithm available for disk persistence", e);
 46   
         }
 47   
 
 48  0
         return super.configure(config);
 49   
     }
 50   
 
 51   
     /**
 52   
      * Generates a file name for the given cache key. In this case the file name is attempted to be
 53   
      * generated from the hash of the standard key name. Cache algorithm is configured via the
 54   
      * <em>cache.persistence.disk.hash.algorithm</em> configuration variable.
 55   
      * @param key cache entry key
 56   
      * @return char[] file name
 57   
      */
 58  0
     protected char[] getCacheFileName(String key) {
 59  0
         byte[] digest;
 60   
 
 61  0
         if ((key == null) || (key.length() == 0)) {
 62  0
             throw new IllegalArgumentException("Invalid key '" + key + "' specified to getCacheFile.");
 63   
         }
 64   
 
 65  0
         digest = md.digest(key.getBytes());
 66   
 
 67  0
         String hexString = byteArrayToHexString(digest);
 68  0
         return hexString.toCharArray();
 69   
     }
 70   
 
 71   
     /**
 72   
      * Nibble conversion. Thanks to our friends at:
 73   
      * http://www.devx.com/tips/Tip/13540
 74   
      * @param in the byte array to convert
 75   
      * @return a java.lang.String based version of they byte array
 76   
      */
 77  0
     static String byteArrayToHexString(byte[] in) {
 78  0
         byte ch = 0x00;
 79  0
         int i = 0;
 80   
 
 81  0
         if ((in == null) || (in.length <= 0)) {
 82  0
             return null;
 83   
         }
 84   
 
 85  0
         String[] pseudo = {
 86   
             "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
 87   
             "E", "F"
 88   
         };
 89  0
         StringBuffer out = new StringBuffer(in.length * 2);
 90   
 
 91  0
         while (i < in.length) {
 92  0
             ch = (byte) (in[i] & 0xF0); // Strip off high nibble
 93  0
             ch = (byte) (ch >>> 4);
 94   
 
 95   
             // shift the bits down
 96  0
             ch = (byte) (ch & 0x0F);
 97   
 
 98   
             //     must do this is high order bit is on!
 99  0
             out.append(pseudo[(int) ch]); // convert the nibble to a String Character
 100  0
             ch = (byte) (in[i] & 0x0F); // Strip off low nibble 
 101  0
             out.append(pseudo[(int) ch]); // convert the nibble to a String Character
 102  0
             i++;
 103   
         }
 104   
 
 105  0
         String rslt = new String(out);
 106  0
         return rslt;
 107   
     }
 108   
 }
 109