001/*
002 * Copyright 2002-2020 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.jcache;
018
019import java.util.Collection;
020import java.util.LinkedHashSet;
021
022import javax.cache.CacheManager;
023import javax.cache.Caching;
024
025import org.springframework.cache.Cache;
026import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;
027import org.springframework.lang.Nullable;
028import org.springframework.util.Assert;
029
030/**
031 * {@link org.springframework.cache.CacheManager} implementation
032 * backed by a JCache {@link CacheManager javax.cache.CacheManager}.
033 *
034 * <p>Note: This class has been updated for JCache 1.0, as of Spring 4.0.
035 *
036 * @author Juergen Hoeller
037 * @author Stephane Nicoll
038 * @since 3.2
039 * @see JCacheCache
040 */
041public class JCacheCacheManager extends AbstractTransactionSupportingCacheManager {
042
043        @Nullable
044        private CacheManager cacheManager;
045
046        private boolean allowNullValues = true;
047
048
049        /**
050         * Create a new {@code JCacheCacheManager} without a backing JCache
051         * {@link CacheManager javax.cache.CacheManager}.
052         * <p>The backing JCache {@code javax.cache.CacheManager} can be set via the
053         * {@link #setCacheManager} bean property.
054         */
055        public JCacheCacheManager() {
056        }
057
058        /**
059         * Create a new {@code JCacheCacheManager} for the given backing JCache
060         * {@link CacheManager javax.cache.CacheManager}.
061         * @param cacheManager the backing JCache {@code javax.cache.CacheManager}
062         */
063        public JCacheCacheManager(CacheManager cacheManager) {
064                this.cacheManager = cacheManager;
065        }
066
067
068        /**
069         * Set the backing JCache {@link CacheManager javax.cache.CacheManager}.
070         */
071        public void setCacheManager(@Nullable CacheManager cacheManager) {
072                this.cacheManager = cacheManager;
073        }
074
075        /**
076         * Return the backing JCache {@link CacheManager javax.cache.CacheManager}.
077         */
078        @Nullable
079        public CacheManager getCacheManager() {
080                return this.cacheManager;
081        }
082
083        /**
084         * Specify whether to accept and convert {@code null} values for all caches
085         * in this cache manager.
086         * <p>Default is "true", despite JSR-107 itself not supporting {@code null} values.
087         * An internal holder object will be used to store user-level {@code null}s.
088         */
089        public void setAllowNullValues(boolean allowNullValues) {
090                this.allowNullValues = allowNullValues;
091        }
092
093        /**
094         * Return whether this cache manager accepts and converts {@code null} values
095         * for all of its caches.
096         */
097        public boolean isAllowNullValues() {
098                return this.allowNullValues;
099        }
100
101        @Override
102        public void afterPropertiesSet() {
103                if (getCacheManager() == null) {
104                        setCacheManager(Caching.getCachingProvider().getCacheManager());
105                }
106                super.afterPropertiesSet();
107        }
108
109
110        @Override
111        protected Collection<Cache> loadCaches() {
112                CacheManager cacheManager = getCacheManager();
113                Assert.state(cacheManager != null, "No CacheManager set");
114
115                Collection<Cache> caches = new LinkedHashSet<>();
116                for (String cacheName : cacheManager.getCacheNames()) {
117                        javax.cache.Cache<Object, Object> jcache = cacheManager.getCache(cacheName);
118                        caches.add(new JCacheCache(jcache, isAllowNullValues()));
119                }
120                return caches;
121        }
122
123        @Override
124        protected Cache getMissingCache(String name) {
125                CacheManager cacheManager = getCacheManager();
126                Assert.state(cacheManager != null, "No CacheManager set");
127
128                // Check the JCache cache again (in case the cache was added at runtime)
129                javax.cache.Cache<Object, Object> jcache = cacheManager.getCache(name);
130                if (jcache != null) {
131                        return new JCacheCache(jcache, isAllowNullValues());
132                }
133                return null;
134        }
135
136}