Package org.geomajas.plugin.caching.cache

Source Code of org.geomajas.plugin.caching.cache.InfinispanCacheFactory$CacheSelector

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.plugin.caching.cache;

import org.geomajas.global.Api;
import org.geomajas.layer.Layer;
import org.geomajas.plugin.caching.configuration.CacheInfo;
import org.geomajas.plugin.caching.configuration.InfinispanConfiguration;
import org.geomajas.plugin.caching.service.CacheCategory;
import org.geomajas.plugin.caching.service.CacheFactory;
import org.geomajas.plugin.caching.service.CacheService;
import org.geomajas.service.ConfigurationService;
import org.geomajas.service.TestRecorder;
import org.infinispan.config.Configuration;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
* Cache factory for creating infinispan caches.
*
* @author Joachim Van der Auwera
* @since 1.0.0
*/
@Api
public class InfinispanCacheFactory implements CacheFactory {

  private final Logger log = LoggerFactory.getLogger(InfinispanCacheFactory.class);

  private EmbeddedCacheManager manager;
  private String configurationFile;
  private CacheInfo defaultConfiguration;
  private NoCacheCacheFactory noCacheFactory = new NoCacheCacheFactory();

  private Map<CacheSelector, CacheService> caches = new HashMap<CacheSelector, CacheService>();

  @Autowired(required = false)
  private Map<String, Layer<?>> layerMap = new LinkedHashMap<String, Layer<?>>();

  @Autowired
  private TestRecorder recorder;

  @Autowired
  private ConfigurationService configurationService;

  /**
   * Set the location of the Infinispan configuration file.
   * <p/>
   * When present, this is the base configuration which can be overwritten by the other settings.
   * <p/>
   * This location is first searched on the classpath and if that fails, as a absolute path.
   *
   * @param configurationFile configuration file
   * @since 1.0.0
   */
  @Api
  public void setConfigurationFile(String configurationFile) {
    this.configurationFile = configurationFile;
  }

  /**
   * Set the default cache configuration. Specifies the default settings for the cache categories.
   * <p/>
   * Cache configurations can be different per layer (with layers sharing caches).
   *
   * @param defaultConfiguration default cache configuration
   */
  public void setDefaultConfiguration(CacheInfo defaultConfiguration) {
    this.defaultConfiguration = defaultConfiguration;
  }

  @PostConstruct
  protected void init() throws IOException {
    // base configuration from XML file
    if (null != configurationFile) {
      log.debug("Get base configuration from {}", configurationFile);
      manager = new DefaultCacheManager(configurationFile);
    } else {
      manager = new DefaultCacheManager();
    }

    // cache for caching the cache configurations (hmmm, sounds a bit strange)
    Map<String, Map<CacheCategory, CacheService>> cacheCache =
        new HashMap<String, Map<CacheCategory, CacheService>>();

    // build default configuration
    if (null != defaultConfiguration) {
      setCaches(cacheCache, null, defaultConfiguration);
    }

    // build layer specific configurations
    for (Layer layer : layerMap.values()) {
      CacheInfo ci = configurationService.getLayerExtraInfo(layer.getLayerInfo(), CacheInfo.class);
      if (null != ci) {
        setCaches(cacheCache, layer, ci);
      }
    }
  }

  /**
   * Add layer specific cache configuration in the caches variable. This assures each cache is only built once and
   * possibly reused (thanks to cacheCache).
   *
   * @param cacheCache cache for built caches
   * @param layer layer (or null)
   * @param cacheInfo cache configuration info
   */
  private void setCaches(Map<String, Map<CacheCategory, CacheService>> cacheCache, Layer layer,
      CacheInfo cacheInfo) {
    Map<CacheCategory, CacheService> ciCaches;
    ciCaches = cacheCache.get(cacheInfo.getId());
    if (null == ciCaches) {
      ciCaches = createCaches(cacheInfo);
      cacheCache.put(cacheInfo.getId(), ciCaches);
    }
    for (Map.Entry<CacheCategory, CacheService> ciEntry : ciCaches.entrySet()) {
      CacheSelector cs = new CacheSelector(ciEntry.getKey(), layer);
      caches.put(cs, ciEntry.getValue());
    }
  }

  private Map<CacheCategory, CacheService> createCaches(CacheInfo cacheInfo) {
    Map<CacheCategory, CacheService> ciCaches = new HashMap<CacheCategory, CacheService>();
    for (Map.Entry<CacheCategory, InfinispanConfiguration> entry : cacheInfo.getConfiguration().entrySet()) {
      CacheService cacheService;
      CacheCategory category = entry.getKey();
      InfinispanConfiguration config = entry.getValue();
      if (config.isCacheEnabled()) {
        String configurationName = config.getConfigurationName();
        if (null == configurationName) {
          Configuration infinispan;
          infinispan = manager.getDefaultConfiguration().clone();
          infinispan.applyOverrides(config.getInfinispanConfiguration());
          configurationName = "$" + category.getName() + "$" + cacheInfo.getId();
          manager.defineConfiguration(configurationName, infinispan);
        }
        recorder.record("infinispan", "configuration name " + configurationName);
        cacheService = new InfinispanCacheService(manager.<String, Object>getCache(configurationName));
      } else {
        cacheService = noCacheFactory.create(null, category);
      }
      ciCaches.put(category, cacheService);
    }
    return ciCaches;
  }

  public CacheService create(Layer layer, CacheCategory category) {
    CacheSelector cacheSelector = new CacheSelector(category, layer);
    CacheService cacheService;
    cacheService = caches.get(cacheSelector);
    if (null == cacheService) {
      cacheSelector = new CacheSelector(category, null);
      cacheService = caches.get(cacheSelector);
    }
    if (null == cacheService) {
      cacheService = noCacheFactory.create(layer, category);
    }
    return cacheService;
  }

  /** Cache selector, key for map. */
  private static class CacheSelector {

    private String category = "";
    private String layer = "";

    public CacheSelector(CacheCategory category, Layer layer) {
      if (null != category) {
        this.category = category.toString();
      }
      if (null != layer) {
        this.layer = layer.getId();
      }
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof CacheSelector)) {
        return false;
      }

      CacheSelector that = (CacheSelector) o;

      return !(category != null ? !category.equals(that.category) : that.category != null) &&
          !(layer != null ? !layer.equals(that.layer) : that.layer != null);

    }

    @Override
    public int hashCode() {
      int result = category != null ? category.hashCode() : 0;
      result = 31 * result + (layer != null ? layer.hashCode() : 0);
      return result;
    }
  }
}
TOP

Related Classes of org.geomajas.plugin.caching.cache.InfinispanCacheFactory$CacheSelector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.