A Simple cache implement

  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. /**
  7.  * A simple implementation of {@link Cache}.
  8.  * <p>
  9.  * This cache implements most of the methods defined in {@link Cache}, using a
  10.  * <tt>ConcurrentHashMap</tt> to store objects, which could provide better
  11.  * performance in concurrent enviroment.
  12.  * </p>
  13.  */
  14. public abstract class AbstractCache implements Cache {
  15.     /**
  16.      * This cache uses a concurrent hash map to store object.
  17.      */
  18.     Map storage = new HashMap();
  19.     public boolean hasKey(Object key) {
  20.         if (key == null) {
  21.             return false;
  22.         }
  23.         return storage.containsKey(key);
  24.     }
  25.     /**
  26.      * Identifier of this cache, unique and not null.
  27.      */
  28.     private final Object identifier;
  29.     /**
  30.      * Constructs a new cache with speicified identifier. The identifier should
  31.      * be unique and not <tt>null</tt>.
  32.      * 
  33.      * @param identifier
  34.      *            the identifier of the new cache, which is unique and not null
  35.      * @throws IllegalArgumentException
  36.      *             if the identifier is <tt>null</tt>
  37.      */
  38.     public AbstractCache(Object identifier) throws IllegalArgumentException {
  39.         if (identifier == null) {
  40.             throw new IllegalArgumentException(
  41.                     "The identifier of cache should NOT be null.");
  42.         }
  43.         this.identifier = identifier;
  44.     }
  45.     public void clear() {
  46.         storage.clear();
  47.     }
  48.     public boolean hasObject(Object object) {
  49.         if (object == null) {
  50.             return false;
  51.         }
  52.         return storage.containsValue(object);
  53.     }
  54.     public Object fetch(Object key) {
  55.         return storage.get(key);
  56.     }
  57.     public Collection fetchAll() {
  58.         return storage.values();
  59.     }
  60.     public Object getIdentifier() {
  61.         return this.identifier;
  62.     }
  63.     public void remove(Object key) {
  64.         storage.remove(key);
  65.     }
  66.     public void save(Object key, Object value) throws IllegalArgumentException {
  67.         if (key == null || value == null) {
  68.             throw new IllegalArgumentException(
  69.                     "No null key or value allowed in cache.");
  70.         }
  71.         storage.put(key, value);
  72.     }
  73.     public void save(Object value) throws IllegalArgumentException {
  74.         save(createKey(value), value);
  75.     }
  76.     public int size() {
  77.         return storage.size();
  78.     }
  79.     public abstract Object createKey(Object object) throws IllegalArgumentException;
  80.     public void saveAll(Collection values) {
  81.         for (Iterator it = values.iterator(); it.hasNext();) {
  82.             save(it.next());
  83.         }
  84.     }
  85.     public void saveAll(Map values) {
  86.         storage.putAll(values);
  87.     }
  88.     public Collection keys() {
  89.         return storage.keySet();
  90.     }
  91. }
  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. import java.util.Map;
  4. /**
  5.  * A cache keeps objects that may be used frequently in memory, it is made up of
  6.  * a pool of entries . Usually cache is used to improve performance, because
  7.  * memory is always faster that DB or disk I/O.
  8.  * <p>
  9.  * Caches do not accept <tt>null</tt> keys or values. They may store kinds of
  10.  * objects, however, it is better that each cache stores only one type of
  11.  * objects, using a key mapping for association.
  12.  * </p>
  13.  * <p>
  14.  * For performance, reading methods is not necessary to be synchronized.
  15.  * However, adding, updating and removing should be synchronized when caches
  16.  * might be accessed by many threads.
  17.  * </p>
  18.  */
  19. public interface Cache {
  20.     /**
  21.      * Clears contents of this caches.
  22.      */
  23.     public void clear();
  24.     /**
  25.      * Creates a unique key for given object using some rules, if the object is
  26.      * not in cache yet. If the object exists in cache, returns its key.
  27.      * 
  28.      * @param object
  29.      *            an object in which the cache would save
  30.      * @return the key of the object
  31.      * @throws IllegalArgumentException
  32.      *             if the object is <tt>null</tt>
  33.      */
  34.     public Object createKey(Object object) throws IllegalArgumentException;
  35.     /**
  36.      * Returns the value to which maps the specified key in cache. Returns
  37.      * <tt>null</tt> if the cache contains no mapping for this key.
  38.      * <p>
  39.      * If this method is not synchronized, the performance might be higher, and
  40.      * would not brings chaos when accessed by more than one thread.
  41.      * </p>
  42.      * 
  43.      * @param key
  44.      *            key whose associated value is to be returned
  45.      * @return the value to which the cache maps the specified key, or null if
  46.      *         the cacache contains no mapping for this key.
  47.      */
  48.     public Object fetch(Object key);
  49.     /**
  50.      * Returns all the objects stored in this cache.
  51.      * <p>
  52.      * This method is not needed to be synchronized.
  53.      * </p>
  54.      * 
  55.      * @return a <code>Collection</code> of objects stored in the cache
  56.      * @see #fetch(Object)
  57.      */
  58.     public Collection fetchAll();
  59.     /**
  60.      * Returns the identifier of this cache, which should be <tt>unique</tt>
  61.      * and NOT <tt>null</tt>.
  62.      * 
  63.      * @return the unique identifier of this cache
  64.      */
  65.     public Object getIdentifier();
  66.     /**
  67.      * Returns <tt>true</tt> if this cache contains a mapping for the
  68.      * specified key. (There can be at most one such mapping.)
  69.      * <p>
  70.      * If the key is <tt>null</tt>, this method always returns <tt>false</tt>.
  71.      * Because cache does allow <tt>null</tt> keys or values.
  72.      * </p>
  73.      * 
  74.      * @param key
  75.      *            key whose presence in this cache is to be tested.
  76.      * @return true if this map contains a mapping for the specified key
  77.      */
  78.     public boolean hasKey(Object key);
  79.     /**
  80.      * Returns <tt>true</tt> if the cache has one or more keys to the
  81.      * specified object. More formally, returns <tt>true</tt> if and only if
  82.      * the cache contains at least one mapping to an object.
  83.      * <p>
  84.      * Since cache does not allow null values, if the object is <tt>null</tt>,
  85.      * always returns <tt>false</tt>.
  86.      * </p>
  87.      * 
  88.      * @param object
  89.      *            value whose presence in this map is to be tested.
  90.      * @return <tt>true</tt> if this cache maps one or more keys to the
  91.      *         specified value
  92.      */
  93.     public boolean hasObject(Object object);
  94.     /**
  95.      * Removes the mapping for this key from this cache if the key presents. If
  96.      * the key is null, this method has no effect on cache.
  97.      * 
  98.      * @param key
  99.      *            mapping key in the cache which is to be removed
  100.      */
  101.     public void remove(Object key);
  102.     /**
  103.      * Store the specified object with the specified key in this cache. If the
  104.      * cache previously contained a mapping for this key, the old value is
  105.      * replaced by the specified value.
  106.      * <p>
  107.      * Note that this method do not accept null key or null value. And this
  108.      * method should be synchronized when possibly accessed by more than one
  109.      * thread.
  110.      * </p>
  111.      * 
  112.      * @param key
  113.      *            key with which the specified object is to be associated.
  114.      * @param value
  115.      *            object to be stored in the cache, and associated with the
  116.      *            specified key
  117.      * @throws IllegalArgumentException
  118.      *             if the key or value is null
  119.      */
  120.     public void save(Object key, Object value) throws IllegalArgumentException;
  121.     /**
  122.      * Save the object to the cache. The implementation must provide a key for
  123.      * the association in the cache.
  124.      * <p>
  125.      * This method does not accepts null values. And it should be synchronized
  126.      * in enviroment of multi-thread.
  127.      * </p>
  128.      * 
  129.      * @param value
  130.      *            the object to save
  131.      * @throws IllegalArgumentException
  132.      *             if the value is null
  133.      * @see #save(Object, Object)
  134.      * @see #createKey(Object)
  135.      */
  136.     public void save(Object value) throws IllegalArgumentException;
  137.     /**
  138.      * Adds all of the elements in the specified collection to this cache.
  139.      * 
  140.      * @param values
  141.      *            objects to be saved into this cache
  142.      * @throws IllegalArgumentException
  143.      *             if one or more objects are null
  144.      */
  145.     public void saveAll(Collection values) throws IllegalArgumentException;
  146.     /**
  147.      * Copies all of the mappings from the specified map to this cache. The
  148.      * effect of this call is equivalent to that of calling
  149.      * {@link #save(Object,Object) save(key, value)} on this cache once for each
  150.      * mapping from key to value in the specified map.
  151.      * 
  152.      * @param values
  153.      *            mappings to be stored in this map
  154.      * @throws IllegalArgumentException
  155.      *             if one key or object is null
  156.      */
  157.     public void saveAll(Map values) throws IllegalArgumentException;
  158.     /**
  159.      * Returns the number of objects stored in this cache. If the cache contains
  160.      * no data, returns zero.
  161.      * 
  162.      * @return the number of objects stored in a cache; returns zero if the
  163.      *         cache contains no data
  164.      */
  165.     public int size();
  166.     /**
  167.      * Returns a collection of the keys contained in this cache.
  168.      * 
  169.      * @return keys in this cache
  170.      */
  171.     public Collection keys();
  172. }
  1. package com.alex.commonutil.cache;
  2. /**
  3.  */
  4. public class CacheIncomingDataValidator {
  5.     
  6.     /**
  7.      * Check whether an object is a valid instance of a specified Class.
  8.      * 
  9.      * @param obj     the object going to be validated
  10.      * @param clazz   the specified Class
  11.      * 
  12.      * @return       true or false
  13.      */
  14.     public static boolean isValidObject(Class clazz, Object obj){
  15.         if(null == obj || null == clazz){
  16.             return false;
  17.         }
  18.         return clazz == obj.getClass();
  19.     }
  20. }
  1. package com.alex.commonutil.cache;
  2. /**
  3.  * This class consists exclusively of static methods that operate on or return
  4.  * caches.
  5.  */
  6. public class Caches {
  7.     /**
  8.      * If the key or value is null, throws an <tt>IllegalArgumentException</tt>.
  9.      * 
  10.      * @param object
  11.      *            the key or value may store in a cache
  12.      * @throws IllegalArgumentException
  13.      *             if the key or value is null
  14.      */
  15.     public static void verifyKeyValue(Object object)
  16.             throws IllegalArgumentException {
  17.         if (object == null) {
  18.             throw new IllegalArgumentException(
  19.                     "Cache does not allow null key or values.");
  20.         }
  21.     }
  22.     /**
  23.      * If the identifier of a cache is null, this method will throw an
  24.      * <tt>IllegalArgumentException</tt>.
  25.      * 
  26.      * @param identifier
  27.      *            the identifier of a cache
  28.      * @throws IllegalArgumentException
  29.      *             if the identifier is null
  30.      */
  31.     public static void verifyIdentifier(Object identifier)
  32.             throws IllegalArgumentException {
  33.         if (identifier == null) {
  34.             throw new IllegalArgumentException(
  35.                     "The identifier of a cache should not be null");
  36.         }
  37.     }
  38. }
  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. import java.util.Iterator;
  4. import java.util.Map;
  5. import java.util.Set;
  6. /**
  7.  * The cache service manages some caches, and providing a unified interface for
  8.  * access them. Caches managed by the service can be located by the identifiers.
  9.  * <p>
  10.  * Since caches do not accept <tt>null</tt> keys or values, there are many
  11.  * validations in those methods.
  12.  * </p>
  13.  */
  14. public abstract class CacheService {
  15.     /**
  16.      * Add a cache into the service's management. The cache must provide an
  17.      * available identifier.
  18.      * 
  19.      * @param cache
  20.      *            a cache to be managed
  21.      * @throws IllegalArgumentException
  22.      *             if the cache does not provide an available identifier
  23.      */
  24.     public abstract void addCache(Cache cache) throws IllegalArgumentException;
  25.     /**
  26.      * Removes a cache of specified identifier out of the management. If the
  27.      * cache is not under control, this method has no effect.
  28.      * 
  29.      * @param identifier
  30.      *            the identifier of a cache
  31.      */
  32.     public abstract void removeCache(Object identifier);
  33.     /**
  34.      * Clear contents of one cache associated with speicified identifier. If the
  35.      * cache does not exists or the identifier is <tt>null</tt>, this method
  36.      * has no effect.
  37.      * 
  38.      * @param identifier
  39.      *            the identifier of a cache
  40.      */
  41.     public void clear(Object identifier) {
  42.         if (hasCache(identifier)) {
  43.             getCache(identifier).clear();
  44.         }
  45.     }
  46.     /**
  47.      * Clears contents of all the caches.
  48.      */
  49.     public void clearAll() {
  50.         for (Iterator it = getCaches().iterator(); it.hasNext();) {
  51.             Cache cache = (Cache) it.next();
  52.             cache.clear();
  53.         }
  54.     }
  55.     /**
  56.      * Determines in which cache the given object will be put. By the cache
  57.      * identifier returned by this method, it would be easy to locate the cache.
  58.      * 
  59.      * @param object
  60.      *            the object to be cached
  61.      * @return the identifier of a cache in which the object will be put
  62.      */
  63.     public abstract Object getCacheIdentifier(Object object);
  64.     /**
  65.      * Get a collection of all the caches managed by this service.
  66.      * 
  67.      * @return an collection of caches managed by the service
  68.      */
  69.     public abstract Collection getCaches();
  70.     /**
  71.      * Returns true if the cache associated with specified identifier has a
  72.      * mapping to the specified object.
  73.      * <p>
  74.      * If the given object is null, always returns false, because cache do not
  75.      * allow <tt>null</tt> keys or values.
  76.      * </p>
  77.      * 
  78.      * @param identifier
  79.      *            the identifier of a cache
  80.      * @param object
  81.      *            key whose presence in the cache is to be tested
  82.      * @param asKey
  83.      *            whether take the object as key
  84.      * @return true if the cache associated with specified identifier has one or
  85.      *         more mapping to the specified key
  86.      */
  87.     public boolean contains(Object identifier, Object object, boolean asKey) {
  88.         if (identifier == null || object == null) {
  89.             return false;
  90.         }
  91.         if (!hasCache(identifier)) {
  92.             return false;
  93.         }
  94.         Cache cache = getCache(identifier);
  95.         return (asKey == true) ? cache.hasKey(object) : cache.hasObject(object);
  96.     }
  97.     /**
  98.      * Returns true if the cache associated with specified identifier has a
  99.      * mapping to the specified key.
  100.      * <p>
  101.      * If the key is <tt>null</tt>, always returns false, because cache do
  102.      * not allow <tt>null</tt> keys or values.
  103.      * </p>
  104.      * 
  105.      * @param identifier
  106.      *            the identifier of a cache
  107.      * @param object
  108.      *            key whose presence in the cache is to be tested
  109.      * @return true if the cache associated with specified identifier has a
  110.      *         mapping to the specified key
  111.      */
  112.     public boolean contains(Object identifier, Object object) {
  113.         return contains(identifier, object, false);
  114.     }
  115.     /**
  116.      * Returns the number of caches managed by the service.
  117.      * 
  118.      * @return count of caches
  119.      */
  120.     public abstract int countOfCaches();
  121.     /**
  122.      * Returns the value to which maps the specified key in cache. Returns
  123.      * <tt>null</tt> if the cache contains no mapping for this key.
  124.      * <p>
  125.      * If this method is not synchronized, the performance might be higher, and
  126.      * would not brings chaos when accessed by more than one thread.
  127.      * </p>
  128.      * 
  129.      * @param identifier
  130.      *            the identifier of a cache
  131.      * @param key
  132.      *            the key whose associated value is to be returned
  133.      * @return the value to which the cache maps the specified key, or
  134.      *         <tt>null</tt> if the cacache contains no mapping for this key.
  135.      */
  136.     public Object fetch(Object identifier, Object key) {
  137.         return getCache(identifier).fetch(key);
  138.     }
  139.     /**
  140.      * Returns all the objects stored in a cache associated with specified
  141.      * identifier.
  142.      * <p>
  143.      * This method is not needed to be synchronized.
  144.      * </p>
  145.      * 
  146.      * @param identifier
  147.      *            the identifier of a cache
  148.      * @return a <code>Collection</code> of objects stored in the cache who is
  149.      *         associated with specified identifier
  150.      * @see #fetch(Object, Object)
  151.      */
  152.     public Collection fetchAll(Object identifier) {
  153.         if (!hasCache(identifier)) {
  154.             return null;
  155.         }
  156.         return getCache(identifier).fetchAll();
  157.     }
  158.     /**
  159.      * Locates a cache by the its identifier. If the cache does not exist,
  160.      * returns <tt>null</tt>.
  161.      * 
  162.      * @param identifier
  163.      *            the identifier of the cache
  164.      * @return a cache located by the identifier
  165.      */
  166.     public abstract Cache getCache(Object identifier);
  167.     /**
  168.      * Returns <tt>true</tt> if a cache is under management of the service,
  169.      * and it can be located by the identifier. If the cache cannot be located
  170.      * by the identifier, this method returns <tt>false</tt>. If the
  171.      * identifier is <tt>null</tt>, this method always returns false.
  172.      * 
  173.      * @param identifier
  174.      *            the identifier of the cache
  175.      * @return <tt>true</tt> if the cache can be located by the identifier
  176.      */
  177.     public abstract boolean hasCache(Object identifier);
  178.     /**
  179.      * Removes the mapping for this key from a cache if it is present. If the
  180.      * key is <tt>null</tt>, this method has no effect on cache.
  181.      * 
  182.      * @param identifier
  183.      *            the identifier of a cache
  184.      * @param key
  185.      *            mapping key in the cache which is to be removed
  186.      */
  187.     public void remove(Object identifier, Object key) {
  188.         if (!hasCache(identifier) || key == null) {
  189.             return;
  190.         }
  191.         getCache(identifier).remove(key);
  192.     }
  193.     /**
  194.      * Save an object to corresponding cache. The implementation must specify a
  195.      * cache by {@link #getCacheIdentifier(Object)}, and provide an available
  196.      * key for the association in the cache.
  197.      * 
  198.      * @param object
  199.      *            the object to save
  200.      * @throws IllegalArgumentException
  201.      *             if the object is <tt>null</tt>
  202.      * @see Cache#createKey(Object)
  203.      * @see #getCacheIdentifier(Object)
  204.      */
  205.     public void save(Object object) throws IllegalArgumentException {
  206.         Caches.verifyKeyValue(object);
  207.         Object identifier = getCacheIdentifier(object);
  208.         Object key = getCache(identifier).createKey(object);
  209.         save(identifier, key, object);
  210.     }
  211.     /**
  212.      * Save the object to the cache with an associated key. The implementation
  213.      * must specify a cache.
  214.      * <p>
  215.      * This method does not accepts <tt>null</tt> values. And it should be
  216.      * <tt>synchronized</tt> in enviroment of multi-thread.
  217.      * </p>
  218.      * 
  219.      * @param key
  220.      *            key with which the specified object is to be associated.
  221.      * @param value
  222.      *            object to be stored in the cache, and associated with the
  223.      *            specified key
  224.      * @throws IllegalArgumentException
  225.      *             if the key or value is <tt>null</tt>
  226.      * @see #save(Object, Object, Object)
  227.      * @see Cache#createKey(Object)
  228.      */
  229.     public void save(Object key, Object value) throws IllegalArgumentException {
  230.         Caches.verifyKeyValue(key);
  231.         Caches.verifyKeyValue(value);
  232.         Object identifier = getCacheIdentifier(value);
  233.         save(identifier, key, value);
  234.     }
  235.     /**
  236.      * Store the specified object with the specified key in a cache associated
  237.      * with specified identifier. If the cache previously contained a mapping
  238.      * for this key, the old value is replaced by the specified value.
  239.      * <p>
  240.      * This is a default implementation. If the cache cannot located by the
  241.      * identifier, it would not be created. The sub classes may want to create a
  242.      * new cache when necessary.
  243.      * </p>
  244.      * <p>
  245.      * Note that this method do not accept <tt>null</tt> key or <tt>null</tt>
  246.      * value. And this method should be synchronized when possibly accessed by
  247.      * more than one thread.
  248.      * </p>
  249.      * 
  250.      * @param identifier
  251.      *            the identifier of a cache
  252.      * @param key
  253.      *            key with which the specified object is to be associated.
  254.      * @param value
  255.      *            object to be stored in the cache, and associated with the
  256.      *            specified key
  257.      * @throws IllegalArgumentException
  258.      *             if the identifier, key or value is <tt>null</tt>
  259.      */
  260.     public void save(final Object identifier, final Object key,
  261.             final Object value) throws IllegalArgumentException {
  262.         /*
  263.          * Make sure the identifier, key and value is not null
  264.          */
  265.         Caches.verifyIdentifier(identifier);
  266.         Caches.verifyKeyValue(key);
  267.         Caches.verifyKeyValue(value);
  268.         getCache(identifier).save(key, value);
  269.     }
  270.     /**
  271.      * Returns the number of objects stored in a cache. If the cache does not
  272.      * exist or the given identifier is <tt>null</tt>, always return zero.
  273.      * 
  274.      * @param identifier
  275.      *            the identifier of a cache
  276.      * @return number of objects stored in a cache; or zero if the identifier is
  277.      *         <tt>null</tt> or the cache does not exist
  278.      */
  279.     public int sizeOfCache(Object identifier) {
  280.         if (!hasCache(identifier)) {
  281.             return 0;
  282.         }
  283.         return getCache(identifier).size();
  284.     }
  285.     /**
  286.      * Save all of the elements in the specified collection to a cache specified
  287.      * by the identifier.
  288.      * 
  289.      * @param identifier
  290.      *            the identifier of a cache
  291.      * @param objects
  292.      *            objects to be saved into a cache
  293.      * @throws IllegalArgumentException
  294.      *             if the identifier, one or more objects in collection are
  295.      *             <tt>null</tt>
  296.      */
  297.     public void saveAll(Object identifier, Collection objects)
  298.             throws IllegalArgumentException {
  299.         Caches.verifyIdentifier(identifier);
  300.         getCache(identifier).saveAll(objects);
  301.     }
  302.     /**
  303.      * Copies all of the mappings from the specified map to a cache speicified
  304.      * by the identifier.
  305.      * 
  306.      * @param identifier
  307.      *            the identifier of a cache
  308.      * @param objects
  309.      *            objects to be saved into a cache
  310.      * @throws IllegalArgumentException
  311.      *             if the identifier, one key or object in mapping is
  312.      *             <tt>null</tt>
  313.      */
  314.     public void saveAll(Object identifier, Map objects)
  315.             throws IllegalArgumentException {
  316.         Caches.verifyIdentifier(identifier);
  317.         getCache(identifier).saveAll(objects);
  318.     }
  319.     /**
  320.      * Save all of the elements in the specified collection to a cache. Before
  321.      * saving these objects, please ensure that the corresponding cache has
  322.      * provided available keys.
  323.      * 
  324.      * @param objects
  325.      *            objects to be saved into a cache
  326.      * @throws IllegalArgumentException
  327.      *             if one object is <tt>null</tt>
  328.      * @see #save(Object)
  329.      * @see Cache#createKey(Object)
  330.      */
  331.     public void saveAll(Collection objects) throws IllegalArgumentException {
  332.         for (Iterator it = objects.iterator(); it.hasNext();) {
  333.             save(it.next());
  334.         }
  335.     }
  336.     /**
  337.      * Copies all of the mappings from the specified map to a cache. The effect
  338.      * of this call is equivalent to that of calling
  339.      * {@link #save(Object,Object) save(key, value)} on this cache once for each
  340.      * mapping from key to value in the specified map.
  341.      * 
  342.      * @param objects
  343.      *            mappings to be stored in this map
  344.      * @see #save(Object, Object)
  345.      * @throws IllegalArgumentException
  346.      *             if one key or object is <tt>null</tt>
  347.      */
  348.     public void saveAll(Map objects) throws IllegalArgumentException {
  349.         Set keys = objects.keySet();
  350.         for (Iterator it = keys.iterator(); it.hasNext();) {
  351.             Object k = (Object) it.next();
  352.             save(k, objects.get(k));
  353.         }
  354.     }
  355. }
  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. public class ConcreteCacheService extends CacheService {
  5.     /**
  6.      * A lock used when creating cache. If a cache does not exist, this lock can
  7.      * make sure that it will be created only once. And this
  8.      * <tt>ReentrantLock</tt> can also provide better performance than the
  9.      * <tt>synchronized</tt> key word.
  10.      */
  11.     private Object lock = new Object();
  12.     /**
  13.      * All the caches managed by the service.
  14.      */
  15.     private HashMap caches = new HashMap();
  16.     public synchronized void addCache(Cache cache) throws IllegalArgumentException {
  17.         if (cache == null) {
  18.             throw new IllegalArgumentException("The cache is null.");
  19.         }
  20.         Object identifier = cache.getIdentifier();
  21.         Caches.verifyIdentifier(identifier);
  22.         caches.put(identifier, cache);
  23.     }
  24.     public synchronized int countOfCaches() {
  25.         return caches.size();
  26.     }
  27.     /**
  28.      * Locates a cache by the class of objects stored in it.
  29.      * 
  30.      * @param identifier
  31.      *            the identifier of the cache
  32.      * @return a cache located by the class
  33.      */
  34.     public synchronized  Cache getCache(Object identifier) {
  35.         return (Cache)caches.get(identifier);
  36.     }
  37.     public  synchronized boolean hasCache(Object identifier) {
  38.         if (!(identifier instanceof Class)) {
  39.             return false;
  40.         }
  41.         return caches.containsKey(identifier);
  42.     }
  43.     /**
  44.      * Store the specified object with the specified key in a cache associated
  45.      * with specified identifier. If the cache cannot located by the identifier,
  46.      * a new cache associated with the identifier will be created.
  47.      * 
  48.      * @param identifier
  49.      *            the identifier of a cache
  50.      * @param key
  51.      *            key with which the specified object is to be associated.
  52.      * @param value
  53.      *            object to be stored in the cache, and associated with the
  54.      *            specified key
  55.      * @throws IllegalArgumentException
  56.      *             if the identifier, key or value is <tt>null</tt>
  57.      */
  58.     public void save(final Object identifier, final Object key,
  59.             final Object value) throws IllegalArgumentException {
  60.         Caches.verifyIdentifier(identifier);
  61.         Caches.verifyKeyValue(key);
  62.         Caches.verifyKeyValue(value);
  63.         /*
  64.          * If a cache of certain class does not exist, a new cache of this class
  65.          * will be created. The lock can make sure that the cache will be
  66.          * created only once.
  67.          */
  68.         if (!hasCache(identifier)) {
  69.             synchronized (lock) {
  70.                 if (!hasCache(identifier)) {
  71.                     Cache cache = new AbstractCache(identifier) {
  72.                         public Object createKey(Object object) {
  73.                             return key;
  74.                         }
  75.                     };
  76.                     addCache(cache);
  77.                     cache.save(key, value);
  78.                 } else {
  79.                     getCache(identifier).save(key, value);
  80.                 }
  81.             }
  82.         } else {
  83.             getCache(identifier).save(key, value);
  84.         }
  85.     }
  86.     public  synchronized Collection getCaches() {
  87.         return caches.values();
  88.     }
  89.     public  synchronized void removeCache(Object identifier) {
  90.         caches.remove(identifier);
  91.     }
  92.     public Object getCacheIdentifier(Object object) {
  93. //      if (object instanceof AbbrTradeLog) {
  94. //          AbbrTradeLog a = (AbbrTradeLog) object;
  95. //          return ((BBCacheServiceManager.TRADERID).equals(a.getCodeType())) ? BBCacheServiceManager.USERIDCACHE
  96. //                  : AbbrTradeLog.class;
  97. //      }
  98.         return object.getClass();
  99.     }
  100. }
  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. /**
  4.  * A persistable cache means it has a persisent storage as its backup, such as a
  5.  * database, file system or some other devices.
  6.  * <p>
  7.  * A cache may need a persistent storage as its backup, because cache can not
  8.  * hold data permanently. If power is off, the server crashes, or the cache
  9.  * crashes, all the data in caches will be lost. It is much better that each new
  10.  * added object can be persisted. When cache crashes, it can easily recover data
  11.  * from persistent storage. And this makes data in a cache much safer than those
  12.  * in caches without persistent storage.
  13.  * </p>
  14.  */
  15. public interface PersistableCache extends Cache {
  16.     /**
  17.      * Persist contents in this cache to certain storage.
  18.      * 
  19.      * @throws Exception
  20.      *             if an error occured
  21.      */
  22.     public void persist() throws Exception;
  23.     /**
  24.      * Persist one object to which maps the specified key in this cache to
  25.      * certain storage.
  26.      * 
  27.      * @param key
  28.      *            key with which the specified object is to be associated in
  29.      *            this cache.
  30.      * @throws Exception
  31.      *             if an error occured
  32.      */
  33.     public void persist(Object key) throws Exception;
  34.     /**
  35.      * Synchronizes contents of the cache with its persistence.
  36.      * 
  37.      * @see #load()
  38.      * @see #persist()
  39.      * @throws Exception
  40.      *             if an error occured
  41.      */
  42.     public void synchronize() throws Exception;
  43.     /**
  44.      * Synchronizes contents of the cache associated with speicified key with
  45.      * its persistence.
  46.      * 
  47.      * @see #load(Object)
  48.      * @see #persist(Object)
  49.      * @throws Exception
  50.      *             if an error occured
  51.      */
  52.     public void synchronize(Object key) throws Exception;
  53.     /**
  54.      * Load all the data from persistence to cache; returns all the loaded
  55.      * objects.
  56.      * 
  57.      * @return all the loaded objects
  58.      * @throws Exception
  59.      *             if an error occured
  60.      */
  61.     public Collection load() throws Exception;
  62.     /**
  63.      * Load object associated with given key to the cache; and retusn the loaded
  64.      * object.
  65.      * 
  66.      * @param key
  67.      *            the key whose associated object is to be loaded
  68.      * @return the object associated with the key
  69.      * @throws Exception
  70.      *             if an error occured
  71.      */
  72.     public Object load(Object key) throws Exception;
  73. }
  1. package com.alex.commonutil.cache;
  2. import java.util.Collection;
  3. import java.util.Iterator;
  4. /**
  5.  * This service manages persistable caches. A persistable cache means it has a
  6.  * persisent storage as its backup, such as a database, file system or some
  7.  * other devices.
  8.  */
  9. public abstract class PersistableCacheService extends CacheService {
  10.     /**
  11.      * Persist contents in a cache associated with specified identifier to
  12.      * certain storage.
  13.      * 
  14.      * @param identifier
  15.      *            the identifier of a cache
  16.      * @throws Exception
  17.      *             if an error occured
  18.      */
  19.     public void persist(Object identifier) throws Exception {
  20.         if (hasCache(identifier)) {
  21.             ((PersistableCache)getCache(identifier)).persist();
  22.         }
  23.     }
  24.     /**
  25.      * Persist one object to which maps the specified key in cache associated
  26.      * with specified identifier to certain storage.
  27.      * 
  28.      * @param identifier
  29.      *            the identifier of a cache
  30.      * @param key
  31.      *            key with which the specified object is to be associated in a
  32.      *            cache.
  33.      * @throws Exception
  34.      *             if an error occured
  35.      */
  36.     public void persist(Object identifier, Object key) throws Exception {
  37.         Caches.verifyKeyValue(key);
  38.         if (hasCache(identifier)) {
  39.             ((PersistableCache)getCache(identifier)).persist(key);
  40.         }
  41.     }
  42.     /**
  43.      * Persists all data in all caches to certain storage.
  44.      * 
  45.      * @throws Exception
  46.      *             if an error occured
  47.      */
  48.     public void persistAll() throws Exception {
  49.         for (Iterator it = getCaches().iterator(); it.hasNext();){
  50.             PersistableCache cache = (PersistableCache) it;
  51.             cache.persist();
  52.         }
  53.     }
  54.     /**
  55.      * Synchronizes contents of the cache with its persistent storage.
  56.      * 
  57.      * @param identifier
  58.      *            the identifier of a cache
  59.      * @throws Exception
  60.      *             if an error occured
  61.      */
  62.     public void synchronize(Object identifier) throws Exception {
  63.         if (hasCache(identifier)) {
  64.             ((PersistableCache)getCache(identifier)).synchronize();
  65.         }
  66.     }
  67.     /**
  68.      * Synchronizes content of specified key in the cache with its persistent
  69.      * storage.
  70.      * 
  71.      * @param identifier
  72.      *            the identifier of a cache
  73.      * @param key
  74.      *            the key with which the specified object is to be associated in
  75.      *            a cache. *
  76.      * @throws Exception
  77.      *             if an error occured
  78.      */
  79.     public void synchronize(Object identifier, Object key) throws Exception {
  80.         Caches.verifyKeyValue(key);
  81.         if (hasCache(identifier)) {
  82.             ((PersistableCache)getCache(identifier)).synchronize(key);
  83.         }
  84.     }
  85.     /**
  86.      * Synchronizes contents of the all caches with their persistent storages.
  87.      * 
  88.      * @throws Exception
  89.      *             if an error occured
  90.      */
  91.     public void synchronizeAll() throws Exception {
  92. //      for (PersistableCache cache : getCaches()) {
  93. //          cache.synchronize();
  94. //      }
  95.         
  96.         for (Iterator it = getCaches().iterator(); it.hasNext();){
  97.             PersistableCache cache = (PersistableCache) it;
  98.             cache.synchronize();
  99.         }
  100.     }
  101.     /**
  102.      * Load all the data from persistence to all caches managed by the service;
  103.      * returns all the loaded objects.
  104.      * 
  105.      * @return all the loaded objects
  106.      * @throws Exception
  107.      *             if an error occured
  108.      */
  109.     public void loadAll() throws Exception {
  110. //      for (PersistableCache cache : getCaches()) {
  111. //          cache.load();
  112. //      }
  113.         
  114.         for (Iterator it = getCaches().iterator(); it.hasNext();){
  115.             PersistableCache cache = (PersistableCache) it;
  116.             cache.load();
  117.         }
  118.     }
  119.     /**
  120.      * Load objects in persistent storage for a cache which can be located by
  121.      * the identifier; and retusn the loaded objects.
  122.      * 
  123.      * @param identifier
  124.      *            the identifier of a cache
  125.      * @return the objects for the cache in persist storage
  126.      * @throws Exception
  127.      *             if an error occured
  128.      */
  129.     public Collection load(Object identifier) throws Exception {
  130.         return (hasCache(identifier)) ? ((PersistableCache)getCache(identifier)).load() : null;
  131.     }
  132.     /**
  133.      * Load objects associated with given key to a cache which can be located by
  134.      * the identifier; and retusn the loaded object.
  135.      * 
  136.      * @param identifier
  137.      *            the identifier of a cache
  138.      * @param key
  139.      *            the key whose associated object is to be loaded
  140.      * @return the object associated with the key
  141.      * @throws Exception
  142.      *             if an error occured
  143.      */
  144.     public Object load(Object identifier, Object key) throws Exception {
  145.         Caches.verifyKeyValue(key);
  146.         return (hasCache(identifier)) ? ((PersistableCache)getCache(identifier)).load(key) : null;
  147.     }
  148.     public abstract Cache getCache(Object identifier);
  149.     public abstract Collection getCaches();
  150. }
  1. package com.alex.commonutil.cache.test;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import com.alex.commonutil.cache.AbstractCache;
  6. import com.alex.commonutil.cache.Cache;
  7. import com.alex.commonutil.cache.CacheService;
  8. import com.alex.commonutil.cache.ConcreteCacheService;
  9. public class CacheTest {
  10.     public static String CACHE_A = "CACHE_A";
  11.     public static String CACHE_B = "CACHE_B";
  12.     public static void main(String[] args) {
  13.         CacheService cs = new ConcreteCacheService();
  14.         Cache cacheA = new AbstractCache(CACHE_A) {
  15.             public Object createKey(Object object)
  16.                     throws IllegalArgumentException {
  17.                 String str = (String) object;
  18.                 return str;// tradeNumber as key
  19.             }
  20.         };
  21.         cs.addCache(cacheA);
  22.         
  23.         List listTest = new ArrayList();
  24.         listTest.add("AAA");
  25.         listTest.add("BBB");
  26.         cacheA.save("listTest", listTest);
  27.         
  28.         Cache cacheB = new AbstractCache(CACHE_B) {
  29.             public Object createKey(Object object)
  30.                     throws IllegalArgumentException {
  31.                 String str = (String) object;
  32.                 return str;// tradeNumber as key
  33.             }
  34.         };
  35.         cs.addCache(cacheB);
  36.         
  37.         Cache cacheAA = cs.getCache(CACHE_A);
  38.         List list=(List)cacheAA.fetch("listTest");
  39.         Iterator itr = list.iterator();
  40.         while (itr.hasNext()) {
  41.             System.out.println(itr.next());
  42.         }
  43.     }
  44. }
  1. package com.alex.commonutil.cache.test;
  2. import java.io.Serializable;
  3. import org.apache.commons.lang.builder.EqualsBuilder;
  4. import org.apache.commons.lang.builder.HashCodeBuilder;
  5. import org.apache.commons.lang.builder.ToStringBuilder;
  6. public class ValueObject implements Serializable {
  7.     private static final long serialVersionUID = 2118933350226194725L;
  8.     public java.lang.String getField1() {
  9.         return field1;
  10.     }
  11.     public void setField1(java.lang.String field1) {
  12.         this.field1 = field1;
  13.     }
  14.     public java.lang.String getField2() {
  15.         return field2;
  16.     }
  17.     public void setField2(java.lang.String field2) {
  18.         this.field2 = field2;
  19.     }
  20.     // fields
  21.     private java.lang.String field1;
  22.     private java.lang.String field2;
  23.     
  24.     public String toString() {
  25.         return new ToStringBuilder(this).toString();
  26.     }
  27.     
  28.     public int hashCode() {
  29.         return new HashCodeBuilder().append(this.getField1()).append(
  30.                 this.getField1()).toHashCode();
  31.     }
  32.     public boolean equals(Object obj) {
  33.         if (obj == null)
  34.             return false;
  35.         if (!(obj instanceof ValueObject))
  36.             return false;
  37.         if (this == obj)
  38.             return true;
  39.         ValueObject other = (ValueObject) obj;
  40.         return new EqualsBuilder()
  41.                 .append(this.getField1(), other.getField1()).append(
  42.                         this.getField2(), other.getField2()).isEquals();
  43.     }
  44. }

猜你喜欢

转载自blog.csdn.net/geggegeda/article/details/3125837