/* * This is a common dao with basic CRUD operations and is not limited to any * persistent layer implementation * * Copyright (C) 2008 Imran M Yousuf (imyousuf@smartitengineering.com) * * 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.smartitengineering.dao.common.cache.impl; import com.smartitengineering.dao.common.cache.CacheEventRegistrar; import com.smartitengineering.dao.common.cache.ChangeEvent; import com.smartitengineering.dao.common.cache.ChangeEvent.ChangeType; import com.smartitengineering.dao.common.cache.ChangeListener; import com.smartitengineering.domain.PersistentDTO; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; /** * * @author imyousuf */ public class CacheEventRegistrarImpl implements CacheEventRegistrar { private static final String ALL = "ALL"; private Map<Class, Set<ListenerTuple>> observers; private Map<ChangeListener, Set<Class>> listeners; { observers = new HashMap<Class, Set<ListenerTuple>>(); listeners = new HashMap<ChangeListener, Set<Class>>(); } public void addCacheEventListeners(Class<? extends PersistentDTO> observe, ChangeType type, ChangeListener... listeners) throws IllegalArgumentException { if (observe == null || listeners == null || listeners.length <= 0) { throw new IllegalArgumentException(); } for(ChangeListener listener : listeners) { ListenerTuple tuple = new ListenerTuple(); tuple.setListener(listener); tuple.setType(type); Set<ListenerTuple> tuples; if(!observers.containsKey(observe)) { tuples = new LinkedHashSet<ListenerTuple>(); observers.put(observe, tuples); } else { tuples = observers.get(observe); } tuples.add(tuple); Set<Class> classes; if(!this.listeners.containsKey(listener)) { classes = new LinkedHashSet<Class>(); this.listeners.put(listener, classes); } else { classes = this.listeners.get(listener); } classes.add(observe); } } public void removeListeners(ChangeListener... listeners) { for(ChangeListener listener : listeners) { if(this.listeners.containsKey(listener)) { Set<Class> classes = this.listeners.get(listener); if(classes != null && !classes.isEmpty()) { for(Class observe : classes) { Set<ListenerTuple> tuples = observers.get(observe); if(tuples != null && !tuples.isEmpty()) { Iterator<ListenerTuple> tupleIterator = new HashSet(tuples).iterator(); while(tupleIterator.hasNext()) { ListenerTuple tuple = tupleIterator.next(); if(tuple.getListener() != null && tuple.getListener() == listener) { tuples.remove(tuple); } } } } } this.listeners.remove(listener); } } } public void fireEvent(ChangeEvent event) { Class observe = event.getSource().getClass(); if(observers.containsKey(observe)) { Set<ListenerTuple> tuples = observers.get(observe); ArrayList<String> types = new ArrayList<String>(); types.add(ALL); if(event.getChangeType() != null) { types.add(event.getChangeType().name()); } if(tuples != null && !tuples.isEmpty()) { for(ListenerTuple tuple : tuples) { if(types.contains(tuple.getType())) { ChangeListener listener = tuple.getListener(); if(listener != null) { listener.cacheChanged(event); } } } } } } private class ListenerTuple { private ChangeListener listener; private String type; public ChangeListener getListener() { return listener; } public void setListener(ChangeListener listener) { this.listener = listener; } public String getType() { return type != null ? type : ""; } public void setType(ChangeType type) { if (type != null) { this.type = type.name(); } else { this.type = ALL; } } public void setType(String type) { if (type != null) { this.type = type; } } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ListenerTuple other = (ListenerTuple) obj; if (this.listener != other.listener && (this.listener == null || !this.listener.equals(other.listener))) { return false; } if (!this.type.equals(other.type)) { return false; } return true; } @Override public int hashCode() { int hash = 5; hash = 29 * hash + (this.listener != null ? this.listener.hashCode() : 0); hash = 29 * hash + (this.type != null ? this.type.hashCode() : 0); return hash; } } }