Package net.sourceforge.squirrel_sql.fw.util

Source Code of net.sourceforge.squirrel_sql.fw.util.ObjectCache$CacheEntry

package net.sourceforge.squirrel_sql.fw.util;
/*
* Copyright (C) 2001-2003 Colin Bell
* colbell@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.swing.event.EventListenerList;

import net.sourceforge.squirrel_sql.fw.id.IHasIdentifier;
import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
/**
* This class is a cache of objects. All objects stored must implement
* <CODE>IHasIdentifier</CODE>.<P>
*
* @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
*/
public class ObjectCache<E extends IHasIdentifier> implements IObjectCache<E>
{
  /** This collection stores <CODE>CacheEntry</CODE> objects. */
  private Map<Class<E>, CacheEntry<E>> _entries = new HashMap<Class<E>, CacheEntry<E>>();

  /**
   * Default constructor.
   */
  public ObjectCache()
  {
    super();
  }

  /**
   * Retrieve a stored object.
   *
   * @param  objClass  The class of the object to be retrieved.
   * @param  id      The <CODE>IIdentifier</CODE> that identifies
   *            the object to be retrieved.
   *
   * @return  The <CODE>IHasIdentifier</CODE> retrieved or <CODE>null</CODE>
   *      if no object exists for <CODE>id</CODE>.
   */
  public synchronized IHasIdentifier get(Class<E> objClass, IIdentifier id)
  {
    return getCacheEntry(objClass).get(id);
  }

  /**
   * Store an object.
   *
   * @param  obj   Object to be stored.
   *
   * @exception  DuplicateObjectException
   *         Thrown if an object of the same class as <CODE>obj</CODE>
   *        and with the same identifier is already in the cache.
   */
  @SuppressWarnings("unchecked")
  public synchronized void add(E obj) throws DuplicateObjectException
  {
    getCacheEntry((Class<E>) obj.getClass()).add(obj);
  }

  /**
   * Remove an object.
   *
   * @param  objClass  Class of object to be removed.
   * @param  id      Identifier for object to be removed.
   */
  public synchronized void remove(Class<E> objClass, IIdentifier id)
  {
    getCacheEntry(objClass).remove(id);
  }

  /**
   * Adds a listener for changes to the cache entry for the passed class.
   *
   * @param  lis      a IObjectCacheChangeListener that will be notified
   *            when objects are added or removed from this cache
   *            entry.
   * @param  objClass  The class of objects whose cache we want to listen
   *            to.
   */
  public void addChangesListener(IObjectCacheChangeListener lis, Class<E> objClass)
  {
    getCacheEntry(objClass).addChangesListener(lis);
  }

  /**
   * Removes a listener for changes to the cache entry for the passed class.
   *
   * @param  lis      a IObjectCacheChangeListener that will be notified
   *            when objects are added or removed from this cache
   *            entry.
   * @param  objClass  The class of objects whose cache we want to listen
   *            to.
   */
  public void removeChangesListener(IObjectCacheChangeListener lis, Class<E> objClass)
  {
    getCacheEntry(objClass).removeChangesListener(lis);
  }

  /**
   * Return an array of <CODE>Class</CODE objects that represent all the
   * different types of objects stored.
   *
   * @return  Class[] of all classes stored.
   */
  @SuppressWarnings("unchecked")
  public synchronized Class<E>[] getAllClasses()
  {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (Iterator<Class<E>> it = _entries.keySet().iterator(); it.hasNext();)
    {
      classes.add(it.next());
      //classes.add(((CacheEntry)it.next())._objClass);
    }
    if (classes.size() > 0)
    {
      return classes.toArray(new Class[classes.size()]);
    }
    return new Class[0];
  }

  /**
   * Return an <CODE>Iterator</CODE> of all objects stored for the
   * passed class.
   *
   * @param  objClass  Class to return objects for.
   *
   * @return  <CODE>Iterator</CODE> over all objects.
   */
  public synchronized Iterator<E> getAllForClass(Class<E> objClass)
  {
    return getCacheEntry(objClass).values().iterator();
  }

  /**
   * Return a <CODE>CacheEntry</CODE> for the passed class. If one doesn't
   * exist then create it and add to <CODE>_entries</CODE>.
   *
   * @param  objClass  Class to return <CODE>CacheEntry</CODE> for.
   *
   * @return  <CODE>CacheEntry</CODE> which stores objects of type
   *      <CODE>objClass</CODE>.
   */
  private CacheEntry<E> getCacheEntry(Class<E> objClass)
  {
    CacheEntry<E> entry = _entries.get(objClass);
    if (entry == null)
    {
      entry = new CacheEntry(objClass);
      _entries.put(objClass, entry);
    }
    return entry;
  }

