blob: 16e6359ab4bc0470939f202d82513104fd62d4e3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.camel.component.jcache.osgi;
import org.apache.camel.component.jcache.JCacheConfiguration;
import org.apache.camel.component.jcache.JCacheHelper;
import org.apache.camel.component.jcache.JCacheManager;
import org.apache.camel.component.jcache.JCacheProvider;
import org.apache.camel.component.jcache.JCacheProviders;
import org.apache.camel.util.ObjectHelper;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.wiring.BundleWiring;
import javax.cache.Cache;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
public final class OSGiCacheManager<K, V> extends JCacheManager {
public OSGiCacheManager(JCacheConfiguration configuration) {
super(configuration);
}
@Override
public synchronized Cache<K, V> doGetCache(JCacheProvider provider) throws Exception {
final ClassLoader jcl = getClassLoader(provider.className());
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
try {
if (jcl != null) {
Thread.currentThread().setContextClassLoader(jcl);
}
Cache<K, V> cache = super.doGetCache(provider);
if (provider == JCacheProviders.hazelcast && jcl != null) {
cache = JCacheHelper.tcclProxy(cache, Cache.class, jcl);
}
return cache;
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
}
private ClassLoader getClassLoader(String providerName) throws Exception {
if (providerName == null || !getConfiguration().isLookupProviders()) {
return null;
}
final BundleContext bc = FrameworkUtil.getBundle(JCacheHelper.class).getBundleContext();
final ClassLoader bcl = bc.getBundle().adapt(BundleWiring.class).getClassLoader();
final ClassLoader acl = getConfiguration().getApplicationContextClassLoader();
for (final Bundle bundle : bc.getBundles()) {
URL spi = bundle.getResource("META-INF/services/javax.cache.spi.CachingProvider");
if (spi != null) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(spi.openStream()))) {
if (ObjectHelper.equal(providerName, in.readLine())) {
return new ClassLoader(bcl) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
return acl.loadClass(name);
} catch (ClassNotFoundException e) {
return bundle.loadClass(name);
}
}
@Override
protected URL findResource(String name) {
URL resource = acl.getResource(name);
if (resource == null) {
resource = bundle.getResource(name);
}
return resource;
}
@Override
protected Enumeration findResources(String name) throws IOException {
try {
return acl.getResources(name);
} catch (IOException e) {
return bundle.getResources(name);
}
}
};
}
}
}
}
return null;
}
}