001/*
002 * Copyright 2002-2016 the original author or authors.
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 *      https://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
017package org.springframework.cache;
018
019import java.util.concurrent.Callable;
020
021/**
022 * Interface that defines common cache operations.
023 *
024 * <b>Note:</b> Due to the generic use of caching, it is recommended that
025 * implementations allow storage of <tt>null</tt> values (for example to
026 * cache methods that return {@code null}).
027 *
028 * @author Costin Leau
029 * @author Juergen Hoeller
030 * @author Stephane Nicoll
031 * @since 3.1
032 */
033public interface Cache {
034
035        /**
036         * Return the cache name.
037         */
038        String getName();
039
040        /**
041         * Return the underlying native cache provider.
042         */
043        Object getNativeCache();
044
045        /**
046         * Return the value to which this cache maps the specified key.
047         * <p>Returns {@code null} if the cache contains no mapping for this key;
048         * otherwise, the cached value (which may be {@code null} itself) will
049         * be returned in a {@link ValueWrapper}.
050         * @param key the key whose associated value is to be returned
051         * @return the value to which this cache maps the specified key,
052         * contained within a {@link ValueWrapper} which may also hold
053         * a cached {@code null} value. A straight {@code null} being
054         * returned means that the cache contains no mapping for this key.
055         * @see #get(Object, Class)
056         */
057        ValueWrapper get(Object key);
058
059        /**
060         * Return the value to which this cache maps the specified key,
061         * generically specifying a type that return value will be cast to.
062         * <p>Note: This variant of {@code get} does not allow for differentiating
063         * between a cached {@code null} value and no cache entry found at all.
064         * Use the standard {@link #get(Object)} variant for that purpose instead.
065         * @param key the key whose associated value is to be returned
066         * @param type the required type of the returned value (may be
067         * {@code null} to bypass a type check; in case of a {@code null}
068         * value found in the cache, the specified type is irrelevant)
069         * @return the value to which this cache maps the specified key
070         * (which may be {@code null} itself), or also {@code null} if
071         * the cache contains no mapping for this key
072         * @throws IllegalStateException if a cache entry has been found
073         * but failed to match the specified type
074         * @since 4.0
075         * @see #get(Object)
076         */
077        <T> T get(Object key, Class<T> type);
078
079        /**
080         * Return the value to which this cache maps the specified key, obtaining
081         * that value from {@code valueLoader} if necessary. This method provides
082         * a simple substitute for the conventional "if cached, return; otherwise
083         * create, cache and return" pattern.
084         * <p>If possible, implementations should ensure that the loading operation
085         * is synchronized so that the specified {@code valueLoader} is only called
086         * once in case of concurrent access on the same key.
087         * <p>If the {@code valueLoader} throws an exception, it is wrapped in
088         * a {@link ValueRetrievalException}
089         * @param key the key whose associated value is to be returned
090         * @return the value to which this cache maps the specified key
091         * @throws ValueRetrievalException if the {@code valueLoader} throws an exception
092         * @since 4.3
093         */
094        <T> T get(Object key, Callable<T> valueLoader);
095
096        /**
097         * Associate the specified value with the specified key in this cache.
098         * <p>If the cache previously contained a mapping for this key, the old
099         * value is replaced by the specified value.
100         * @param key the key with which the specified value is to be associated
101         * @param value the value to be associated with the specified key
102         */
103        void put(Object key, Object value);
104
105        /**
106         * Atomically associate the specified value with the specified key in this cache
107         * if it is not set already.
108         * <p>This is equivalent to:
109         * <pre><code>
110         * Object existingValue = cache.get(key);
111         * if (existingValue == null) {
112         *     cache.put(key, value);
113         *     return null;
114         * } else {
115         *     return existingValue;
116         * }
117         * </code></pre>
118         * except that the action is performed atomically. While all out-of-the-box
119         * {@link CacheManager} implementations are able to perform the put atomically,
120         * the operation may also be implemented in two steps, e.g. with a check for
121         * presence and a subsequent put, in a non-atomic way. Check the documentation
122         * of the native cache implementation that you are using for more details.
123         * @param key the key with which the specified value is to be associated
124         * @param value the value to be associated with the specified key
125         * @return the value to which this cache maps the specified key (which may be
126         * {@code null} itself), or also {@code null} if the cache did not contain any
127         * mapping for that key prior to this call. Returning {@code null} is therefore
128         * an indicator that the given {@code value} has been associated with the key.
129         * @since 4.1
130         */
131        ValueWrapper putIfAbsent(Object key, Object value);
132
133        /**
134         * Evict the mapping for this key from this cache if it is present.
135         * @param key the key whose mapping is to be removed from the cache
136         */
137        void evict(Object key);
138
139        /**
140         * Remove all mappings from the cache.
141         */
142        void clear();
143
144
145        /**
146         * A (wrapper) object representing a cache value.
147         */
148        interface ValueWrapper {
149
150                /**
151                 * Return the actual value in the cache.
152                 */
153                Object get();
154        }
155
156
157        /**
158         * Wrapper exception to be thrown from {@link #get(Object, Callable)}
159         * in case of the value loader callback failing with an exception.
160         * @since 4.3
161         */
162        @SuppressWarnings("serial")
163        class ValueRetrievalException extends RuntimeException {
164
165                private final Object key;
166
167                public ValueRetrievalException(Object key, Callable<?> loader, Throwable ex) {
168                        super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);
169                        this.key = key;
170                }
171
172                public Object getKey() {
173                        return this.key;
174                }
175        }
176
177}