/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.resource.adapter.infinispan.hotrod; import javax.resource.ResourceException; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.commons.api.BasicCache; import org.infinispan.commons.api.BasicCacheContainer; import org.infinispan.protostream.BaseMarshaller; import org.infinispan.protostream.SerializationContext; import org.infinispan.protostream.SerializationContext.MarshallerProvider; import org.teiid.infinispan.api.InfinispanConnection; import org.teiid.infinispan.api.InfinispanDocument; import org.teiid.infinispan.api.ProtobufResource; import org.teiid.resource.adapter.infinispan.hotrod.InfinispanManagedConnectionFactory.InfinispanConnectionFactory; import org.teiid.resource.spi.BasicConnection; import org.teiid.translator.TranslatorException; public class InfinispanConnectionImpl extends BasicConnection implements InfinispanConnection { private RemoteCacheManager cacheManager; private String cacheName; private BasicCache<?, ?> defaultCache; private SerializationContext ctx; private ThreadAwareMarshallerProvider marshallerProvider = new ThreadAwareMarshallerProvider(); private InfinispanConnectionFactory icf; public InfinispanConnectionImpl(RemoteCacheManager manager, String cacheName, SerializationContext ctx, InfinispanConnectionFactory icf) throws ResourceException { this.cacheManager = manager; this.cacheName = cacheName; this.ctx = ctx; this.ctx.registerMarshallerProvider(this.marshallerProvider); this.icf = icf; try { this.defaultCache = this.cacheManager.getCache(this.cacheName); } catch (Throwable t) { throw new ResourceException(t); } } @Override public void registerProtobufFile(ProtobufResource protobuf) throws TranslatorException { this.icf.registerProtobufFile(protobuf); } @Override public BasicCacheContainer getCacheFactory() throws TranslatorException { return this.cacheManager; } @Override public void close() throws ResourceException { // do not want to close on per cache basis // TODO: what needs to be done here? this.ctx.unregisterMarshallerProvider(this.marshallerProvider); } @Override public BasicCache getCache() throws TranslatorException { return defaultCache; } @Override public void registerMarshaller(BaseMarshaller<InfinispanDocument> marshaller) throws TranslatorException { ThreadAwareMarshallerProvider.setMarsheller(marshaller); } @Override public void unRegisterMarshaller(BaseMarshaller<InfinispanDocument> marshaller) throws TranslatorException { ThreadAwareMarshallerProvider.setMarsheller(null); } /** * The reason for thread aware marshaller is due to fact the serialization context is JVM wide, so if some other * connection is also trying to register a marshaller for same object, they should not conflict. */ static class ThreadAwareMarshallerProvider implements MarshallerProvider { private static ThreadLocal<BaseMarshaller<?>> context = new ThreadLocal<BaseMarshaller<?>>() { @Override protected BaseMarshaller<?> initialValue() { return null; } }; public static void setMarsheller(BaseMarshaller<?> marshaller) { context.set(marshaller); } @Override public BaseMarshaller<?> getMarshaller(String typeName) { BaseMarshaller<?> m = context.get(); if (m != null && typeName.equals(m.getTypeName())) { return context.get(); } return null; } @Override public BaseMarshaller<?> getMarshaller(Class<?> javaClass) { BaseMarshaller<?> m = context.get(); if (m != null && javaClass.isAssignableFrom(InfinispanDocument.class)) { return context.get(); } return null; } } }