001package org.apache.commons.jcs3.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 java.io.IOException;
023import java.io.Serializable;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.commons.jcs3.engine.behavior.ICacheElement;
028import org.apache.commons.jcs3.engine.logging.behavior.ICacheEvent;
029import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
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( final 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( final ICacheElement<K, V> cacheElement )
060        throws IOException
061    {
062        final 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( final 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( final K key )
104        throws IOException
105    {
106        final 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(final 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(final Set<K> keys )
151        throws IOException
152    {
153        final 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     * Gets items from the cache matching the given pattern. Items from memory will replace those
167     * from remote sources.
168     *
169     * This only works with string keys. It's too expensive to do a toString on every key.
170     *
171     * Auxiliaries will do their best to handle simple expressions. For instance, the JDBC disk
172     * cache will convert * to % and . to _
173     *
174     * @param pattern
175     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
176     *         data matching the pattern.
177     * @throws IOException
178     */
179    @Override
180    public Map<K, ICacheElement<K, V>> getMatching( final String pattern )
181        throws IOException
182    {
183        return getMatchingWithEventLogging( pattern );
184    }
185
186    /**
187     * Gets matching items from the cache based on the given pattern.
188     *
189     * @param pattern
190     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
191     *         data matching the pattern.
192     * @throws IOException
193     */
194    protected final Map<K, ICacheElement<K, V>> getMatchingWithEventLogging( final String pattern )
195        throws IOException
196    {
197        final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), pattern, ICacheEventLogger.GETMATCHING_EVENT );
198        try
199        {
200            return processGetMatching( pattern );
201        }
202        finally
203        {
204            logICacheEvent( cacheEvent );
205        }
206    }
207
208    /**
209     * Implementation of getMatching.
210     *
211     * @param pattern
212     * @return a map of K key to ICacheElement&lt;K, V&gt; element, or an empty map if there is no
213     *         data matching the pattern.
214     * @throws IOException
215     */
216    protected abstract Map<K, ICacheElement<K, V>> processGetMatching( String pattern )
217        throws IOException;
218
219    /**
220     * Removes the item from the cache. Wraps the remove in event logs.
221     *
222     * @param key
223     * @return boolean, whether or not the item was removed
224     * @throws IOException
225     */
226    @Override
227    public boolean remove( final K key )
228        throws IOException
229    {
230        return removeWithEventLogging( key );
231    }
232
233    /**
234     * Removes the item from the cache. Wraps the remove in event logs.
235     *
236     * @param key
237     * @return boolean, whether or not the item was removed
238     * @throws IOException
239     */
240    protected final boolean removeWithEventLogging( final K key )
241        throws IOException
242    {
243        final ICacheEvent<K> cacheEvent = createICacheEvent( getCacheName(), key, ICacheEventLogger.REMOVE_EVENT );
244        try
245        {
246            return processRemove( key );
247        }
248        finally
249        {
250            logICacheEvent( cacheEvent );
251        }
252    }
253
254    /**
255     * Specific implementation of remove.
256     *
257     * @param key
258     * @return boolean, whether or not the item was removed
259     * @throws IOException
260     */
261    protected abstract boolean processRemove( K key )
262        throws IOException;
263
264    /**
265     * Removes all from the region. Wraps the removeAll in event logs.
266     *
267     * @throws IOException
268     */
269    @Override
270    public void removeAll()
271        throws IOException
272    {
273        removeAllWithEventLogging();
274    }
275
276    /**
277     * Removes all from the region. Wraps the removeAll in event logs.
278     *
279     * @throws IOException
280     */
281    protected final void removeAllWithEventLogging()
282        throws IOException
283    {
284        final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "all", ICacheEventLogger.REMOVEALL_EVENT );
285        try
286        {
287            processRemoveAll();
288        }
289        finally
290        {
291            logICacheEvent( cacheEvent );
292        }
293    }
294
295    /**
296     * Specific implementation of removeAll.
297     *
298     * @throws IOException
299     */
300    protected abstract void processRemoveAll()
301        throws IOException;
302
303    /**
304     * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
305     *
306     * @throws IOException
307     */
308    @Override
309    public void dispose()
310        throws IOException
311    {
312        disposeWithEventLogging();
313    }
314
315    /**
316     * Synchronously dispose the remote cache; if failed, replace the remote handle with a zombie.
317     * Wraps the removeAll in event logs.
318     *
319     * @throws IOException
320     */
321    protected final void disposeWithEventLogging()
322        throws IOException
323    {
324        final ICacheEvent<String> cacheEvent = createICacheEvent( getCacheName(), "none", ICacheEventLogger.DISPOSE_EVENT );
325        try
326        {
327            processDispose();
328        }
329        finally
330        {
331            logICacheEvent( cacheEvent );
332        }
333    }
334
335    /**
336     * Specific implementation of dispose.
337     *
338     * @throws IOException
339     */
340    protected abstract void processDispose()
341        throws IOException;
342}