Package org.springmodules.cache.interceptor.flush

Source Code of org.springmodules.cache.interceptor.flush.AbstractFlushingInterceptor

/*
* Created on Oct 21, 2004
*
* 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 @2004 the original author or authors.
*/

package org.springmodules.cache.interceptor.flush;

import java.beans.PropertyEditor;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;

import org.springmodules.cache.FatalCacheException;
import org.springmodules.cache.FlushingModel;
import org.springmodules.cache.provider.CacheModelValidator;
import org.springmodules.cache.provider.CacheProviderFacade;

/**
* <p>
* Template for advices that flush a cache when the intercepted method is
* executed.
* </p>
*
* @author Alex Ruiz
*/
public abstract class AbstractFlushingInterceptor implements MethodInterceptor,
    InitializingBean {

  /** Logger available to subclasses */
  protected final Log logger = LogFactory.getLog(getClass());

  private CacheProviderFacade cacheProviderFacade;

  /**
   * Map of <code>{@link FlushingModel}</code>s that specify how to flush the
   * cache. Each cache model is stored under a unique id (a String).
   */
  private Map flushingModels;

  /**
   * @throws FatalCacheException
   *           if the cache provider facade is <code>null</code>.
   *
   * @see InitializingBean#afterPropertiesSet()
   * @see #onAfterPropertiesSet()
   */
  public final void afterPropertiesSet() throws FatalCacheException {
    if (cacheProviderFacade == null) {
      throw new FatalCacheException(
          "The cache provider facade should not be null");
    }

    if (flushingModels == null || flushingModels.isEmpty()) {
      return;
    }

    CacheModelValidator validator = cacheProviderFacade
        .modelValidator();

    if (flushingModels instanceof Properties) {
      PropertyEditor editor = cacheProviderFacade.getFlushingModelEditor();
      Properties properties = (Properties) flushingModels;
      Map newFlushingModels = new HashMap();

      String id = null;

      try {
        for (Iterator i = properties.keySet().iterator(); i.hasNext();) {
          id = (String) i.next();

          String property = properties.getProperty(id);
          editor.setAsText(property);
          Object flushingModel = editor.getValue();
          validator.validateFlushingModel(flushingModel);

          newFlushingModels.put(id, flushingModel);
        }
      } catch (Exception exception) {
        throw new FatalCacheException(
            "Unable to create the flushing model with id "
                + StringUtils.quote(id), exception);
      }

      setFlushingModels(newFlushingModels);

    } else {
      String id = null;

      try {
        for (Iterator i = flushingModels.keySet().iterator(); i.hasNext();) {
          id = (String) i.next();
          Object flushingModel = flushingModels.get(id);
          validator.validateFlushingModel(flushingModel);
        }
      } catch (Exception exception) {
        throw new FatalCacheException(
            "Unable to validate flushing model with id "
                + StringUtils.quote(id), exception);
      }
    }

    onAfterPropertiesSet();
  }

  /**
   * Flushes the cache.
   *
   * @param methodInvocation
   *          the description of the intercepted method.
   * @return the return value of the intercepted method.
   * @throws Throwable
   *           any exception thrown when executing the intercepted method
   */
  public final Object invoke(MethodInvocation methodInvocation)
      throws Throwable {
    FlushingModel model = getModel(methodInvocation);

    if (null == model) {
      logger.info("Unable to flush cache. "
          + "No model is associated to the intercepted method");
      return methodInvocation.proceed();
    }

    Object proceedReturnValue = null;

    if (model.flushBeforeMethodExecution()) {
      cacheProviderFacade.flushCache(model);
      proceedReturnValue = methodInvocation.proceed();

    } else {
      proceedReturnValue = methodInvocation.proceed();
      cacheProviderFacade.flushCache(model);
    }

    return proceedReturnValue;
  }

  /**
   * Sets the facade for the cache provider to use.
   *
   * @param newCacheProviderFacade
   *          the new cache provider facade
   */
  public final void setCacheProviderFacade(
      CacheProviderFacade newCacheProviderFacade) {
    cacheProviderFacade = newCacheProviderFacade;
  }

  /**
   * Sets the flushing models to use.
   *
   * @param newFlushingModels
   *          the new flushing models
   */
  public final void setFlushingModels(Map newFlushingModels) {
    flushingModels = newFlushingModels;
  }

  /**
   * @return the map that specifies how caching models should be bound to class
   *         methods
   */
  protected final Map getFlushingModels() {
    return flushingModels;
  }

  /**
   * Returns the flushing model bound to an intercepted method.
   *
   * @param methodInvocation
   *          the description of the invocation to the intercepted method
   * @return the flushing model boudn to the given intercepted method
   */
  protected abstract FlushingModel getModel(MethodInvocation methodInvocation);

  /**
   * Gives subclasses the opportunity to set up their own properties.
   *
   * @throws FatalCacheException
   *           if one or more properties of this interceptor contain invalid
   *           values or have an illegal state.
   */
  protected void onAfterPropertiesSet() throws FatalCacheException {
    // no implementation.
  }

}
TOP

Related Classes of org.springmodules.cache.interceptor.flush.AbstractFlushingInterceptor

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.