001    /*
002     * Copyright 2001-2004 The Apache Software Foundation
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.commons.cache;
017    
018    import java.util.ArrayList;
019    import java.io.Serializable;
020    
021    /**
022     * An abstract base {@link Cache} implementation,
023     * managing the registration of listeners and the
024     * broadcast of events.
025     *
026     * @version $Id: BaseCache.java 155435 2005-02-26 13:17:27Z dirkv $
027     * @author Rodney Waldhoff
028     */
029    public abstract class BaseCache implements Cache {
030      public abstract boolean store(Serializable key, Serializable val, Long expiry, Long cost, Serializable group);
031      public abstract Serializable retrieve(Serializable key);
032      public abstract Serializable[] getKeysForGroup(Serializable group);
033      public abstract boolean contains(Serializable key);
034      public abstract void clear(Serializable key);
035      public abstract void clear();
036    
037      public long getStat(CacheStat stat) throws UnsupportedOperationException {
038        throw new UnsupportedOperationException();
039      }
040    
041      public synchronized void clearGroup(Serializable group) {
042        Serializable[] keys = getKeysForGroup(group);
043        if(null != keys) {
044          for(int i=0,m=keys.length;i<m;i++) {
045            try {
046              clear(keys[i]);
047            } catch(Exception e) {
048              e.printStackTrace();
049              /* ignored */
050            }
051          }
052        }
053      }
054    
055      public boolean store(Serializable key, Serializable val, Long expiry, Long cost) {
056        return store(key,val,expiry,cost,null);
057      }
058    
059      /** My list of {@link StorageListener}s. */
060      protected ArrayList _storageListeners = new ArrayList();
061    
062      /** My list of {@link RetrievalListener}s. */
063      protected ArrayList _retrievalListeners = new ArrayList();
064    
065      /**
066       * Add the given {@link StorageListener} to my
067       * set of {@link StorageListener}s.
068       * @link obs the observer to add
069       */
070      public synchronized void registerStorageListener(StorageListener obs) {
071        if(!_storageListeners.contains(obs)) {
072          _storageListeners.add(obs);
073        }
074      }
075    
076      /**
077       * Remove the given {@link StorageListener} from my
078       * set of {@link StorageListener}s.
079       * @link obs the observer to remove
080       */
081      public synchronized void unregisterStorageListener(StorageListener obs) {
082        for(boolean found=true;found;found=_storageListeners.remove(obs));
083      }
084    
085      /**
086       * Clear my set of {@link StorageListener}s.
087       */
088      public synchronized void unregisterStorageListeners() {
089        _storageListeners.clear();
090      }
091    
092      /**
093       * Add the given {@link RetrievalListener} to my
094       * set of {@link RetrievalListener}s.
095       * @link obs the observer to add
096       */
097      public synchronized void registerRetrievalListener(RetrievalListener obs) {
098        if(!_retrievalListeners.contains(obs)) {
099          _retrievalListeners.add(obs);
100        }
101      }
102    
103      /**
104       * Remove the given {@link RetrievalListener} from my
105       * set of {@link RetrievalListener}s.
106       * @link obs the observer to remove
107       */
108      public synchronized void unregisterRetrievalListener(RetrievalListener obs) {
109        for(boolean found=true;found;found=_retrievalListeners.remove(obs));
110      }
111    
112      /**
113       * Clear my set of {@link RetrievalListener}s.
114       */
115      public synchronized void unregisterRetrievalListeners() {
116        _retrievalListeners.clear();
117      }
118    
119      /**
120       * Broadcast a {@link StorageListener#storeRequested(java.io.Serializable,java.io.Serializable,java.lang.Long,java.lang.Long,java.io.Serializable)}
121       * event to my set of {@link StorageListener}s.
122       *
123       * @param key the cache key
124       * @param val the cache value
125       * @param expiresAt the expiration timestamp, or <tt>null</tt>
126       * @param cost the cost of the object, or <tt>null</tt>
127       */
128      protected synchronized void broadcastStoreRequested(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group) {
129        for(int i=0,m=_storageListeners.size();i<m;i++) {
130          ((StorageListener)(_storageListeners.get(i))).storeRequested(key,val,expiresAt,cost,group);
131        }
132      }
133    
134      /**
135       * Broadcast a {@link StorageListener#stored(java.io.Serializable,java.io.Serializable,java.lang.Long,java.lang.Long,java.io.Serializable)}
136       * event to my set of {@link StorageListener}s.
137       *
138       * @param key the cache key
139       * @param val the cache value
140       * @param expiresAt the expiration timestamp, or <tt>null</tt>
141       * @param cost the cost of the object, or <tt>null</tt>
142       */
143      protected synchronized void broadcastStored(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group) {
144        for(int i=0,m=_storageListeners.size();i<m;i++) {
145          ((StorageListener)(_storageListeners.get(i))).stored(key,val,expiresAt,cost,group);
146        }
147      }
148    
149      /**
150       * Broadcast a {@link StorageListener#notStored(java.io.Serializable,java.io.Serializable,java.lang.Long,java.lang.Long,java.io.Serializable)}
151       * event to my set of {@link StorageListener}s.
152       *
153       * @param key the cache key
154       * @param val the cache value
155       * @param expiresAt the expiration timestamp, or <tt>null</tt>
156       * @param cost the cost of the object, or <tt>null</tt>
157       */
158      protected synchronized void broadcastNotStored(Serializable key, Serializable val, Long expiresAt, Long cost, Serializable group) {
159        for(int i=0,m=_storageListeners.size();i<m;i++) {
160          ((StorageListener)(_storageListeners.get(i))).notStored(key,val,expiresAt,cost, group);
161        }
162      }
163    
164      /**
165       * Broadcast a {@link StorageListener#cleared(java.io.Serializable)}
166       * event to my set of {@link StorageListener}s.
167       *
168       * @param key the cache key
169       */
170      protected synchronized void broadcastCleared(Serializable key) {
171        for(int i=0,m=_storageListeners.size();i<m;i++) {
172          ((StorageListener)(_storageListeners.get(i))).cleared(key);
173        }
174      }
175    
176      /**
177       * Broadcast a {@link StorageListener#cleared()}
178       * event to my set of {@link StorageListener}s.
179       */
180      protected synchronized void broadcastCleared() {
181        for(int i=0,m=_storageListeners.size();i<m;i++) {
182          ((StorageListener)(_storageListeners.get(i))).cleared();
183        }
184      }
185    
186      /**
187       * Broadcast a {@link RetrievalListener#retrieveRequested(java.io.Serializable)}
188       * event to my set of {@link RetrievalListener}s.
189       *
190       * @param key the cache key
191       */
192      protected synchronized void broadcastRetrieveRequested(Serializable key) {
193        for(int i=0,m=_retrievalListeners.size();i<m;i++) {
194          ((RetrievalListener)(_retrievalListeners.get(i))).retrieveRequested(key);
195        }
196      }
197    
198      /**
199       * Broadcast a {@link RetrievalListener#retrieved(java.io.Serializable)}
200       * event to my set of {@link RetrievalListener}s.
201       *
202       * @param key the cache key
203       */
204      protected synchronized void broadcastRetrieved(Serializable key) {
205    // System.out.println(System.currentTimeMillis() + ": BaseCache.broadcastRetrieved starting");
206        for(int i=0,m=_retrievalListeners.size();i<m;i++) {
207    // System.out.println(System.currentTimeMillis() + ": BaseCache.broadcastRetrieved about to broadcast to " + _retrievalListeners.get(i));
208          ((RetrievalListener)(_retrievalListeners.get(i))).retrieved(key);
209    // System.out.println(System.currentTimeMillis() + ": BaseCache.broadcastRetrieved just broadcasted to " + _retrievalListeners.get(i));
210        }
211    // System.out.println(System.currentTimeMillis() + ": BaseCache.broadcastRetrieved ending");
212      }
213    
214      /**
215       * Broadcast a {@link RetrievalListener#notRetrieved(java.io.Serializable)}
216       * event to my set of {@link RetrievalListener}s.
217       *
218       * @param key the cache key
219       */
220      protected synchronized void broadcastNotRetrieved(Serializable key) {
221        for(int i=0,m=_retrievalListeners.size();i<m;i++) {
222          ((RetrievalListener)(_retrievalListeners.get(i))).notRetrieved(key);
223        }
224      }
225    }