/* ********************************************************************** ** ** 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.persist.dao; import org.rssowl.core.Owl; import org.rssowl.core.persist.IEntity; import org.rssowl.core.persist.IPersistable; import org.rssowl.core.persist.event.EntityListener; import org.rssowl.core.persist.event.ModelEvent; import org.rssowl.core.persist.service.PersistenceException; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Convinient access to commonly used methods from the persistence layer. */ public final class DynamicDAO { /* Singleton Instance */ private static DAOService DAO_SERVICE; private synchronized static final DAOService getDAOService() { if (DAO_SERVICE == null) DAO_SERVICE = Owl.getPersistenceService().getDAOService(); return DAO_SERVICE; } /** * Returns <code>true</code> if there's an entity with <code>id</code> and * <code>entityClass</code> in the persistence system. Returns * <code>false</code> otherwise. * * @param entityClass The Class of the entity. * @param id The id to be checked. * @return <code>true</code> if there's an entity with <code>id</code> and * <code>entityClass</code> in the persistence system. Returns * <code>false</code> otherwise. * @throws PersistenceException In case of an error while accessing the * persistence system. * @throws IllegalArgumentException if there is no DAO for * <code>entityClass</code>. */ public static boolean exists(Class<? extends IEntity> entityClass, long id) throws PersistenceException { IEntityDAO<?, ?, ?> dao = getDAOFromEntity(entityClass); checkEntityDAO(entityClass, dao); return dao.exists(id); } /** * Loads the persistable with <code>id</code> and <code>entityClass</code> * from the persistence system and returns it. If no persistable that match * these conditions exists, <code>null</code> is returned. * * @param <T> The type of the entity to be loaded. * @param entityClass The Class of the entity to be loaded. * @param id The id of the persistable to load from the persistence system. * @return the persistable with <code>id</code> or <code>null</code> in case * none exists. * @throws PersistenceException In case of an error while loading the * persistable. * @throws IllegalArgumentException if there is no DAO for * <code>entityClass</code>. */ public static <T extends IEntity> T load(Class<T> entityClass, long id) throws PersistenceException { IEntityDAO<T, ?, ?> dao = getDAOFromEntity(entityClass); checkEntityDAO(entityClass, dao); return dao.load(id); } /** * Loads a <code>Collection</code> of all <code>IPersistable</code>s of type * <code>persistableClass</code>. * * @param <T> The type of IPersistable to be loaded. * @param persistableClass The Class of IPersistable to be loaded. * @return Returns a <code>Collection</code> of all <code>IPersistable</code>s * this DAO of type <code>persistableClass</code>. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for * <code>persistableClass</code>. */ public static <T extends IPersistable> Collection<T> loadAll(Class<T> persistableClass) throws PersistenceException { IPersistableDAO<T> dao = getDAOFromPersistable(persistableClass); checkPersistableDAO(persistableClass, dao); return dao.loadAll(); } /** * Saves <code>persistable</code> to the persistence system. This method * handles new and existing persistables. In other words, it will add or * update the persistable as appropriate. * * @param <T> The type of the persistable to be saved. * @param persistable The persistable to save. * @return The persistable saved. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for * <code>persistable</code>. */ @SuppressWarnings("unchecked") public static <T extends IPersistable> T save(T persistable) throws PersistenceException { Class<? extends IPersistable> persistableClass = persistable.getClass(); IPersistableDAO<T> dao = (IPersistableDAO<T>) getDAOFromPersistable(persistableClass); checkPersistableDAO(persistableClass, dao); return dao.save(persistable); } /** * Saves the given Collection of <code>persistable</code>s to the persistence * system in a single operation. This method handles new and existing * persistables. In other words, it will add or update the persistable as * appropriate. * * @param <T> The supertype of persistables to be saved. * @param persistables The persistables to save. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for any of the * persistables in the provided collection. */ @SuppressWarnings("unchecked") public static <T extends IPersistable> void saveAll(Collection<T> persistables) throws PersistenceException { if (persistables.size() == 0) return; Map<Class<? extends IPersistable>, List<T>> persistablesMap = getPersistablesMap(persistables); for (Map.Entry<Class<? extends IPersistable>, List<T>> entry : persistablesMap.entrySet()) { Class<? extends IPersistable> key = entry.getKey(); IPersistableDAO<T> dao = (IPersistableDAO<T>) getDAOFromPersistable(key); checkPersistableDAO(key, dao); dao.saveAll(entry.getValue()); } } private static <T extends IPersistable> Map<Class<? extends IPersistable>, List<T>> getPersistablesMap(Collection<T> persistables) { Map<Class<? extends IPersistable>, List<T>> persistablesMap = new LinkedHashMap<Class<? extends IPersistable>, List<T>>(3); for (T persistable : persistables) { Class<? extends IPersistable> persistableClass = persistable.getClass(); List<T> persistableList = persistablesMap.get(persistableClass); if (persistableList == null) { persistableList = new ArrayList<T>(persistables.size()); persistablesMap.put(persistableClass, persistableList); } persistableList.add(persistable); } return persistablesMap; } /** * Deletes <code>persistable</code> from the persistence system. * * @param <T> The type of the persistable to delete. * @param persistable The persistable to delete. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for * <code>entityClass</code>. */ @SuppressWarnings("unchecked") public static <T extends IPersistable> void delete(T persistable) throws PersistenceException { Class<? extends IPersistable> persistableClass = persistable.getClass(); IPersistableDAO<T> dao = (IPersistableDAO<T>) getDAOFromPersistable(persistableClass); checkPersistableDAO(persistableClass, dao); dao.delete(persistable); } /** * Deletes the given Collection of <code>persistable</code>s from the * persistence system in a single operation. * * @param <T> The supertype of the persistables to delete. * @param persistables The persistables to delete. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for any of the * persistables in the provided collection. */ @SuppressWarnings("unchecked") public static <T extends IPersistable> void deleteAll(Collection<T> persistables) throws PersistenceException { if (persistables.size() == 0) return; Map<Class<? extends IPersistable>, List<T>> persistablesMap = getPersistablesMap(persistables); for (Map.Entry<Class<? extends IPersistable>, List<T>> entry : persistablesMap.entrySet()) { Class<? extends IPersistable> key = entry.getKey(); IPersistableDAO<T> dao = (IPersistableDAO<T>) getDAOFromPersistable(key); checkPersistableDAO(key, dao); dao.deleteAll(entry.getValue()); } } /** * Counts the number of <code>IPersistable</code>s of type * <code>persistableClass</code> stored in the persistence layer. * * @param <T> * @param persistableClass * @return The number of <code>IPersistable</code>s of type * <code>persistableClass</code> stored in the persistence layer. * @throws PersistenceException In case of an error while trying to perform * the operation. * @throws IllegalArgumentException if there is no DAO for * <code>persistableClass</code>. */ public static <T extends IPersistable> long countAll(Class<T> persistableClass) throws PersistenceException { IPersistableDAO<T> dao = getDAOFromPersistable(persistableClass); checkPersistableDAO(persistableClass, dao); return dao.countAll(); } private static void checkPersistableDAO(Class<? extends IPersistable> persistableClass, IPersistableDAO<?> dao) { if (dao == null) throw new IllegalArgumentException("There is no DAO for persistable of type: " + persistableClass); //$NON-NLS-1$ } private static void checkEntityDAO(Class<? extends IPersistable> entityClass, IEntityDAO<?, ?, ?> dao) { if (dao == null) throw new IllegalArgumentException("There is no DAO for entity of type: " + entityClass); //$NON-NLS-1$ } /** * Adds a listener to the collection of listeners who will be notified * whenever entities of type <code>T extends IEntity</code> get added, updated * or removed. * * @param <T> The type of the entity. * @param <L> The type of the listener. * @param <E> The type of the event. * @param entityClass The class of the entity. * @param listener The listener that will be added to the collection of * listeners for the given Entity. * @throws IllegalArgumentException if there is no DAO for * <code>entityClass</code>. */ @SuppressWarnings("unchecked") public static <T extends IEntity, L extends EntityListener<E, T>, E extends ModelEvent> void addEntityListener(Class<T> entityClass, L listener) { IEntityDAO<T, L, E> dao = (IEntityDAO<T, L, E>) getDAOFromPersistable(entityClass); checkEntityDAO(entityClass, dao); dao.addEntityListener(listener); } /** * Removes a listener from the collection of listeners who will be notified * whenever entities of type <code>T extends IEntity</code> get added, updated * or removed. * * @param <T> The type of the entity. * @param <L> The type of the listener. * @param <E> The type of the event. * @param entityClass The class of the entity. * @param listener The listener that will be removed from the collection of * listeners for the given Entity. * @throws IllegalArgumentException if there is no DAO for * <code>entityClass</code>. */ @SuppressWarnings("unchecked") public static <T extends IEntity, L extends EntityListener<E, T>, E extends ModelEvent> void removeEntityListener(Class<T> entityClass, L listener) { IEntityDAO<T, L, E> dao = (IEntityDAO<T, L, E>) getDAOFromPersistable(entityClass); checkEntityDAO(entityClass, dao); dao.removeEntityListener(listener); } /** * Returns the current implementation of the DAO for the specified interface * or <code>null</code> if no such DAO exists. * * @param <D> The subinterface of IPersistableDAO required. * @param <T> The type of persistable that the required DAO is responsible * for. * @param daoInterface The class object of type <code>D</code>. * @return The current implementation of the DAO for the specified interface * or <code>null</code> if no such DAO exists. */ public static <D extends IPersistableDAO<T>, T extends IPersistable> D getDAO(Class<D> daoInterface) { return getDAOService().getDAO(daoInterface); } /** * Returns the DAO responsible for <code>persistableClass</code> or * <code>null</code> if no such DAO exists. * * @param <T> The type of the persistable that the required DAO is responsible * for. * @param persistableClass A Class instance representing <code>T</code>. * @return The DAO responsible for <code>persistableClass</code> or * <code>null</code> if no such DAO exists. */ public static <T extends IPersistable> IPersistableDAO<T> getDAOFromPersistable(Class<? extends T> persistableClass) { return getDAOService().getDAOFromPersistable(persistableClass); } /** * Returns the DAO responsible for <code>entityClass</code> or * <code>null</code> if no such DAO exists. * * @param <T> The type of the entity that the required DAO is responsible for. * @param entityClass A Class instance representing <code>T</code>. * @return The DAO responsible for <code>entityClass</code> or * <code>null</code> if no such DAO exists. */ public static <T extends IEntity> IEntityDAO<T, ?, ?> getDAOFromEntity(Class<? extends T> entityClass) { return getDAOService().getDAOFromPersistable(entityClass); } }