/* * Copyright Terracotta, Inc. * * 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 org.ehcache.core.config; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.ehcache.config.CacheConfiguration; import org.ehcache.config.CacheRuntimeConfiguration; import org.ehcache.config.Configuration; import org.ehcache.core.HumanReadable; import org.ehcache.core.internal.util.ClassLoading; import org.ehcache.spi.service.ServiceCreationConfiguration; import static java.util.Collections.unmodifiableCollection; import static java.util.Collections.unmodifiableMap; /** * Base implementation of {@link Configuration}. */ public final class DefaultConfiguration implements Configuration, HumanReadable { private final ConcurrentMap<String,CacheConfiguration<?, ?>> caches; private final Collection<ServiceCreationConfiguration<?>> services; private final ClassLoader classLoader; /** * Copy constructor * * @param cfg the configuration to copy */ public DefaultConfiguration(Configuration cfg) { if (cfg.getClassLoader() == null) { throw new NullPointerException(); } this.caches = new ConcurrentHashMap<String, CacheConfiguration<?, ?>>(cfg.getCacheConfigurations()); this.services = unmodifiableCollection(cfg.getServiceCreationConfigurations()); this.classLoader = cfg.getClassLoader(); } /** * Creates a new configuration with the specified class loader. * <p> * This means no cache configurations nor service configurations. * * @param classLoader the class loader to use * @param services an array of service configurations * * @see #addCacheConfiguration(String, CacheConfiguration) */ public DefaultConfiguration(ClassLoader classLoader, ServiceCreationConfiguration<?>... services) { this(emptyCacheMap(), classLoader, services); } /** * Creates a new configuration with the specified {@link CacheConfiguration cache configurations}, class loader and * {@link org.ehcache.spi.service.ServiceConfiguration service configurations}. * * @param caches a map from alias to cache configuration * @param classLoader the class loader to use for user types * @param services an array of service configurations */ public DefaultConfiguration(Map<String, CacheConfiguration<?, ?>> caches, ClassLoader classLoader, ServiceCreationConfiguration<?>... services) { this.services = unmodifiableCollection(Arrays.asList(services)); this.caches = new ConcurrentHashMap<String, CacheConfiguration<?, ?>>(caches); this.classLoader = classLoader == null ? ClassLoading.getDefaultClassLoader() : classLoader; } /** * {@inheritDoc} */ @Override public Map<String, CacheConfiguration<?, ?>> getCacheConfigurations() { return unmodifiableMap(caches); } /** * {@inheritDoc} */ @Override public Collection<ServiceCreationConfiguration<?>> getServiceCreationConfigurations() { return services; } /** * {@inheritDoc} */ @Override public ClassLoader getClassLoader() { return classLoader; } private static Map<String, CacheConfiguration<?, ?>> emptyCacheMap() { return Collections.emptyMap(); } /** * Adds a {@link CacheConfiguration} tied to the provided alias. * * @param alias the alias of the cache * @param config the configuration of the cache */ public void addCacheConfiguration(final String alias, final CacheConfiguration<?, ?> config) { if (caches.put(alias, config) != null) { throw new IllegalStateException("Cache '" + alias + "' already present!"); } } /** * Removes the {@link CacheConfiguration} tied to the provided alias. * * @param alias the alias for which to remove configuration */ public void removeCacheConfiguration(final String alias) { caches.remove(alias); } /** * Replaces a {@link CacheConfiguration} with a {@link CacheRuntimeConfiguration} for the provided alias. * * @param alias the alias of the cache * @param config the existing configuration * @param runtimeConfiguration the new configuration * @param <K> the key type * @param <V> the value type * * @throws IllegalStateException if the replace fails */ public <K, V> void replaceCacheConfiguration(final String alias, final CacheConfiguration<K, V> config, final CacheRuntimeConfiguration<K, V> runtimeConfiguration) { if (!caches.replace(alias, config, runtimeConfiguration)) { throw new IllegalStateException("The expected configuration doesn't match!"); } } @Override public String readableString() { StringBuilder cachesToStringBuilder = new StringBuilder(); for (Map.Entry<String, CacheConfiguration<?, ?>> cacheConfigurationEntry : caches.entrySet()) { if(cacheConfigurationEntry.getValue() instanceof HumanReadable) { cachesToStringBuilder .append(cacheConfigurationEntry.getKey()) .append(":\n ") .append(((HumanReadable)cacheConfigurationEntry.getValue()).readableString().replace("\n","\n ")) .append("\n"); } } if(cachesToStringBuilder.length() > 0) { cachesToStringBuilder.deleteCharAt(cachesToStringBuilder.length() -1); } StringBuilder serviceCreationConfigurationsToStringBuilder = new StringBuilder(); for (ServiceCreationConfiguration serviceCreationConfiguration : services) { serviceCreationConfigurationsToStringBuilder.append("- "); if(serviceCreationConfiguration instanceof HumanReadable) { serviceCreationConfigurationsToStringBuilder .append(((HumanReadable)serviceCreationConfiguration).readableString()) .append("\n"); } else { serviceCreationConfigurationsToStringBuilder .append(serviceCreationConfiguration.getClass().getName()) .append("\n"); } } if(serviceCreationConfigurationsToStringBuilder.length() > 0) { serviceCreationConfigurationsToStringBuilder.deleteCharAt(serviceCreationConfigurationsToStringBuilder.length() -1); } return "caches:\n " + cachesToStringBuilder.toString().replace("\n","\n ") + "\n" + "services: \n " + serviceCreationConfigurationsToStringBuilder.toString().replace("\n","\n ") ; } }