  /**
   * These objects are collections for a single class.
   */
  private final class CacheEntry<T extends E>
  {
    /** Class of objects stored here. */
    private Class<? extends T> _objClass;

    /** Collection of stored objects keyed by their <CODE>IIdentifier</CODE>. */
    private Map<IIdentifier, T> _coll = new HashMap<IIdentifier, T>();

    /**
     * Collection of listeners that are told of additions and removals
     * from this collection.
     */
    private EventListenerList _listenerList = new EventListenerList();

    /**
     * Ctor.
     *
     * @param   objClass  Class of objects to be stored in this collection.
     */
    CacheEntry(Class<? extends T> objClass)
    {
      super();
      _objClass = objClass;
    }

    /**
     * Retrieve an object from this collection.
     *
     * @param   id    ID of object to be returned.
     *
     * @return  The object stored for <CODE>id</CODE> or <CODE>null</CODE>
     *      if none exists.
     */
    IHasIdentifier get(IIdentifier id)
    {
      return _coll.get(id);
    }

    /**
     * Store an object.
     *
     * @param   obj   Object to be stored.
     *
     * @exception   DuplicateObjectException
     *        Thrown if an object of the same class as <CODE>obj</CODE>
     *        and with the same identifier is already in the cache.
     *
     * @exception   IllegalArgumentException
     *        Thrown if <CODE>obj</CODE> is not of type <CODE>_objClass</CODE>.
     */
    void add(T obj)
        throws DuplicateObjectException, IllegalArgumentException{
      if (get(obj.getIdentifier()) != null)
      {
        throw new DuplicateObjectException(obj);
      }
      if (!_objClass.isInstance(obj))
      {
        throw new IllegalArgumentException("IHasIdentifier is not an instance of " + _objClass.getName()); //i18n
      }
      _coll.put(obj.getIdentifier(), obj);
      fireObjectAdded(obj);
    }

    /**
     * Remove an object.
     *
     * @param   id    Identifier of object to be removed.
     */
    void remove(IIdentifier id)
    {
      IHasIdentifier obj = get(id);
      if (obj != null)
      {
        _coll.remove(id);
        fireObjectRemoved(obj);
      }
    }

    /**
     * Return a <CODE>Collection</CODE> of all objects in this entry.
     */
    Collection<T> values()
    {
      return _coll.values();
    }

    /**
     * Adds a listener for changes in this cache entry.
     *
     * @param   lis a IObjectCacheChangeListener that will be notified when
     *      objects are added and removed from this cache entry.
     */
    void addChangesListener(IObjectCacheChangeListener lis)
    {
      _listenerList.add(IObjectCacheChangeListener.class, lis);
    }

    /**
     * Removes a listener for changes in this cache entry.
     *
     * @param   lis a IObjectCacheChangeListener that will be notified when
     *      objects are added and removed from this cache entry.
     */
    void removeChangesListener(IObjectCacheChangeListener lis)
    {
      _listenerList.remove(IObjectCacheChangeListener.class, lis);
    }

    /**
     * Fire an "Object Added" event to all listeners.
     *
     * @param   obj   The object added.
     */
    private void fireObjectAdded(IHasIdentifier obj)
    {
      // Guaranteed to be non-null.
      Object[] listeners = _listenerList.getListenerList();
      // Process the listeners last to first, notifying
      // those that are interested in this event.
      ObjectCacheChangeEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i-=2 )
      {
        if (listeners[i] == IObjectCacheChangeListener.class)
        {
          // Lazily create the event.
          if (evt == null)
          {
            evt = new ObjectCacheChangeEvent(ObjectCache.this, obj);
          }
          ((IObjectCacheChangeListener)listeners[i + 1]).objectAdded(evt);
        }
      }
    }

    /**
     * Fire an "Object Removed" event to all listeners.
     *
     * @param   obj   The object added.
     */
    private void fireObjectRemoved(IHasIdentifier obj)
    {
      // Guaranteed to be non-null.
      Object[] listeners = _listenerList.getListenerList();
      // Process the listeners last to first, notifying
      // those that are interested in this event.
      ObjectCacheChangeEvent evt = null;
      for (int i = listeners.length - 2; i >= 0; i-=2 )
      {
        if (listeners[i] == IObjectCacheChangeListener.class)
        {
          // Lazily create the event:
          if (evt == null)
          {
            evt = new ObjectCacheChangeEvent(ObjectCache.this, obj);
          }
          ((IObjectCacheChangeListener)listeners[i + 1]).objectRemoved(evt);
        }
      }
    }
  }
}
TOP

Related Classes of net.sourceforge.squirrel_sql.fw.util.ObjectCache$CacheEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.