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