001/*
002 * Copyright 2002-2018 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.interceptor;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022
023import org.springframework.beans.factory.InitializingBean;
024import org.springframework.cache.Cache;
025import org.springframework.cache.CacheManager;
026import org.springframework.util.Assert;
027
028/**
029 * A base {@link CacheResolver} implementation that requires the concrete
030 * implementation to provide the collection of cache name(s) based on the
031 * invocation context.
032 *
033 * @author Stephane Nicoll
034 * @author Juergen Hoeller
035 * @since 4.1
036 */
037public abstract class AbstractCacheResolver implements CacheResolver, InitializingBean {
038
039        private CacheManager cacheManager;
040
041
042        /**
043         * Construct a new {@code AbstractCacheResolver}.
044         * @see #setCacheManager
045         */
046        protected AbstractCacheResolver() {
047        }
048
049        /**
050         * Construct a new {@code AbstractCacheResolver} for the given {@link CacheManager}.
051         * @param cacheManager the CacheManager to use
052         */
053        protected AbstractCacheResolver(CacheManager cacheManager) {
054                this.cacheManager = cacheManager;
055        }
056
057
058        /**
059         * Set the {@link CacheManager} that this instance should use.
060         */
061        public void setCacheManager(CacheManager cacheManager) {
062                this.cacheManager = cacheManager;
063        }
064
065        /**
066         * Return the {@link CacheManager} that this instance uses.
067         */
068        public CacheManager getCacheManager() {
069                return this.cacheManager;
070        }
071
072        @Override
073        public void afterPropertiesSet()  {
074                Assert.notNull(this.cacheManager, "CacheManager is required");
075        }
076
077
078        @Override
079        public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
080                Collection<String> cacheNames = getCacheNames(context);
081                if (cacheNames == null) {
082                        return Collections.emptyList();
083                }
084                Collection<Cache> result = new ArrayList<Cache>(cacheNames.size());
085                for (String cacheName : cacheNames) {
086                        Cache cache = getCacheManager().getCache(cacheName);
087                        if (cache == null) {
088                                throw new IllegalArgumentException("Cannot find cache named '" +
089                                                cacheName + "' for " + context.getOperation());
090                        }
091                        result.add(cache);
092                }
093                return result;
094        }
095
096        /**
097         * Provide the name of the cache(s) to resolve against the current cache manager.
098         * <p>It is acceptable to return {@code null} to indicate that no cache could
099         * be resolved for this invocation.
100         * @param context the context of the particular invocation
101         * @return the cache name(s) to resolve, or {@code null} if no cache should be resolved
102         */
103        protected abstract Collection<String> getCacheNames(CacheOperationInvocationContext<?> context);
104
105}