ScopeProtocol.java :  » Net » Terracotta » com » tcspring » Java Open Source

Java Open Source » Net » Terracotta 
Terracotta » com » tcspring » ScopeProtocol.java
/*
 * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice.  All rights reserved.
 */
package com.tcspring;

import org.springframework.beans.factory.config.Scope;
import org.springframework.beans.factory.support.AbstractBeanFactory;

import com.tc.aspectwerkz.joinpoint.StaticJoinPoint;

/**
 * @author Eugene Kuleshov
 */
public class ScopeProtocol {
  
  private final ThreadLocal scopedBeanId = new ThreadLocal();
  
  /**
   * @see org.springframework.beans.factory.support.AbstractBeanFactory#registerScope(String, Scope)
   */
  public void setDistributableBeanFactory(String scopeName, Scope scope, AbstractBeanFactory beanFactory) {
    if(beanFactory instanceof DistributableBeanFactory) {
      if(scope instanceof DistributableBeanFactoryAware) {
        ((DistributableBeanFactoryAware) scope).setBeanFactory((DistributableBeanFactory) beanFactory);
      }
    }
  }
  
  /**
   * @see org.springframework.beans.factory.config.Scope#get(String, org.springframework.beans.factory.ObjectFactory)
   */
  public Object virtualizeScopedBean(StaticJoinPoint jp, Scope s, String beanName) throws Throwable {
    if(s instanceof DistributableBeanFactoryAware) {
      DistributableBeanFactoryAware scope = (DistributableBeanFactoryAware) s;

      DistributableBeanFactory factory = scope.getBeanFactory();
      if(factory!=null && factory.isDistributedScoped(beanName)) {
        ComplexBeanId beanId = new ComplexBeanId(s.getConversationId(), beanName);
        
        BeanContainer container = factory.getBeanContainer(beanId);
        
        if(container!=null && container.isInitialized()) {
            return container.getBean();
        }
        
        if(container==null) {
          container = new BeanContainer(null, false);
          factory.putBeanContainer(beanId, container);
        }
        
        Object bean = null;
        scopedBeanId.set(beanId);
        try {
          bean = jp.proceed();
        } finally {
          scopedBeanId.set(null);
        }

        if(container.getBean()==null) {
          container.setBean(bean);
        } else {
          factory.initializeBean(beanId, bean, container);
        }

        if(container.getDestructionCallBack()==null) {
          ScopedBeanDestructionCallBack destructionCallBack = new ScopedBeanDestructionCallBack(beanId, factory, null);
          s.registerDestructionCallback(beanName, destructionCallBack);
        }

        container.setInitialized(true);
        
        return container.getBean();
      }
    }
    
    return jp.proceed();
  }
  
  /**
   * @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(String, Runnable)
   */
  public Object wrapDestructionCallback(StaticJoinPoint jp, String beanName, Runnable callback, Scope scope) throws Throwable {
    if (!(callback instanceof ScopedBeanDestructionCallBack) &&
        scope instanceof DistributableBeanFactoryAware) {
      ComplexBeanId beanId = new ComplexBeanId(scope.getConversationId(), beanName);

      DistributableBeanFactoryAware distributableScope = (DistributableBeanFactoryAware) scope;
      
      DistributableBeanFactory factory = distributableScope.getBeanFactory();
      BeanContainer container = factory.getBeanContainer(beanId);
      
      ScopedBeanDestructionCallBack destructionCallBack = container.getDestructionCallBack();
      if(destructionCallBack==null) {
        destructionCallBack = new ScopedBeanDestructionCallBack(beanId, factory, callback);
        container.setDestructionCallBack(destructionCallBack);
      } else {
        if(destructionCallBack.getBeanFactory()==null) {
          destructionCallBack.setBeanFactory(factory);
        }
        if(destructionCallBack.getCallback()==null) {
          destructionCallBack.setCallback(callback);
        }
      }

      scope.registerDestructionCallback(beanName, destructionCallBack);
      return null;
    }
    return jp.proceed();
  }
  
  
  public Object suspendRequestAttributeGet(StaticJoinPoint jp, Scope s, String beanName) throws Throwable {
    return isInRehydration(s, beanName) ? null : jp.proceed();
  }

  public Object suspendRequestAttributeSet(StaticJoinPoint jp, Scope s, String beanName) throws Throwable {
    return isInRehydration(s, beanName) ? null : jp.proceed();
  }

  private boolean isInRehydration(Scope s, String beanName) {
    if (s instanceof DistributableBeanFactoryAware) {
      DistributableBeanFactory factory = ((DistributableBeanFactoryAware) s).getBeanFactory();
      ComplexBeanId beanId = (ComplexBeanId) scopedBeanId.get();
      BeanContainer container = factory.getBeanContainer(beanId);
      if(container!=null && !container.isInitialized()) {
        return true;
      }
    }
    return false;
  }

  
  public interface DistributableBeanFactoryAware {
    void setBeanFactory(DistributableBeanFactory beanFactory);
    DistributableBeanFactory getBeanFactory();
  }
  
  
  public static class DistributableBeanFactoryAwareMixin implements DistributableBeanFactoryAware {
    private DistributableBeanFactory beanFactory;
    
    public DistributableBeanFactory getBeanFactory() {
      return beanFactory;
    }
    
    public void setBeanFactory(DistributableBeanFactory beanFactory) {
      this.beanFactory = beanFactory;
    }
    
  }
  
}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.