miércoles, 13 de octubre de 2010

Java - Creación de cachés

La siguiente clase define la estructura de una caché de elementos de tipo genérico. Puede resultar muy útil cuando, por ejemplo, debemos mostrar una lista de valores obtenida de un sistema externo: base de datos, servicio web, etc.

La primera vez que se llame al método 'getItems()' para obtener el listado de elementos se realizará una llamada al método 'getNewItems()' que será el encargado de obtenerlos. Este método es abstracto para mayor libertad, ya que permite que el desarrollador realice tantas implementaciones del método como sistemas y/o mecanismos de recogida de datos desee utilizar.

Como se menciona en el javadoc del método 'getItems()', la lista de elementos de la caché se actualizará si dicha lista está vacía o si ha transcurrido más de un día desde la última actualización.


/**
* Generic cache is updated dayly. If there's any problem while trying to
* update the cache, the stored data is kept in the cache and the last modification
* time is updated.
*
* @param Type of the stored element
**/
public abstract class GenericCache {

private Calendar
lastModification;
private List itemList;

/**
* Constructor
**/
protected GenericCache() {
lastModification = new GregorianCalendar();
itemList = new ArrayList();
}

/**
* Checks if cache is empty
* @return true, if cache is empty; false, otherwise
**/
private boolean isEmpty() {
return (itemList == null || (itemList.size() == 0));
}

/**
* Gets the items to be inserted in cache.
*
* @return item list
* @throws Exception if the operation fails when getting items
**/
protected abstract List getNewItems() throws Exception;


/**
* Gets the latest item list from cache. If the cache is empty or if it's
* one day old, there will be an attempt to update it.
*
* @return item list from cache
**/
public List getItems() {
Calendar currentDate = new GregorianCalendar();
try {
if (isEmpty() ||
(lastModification.get(Calendar.DATY_OF_YEAR) != currentDate.get(Calendar.DAY_OF_YEAR))) {
List items = getNewItems();
if ((items != null) && (items.size() > 0)) {
itemList = items;
lastModification = currentDate;
}
}
} catch (Exception e) {
lastModification = currentDate;
}
return itemList;
}



Una posible implementación de esta caché abstracta sería la que se muestra a continuación:

public final class CompanyNamesCache extends GenericCache {

private static CompanyNames c
ompanyNames;
private LocalService localService;

/**
* Constructor
**/
private CompanyNamesCache() {
super();
try {
localService = (LocalService) ServiceLocator.getInstance().getLocalService("java:comp/env/ejb/LocalService");
} catch (NamingException ne) {
localService = null;
}
}

/**
* Gets an instance of the company names cache
*
* @return cache instance
**/
public static synchronized CompanyNamesCache getInstance() {
if (
companyNames == null) {
companyNames = new CompanyNamesCache();
}
return companyNames;
}

/**
* Gets new company names
*
* @return new company names list
* @throw Exception if an error occurs when getting company names
**/
@Override
protected List getNewItems() throws Exception {
List localService.getCompanyNames();
}

}

No hay comentarios: