| /* |
| * Copyright 2010 Niclas Hedhman. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| * implied. |
| * |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.zest.cache.ehcache; |
| |
| import java.util.concurrent.ConcurrentHashMap; |
| import net.sf.ehcache.CacheManager; |
| import net.sf.ehcache.config.CacheConfiguration; |
| import net.sf.ehcache.config.PersistenceConfiguration; |
| import net.sf.ehcache.config.PersistenceConfiguration.Strategy; |
| import org.apache.zest.api.common.Optional; |
| import org.apache.zest.api.configuration.Configuration; |
| import org.apache.zest.api.injection.scope.This; |
| import org.apache.zest.api.util.NullArgumentException; |
| import org.apache.zest.spi.cache.Cache; |
| |
| public abstract class EhCachePoolMixin |
| implements EhCachePoolService |
| { |
| |
| private final ConcurrentHashMap<String, EhCacheImpl<?>> caches = new ConcurrentHashMap<>(); |
| @This @Optional |
| private Configuration<EhCacheConfiguration> config; |
| private CacheManager cacheManager; |
| |
| @Override |
| @SuppressWarnings( "unchecked" ) |
| public <T> Cache<T> fetchCache( String cacheId, Class<T> valueType ) |
| { |
| // Note: Small bug in Ehcache; If the cache name is an empty String it will actually work until |
| // you try to remove the Cache instance from the CacheManager, at which point it is silently |
| // ignored but not removed so there is an follow up problem of too much in the CacheManager. |
| NullArgumentException.validateNotEmpty( "cacheId", cacheId ); |
| EhCacheImpl<?> cache = caches.get( cacheId ); |
| if( cache == null ) |
| { |
| cache = createNewCache( cacheId, valueType ); |
| caches.put( cacheId, cache ); |
| } |
| cache.incRefCount(); |
| return (Cache<T>) cache; |
| } |
| |
| private <T> EhCacheImpl<T> createNewCache( String cacheId, Class<T> valueType ) |
| { |
| CacheConfiguration cc = createCacheConfiguration( cacheId ); |
| |
| // TODO: We also need all the other Configurations that are possible, like cacheLoaderFactoryConfiguration |
| net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache( cc ); |
| cacheManager.addCache( cache ); |
| |
| return new EhCacheImpl<>( cacheId, cache, valueType ); |
| } |
| |
| @Override |
| public void returnCache( Cache<?> cache ) |
| { |
| EhCacheImpl<?> eh = (EhCacheImpl<?>) cache; |
| eh.decRefCount(); |
| if( eh.isNotUsed() ) |
| { |
| caches.remove( eh.cacheId() ); |
| cacheManager.removeCache( eh.cacheId() ); |
| } |
| } |
| |
| @Override |
| public void activateService() |
| throws Exception |
| { |
| net.sf.ehcache.config.Configuration configuration = new net.sf.ehcache.config.Configuration(); |
| configureEhCache( configuration ); |
| CacheConfiguration cc = createCacheConfiguration( "qi4j.ehcache.config.default" ); |
| configuration.setDefaultCacheConfiguration( cc ); |
| cacheManager = CacheManager.newInstance( configuration ); |
| } |
| |
| @Override |
| public void passivateService() |
| throws Exception |
| { |
| cacheManager.shutdown(); |
| } |
| |
| private void configureEhCache( net.sf.ehcache.config.Configuration configuration ) |
| { |
| EhCacheConfiguration conf = config.get(); |
| Boolean updateCheck = conf.updateCheck().get(); |
| configuration.setUpdateCheck( updateCheck ); |
| configuration.setDynamicConfig( true ); |
| String monitoring = conf.monitoring().get().trim(); |
| if( monitoring.length() > 0 ) |
| { |
| configuration.setMonitoring( monitoring ); |
| } |
| String name = conf.cacheManagerName().get(); |
| if( name == null ) |
| { |
| name = "Zest Cache Extension"; |
| } |
| configuration.setName( name ); |
| String diskStorePath = conf.diskStorePath().get(); |
| if( diskStorePath.length() > 0 ) |
| { |
| configuration.getDiskStoreConfiguration().path( diskStorePath ); |
| } |
| } |
| |
| private CacheConfiguration createCacheConfiguration( String cacheId ) |
| { |
| EhCacheConfiguration conf = config.get(); |
| Integer maxElementsInMemory = conf.maxElementsInMemory().get(); |
| if( maxElementsInMemory <= 0 ) |
| { |
| maxElementsInMemory = 10000; |
| } |
| CacheConfiguration cacheConfig = new CacheConfiguration( cacheId, maxElementsInMemory ); |
| String transactionalMode = conf.transactionalMode().get(); |
| if( transactionalMode.length() > 0 ) |
| { |
| cacheConfig.transactionalMode( transactionalMode ); |
| } |
| |
| Long timeToLiveSeconds = conf.timeToLiveSeconds().get(); |
| if( timeToLiveSeconds > 0 ) |
| { |
| cacheConfig.timeToLiveSeconds( timeToLiveSeconds ); |
| } |
| |
| Long timeToIdleSeconds = conf.timeToIdleSeconds().get(); |
| if( timeToIdleSeconds > 0 ) |
| { |
| cacheConfig.timeToIdleSeconds( timeToIdleSeconds ); |
| } |
| |
| String name = conf.name().get(); |
| if( name.length() > 0 ) |
| { |
| cacheConfig.name( name ); |
| } |
| |
| String memoryStoreEvictionPolicy = conf.memoryStoreEvictionPolicy().get(); |
| if( memoryStoreEvictionPolicy.length() > 0 ) |
| { |
| cacheConfig.memoryStoreEvictionPolicy( memoryStoreEvictionPolicy ); |
| } |
| |
| Integer maxElementsOnDisk = conf.maxElementsOnDisk().get(); |
| if( maxElementsOnDisk > 0 ) |
| { |
| cacheConfig.maxElementsOnDisk( maxElementsOnDisk ); |
| } |
| |
| Boolean loggingEnabled = conf.loggingEnabled().get(); |
| if( loggingEnabled != null ) |
| { |
| cacheConfig.logging( loggingEnabled ); |
| } |
| |
| Boolean eternal = conf.eternal().get(); |
| cacheConfig.eternal( eternal ); |
| |
| Integer diskSpoolBufferSizeMB = conf.diskSpoolBufferSizeMB().get(); |
| if( diskSpoolBufferSizeMB > 0 ) |
| { |
| cacheConfig.diskSpoolBufferSizeMB( diskSpoolBufferSizeMB ); |
| } |
| |
| Long diskExpiryThreadIntervalSeconds = conf.diskExpiryThreadIntervalSeconds().get(); |
| if( diskExpiryThreadIntervalSeconds > 0 ) |
| { |
| cacheConfig.diskExpiryThreadIntervalSeconds( diskExpiryThreadIntervalSeconds ); |
| } |
| |
| Integer diskAccessStripes = conf.diskAccessStripes().get(); |
| if( diskAccessStripes > 0 ) |
| { |
| cacheConfig.diskAccessStripes( diskAccessStripes ); |
| } |
| Boolean clearOnFlush = conf.clearOnFlush().get(); |
| if( clearOnFlush != null ) |
| { |
| cacheConfig.clearOnFlush( clearOnFlush ); |
| } |
| |
| // Persistence Configuration |
| PersistenceConfiguration persistenceConfig = new PersistenceConfiguration(); |
| Strategy strategy = conf.persistenceStrategy().get(); |
| if( strategy == null ) |
| { |
| persistenceConfig.strategy( Strategy.NONE ); |
| } |
| else |
| { |
| persistenceConfig.strategy( strategy ); |
| } |
| cacheConfig.persistence( persistenceConfig ); |
| |
| return cacheConfig; |
| } |
| |
| } |