javax.cache.configuration.MutableConfiguration Maven / Gradle / Ivy
/**
* Copyright 2011-2016 Terracotta, Inc.
* Copyright 2011-2016 Oracle America Incorporated
*
* 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 javax.cache.configuration;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.event.CacheEntryListener;
import javax.cache.expiry.EternalExpiryPolicy;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.integration.CacheLoader;
import javax.cache.integration.CacheWriter;
import java.util.HashSet;
/**
* A simple mutable implementation of a {@link Configuration}.
*
* @param the type of keys maintained the cache
* @param the type of cached values
* @author Brian Oliver
* @author Greg Luck
* @since 1.0
*/
public class MutableConfiguration implements CompleteConfiguration {
/**
* The serialVersionUID required for {@link java.io.Serializable}.
*/
public static final long serialVersionUID = 201306200821L;
/**
* The type of keys for {@link Cache}s configured with this
* {@link Configuration}.
*/
protected Class keyType;
/**
* The type of values for {@link Cache}s configured with this
* {@link Configuration}.
*/
protected Class valueType;
/**
* The {@link CacheEntryListenerConfiguration}s for the {@link Configuration}.
*/
protected HashSet> listenerConfigurations;
/**
* The {@link Factory} for the {@link CacheLoader}.
*/
protected Factory> cacheLoaderFactory;
/**
* The {@link Factory} for the {@link CacheWriter}.
*/
protected Factory> cacheWriterFactory;
/**
* The {@link Factory} for the {@link ExpiryPolicy}.
*/
protected Factory expiryPolicyFactory;
/**
* A flag indicating if "read-through" mode is required.
*/
protected boolean isReadThrough;
/**
* A flag indicating if "write-through" mode is required.
*/
protected boolean isWriteThrough;
/**
* A flag indicating if statistics gathering is enabled.
*/
protected boolean isStatisticsEnabled;
/**
* A flag indicating if the cache will be store-by-value or store-by-reference.
*/
protected boolean isStoreByValue;
/**
* Whether management is enabled
*/
protected boolean isManagementEnabled;
/**
* Default JavaBean constructor.
*
* Creates a default configuration. Default configurations have no
* runtime type checking and are set for eternal expiry.
*
* To enable runtime type enforcement, if supported by the implementation, call
* {@link #setTypes} after construction.
*
* After construction set any other configuration parameters in the
* fluent style. e.g.
*
* {@code
* CacheConfiguration = new MutableConfiguration()
* .setTypes(Integer.class, String.class)
* .setReadThrough(true)
* . . .
* }
* @see #setTypes(Class, Class)
*/
public MutableConfiguration() {
//Due to erasure in generics the type will always be Object.class. i.e. cast is ignored
this.keyType = (Class)Object.class;
//Due to erasure in generics the type will always be Object.class. i.e. cast is ignored
this.valueType = (Class)Object.class;
this.listenerConfigurations = new
HashSet>();
this.cacheLoaderFactory = null;
this.cacheWriterFactory = null;
this.expiryPolicyFactory = EternalExpiryPolicy.factoryOf();
this.isReadThrough = false;
this.isWriteThrough = false;
this.isStatisticsEnabled = false;
this.isStoreByValue = true;
this.isManagementEnabled = false;
}
/**
* Constructs a {@link MutableConfiguration} based on another
* {@link CompleteConfiguration}.
*
* @param configuration the {@link CompleteConfiguration}
*/
public MutableConfiguration(CompleteConfiguration configuration) {
this.keyType = configuration.getKeyType();
this.valueType = configuration.getValueType();
listenerConfigurations = new
HashSet>();
for (CacheEntryListenerConfiguration definition : configuration
.getCacheEntryListenerConfigurations()) {
addCacheEntryListenerConfiguration(definition);
}
this.cacheLoaderFactory = configuration.getCacheLoaderFactory();
this.cacheWriterFactory = configuration.getCacheWriterFactory();
if (configuration.getExpiryPolicyFactory() == null) {
this.expiryPolicyFactory = EternalExpiryPolicy.factoryOf();
} else {
this.expiryPolicyFactory = configuration.getExpiryPolicyFactory();
}
this.isReadThrough = configuration.isReadThrough();
this.isWriteThrough = configuration.isWriteThrough();
this.isStatisticsEnabled = configuration.isStatisticsEnabled();
this.isStoreByValue = configuration.isStoreByValue();
this.isManagementEnabled = configuration.isManagementEnabled();
}
/**
* {@inheritDoc}
*/
@Override
public Class getKeyType() {
return keyType;
}
/**
* {@inheritDoc}
*/
@Override
public Class getValueType() {
return valueType;
}
/**
* Sets the expected type of keys and values for a {@link Cache}
* configured with this {@link Configuration}. Setting both to
* Object.class
means type-safety checks are not required.
*
* This is used by {@link CacheManager} to ensure that the key and value
* types are the same as those configured for the {@link Cache} prior to
* returning a requested cache from this method.
*
* Implementations may further perform type checking on mutative cache operations
* and throw a {@link ClassCastException} if these checks fail.
*
* @param keyType the expected key type
* @param valueType the expected value type
* @return the {@link MutableConfiguration} to permit fluent-style method calls
* @throws NullPointerException should the key or value type be null
* @see CacheManager#getCache(String, Class, Class)
*/
public MutableConfiguration setTypes(Class keyType, Class valueType) {
if (keyType == null || valueType == null) {
throw new NullPointerException("keyType and/or valueType can't be null");
} else {
this.keyType = keyType;
this.valueType = valueType;
return this;
}
}
/**
* {@inheritDoc}
*/
@Override
public Iterable> getCacheEntryListenerConfigurations() {
return listenerConfigurations;
}
/**
* Add a configuration for a {@link CacheEntryListener}.
*
* @param cacheEntryListenerConfiguration the
* {@link CacheEntryListenerConfiguration}
* @return the {@link MutableConfiguration} to permit fluent-style method calls
* @throws IllegalArgumentException is the same CacheEntryListenerConfiguration
* is used more than once
*/
public MutableConfiguration addCacheEntryListenerConfiguration(
CacheEntryListenerConfiguration cacheEntryListenerConfiguration) {
if (cacheEntryListenerConfiguration == null) {
throw new NullPointerException("CacheEntryListenerConfiguration can't be null");
}
boolean alreadyExists = false;
for (CacheEntryListenerConfiguration super K, ? super V> c : listenerConfigurations) {
if (c.equals(cacheEntryListenerConfiguration)) {
alreadyExists = true;
}
}
if (!alreadyExists) {
this.listenerConfigurations.add(cacheEntryListenerConfiguration);
} else {
throw new IllegalArgumentException("A CacheEntryListenerConfiguration can " +
"be registered only once");
}
return this;
}
/**
* Remove a configuration for a {@link CacheEntryListener}.
*
* @param cacheEntryListenerConfiguration the
* {@link CacheEntryListenerConfiguration} to remove
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration removeCacheEntryListenerConfiguration(
CacheEntryListenerConfiguration cacheEntryListenerConfiguration) {
if (cacheEntryListenerConfiguration == null) {
throw new NullPointerException("CacheEntryListenerConfiguration can't be null");
}
listenerConfigurations.remove(cacheEntryListenerConfiguration);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Factory> getCacheLoaderFactory() {
return this.cacheLoaderFactory;
}
/**
* Set the {@link CacheLoader} factory.
*
* @param factory the {@link CacheLoader} {@link Factory}
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setCacheLoaderFactory(Factory extends
CacheLoader> factory) {
this.cacheLoaderFactory = (Factory>) factory;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Factory> getCacheWriterFactory() {
return this.cacheWriterFactory;
}
/**
* Set the {@link CacheWriter} factory.
*
* @param factory the {@link CacheWriter} {@link Factory}
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setCacheWriterFactory(Factory extends
CacheWriter super K, ? super V>> factory) {
this.cacheWriterFactory = (Factory>) factory;
return this;
}
/**
* {@inheritDoc}
*/
public Factory getExpiryPolicyFactory() {
return this.expiryPolicyFactory;
}
/**
* Set the {@link Factory} for the {@link ExpiryPolicy}. If null
* is specified the default {@link ExpiryPolicy} is used.
*
* Only one expiry policy can be set for a cache. The last policy applied
* before cache construction will be the one used.
* @param factory the {@link ExpiryPolicy} {@link Factory}
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setExpiryPolicyFactory(Factory extends
ExpiryPolicy> factory) {
if (factory == null) {
this.expiryPolicyFactory = EternalExpiryPolicy.factoryOf();
} else {
this.expiryPolicyFactory = (Factory) factory;
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isReadThrough() {
return this.isReadThrough;
}
/**
* Set if read-through caching should be used.
*
* It is an invalid configuration to set this to true without specifying a
* {@link CacheLoader} {@link Factory}.
*
* @param isReadThrough true
if read-through is required
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setReadThrough(boolean isReadThrough) {
this.isReadThrough = isReadThrough;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isWriteThrough() {
return this.isWriteThrough;
}
/**
* Set if write-through caching should be used.
*
* It is an invalid configuration to set this to true without specifying a
* {@link CacheWriter} {@link Factory}.
*
* @param isWriteThrough true
if write-through is required
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setWriteThrough(boolean isWriteThrough) {
this.isWriteThrough = isWriteThrough;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isStoreByValue() {
return this.isStoreByValue;
}
/**
* Set if a configured cache should use store-by-value or store-by-reference
* semantics.
*
* @param isStoreByValue true
if store-by-value is required,
* false
for store-by-reference
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setStoreByValue(boolean isStoreByValue) {
this.isStoreByValue = isStoreByValue;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isStatisticsEnabled() {
return this.isStatisticsEnabled;
}
/**
* Sets whether statistics gathering is enabled on a cache.
*
* Statistics may be enabled or disabled at runtime via
* {@link CacheManager#enableStatistics(String, boolean)}.
*
* @param enabled true to enable statistics, false to disable.
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setStatisticsEnabled(boolean enabled) {
this.isStatisticsEnabled = enabled;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isManagementEnabled() {
return this.isManagementEnabled;
}
/**
* Sets whether management is enabled on a cache.
*
* Management may be enabled or disabled at runtime via
* {@link CacheManager#enableManagement(String, boolean)}.
*
* @param enabled true to enable statistics, false to disable.
* @return the {@link MutableConfiguration} to permit fluent-style method calls
*/
public MutableConfiguration setManagementEnabled(boolean enabled) {
this.isManagementEnabled = enabled;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + keyType.hashCode();
result = prime * result + valueType.hashCode();
result = prime
* result
+ ((listenerConfigurations == null) ? 0 : listenerConfigurations
.hashCode());
result = prime * result
+ ((cacheLoaderFactory == null) ? 0 : cacheLoaderFactory.hashCode());
result = prime * result
+ ((cacheWriterFactory == null) ? 0 : cacheWriterFactory.hashCode());
result = prime * result
+ ((expiryPolicyFactory == null) ? 0 : expiryPolicyFactory.hashCode());
result = prime * result + (isReadThrough ? 1231 : 1237);
result = prime * result + (isStatisticsEnabled ? 1231 : 1237);
result = prime * result + (isStoreByValue ? 1231 : 1237);
result = prime * result + (isWriteThrough ? 1231 : 1237);
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object == null) {
return false;
}
if (!(object instanceof MutableConfiguration)) {
return false;
}
MutableConfiguration, ?> other = (MutableConfiguration, ?>) object;
if (!keyType.equals(other.keyType)) {
return false;
}
if (!valueType.equals(other.valueType)) {
return false;
}
if (!listenerConfigurations.equals(other.listenerConfigurations)) {
return false;
}
if (cacheLoaderFactory == null) {
if (other.cacheLoaderFactory != null) {
return false;
}
} else if (!cacheLoaderFactory.equals(other.cacheLoaderFactory)) {
return false;
}
if (cacheWriterFactory == null) {
if (other.cacheWriterFactory != null) {
return false;
}
} else if (!cacheWriterFactory.equals(other.cacheWriterFactory)) {
return false;
}
if (expiryPolicyFactory == null) {
if (other.expiryPolicyFactory != null) {
return false;
}
} else if (!expiryPolicyFactory.equals(other.expiryPolicyFactory)) {
return false;
}
if (isReadThrough != other.isReadThrough) {
return false;
}
if (isStatisticsEnabled != other.isStatisticsEnabled) {
return false;
}
if (isStoreByValue != other.isStoreByValue) {
return false;
}
if (isWriteThrough != other.isWriteThrough) {
return false;
}
return true;
}
}