/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * See the copyright.txt in the distribution for a full listing of * individual contributors. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.infinispan.config; import org.infinispan.config.FluentConfiguration.LoadersConfig; import org.infinispan.loaders.CacheLoaderConfig; import org.infinispan.loaders.CacheStoreConfig; import org.infinispan.util.Util; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import java.util.LinkedList; import java.util.List; /** * Holds the configuration of the cache loader chain. All cache loaders should be defined using this * class, adding individual cache loaders to the chain by calling * {@link CacheLoaderManagerConfig#addCacheLoaderConfig} * * * * @see <a href="../../../config.html#ce_default_loaders">Configuration reference</a> * * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a> * @author Brian Stansberry * @author Vladimir Blagojevic * @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a> * @since 4.0 */ @XmlAccessorType(XmlAccessType.PROPERTY) @ConfigurationDoc(name="loaders",desc="Holds the configuration for cache loaders and stores") @SuppressWarnings("boxing") public class CacheLoaderManagerConfig extends AbstractFluentConfigurationBean implements LoadersConfig { private static final long serialVersionUID = 2210349340378984424L; @ConfigurationDocRef(bean=CacheLoaderManagerConfig.class,targetElement="setPassivation") protected Boolean passivation = false; @ConfigurationDocRef(bean=CacheLoaderManagerConfig.class,targetElement="setPreload") protected Boolean preload = false; @ConfigurationDocRef(bean=CacheLoaderManagerConfig.class,targetElement="setShared") protected Boolean shared = false; protected List<CacheLoaderConfig> cacheLoaderConfigs = new LinkedList<CacheLoaderConfig>(); public CacheLoaderManagerConfig() { } public CacheLoaderManagerConfig(CacheLoaderConfig clc) { addCacheLoaderConfig(clc); } public Boolean isPreload() { return preload; } /** * If true, when the cache starts, data stored in the cache store will be pre-loaded into memory. * This is particularly useful when data in the cache store will be needed immediately after * startup and you want to avoid cache operations being delayed as a result of loading this data * lazily. Can be used to provide a 'warm-cache' on startup, however there is a performance * penalty as startup time is affected by this process. * * @param preload */ @Override public LoadersConfig preload(Boolean preload) { testImmutability("preload"); this.preload = preload; return this; } /** * @deprecated The visibility of this method will be reduced. Use {@link #preload(Boolean)} instead. */ @XmlAttribute @Deprecated public void setPreload(Boolean preload) { testImmutability("preload"); this.preload = preload; } /** * If true, data is only written to the cache store when it is evicted from memory, a phenomenon * known as 'passivation'. Next time the data is requested, it will be 'activated' which means * that data will be brought back to memory and removed from the persistent store. This gives you * the ability to 'overflow' to disk, similar to swapping in an operating system. <br /> * <br /> * If false, the cache store contains a copy of the contents in memory, so writes to cache result * in cache store writes. This essentially gives you a 'write-through' configuration. * * @param passivation */ @Override public LoadersConfig passivation(Boolean passivation) { testImmutability("passivation"); this.passivation = passivation; return this; } /** * @deprecated The visibility of this method will be reduced. Use {@link #passivation(Boolean)} instead. */ @XmlAttribute @Deprecated public void setPassivation(Boolean passivation) { testImmutability("passivation"); this.passivation = passivation; } public Boolean isPassivation() { return passivation; } /** * This setting should be set to true when multiple cache instances share the same cache store * (e.g., multiple nodes in a cluster using a JDBC-based CacheStore pointing to the same, shared * database.) Setting this to true avoids multiple cache instances writing the same modification * multiple times. If enabled, only the node where the modification originated will write to the * cache store. <br /> * <br /> * If disabled, each individual cache reacts to a potential remote update by storing the data to * the cache store. Note that this could be useful if each individual node has its own cache * store - perhaps local on-disk. * * @param shared */ @Override public LoadersConfig shared(Boolean shared) { testImmutability("shared"); this.shared = shared; return this; } @Override public LoadersConfig addCacheLoader(CacheLoaderConfig... configs) { for (CacheLoaderConfig config : configs) addCacheLoaderConfig(config); return this; } /** * @deprecated The visibility of this method will be reduced. Use {@link #shared(Boolean)} instead. */ @XmlAttribute @Deprecated public void setShared(Boolean shared) { testImmutability("shared"); this.shared = shared; } public Boolean isShared() { return shared; } /** * * @param clc * @return * @deprecated use {@link #addCacheLoader(org.infinispan.loaders.CacheLoaderConfig...)} instead */ @Deprecated public LoadersConfig addCacheLoaderConfig(CacheLoaderConfig clc) { testImmutability("cacheLoaderConfigs"); cacheLoaderConfigs.add(clc); return this; } public List<CacheLoaderConfig> getCacheLoaderConfigs() { return cacheLoaderConfigs; } // JAXB method private List<CacheLoaderConfig> getCacheLoaders() { testImmutability("cacheLoaderConfigs"); return cacheLoaderConfigs; } // JAXB method @XmlElement(name = "loader") private LoadersConfig setCacheLoaders(List<CacheLoaderConfig> configs) { testImmutability("cacheLoaderConfigs"); this.cacheLoaderConfigs = configs == null ? new LinkedList<CacheLoaderConfig>() : configs; return this; } /** * @deprecated The visibility of this method will be reduced and * XMLElement definition is likely to move to the getCacheLoaderConfigs(). */ @Deprecated @XmlTransient // Avoid JAXB finding this method public LoadersConfig setCacheLoaderConfigs(List<CacheLoaderConfig> configs) { testImmutability("cacheLoaderConfigs"); this.cacheLoaderConfigs = configs == null ? new LinkedList<CacheLoaderConfig>() : configs; return this; } public CacheLoaderConfig getFirstCacheLoaderConfig() { if (cacheLoaderConfigs.isEmpty()) return null; return cacheLoaderConfigs.get(0); } /** * Loops through all individual cache loader configs and checks if fetchPersistentState is set on * any of them */ public Boolean isFetchPersistentState() { for (CacheLoaderConfig iclc : cacheLoaderConfigs) { if (iclc instanceof CacheStoreConfig) if (((CacheStoreConfig) iclc).isFetchPersistentState()) return true; } return false; } @Override protected CacheLoaderManagerConfig setConfiguration(Configuration config) { super.setConfiguration(config); return this; } public boolean usingChainingCacheLoader() { return !isPassivation() && cacheLoaderConfigs.size() > 1; } @Override public String toString() { return new StringBuilder().append("CacheLoaderManagerConfig{").append("shared=").append( shared).append(", passivation=").append(passivation).append(", preload='").append( preload).append('\'').append(", cacheLoaderConfigs.size()=").append( cacheLoaderConfigs.size()).append('}').toString(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof CacheLoaderManagerConfig) { CacheLoaderManagerConfig other = (CacheLoaderManagerConfig) obj; return (this.passivation.equals(other.passivation)) && (this.shared.equals(other.shared)) && Util.safeEquals(this.preload, other.preload) && Util.safeEquals(this.cacheLoaderConfigs, other.cacheLoaderConfigs); } return false; } public void accept(ConfigurationBeanVisitor v) { for (CacheLoaderConfig clc : cacheLoaderConfigs) { clc.accept(v); } v.visitCacheLoaderManagerConfig(this); } @Override public int hashCode() { int result = 19; result = 51 * result + (passivation ? 0 : 1); result = 51 * result + (shared ? 0 : 1); result = 51 * result + (preload ? 0 : 1); result = 51 * result + (cacheLoaderConfigs == null ? 0 : cacheLoaderConfigs.hashCode()); return result; } @Override public CacheLoaderManagerConfig clone() throws CloneNotSupportedException { CacheLoaderManagerConfig clone = (CacheLoaderManagerConfig) super.clone(); if (cacheLoaderConfigs != null) { List<CacheLoaderConfig> clcs = new LinkedList<CacheLoaderConfig>(); for (CacheLoaderConfig clc : cacheLoaderConfigs) { clcs.add(clc.clone()); } clone.cacheLoaderConfigs = clcs; } return clone; } }