001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tcspring;
005:
006: import org.springframework.beans.factory.config.Scope;
007: import org.springframework.beans.factory.support.AbstractBeanFactory;
008:
009: import com.tc.aspectwerkz.joinpoint.StaticJoinPoint;
010:
011: /**
012: * @author Eugene Kuleshov
013: */
014: public class ScopeProtocol {
015:
016: private final ThreadLocal scopedBeanId = new ThreadLocal();
017:
018: /**
019: * @see org.springframework.beans.factory.support.AbstractBeanFactory#registerScope(String, Scope)
020: */
021: public void setDistributableBeanFactory(String scopeName,
022: Scope scope, AbstractBeanFactory beanFactory) {
023: if (beanFactory instanceof DistributableBeanFactory) {
024: if (scope instanceof DistributableBeanFactoryAware) {
025: ((DistributableBeanFactoryAware) scope)
026: .setBeanFactory((DistributableBeanFactory) beanFactory);
027: }
028: }
029: }
030:
031: /**
032: * @see org.springframework.beans.factory.config.Scope#get(String, org.springframework.beans.factory.ObjectFactory)
033: */
034: public Object virtualizeScopedBean(StaticJoinPoint jp, Scope s,
035: String beanName) throws Throwable {
036: if (s instanceof DistributableBeanFactoryAware) {
037: DistributableBeanFactoryAware scope = (DistributableBeanFactoryAware) s;
038:
039: DistributableBeanFactory factory = scope.getBeanFactory();
040: if (factory != null
041: && factory.isDistributedScoped(beanName)) {
042: ComplexBeanId beanId = new ComplexBeanId(s
043: .getConversationId(), beanName);
044:
045: BeanContainer container = factory
046: .getBeanContainer(beanId);
047:
048: if (container != null && container.isInitialized()) {
049: return container.getBean();
050: }
051:
052: if (container == null) {
053: container = new BeanContainer(null, false);
054: factory.putBeanContainer(beanId, container);
055: }
056:
057: Object bean = null;
058: scopedBeanId.set(beanId);
059: try {
060: bean = jp.proceed();
061: } finally {
062: scopedBeanId.set(null);
063: }
064:
065: if (container.getBean() == null) {
066: container.setBean(bean);
067: } else {
068: factory.initializeBean(beanId, bean, container);
069: }
070:
071: if (container.getDestructionCallBack() == null) {
072: ScopedBeanDestructionCallBack destructionCallBack = new ScopedBeanDestructionCallBack(
073: beanId, factory, null);
074: s.registerDestructionCallback(beanName,
075: destructionCallBack);
076: }
077:
078: container.setInitialized(true);
079:
080: return container.getBean();
081: }
082: }
083:
084: return jp.proceed();
085: }
086:
087: /**
088: * @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(String, Runnable)
089: */
090: public Object wrapDestructionCallback(StaticJoinPoint jp,
091: String beanName, Runnable callback, Scope scope)
092: throws Throwable {
093: if (!(callback instanceof ScopedBeanDestructionCallBack)
094: && scope instanceof DistributableBeanFactoryAware) {
095: ComplexBeanId beanId = new ComplexBeanId(scope
096: .getConversationId(), beanName);
097:
098: DistributableBeanFactoryAware distributableScope = (DistributableBeanFactoryAware) scope;
099:
100: DistributableBeanFactory factory = distributableScope
101: .getBeanFactory();
102: BeanContainer container = factory.getBeanContainer(beanId);
103:
104: ScopedBeanDestructionCallBack destructionCallBack = container
105: .getDestructionCallBack();
106: if (destructionCallBack == null) {
107: destructionCallBack = new ScopedBeanDestructionCallBack(
108: beanId, factory, callback);
109: container.setDestructionCallBack(destructionCallBack);
110: } else {
111: if (destructionCallBack.getBeanFactory() == null) {
112: destructionCallBack.setBeanFactory(factory);
113: }
114: if (destructionCallBack.getCallback() == null) {
115: destructionCallBack.setCallback(callback);
116: }
117: }
118:
119: scope.registerDestructionCallback(beanName,
120: destructionCallBack);
121: return null;
122: }
123: return jp.proceed();
124: }
125:
126: public Object suspendRequestAttributeGet(StaticJoinPoint jp,
127: Scope s, String beanName) throws Throwable {
128: return isInRehydration(s, beanName) ? null : jp.proceed();
129: }
130:
131: public Object suspendRequestAttributeSet(StaticJoinPoint jp,
132: Scope s, String beanName) throws Throwable {
133: return isInRehydration(s, beanName) ? null : jp.proceed();
134: }
135:
136: private boolean isInRehydration(Scope s, String beanName) {
137: if (s instanceof DistributableBeanFactoryAware) {
138: DistributableBeanFactory factory = ((DistributableBeanFactoryAware) s)
139: .getBeanFactory();
140: ComplexBeanId beanId = (ComplexBeanId) scopedBeanId.get();
141: BeanContainer container = factory.getBeanContainer(beanId);
142: if (container != null && !container.isInitialized()) {
143: return true;
144: }
145: }
146: return false;
147: }
148:
149: public interface DistributableBeanFactoryAware {
150: void setBeanFactory(DistributableBeanFactory beanFactory);
151:
152: DistributableBeanFactory getBeanFactory();
153: }
154:
155: public static class DistributableBeanFactoryAwareMixin implements
156: DistributableBeanFactoryAware {
157: private DistributableBeanFactory beanFactory;
158:
159: public DistributableBeanFactory getBeanFactory() {
160: return beanFactory;
161: }
162:
163: public void setBeanFactory(DistributableBeanFactory beanFactory) {
164: this.beanFactory = beanFactory;
165: }
166:
167: }
168:
169: }
|