Package org.rssowl.core.internal.persist.dao

Source Code of org.rssowl.core.internal.persist.dao.CachingDAO

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2009 RSSOwl Development Team                                  **
**   http://www.rssowl.org/                                                 **
**                                                                          **
**   All rights reserved                                                    **
**                                                                          **
**   This program and the accompanying materials are made available under   **
**   the terms of the Eclipse Public License v1.0 which accompanies this    **
**   distribution, and is available at:                                     **
**   http://www.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */

package org.rssowl.core.internal.persist.dao;

import org.rssowl.core.internal.persist.service.DBManager;
import org.rssowl.core.internal.persist.service.DatabaseEvent;
import org.rssowl.core.internal.persist.service.DatabaseListener;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.dao.IEntityDAO;
import org.rssowl.core.persist.event.EntityListener;
import org.rssowl.core.persist.event.ModelEvent;
import org.rssowl.core.persist.event.runnable.EventType;
import org.rssowl.core.persist.service.PersistenceException;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
* Cache that stores all entities of type T in memory. In the future, we could
* improve it to store only entities that have been requested. We could also add
* eviction strategies at some point.
*
* @param <D>
* @param <T>
* @param <L>
* @param <E>
*/
public abstract class CachingDAO<D extends AbstractEntityDAO<T, L, E>, T extends IEntity, L extends EntityListener<E, T>, E extends ModelEvent> implements IEntityDAO<T, L, E> {
  protected static final boolean USE_LEGACY_CACHE_ACTIVATION = true;

  private final D fDAO;
  private final ConcurrentMap<Long, T> fCache;

  public CachingDAO(D dao) {
    fDAO = dao;
    fDAO.addEntityListener(createEntityListener());
    fCache = new ConcurrentHashMap<Long, T>(16, 0.75f, 1);

    /* Update the Cache based on Database Events */
    DBManager.getDefault().addEntityStoreListener(new DatabaseListener() {
      public void databaseClosed(DatabaseEvent event) {
        onDatabaseClosed(event);
      }

      public void databaseOpened(DatabaseEvent event) {
        onDatabaseOpened(event);
      }
    });
  }

  protected void putAll(Set<E> events) {
    for (E event : events) {
      fCache.put(event.getEntity().getId(), fDAO.getEntityClass().cast(event.getEntity()));
    }
  }

  protected void removeAll(Set<E> events) {
    for (E event : events) {
      fCache.remove(event.getEntity().getId());
    }
  }

  protected void onDatabaseClosed(@SuppressWarnings("unused") DatabaseEvent event) {
    fCache.clear();
  }

  protected void onDatabaseOpened(@SuppressWarnings("unused") DatabaseEvent event) {

    /* Ensure we start with a fresh cache */
    fCache.clear();

    /* Add all from DAO */
    for (T entity : fDAO.loadAll()) {
      fCache.put(entity.getId(), entity);
    }
  }

  /**
   * @return the listener to properly handle updates to the cache.
   */
  protected abstract L createEntityListener();

  /**
   * @return the DAO this cache is wrapping around.
   */
  protected final D getDAO() {
    return fDAO;
  }

  /**
   * @return the cache implementation (Map).
   */
  protected final ConcurrentMap<Long, T> getCache() {
    return fCache;
  }

  /*
   * @see org.rssowl.core.persist.dao.IEntityDAO#exists(long)
   */
  public final boolean exists(long id) throws PersistenceException {
    return fCache.containsKey(id);
  }

  /*
   * @see org.rssowl.core.persist.dao.IEntityDAO#load(long)
   */
  public final T load(long id) throws PersistenceException {
    return fCache.get(id);
  }

  /*
   * @see org.rssowl.core.persist.dao.IPersistableDAO#loadAll()
   */
  public final Collection<T> loadAll() throws PersistenceException {
    return Collections.unmodifiableCollection(fCache.values());
  }

  /*
   * @see org.rssowl.core.persist.dao.IEntityDAO#fireEvents(java.util.Set,
   * org.rssowl.core.persist.event.runnable.EventType)
   */
  public final void fireEvents(Set<E> events, EventType eventType) {
    fDAO.fireEvents(events, eventType);
  }

  /*
   * @see org.rssowl.core.persist.dao.IPersistableDAO#countAll()
   */
  public final long countAll() throws PersistenceException {
    return fCache.size();
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IEntityDAO#addEntityListener(org.rssowl.core
   * .persist.event.EntityListener)
   */
  public final void addEntityListener(L listener) {
    fDAO.addEntityListener(listener);
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IEntityDAO#removeEntityListener(org.rssowl.
   * core.persist.event.EntityListener)
   */
  public final void removeEntityListener(L listener) {
    fDAO.removeEntityListener(listener);
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IPersistableDAO#delete(org.rssowl.core.persist
   * .IPersistable)
   */
  public final void delete(T persistable) throws PersistenceException {
    fDAO.delete(persistable);
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IPersistableDAO#deleteAll(java.util.Collection)
   */
  public final void deleteAll(Collection<T> persistables) throws PersistenceException {
    fDAO.deleteAll(persistables);
  }

  /*
   * @see org.rssowl.core.persist.dao.IPersistableDAO#getEntityClass()
   */
  public final Class<? extends T> getEntityClass() {
    return fDAO.getEntityClass();
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IPersistableDAO#save(org.rssowl.core.persist
   * .IPersistable)
   */
  public final T save(T persistable) throws PersistenceException {
    return fDAO.save(persistable);
  }

  /*
   * @see
   * org.rssowl.core.persist.dao.IPersistableDAO#saveAll(java.util.Collection)
   */
  public final void saveAll(Collection<T> persistables) throws PersistenceException {
    fDAO.saveAll(persistables);
  }
}
TOP

Related Classes of org.rssowl.core.internal.persist.dao.CachingDAO

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.