001package org.apache.commons.jcs.auxiliary;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.commons.jcs.engine.behavior.ICacheElement;
023import org.apache.commons.jcs.engine.logging.behavior.ICacheEvent;
024import org.apache.commons.jcs.engine.logging.behavior.ICacheEventLogger;
025
026import java.io.IOException;
027import java.io.Serializable;
028import java.util.Map;
029import java.util.Set;
030
031/**
032 * All ICacheEvents are defined as final. Children must implement process events. These are wrapped
033 * in event log parent calls.
034 * 
035 * You can override the public method, but if you don't, the default will call getWithTiming.
036 */
037public abstract class AbstractAuxiliaryCacheEventLogging<K, V>
038    extends AbstractAuxiliaryCache<K, V>
039{
040    /**
041     * Puts an item into the cache.
042     * 
043     * @param cacheElement
044     * @throws IOException
045     */
046    @Override
047    public void update( ICacheElement<K, V> cacheElement )
048        throws IOException
049    {
050        updateWithEventLogging( cacheElement );
051    }
052
053    /**
054     * Puts an item into the cache. Wrapped in logging.
055     * 
056     * @param cacheElement
057     * @throws IOException
058     */
059    protected final void updateWithEventLogging( ICacheElement<K, V> cacheElement )
060        throws IOException
061    {
062        ICacheEvent<K> cacheEvent = createICacheEvent( cacheElement, ICacheEventLogger.UPDATE_EVENT );
063        try
064        {
065            processUpdate( cacheElement );
066        }
067        finally
068        {
069            logICacheEvent( cacheEvent );
070        }
071    }
072
073    /**
074     * Implementation of put.
075     * 
076     * @param cacheElement
077     * @throws IOException
078     */
079    protected abstract void processUpdate( ICacheElement<K, V> cacheElement )
080        throws IOException;
081
082    /**
083     * Gets the item from the cache.
084     * 
085     * @param key
086     * @return ICacheElement, a wrapper around the key, value, and attributes
087     * @throws IOException
088     */
089    @Override
090    public ICacheElement<K, V> get( K key )
091        throws IOException
092    {
093        return getWithEventLogging( key );
094    }
095
096    /**
097     * Gets the item from the cache. Wrapped in logging.
098     * 
099     * @param key
100     * @return ICacheElement, a wrapper around the key, value, and attributes
101     * @throws IOException
102     */
103    protected final ICacheElement<K, V> getWithEventLogging( K key )
104        throws IOException
105    {
106        ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.GET_EVENT );
107        try
108        {
109            return processGet( key );
110        }
111        finally
112        {
113            logICacheEvent( cacheEvent );
114        }
115    }
116
117    /**
118     * Implementation of get.
119     * 
120     * @param key
121     * @return ICacheElement, a wrapper around the key, value, and attributes
122     * @throws IOException
123     */
124    protected abstract ICacheElement<K, V> processGet( K key )
125        throws IOException;
126
127    /**
128     * Gets multiple items from the cache based on the given set of keys.
129     * 
130     * @param keys
131     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
132     *         data in cache for any of these keys
133     * @throws IOException
134     */
135    @Override
136    public Map<K, ICacheElement<K, V>> getMultiple(Set<K> keys)
137        throws IOException
138    {
139        return getMultipleWithEventLogging( keys );
140    }
141
142    /**
143     * Gets multiple items from the cache based on the given set of keys.
144     * 
145     * @param keys
146     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
147     *         data in cache for any of these keys
148     * @throws IOException
149     */
150    protected final Map<K, ICacheElement<K, V>> getMultipleWithEventLogging(Set<K> keys )
151        throws IOException
152    {
153        ICacheEvent<Serializable> cacheEvent = createICacheEvent( getCacheName(), (Serializable) keys,
154                                                    ICacheEventLogger.GETMULTIPLE_EVENT );
155        try
156        {
157            return processGetMultiple( keys );
158        }
159        finally
160        {
161            logICacheEvent( cacheEvent );
162        }
163    }
164
165    /**
166     * Implementation of getMultiple.
167     * 
168     * @param keys
169     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
170     *         data in cache for any of these keys
171     * @throws IOException
172     */
173    protected abstract Map<K, ICacheElement<K, V>> processGetMultiple(Set<K> keys)
174        throws IOException;
175
176    /**
177     * Gets items from the cache matching the given pattern. Items from memory will replace those
178     * from remote sources.
179     * 
180     * This only works with string keys. It's too expensive to do a toString on every key.
181     * 
182     * Auxiliaries will do their best to handle simple expressions. For instance, the JDBC disk
183     * cache will convert * to % and . to _
184     * 
185     * @param pattern
186     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
187     *         data matching the pattern.
188     * @throws IOException
189     */
190    @Override
191    public Map<K, ICacheElement<K, V>> getMatching( String pattern )
192        throws IOException
193    {
194        return getMatchingWithEventLogging( pattern );
195    }
196
197    /**
198     * Gets mmatching items from the cache based on the given pattern.
199     * 
200     * @param pattern
201     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
202     *         data matching the pattern.
203     * @throws IOException
204     */
205    protected final Map<K, ICacheElement<K, V>> getMatchingWithEventLogging( String pattern )
206        throws IOException
207    {
208        ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), pattern, ICacheEventLogger.GETMATCHING_EVENT );
209        try
210        {
211            return processGetMatching( pattern );
212        }
213        finally
214        {
215            logICacheEvent( cacheEvent );
216        }
217    }
218
219    /**
220     * Implementation of getMatching.
221     * 
222     * @param pattern
223     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
224     *         data matching the pattern.
225     * @throws IOException
226     */
227    protected abstract Map<K, ICacheElement<K, V>> processGetMatching( String pattern )
228        throws IOException;
229
230    /**
231     * Removes the item from the cache. Wraps the remove in event logs.
232     * 
233     * @param key
234     * @return boolean, whether or not the item was removed
235     * @throws IOException
236     */
237    @Override
238    public boolean remove( K key )
239        throws IOException
240    {
241        return removeWithEventLogging( key );
242    }
243
244    /**
245     * Removes the item from the cache. Wraps the remove in event logs.
246     * 
247     * @param key
248     * @return boolean, whether or not the item was removed
249     * @throws IOException
250     */
251    protected final boolean removeWithEventLogging( K key )
252        throws IOException
253    {
254        ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.REMOVE_EVENT );
255        try
256        {
257            return processRemove( key );
258        }
259        finally
260        {
261            logICacheEvent( cacheEvent );
262        }
263    }
264
265    /**
266     * Specific implementation of remove.
267     * 
268     * @param key
269     * @return boolean, whether or not the item was removed
270     * @throws IOException
271     */
272    protected abstract boolean processRemove( K key )
273        throws IOException;
274
275    /**
276     * Removes all from the region. Wraps the removeAll in event logs.
277     * 
278     * @throws IOException
279     */
280    @Override
281    public void removeAll()
282        throws IOException
283    {
284        removeAllWithEventLogging();
285    }
286
287    /**
288     * Removes all from the region. Wraps the removeAll in event logs.
289     * 
290     * @throws IOException
291     */
292    protected final void removeAllWithEventLogging()
293        throws IOException
294    {
295        ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT );
296        try
297        {
298            processRemoveAll();
299        }
300        finally
301        {
302            logICacheEvent( cacheEvent );
303        }
304    }
305
306    /**
307     * Specific implementation of removeAll.
308     * 
309     * @throws IOException
310     */
311    protected abstract void processRemoveAll()
312        throws IOException;
313
314    /**
315     * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
316     * 
317     * @throws IOException
318     */
319    @Override
320    public void dispose()
321        throws IOException
322    {
323        disposeWithEventLogging();
324    }
325
326    /**
327     * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
328     * Wraps the removeAll in event logs.
329     * 
330     * @throws IOException
331     */
332    protected final void disposeWithEventLogging()
333        throws IOException
334    {
335        ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT );
336        try
337        {
338            processDispose();
339        }
340        finally
341        {
342            logICacheEvent( cacheEvent );
343        }
344    }
345
346    /**
347     * Specific implementation of dispose.
348     * 
349     * @throws IOException
350     */
351    protected abstract void processDispose()
352        throws IOException;
353}