/** @author Alex Snaps */
public class StandaloneCacheBuilder<K, V, T extends StandaloneCache<K, V>> {

  private final Class<K> keyType;
  private final Class<V> valueType;
  private Expiry<? super K, ? super V> expiry = Expirations.noExpiration();
  private ClassLoader classLoader = ClassLoading.getDefaultClassLoader();
  private Comparable<Long> capacityConstraint;
  private EvictionVeto<? super K, ? super V> evictionVeto;
  private EvictionPrioritizer<? super K, ? super V> evictionPrioritizer;
  private CacheLoader<? super K, ? extends V> cacheLoader;
  private CacheWriter<? super K, ? super V> cacheWriter;
  private SerializationProvider serializationProvider;
  private ScheduledExecutorService statisticsExecutor;

  public StandaloneCacheBuilder(final Class<K> keyType, final Class<V> valueType) {
    this.keyType = keyType;
    this.valueType = valueType;
  }

  T build(ServiceLocator serviceLocator) {
    Store.Provider storeProvider = serviceLocator.findService(Store.Provider.class);
    if (serializationProvider == null) {
      this.serializationProvider = serviceLocator.findService(SerializationProvider.class);
    }
    ExecutorFactoryService executorService =
        serviceLocator.findService(ExecutorFactoryService.class);
    if (executorService != null && executorService.getStatisticsExecutor() != null) {
      statisticsExecutor = executorService.getStatisticsExecutor();
    } else {
      statisticsExecutor = StatisticsThreadPoolUtil.getDefaultStatisticsExecutorService();
    }

    final StoreConfigurationImpl<K, V> storeConfig =
        new StoreConfigurationImpl<K, V>(
            keyType,
            valueType,
            capacityConstraint,
            evictionVeto,
            evictionPrioritizer,
            classLoader,
            expiry,
            serializationProvider);
    final Store<K, V> store = storeProvider.createStore(storeConfig);

    CacheConfiguration<K, V> cacheConfig =
        new BaseCacheConfiguration<K, V>(
            keyType,
            valueType,
            capacityConstraint,
            evictionVeto,
            evictionPrioritizer,
            classLoader,
            expiry,
            serializationProvider,
            new ServiceConfiguration<?>[] {});

    final Ehcache<K, V> ehcache =
        new Ehcache<K, V>(cacheConfig, store, cacheLoader, cacheWriter, statisticsExecutor);

    return (T) ehcache;
  }

  public final T build() {
    return build(new ServiceLocator());
  }

  public final <N extends T> StandaloneCacheBuilder<K, V, N> with(
      StandaloneCacheConfiguration<K, V, N> cfg) {
    return cfg.builder(this);
  }

