Package org.sugarj.driver.caching

Source Code of org.sugarj.driver.caching.StrategoContextCache

package org.sugarj.driver.caching;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.strategoxt.lang.Context;
import org.sugarj.util.Pair;

/**
* Manages instances of org.strategoxt.lang.Context to enable
*   reuse and exclusive access.
*
* @author seba
*/
public class StrategoContextCache {

  /**
   * Class represents the actual type of the context,
   * first List denotes currently used contexts,
   * second List denotes currently unused contexts.
   */
  private final Map<Class<?>, Pair<? extends List<Context>, ? extends List<WeakReference<Context>>>> cache
    = new HashMap<Class<?>, Pair<? extends List<Context>,? extends List<WeakReference<Context>>>>();
 
  private final Map<Context, Class<?>> ctxToInit = new HashMap<Context, Class<?>>();
 
  /**
   * Retrieves a free context from the cache or generates a new one.
   *
   * @param purpose
   * @return a context of the given actual type.
   */
  public synchronized Context acquireContext(Class<?> initType) {
    Pair<? extends List<Context>,? extends List<WeakReference<Context>>> p = cache.get(initType);
    if (p == null) {
      p = Pair.create(new ArrayList<Context>(), new ArrayList<WeakReference<Context>>());
      cache.put(initType, p);
    }
   
    Context fresh = null;
    while (fresh == null && !p.b.isEmpty())
      fresh = p.b.remove(0).get();
   
    if (fresh == null)
      try {
        fresh = (Context) initType.getMethod("init").invoke(initType);
      } catch (IllegalAccessException e) {
        throw new IllegalArgumentException("Illegal actual type " + initType, e);
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException("Illegal actual type " + initType, e);
      } catch (InvocationTargetException e) {
        throw new IllegalArgumentException("Illegal actual type " + initType, e);
      } catch (NoSuchMethodException e) {
        throw new IllegalArgumentException("Illegal actual type " + initType, e);
      } catch (SecurityException e) {
        throw new IllegalArgumentException("Illegal actual type " + initType, e);
      }
   
    p.a.add(fresh);
    ctxToInit.put(fresh, initType);
   
    return fresh;
  }
 
  /**
   * Releases a previously acquired context.
   */
  public synchronized void releaseContext(Context ctx) {
    Class<?> initType = ctxToInit.remove(ctx);
   
    Pair<? extends List<Context>,? extends List<WeakReference<Context>>> p = cache.get(initType);
    if (p == null || !p.a.contains(ctx))
      throw new IllegalArgumentException("unknown context from initializer " + initType);
   
    p.a.remove(ctx);
    p.b.add(new WeakReference<Context>(ctx));
  }
}
TOP

Related Classes of org.sugarj.driver.caching.StrategoContextCache

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.