package org.infinispan.factories; import org.infinispan.AdvancedCache; import org.infinispan.Cache; import org.infinispan.cache.impl.CacheImpl; import org.infinispan.cache.impl.CompatibilityAdvancedCache; import org.infinispan.cache.impl.SimpleCacheImpl; import org.infinispan.cache.impl.StatsCollectingCache; import org.infinispan.cache.impl.TypeConverterDelegatingAdvancedCache; import org.infinispan.commons.CacheConfigurationException; import org.infinispan.commons.marshall.Marshaller; import org.infinispan.commons.marshall.StreamingMarshaller; import org.infinispan.compat.TypeConverter; import org.infinispan.configuration.cache.CompatibilityModeConfiguration; import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.JMXStatisticsConfiguration; import org.infinispan.configuration.cache.StorageType; import org.infinispan.eviction.ActivationManager; import org.infinispan.eviction.PassivationManager; import org.infinispan.eviction.impl.ActivationManagerStub; import org.infinispan.eviction.impl.PassivationManagerStub; import org.infinispan.expiration.ExpirationManager; import org.infinispan.interceptors.impl.MarshallerConverter; import org.infinispan.interceptors.impl.WrappedByteArrayConverter; import org.infinispan.jmx.CacheJmxRegistration; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.notifications.cachelistener.cluster.ClusterEventManager; import org.infinispan.notifications.cachelistener.cluster.impl.ClusterEventManagerStub; import org.infinispan.persistence.manager.PersistenceManager; import org.infinispan.persistence.manager.PersistenceManagerStub; import org.infinispan.stats.impl.StatsCollector; import org.infinispan.transaction.xa.recovery.RecoveryAdminOperations; import org.infinispan.upgrade.RollingUpgradeManager; import org.infinispan.xsite.XSiteAdminOperations; /** * An internal factory for constructing Caches. Used by the {@link DefaultCacheManager}, this is not intended as public * API. * <p/> * This is a special instance of a {@link AbstractComponentFactory} which contains bootstrap information for the {@link * ComponentRegistry}. * <p/> * * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a> * @since 4.0 */ public class InternalCacheFactory<K, V> extends AbstractNamedCacheComponentFactory { /** * This implementation clones the configuration passed in before using it. * * * @param configuration to use * @param globalComponentRegistry global component registry to attach the cache to * @param cacheName name of the cache * @return a cache * @throws CacheConfigurationException if there are problems with the cfg */ public Cache<K, V> createCache(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws CacheConfigurationException { try { if (configuration.simpleCache()) { return createSimpleCache(configuration, globalComponentRegistry, cacheName); } else { return createAndWire(configuration, globalComponentRegistry, cacheName); } } catch (CacheConfigurationException ce) { throw ce; } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException(e); } } protected AdvancedCache<K, V> createAndWire(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws Exception { AdvancedCache<K, V> cache = new CacheImpl<K, V>(cacheName); CompatibilityModeConfiguration compatibilityModeConfiguration = configuration.compatibility(); StorageType type = configuration.memory().storageType(); Marshaller marshaller; TypeConverter converter; if (compatibilityModeConfiguration.enabled()) { converter = new WrappedByteArrayConverter(); marshaller = compatibilityModeConfiguration.marshaller(); cache = new CompatibilityAdvancedCache<>(cache, marshaller, converter); } else if (type != StorageType.OBJECT) { // Both other types require storing as byte[] converter = new MarshallerConverter(globalComponentRegistry.getOrCreateComponent(StreamingMarshaller.class), type == StorageType.OFF_HEAP); marshaller = null; cache = new TypeConverterDelegatingAdvancedCache<>(cache, converter); } else { marshaller = null; converter = new WrappedByteArrayConverter(); cache = new TypeConverterDelegatingAdvancedCache<>(cache, converter); } bootstrap(cacheName, cache, configuration, globalComponentRegistry, converter); if (marshaller != null) { componentRegistry.wireDependencies(marshaller); } return cache; } private AdvancedCache<K, V> createSimpleCache(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) { AdvancedCache<K, V> cache; JMXStatisticsConfiguration jmxStatistics = configuration.jmxStatistics(); boolean statisticsAvailable = jmxStatistics != null && jmxStatistics.available(); if (statisticsAvailable) { cache = new StatsCollectingCache<>(cacheName); } else { cache = new SimpleCacheImpl<>(cacheName); } this.configuration = configuration; StorageType type = configuration.memory().storageType(); TypeConverter converter; if (type != StorageType.OBJECT) { converter = new MarshallerConverter(globalComponentRegistry.getOrCreateComponent(StreamingMarshaller.class), type == StorageType.OFF_HEAP); } else { converter = new WrappedByteArrayConverter(); } cache = new TypeConverterDelegatingAdvancedCache<>(cache, converter); componentRegistry = new ComponentRegistry(cacheName, configuration, cache, globalComponentRegistry, globalComponentRegistry.getClassLoader()) { @Override protected void bootstrapComponents() { if (statisticsAvailable) { registerComponent(new StatsCollector.Factory(), StatsCollector.Factory.class); } registerComponent(converter, TypeConverter.class); registerComponent(new ClusterEventManagerStub<K, V>(), ClusterEventManager.class); registerComponent(new PassivationManagerStub(), PassivationManager.class); registerComponent(new ActivationManagerStub(), ActivationManager.class); registerComponent(new PersistenceManagerStub(), PersistenceManager.class); } @Override public void cacheComponents() { getOrCreateComponent(ExpirationManager.class); } }; componentRegistry.registerComponent(new CacheJmxRegistration(), CacheJmxRegistration.class.getName(), true); componentRegistry.registerComponent(new RollingUpgradeManager(), RollingUpgradeManager.class.getName(), true); componentRegistry.registerComponent(cache, Cache.class.getName(), true); return cache; } /** * Bootstraps this factory with a Configuration and a ComponentRegistry. */ private void bootstrap(String cacheName, AdvancedCache<?, ?> cache, Configuration configuration, GlobalComponentRegistry globalComponentRegistry, TypeConverter converter) { this.configuration = configuration; // injection bootstrap stuff componentRegistry = new ComponentRegistry(cacheName, configuration, cache, globalComponentRegistry, globalComponentRegistry.getClassLoader()) { @Override protected void bootstrapComponents() { registerComponent(converter, TypeConverter.class); } }; /* -------------------------------------------------------------------------------------------------------------- This is where the bootstrap really happens. Registering the cache in the component registry will cause the component registry to look at the cache's @Inject methods, and construct various components and their dependencies, in turn. -------------------------------------------------------------------------------------------------------------- */ componentRegistry.registerComponent(cache, Cache.class.getName(), true); componentRegistry.registerComponent(new CacheJmxRegistration(), CacheJmxRegistration.class.getName(), true); if (configuration.transaction().recovery().enabled()) { componentRegistry.registerComponent(new RecoveryAdminOperations(), RecoveryAdminOperations.class.getName(), true); } if (configuration.sites().hasEnabledBackups()) { componentRegistry.registerComponent(new XSiteAdminOperations(), XSiteAdminOperations.class.getName(), true); } // The RollingUpgradeManager should always be added so it is registered in JMX. componentRegistry.registerComponent(new RollingUpgradeManager(), RollingUpgradeManager.class.getName(), true); } @Override public <T> T construct(Class<T> componentType) { throw new UnsupportedOperationException("Should never be invoked - this is a bootstrap factory."); } }