
com.hazelcast.cache.impl.AbstractHazelcastCachingProvider Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
*
* 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 com.hazelcast.cache.impl;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.Logger;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import javax.cache.configuration.OptionalFeature;
import javax.cache.spi.CachingProvider;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.WeakHashMap;
/**
* Abstract {@link CachingProvider} implementation providing shared functionality to server and client caching
* providers.
* This class encapsulates following details:
*
* - Hazelcast instance for default uri and default class loader.
* - default uri.
* - default class loader.
* - accessing the singleton {@link CacheManager} by uri and class loader.
* - managing lifecycle of cache managers.
*
*
* @see CachingProvider
*/
public abstract class AbstractHazelcastCachingProvider
implements CachingProvider {
protected static final ILogger LOGGER = Logger.getLogger(HazelcastCachingProvider.class);
protected static final String INVALID_HZ_INSTANCE_SPECIFICATION_MESSAGE =
"Not available Hazelcast instance. "
+ "Please specify your Hazelcast configuration file path via "
+ "\"HazelcastCachingProvider.HAZELCAST_CONFIG_LOCATION\" property or "
+ "specify Hazelcast instance name via "
+ "\"HazelcastCachingProvider.HAZELCAST_INSTANCE_NAME\" property "
+ "in \"properties\" parameter.";
protected volatile HazelcastInstance hazelcastInstance;
protected final ClassLoader defaultClassLoader;
protected final URI defaultURI;
private final Map> cacheManagers;
public AbstractHazelcastCachingProvider() {
// We use a WeakHashMap to prevent strong references to a classLoader to avoid memory leak.
this.cacheManagers = new WeakHashMap>();
this.defaultClassLoader = this.getClass().getClassLoader();
try {
defaultURI = new URI("hazelcast");
} catch (URISyntaxException e) {
throw new CacheException("Cannot create Default URI", e);
}
}
@Override
public CacheManager getCacheManager(URI uri, ClassLoader classLoader, Properties properties) {
final URI managerURI = getManagerUri(uri);
final ClassLoader managerClassLoader = getManagerClassLoader(classLoader);
final Properties managerProperties = properties == null ? new Properties() : properties;
synchronized (cacheManagers) {
Map cacheManagersByURI = cacheManagers.get(managerClassLoader);
if (cacheManagersByURI == null) {
cacheManagersByURI = new HashMap();
cacheManagers.put(managerClassLoader, cacheManagersByURI);
}
AbstractHazelcastCacheManager cacheManager = cacheManagersByURI.get(managerURI);
if (cacheManager == null || cacheManager.isClosed()) {
try {
cacheManager = createHazelcastCacheManager(uri, classLoader, managerProperties);
cacheManagersByURI.put(managerURI, cacheManager);
} catch (Exception e) {
throw new CacheException("Error opening URI [" + managerURI.toString() + ']', e);
}
}
return cacheManager;
}
}
@Override
public ClassLoader getDefaultClassLoader() {
return defaultClassLoader;
}
@Override
public URI getDefaultURI() {
return defaultURI;
}
@Override
public Properties getDefaultProperties() {
return null;
}
@Override
public CacheManager getCacheManager(URI uri, ClassLoader classLoader) {
return getCacheManager(uri, classLoader, null);
}
@Override
public CacheManager getCacheManager() {
return getCacheManager(null, null, null);
}
@Override
public void close() {
// Closing a `CachingProvider` does not mean to close it forever see javadoc of `close()`
synchronized (cacheManagers) {
for (Map cacheManagersByURI : cacheManagers.values()) {
for (AbstractHazelcastCacheManager cacheManager : cacheManagersByURI.values()) {
if (cacheManager.isDefaultClassLoader) {
cacheManager.close();
} else {
cacheManager.destroy();
}
}
}
}
this.cacheManagers.clear();
shutdownHazelcastInstance();
}
protected void shutdownHazelcastInstance() {
final HazelcastInstance localInstanceRef = hazelcastInstance;
if (localInstanceRef != null) {
localInstanceRef.shutdown();
}
hazelcastInstance = null;
}
@Override
public void close(ClassLoader classLoader) {
final ClassLoader managerClassLoader = getManagerClassLoader(classLoader);
synchronized (cacheManagers) {
final Map cacheManagersByURI = this.cacheManagers.get(managerClassLoader);
if (cacheManagersByURI != null) {
for (CacheManager cacheManager : cacheManagersByURI.values()) {
cacheManager.close();
}
}
}
}
@Override
public void close(URI uri, ClassLoader classLoader) {
final URI managerURI = getManagerUri(uri);
final ClassLoader managerClassLoader = getManagerClassLoader(classLoader);
synchronized (cacheManagers) {
final Map cacheManagersByURI = this.cacheManagers.get(managerClassLoader);
if (cacheManagersByURI != null) {
final CacheManager cacheManager = cacheManagersByURI.remove(managerURI);
if (cacheManager != null) {
cacheManager.close();
}
if (cacheManagersByURI.isEmpty()) {
cacheManagers.remove(classLoader);
}
}
}
}
@Override
public boolean isSupported(OptionalFeature optionalFeature) {
switch (optionalFeature) {
// Hazelcast is distributed only and does not have a local in-process mode.
// Therefore the optional store-by-reference mode is not supported.
case STORE_BY_REFERENCE:
return false;
default:
return false;
}
}
protected URI getManagerUri(URI uri) {
return uri == null ? defaultURI : uri;
}
protected ClassLoader getManagerClassLoader(ClassLoader classLoader) {
return classLoader == null ? defaultClassLoader : classLoader;
}
protected abstract T createHazelcastCacheManager(URI uri, ClassLoader classLoader,
Properties managerProperties);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy