package org.goko.core.common.utils; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.collections.CollectionUtils; import org.goko.core.common.exception.GkException; import org.goko.core.common.exception.GkTechnicalException; /** * Implementation of a generic cache for IIdBean objects * * @author Psyko * * @param <T> the type of objects to store */ public class SortedCacheById<T extends IIdBean> { /** The actual content */ private SortedMap<Integer, T> cacheById; /** The id generator (may be <code>null</code>)*/ private IIdGenerator idGenerator; /** * Constructor */ public SortedCacheById(Comparator<Integer> comparator) { this(null, comparator); } /** * Constructor * @param idGenerator the internal id generator to use */ public SortedCacheById(IIdGenerator idGenerator, Comparator<Integer> comparator) { this.cacheById = new TreeMap<Integer, T>(comparator); this.idGenerator = idGenerator; } /** * Returns the full content of this cache. Order is not guaranted * @return a list of element T * @throws GkException GkException */ public List<T> get() throws GkException{ return new ArrayList<T>(cacheById.values()); } /** * Return the element with the given id in this cache if it exists * @param id the id of the element to retrieve * @return an element T if any exists for the given id * @throws GkException if the requested element does not exist */ public T get(Integer id) throws GkException{ T result = find(id); if(result == null){ throw new GkTechnicalException("Unable to find object with id ["+String.valueOf(id)+"]"); } return result; } /** * Return the list of element for the given list of id * @param lstId the list of id of the element to retrieve * @return a list of elements * @throws GkException GkException */ public List<T> get(List<Integer> lstId) throws GkException{ List<T> result = new ArrayList<T>(); if(CollectionUtils.isNotEmpty(lstId)){ for (Integer id : lstId) { result.add(get(id)); } } return result; } /** * Return the element with the given id in this cache if it exists, or <code>null</code> otherwise * @param id the id of the element to retrieve * @return an element T if any exists for the given id, or <code>null</code> * @throws GkException GkException */ public T find(Integer id) throws GkException{ return cacheById.get(id); } /** * Check the existence of the element with the given id in this cache * @param id the id of the element to check * @return <code>true</code> if the element exists, <code>false</code> otherwise * @throws GkException GkException */ public boolean exist(Integer id) throws GkException{ return find(id) != null; } /** * Add the given element to this cache * @param element the element to add * @throws GkException GkException */ public void add(T element) throws GkException{ if(idGenerator != null && element.getId() == null){ element.setId(idGenerator.getNextValue()); } if(exist(element.getId())){ throw new GkTechnicalException("Duplicate entry : an object with id ["+String.valueOf(element.getId())+"] already exists"); } cacheById.put(element.getId(), element); } /** * Removes all the element from this cache */ public void removeAll(){ cacheById.clear(); } /** * Add the given list of element to this cache * @param lstElement the list of elements * @throws GkException GkException */ public void add(List<T> lstElement) throws GkException{ for (T element : lstElement) { add(element); } } /** * Removes the given element from this cache * @param element the id of the element to remove */ public void remove(Integer id){ cacheById.remove(id); } /** * Removes the given element from this cache * @param element the element to remove */ public void remove(T element){ remove(element.getId()); } /** * Returns the number of element in this cache * @return the number of element */ public int size(){ return cacheById.size(); } }