  public final StandaloneCacheBuilder<K, V, T> withCapacity(Comparable<Long> constraint) {
    capacityConstraint = constraint;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> vetoEviction(
      EvictionVeto<? super K, ? super V> predicate) {
    this.evictionVeto = predicate;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> prioritizeEviction(
      EvictionPrioritizer<? super K, ? super V> criteria) {
    this.evictionPrioritizer = criteria;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> loadingWith(
      CacheLoader<? super K, ? extends V> cacheLoader) {
    this.cacheLoader = cacheLoader;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> withClassLoader(ClassLoader classLoader) {
    if (classLoader == null) {
      throw new NullPointerException("Null classloader");
    }
    this.classLoader = classLoader;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> withExpiry(Expiry<K, V> expiry) {
    if (expiry == null) {
      throw new NullPointerException("Null expiry");
    }

    this.expiry = expiry;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> writingWith(
      CacheWriter<? super K, ? super V> cacheWriter) {
    this.cacheWriter = cacheWriter;
    return this;
  }

  public final StandaloneCacheBuilder<K, V, T> withSerializationProvider(
      SerializationProvider serializationProvider) {
    this.serializationProvider = serializationProvider;
    return this;
  }

  public static <K, V, T extends StandaloneCache<K, V>>
      StandaloneCacheBuilder<K, V, T> newCacheBuilder(Class<K> keyType, Class<V> valueType) {
    return new StandaloneCacheBuilder<K, V, T>(keyType, valueType);
  }
}
  @SuppressWarnings({"rawtypes", "unchecked"})
  private void parseConfiguration()
      throws ClassNotFoundException, IOException, SAXException, InstantiationException,
          IllegalAccessException {
    LOGGER.info("Loading Ehcache XML configuration from {}.", xml.getPath());
    ConfigurationParser configurationParser =
        new ConfigurationParser(xml.toExternalForm(), CORE_SCHEMA_URL);

    final ArrayList<ServiceCreationConfiguration<?>> serviceConfigs =
        new ArrayList<ServiceCreationConfiguration<?>>();

    for (ServiceType serviceType : configurationParser.getServiceElements()) {
      if (serviceType.getDefaultSerializers() != null) {
        DefaultSerializationProviderConfiguration configuration =
            new DefaultSerializationProviderConfiguration();

        for (SerializerType.Serializer serializer :
            serviceType.getDefaultSerializers().getSerializer()) {
          try {
            configuration.addSerializerFor(
                getClassForName(serializer.getType(), classLoader),
                (Class) getClassForName(serializer.getValue(), classLoader));
          } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
          }
        }
        serviceConfigs.add(configuration);
      } else if (serviceType.getPersistence() != null) {
        serviceConfigs.add(
            new CacheManagerPersistenceConfiguration(
                new File(serviceType.getPersistence().getDirectory())));
      } else {
        final ServiceCreationConfiguration<?> serviceConfiguration1 =
            configurationParser.parseExtension((Element) serviceType.getAny());
        serviceConfigs.add(serviceConfiguration1);
      }
    }

    for (ServiceCreationConfiguration<?> serviceConfiguration :
        Collections.unmodifiableList(serviceConfigs)) {
      serviceConfigurations.add(serviceConfiguration);
    }

    for (ConfigurationParser.CacheDefinition cacheDefinition :
        configurationParser.getCacheElements()) {
      CacheConfigurationBuilder<Object, Object> builder =
          CacheConfigurationBuilder.newCacheConfigurationBuilder();
      String alias = cacheDefinition.id();

      ClassLoader cacheClassLoader = cacheClassLoaders.get(alias);
      if (cacheClassLoader != null) {
        builder = builder.withClassLoader(cacheClassLoader);
      }

      if (cacheClassLoader == null) {
        if (classLoader != null) {
          cacheClassLoader = classLoader;
        } else {
          cacheClassLoader = ClassLoading.getDefaultClassLoader();
        }
      }

      Class keyType = getClassForName(cacheDefinition.keyType(), cacheClassLoader);
      Class valueType = getClassForName(cacheDefinition.valueType(), cacheClassLoader);
      if (cacheDefinition.keySerializer() != null) {
        Class keySerializer = getClassForName(cacheDefinition.keySerializer(), cacheClassLoader);
        builder =
            builder.add(
                new DefaultSerializerConfiguration(
                    keySerializer, DefaultSerializerConfiguration.Type.KEY));
      }
      if (cacheDefinition.valueSerializer() != null) {
        Class valueSerializer =
            getClassForName(cacheDefinition.valueSerializer(), cacheClassLoader);
        builder =
            builder.add(
                new DefaultSerializerConfiguration(
                    valueSerializer, DefaultSerializerConfiguration.Type.VALUE));
      }
      EvictionVeto evictionVeto =
          getInstanceOfName(cacheDefinition.evictionVeto(), cacheClassLoader, EvictionVeto.class);
      EvictionPrioritizer evictionPrioritizer =
          getInstanceOfName(
              cacheDefinition.evictionPrioritizer(),
              cacheClassLoader,
              EvictionPrioritizer.class,
              Eviction.Prioritizer.class);
      final ConfigurationParser.Expiry parsedExpiry = cacheDefinition.expiry();
      if (parsedExpiry != null) {
        builder = builder.withExpiry(getExpiry(cacheClassLoader, parsedExpiry));
      }
      ResourcePoolsBuilder resourcePoolsBuilder = newResourcePoolsBuilder();
      for (ResourcePool resourcePool : cacheDefinition.resourcePools()) {
        resourcePoolsBuilder =
            resourcePoolsBuilder.with(
                resourcePool.getType(),
                resourcePool.getSize(),
                resourcePool.getUnit(),
                resourcePool.isPersistent());
      }
      builder = builder.withResourcePools(resourcePoolsBuilder);
      for (ServiceConfiguration<?> serviceConfig : cacheDefinition.serviceConfigs()) {
        builder = builder.add(serviceConfig);
      }
      if (cacheDefinition.loaderWriter() != null) {
        final Class<CacheLoaderWriter<?, ?>> cacheLoaderWriterClass =
            (Class<CacheLoaderWriter<?, ?>>)
                getClassForName(cacheDefinition.loaderWriter(), cacheClassLoader);
        builder = builder.add(new DefaultCacheLoaderWriterConfiguration(cacheLoaderWriterClass));
        if (cacheDefinition.writeBehind() != null) {
          WriteBehind writeBehind = cacheDefinition.writeBehind();
          WriteBehindConfigurationBuilder writeBehindConfigurationBuilder =
              WriteBehindConfigurationBuilder.newWriteBehindConfiguration()
                  .concurrencyLevel(writeBehind.concurrency())
                  .queueSize(writeBehind.maxQueueSize())
                  .rateLimit(writeBehind.rateLimitPerSecond())
                  .retry(writeBehind.retryAttempts(), writeBehind.retryAttemptsDelay())
                  .delay(writeBehind.minWriteDelay(), writeBehind.maxWriteDelay());
          if (writeBehind.isBatched()) {
            writeBehindConfigurationBuilder =
                writeBehindConfigurationBuilder.batchSize(writeBehind.batchSize());
          }
          if (writeBehind.isCoalesced()) {
            writeBehindConfigurationBuilder = writeBehindConfigurationBuilder.enableCoalescing();
          }
          builder = builder.add(writeBehindConfigurationBuilder);
        }
      }
      if (cacheDefinition.listeners() != null) {
        for (ConfigurationParser.Listener listener : cacheDefinition.listeners()) {
          final Class<CacheEventListener<?, ?>> cacheEventListenerClass =
              (Class<CacheEventListener<?, ?>>)
                  getClassForName(listener.className(), cacheClassLoader);
          final List<EventType> eventListToFireOn = listener.fireOn();
          Set<org.ehcache.event.EventType> eventSetToFireOn =
              new HashSet<org.ehcache.event.EventType>();
          for (EventType events : eventListToFireOn) {
            switch (events) {
              case CREATED:
                eventSetToFireOn.add(org.ehcache.event.EventType.CREATED);
                break;
              case EVICTED:
                eventSetToFireOn.add(org.ehcache.event.EventType.EVICTED);
                break;
              case EXPIRED:
                eventSetToFireOn.add(org.ehcache.event.EventType.EXPIRED);
                break;
              case UPDATED:
                eventSetToFireOn.add(org.ehcache.event.EventType.UPDATED);
                break;
              case REMOVED:
                eventSetToFireOn.add(org.ehcache.event.EventType.REMOVED);
                break;
              default:
                throw new IllegalArgumentException("Invalid Event Type provided");
            }
          }
          CacheEventListenerConfigurationBuilder listenerBuilder =
              CacheEventListenerConfigurationBuilder.newEventListenerConfiguration(
                      cacheEventListenerClass, eventSetToFireOn)
                  .firingMode(EventFiring.valueOf(listener.eventFiring().value()))
                  .eventOrdering(EventOrdering.valueOf(listener.eventOrdering().value()));
          builder = builder.add(listenerBuilder);
        }
      }
      if (cacheDefinition.storeByValueOnHeap() != null) {
        final OnHeapStoreServiceConfiguration onHeapStoreServiceConfig =
            new OnHeapStoreServiceConfiguration();
        onHeapStoreServiceConfig.storeByValue(cacheDefinition.storeByValueOnHeap());
        builder = builder.add(onHeapStoreServiceConfig);
      }
      final CacheConfiguration<?, ?> config =
          builder.buildConfig(keyType, valueType, evictionVeto, evictionPrioritizer);
      cacheConfigurations.put(alias, config);
    }

    templates.putAll(configurationParser.getTemplates());
  }
  /**
   * Creates a new {@link org.ehcache.config.CacheConfigurationBuilder} seeded with the
   * cache-template configuration by the given {@code name} in the XML configuration parsed using
   * {@link #parseConfiguration()}
   *
   * @param name the unique name identifying the cache-template element in the XML
   * @param keyType the type of keys for the {@link org.ehcache.config.CacheConfigurationBuilder} to
   *     use, would need to match the {@code key-type} declared in the template if declared in XML
   * @param valueType the type of values for the {@link
   *     org.ehcache.config.CacheConfigurationBuilder} to use, would need to match the {@code
   *     value-type} declared in the template if declared in XML
   * @param <K> type of keys
   * @param <V> type of values
   * @return the preconfigured {@link org.ehcache.config.CacheConfigurationBuilder} or {@code null}
   *     if no cache-template for the provided {@code name}
   * @throws IllegalStateException if {@link #parseConfiguration()} hasn't yet been successfully
   *     invoked
   * @throws IllegalArgumentException if {@code keyType} or {@code valueType} don't match the
   *     declared type(s) of the template
   * @throws ClassNotFoundException if a {@link java.lang.Class} declared in the XML couldn't be
   *     found
   * @throws InstantiationException if a user provided {@link java.lang.Class} couldn't get
   *     instantiated
   * @throws IllegalAccessException if a method (including constructor) couldn't be invoked on a
   *     user provided type
   */
  @SuppressWarnings("unchecked")
  public <K, V> CacheConfigurationBuilder<K, V> newCacheConfigurationBuilderFromTemplate(
      final String name, final Class<K> keyType, final Class<V> valueType)
      throws InstantiationException, IllegalAccessException, ClassNotFoundException {

    final ConfigurationParser.CacheTemplate cacheTemplate = templates.get(name);
    if (cacheTemplate == null) {
      return null;
    }
    final ClassLoader defaultClassLoader = ClassLoading.getDefaultClassLoader();
    Class keyClass = getClassForName(cacheTemplate.keyType(), defaultClassLoader);
    Class valueClass = getClassForName(cacheTemplate.valueType(), defaultClassLoader);
    if (keyType != null && cacheTemplate.keyType() != null && !keyClass.isAssignableFrom(keyType)) {
      throw new IllegalArgumentException(
          "CacheTemplate '" + name + "' declares key type of " + cacheTemplate.keyType());
    }
    if (valueType != null
        && cacheTemplate.valueType() != null
        && !valueClass.isAssignableFrom(valueType)) {
      throw new IllegalArgumentException(
          "CacheTemplate '" + name + "' declares value type of " + cacheTemplate.valueType());
    }

    CacheConfigurationBuilder<K, V> builder =
        CacheConfigurationBuilder.newCacheConfigurationBuilder();
    builder =
        builder
            .usingEvictionPrioritizer(
                getInstanceOfName(
                    cacheTemplate.evictionPrioritizer(),
                    defaultClassLoader,
                    EvictionPrioritizer.class,
                    Eviction.Prioritizer.class))
            .evictionVeto(
                getInstanceOfName(
                    cacheTemplate.evictionVeto(), defaultClassLoader, EvictionVeto.class));
    final ConfigurationParser.Expiry parsedExpiry = cacheTemplate.expiry();
    if (parsedExpiry != null) {
      builder = builder.withExpiry(getExpiry(defaultClassLoader, parsedExpiry));
    }

    if (cacheTemplate.keySerializer() != null) {
      final Class<Serializer<?>> keySerializer =
          (Class<Serializer<?>>) getClassForName(cacheTemplate.keySerializer(), defaultClassLoader);
      builder =
          builder.add(
              new DefaultSerializerConfiguration(
                  keySerializer, DefaultSerializerConfiguration.Type.KEY));
    }
    if (cacheTemplate.valueSerializer() != null) {
      final Class<Serializer<?>> valueSerializer =
          (Class<Serializer<?>>)
              getClassForName(cacheTemplate.valueSerializer(), defaultClassLoader);
      builder =
          builder.add(
              new DefaultSerializerConfiguration(
                  valueSerializer, DefaultSerializerConfiguration.Type.VALUE));
    }
    final String loaderWriter = cacheTemplate.loaderWriter();
    if (loaderWriter != null) {
      final Class<CacheLoaderWriter<?, ?>> cacheLoaderWriterClass =
          (Class<CacheLoaderWriter<?, ?>>) getClassForName(loaderWriter, defaultClassLoader);
      builder = builder.add(new DefaultCacheLoaderWriterConfiguration(cacheLoaderWriterClass));
      if (cacheTemplate.writeBehind() != null) {
        WriteBehind writeBehind = cacheTemplate.writeBehind();
        WriteBehindConfigurationBuilder writeBehindConfigurationBuilder =
            WriteBehindConfigurationBuilder.newWriteBehindConfiguration()
                .concurrencyLevel(writeBehind.concurrency())
                .queueSize(writeBehind.maxQueueSize())
                .rateLimit(writeBehind.rateLimitPerSecond())
                .retry(writeBehind.retryAttempts(), writeBehind.retryAttemptsDelay())
                .delay(writeBehind.minWriteDelay(), writeBehind.maxWriteDelay());
        if (writeBehind.isBatched()) {
          writeBehindConfigurationBuilder =
              writeBehindConfigurationBuilder.batchSize(writeBehind.batchSize());
        }
        if (writeBehind.isCoalesced()) {
          writeBehindConfigurationBuilder = writeBehindConfigurationBuilder.enableCoalescing();
        }
        builder = builder.add(writeBehindConfigurationBuilder);
      }
    }
    if (cacheTemplate.listeners() != null) {
      for (ConfigurationParser.Listener listener : cacheTemplate.listeners()) {
        final Class<CacheEventListener<?, ?>> cacheEventListenerClass =
            (Class<CacheEventListener<?, ?>>)
                getClassForName(listener.className(), defaultClassLoader);
        final List<EventType> eventListToFireOn = listener.fireOn();
        Set<org.ehcache.event.EventType> eventSetToFireOn =
            new HashSet<org.ehcache.event.EventType>();
        for (EventType events : eventListToFireOn) {
          switch (events) {
            case CREATED:
              eventSetToFireOn.add(org.ehcache.event.EventType.CREATED);
              break;
            case EVICTED:
              eventSetToFireOn.add(org.ehcache.event.EventType.EVICTED);
              break;
            case EXPIRED:
              eventSetToFireOn.add(org.ehcache.event.EventType.EXPIRED);
              break;
            case UPDATED:
              eventSetToFireOn.add(org.ehcache.event.EventType.UPDATED);
              break;
            case REMOVED:
              eventSetToFireOn.add(org.ehcache.event.EventType.REMOVED);
              break;
            default:
              throw new IllegalArgumentException("Invalid Event Type provided");
          }
        }
        CacheEventListenerConfigurationBuilder listenerBuilder =
            CacheEventListenerConfigurationBuilder.newEventListenerConfiguration(
                    cacheEventListenerClass, eventSetToFireOn)
                .firingMode(EventFiring.valueOf(listener.eventFiring().value()))
                .eventOrdering(EventOrdering.valueOf(listener.eventOrdering().value()));
        builder = builder.add(listenerBuilder);
      }
    }
    ResourcePoolsBuilder resourcePoolsBuilder = newResourcePoolsBuilder();
    for (ResourcePool resourcePool : cacheTemplate.resourcePools()) {
      resourcePoolsBuilder =
          resourcePoolsBuilder.with(
              resourcePool.getType(),
              resourcePool.getSize(),
              resourcePool.getUnit(),
              resourcePool.isPersistent());
    }
    builder = builder.withResourcePools(resourcePoolsBuilder);
    for (ServiceConfiguration<?> serviceConfiguration : cacheTemplate.serviceConfigs()) {
      builder = builder.add(serviceConfiguration);
    }
    if (cacheTemplate.storeByValueOnHeap() != null) {
      final OnHeapStoreServiceConfiguration onHeapStoreServiceConfig =
          new OnHeapStoreServiceConfiguration();
      onHeapStoreServiceConfig.storeByValue(cacheTemplate.storeByValueOnHeap());
      builder = builder.add(onHeapStoreServiceConfig);
    }
    return builder;
  }
Esempio n. 4
0
 /**
  * Constructs an instance of XmlConfiguration mapping to the XML file located at {@code url}
  *
  * <p>Parses the XML file at the {@code url} provided.
  *
  * @param url URL pointing to the XML file's location
  * @throws IOException if anything went wrong accessing the URL
  * @throws SAXException if anything went wrong parsing or validating the XML
  * @throws ClassNotFoundException if a {@link java.lang.Class} declared in the XML couldn't be
  *     found
  * @throws InstantiationException if a user provided {@link java.lang.Class} couldn't get
  *     instantiated
  * @throws IllegalAccessException if a method (including constructor) couldn't be invoked on a
  *     user provided type
  */
 public XmlConfiguration(URL url)
     throws ClassNotFoundException, SAXException, InstantiationException, IllegalAccessException,
         IOException {
   this(url, ClassLoading.getDefaultClassLoader());
 }