001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.jcs3.jcache; 020 021import javax.cache.CacheManager; 022import javax.cache.configuration.OptionalFeature; 023import javax.cache.spi.CachingProvider; 024import java.net.URI; 025import java.util.Map; 026import java.util.Properties; 027import java.util.concurrent.ConcurrentHashMap; 028import java.util.concurrent.ConcurrentMap; 029 030public class JCSCachingProvider implements CachingProvider 031{ 032 public static final URI DEFAULT_URI = URI.create("jcs://jcache.ccf"); 033 034 private final ConcurrentMap<ClassLoader, ConcurrentMap<URI, CacheManager>> cacheManagersByLoader = new ConcurrentHashMap<>(); 035 036 @Override 037 public CacheManager getCacheManager(final URI inUri, final ClassLoader inClassLoader, final Properties properties) 038 { 039 final URI uri = inUri != null ? inUri : getDefaultURI(); 040 final ClassLoader classLoader = inClassLoader != null ? inClassLoader : getDefaultClassLoader(); 041 042 ConcurrentMap<URI, CacheManager> managers = cacheManagersByLoader.get(classLoader); 043 if (managers == null) 044 { 045 managers = new ConcurrentHashMap<>(); 046 final ConcurrentMap<URI, CacheManager> existingManagers = cacheManagersByLoader.putIfAbsent(classLoader, managers); 047 if (existingManagers != null) 048 { 049 managers = existingManagers; 050 } 051 } 052 053 CacheManager mgr = managers.get(uri); 054 if (mgr == null) 055 { 056 mgr = new JCSCachingManager(this, uri, classLoader, properties); 057 final CacheManager existing = managers.putIfAbsent(uri, mgr); 058 if (existing != null) 059 { 060 mgr = existing; 061 } 062 } 063 064 return mgr; 065 } 066 067 @Override 068 public URI getDefaultURI() 069 { 070 return DEFAULT_URI; 071 } 072 073 @Override 074 public void close() 075 { 076 for (final Map<URI, CacheManager> v : cacheManagersByLoader.values()) 077 { 078 for (final CacheManager m : v.values()) 079 { 080 m.close(); 081 } 082 v.clear(); 083 } 084 cacheManagersByLoader.clear(); 085 } 086 087 @Override 088 public void close(final ClassLoader classLoader) 089 { 090 final Map<URI, CacheManager> cacheManagers = cacheManagersByLoader.remove(classLoader); 091 if (cacheManagers != null) 092 { 093 for (final CacheManager mgr : cacheManagers.values()) 094 { 095 mgr.close(); 096 } 097 cacheManagers.clear(); 098 } 099 } 100 101 @Override 102 public void close(final URI uri, final ClassLoader classLoader) 103 { 104 final Map<URI, CacheManager> cacheManagers = cacheManagersByLoader.remove(classLoader); 105 if (cacheManagers != null) 106 { 107 final CacheManager mgr = cacheManagers.remove(uri); 108 if (mgr != null) 109 { 110 mgr.close(); 111 } 112 } 113 } 114 115 @Override 116 public CacheManager getCacheManager(final URI uri, final ClassLoader classLoader) 117 { 118 return getCacheManager(uri, classLoader, getDefaultProperties()); 119 } 120 121 @Override 122 public CacheManager getCacheManager() 123 { 124 return getCacheManager(getDefaultURI(), getDefaultClassLoader()); 125 } 126 127 @Override 128 public boolean isSupported(final OptionalFeature optionalFeature) 129 { 130 return optionalFeature == OptionalFeature.STORE_BY_REFERENCE; 131 } 132 133 @Override 134 public ClassLoader getDefaultClassLoader() 135 { 136 return JCSCachingProvider.class.getClassLoader(); 137 } 138 139 @Override 140 public Properties getDefaultProperties() 141 { 142 return new Properties(); 143 } 144 145 void remove(final CacheManager mgr) 146 { 147 final ClassLoader classLoader = mgr.getClassLoader(); 148 final Map<URI, CacheManager> mgrs = cacheManagersByLoader.get(classLoader); 149 if (mgrs != null) 150 { 151 mgrs.remove(mgr.getURI()); 152 if (mgrs.isEmpty()) 153 { 154 cacheManagersByLoader.remove(classLoader); 155 } 156 } 157 } 158}