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.BeanDefinitionHolder;
007: import org.springframework.beans.factory.support.AbstractBeanDefinition;
008: import org.springframework.beans.factory.support.BeanDefinitionReader;
009: import org.springframework.beans.factory.support.DefaultListableBeanFactory;
010: import org.springframework.core.io.ClassPathResource;
011: import org.springframework.core.io.FileSystemResource;
012: import org.springframework.core.io.Resource;
013: import org.springframework.util.ClassUtils;
014: import org.springframework.web.context.support.ServletContextResource;
015:
016: import com.tc.aspectwerkz.joinpoint.StaticJoinPoint;
017: import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: /**
024: * Advice for collecting bean metadata.
025: *
026: * @see com.tc.object.config.SpringAspectModule#buildDefinitionForBeanDefinitionProtocol()
027: *
028: * @author Eugene Kuleshov
029: */
030: public class BeanDefinitionProtocol {
031:
032: private final Map beanMap = new HashMap();
033: private final Map classes = new HashMap();
034:
035: /**
036: * Invoked after loadBeanDefinitions method in BeanDefinitionReader. Adds resource location to the DistributableBeanFactory mixin.
037: *
038: * @see org.springframework.beans.factory.support.BeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
039: */
040: public void captureIdentity(StaticJoinPoint jp, Resource resource,
041: BeanDefinitionReader reader) throws Throwable {
042: Object beanFactory = reader.getBeanFactory();
043: if (beanFactory instanceof DistributableBeanFactory) {
044: String location;
045: if (resource instanceof ClassPathResource) {
046: location = ((ClassPathResource) resource).getPath();
047: } else if (resource instanceof FileSystemResource) {
048: location = ((FileSystemResource) resource).getPath();
049: } else if (resource instanceof ServletContextResource) {
050: location = ((ServletContextResource) resource)
051: .getPath();
052: } else {
053: location = resource.getDescription();
054: }
055:
056: DistributableBeanFactory distributableBeanFactory = (DistributableBeanFactory) beanFactory;
057: distributableBeanFactory.addLocation(location);
058: }
059: }
060:
061: /**
062: * Collects the different spring bean configuration files.
063: * <tt>
064: * Advices: Around(
065: * execution(* org.springframework.context.support.AbstractRefreshableApplicationContext+.loadBeanDefinitions(..))
066: * AND args(beanFactory))
067: * </tt>
068: */
069: public Object collectDefinitions(StaticJoinPoint jp,
070: DefaultListableBeanFactory beanFactory) throws Throwable {
071: try {
072: return jp.proceed();
073: } finally {
074:
075: if (beanFactory instanceof DistributableBeanFactory) {
076: ((DistributableBeanFactory) beanFactory)
077: .registerBeanDefinitions(beanMap);
078: }
079:
080: for (Iterator it = beanMap.entrySet().iterator(); it
081: .hasNext();) {
082: Map.Entry entry = (Map.Entry) it.next();
083: AbstractBeanDefinition definition = (AbstractBeanDefinition) entry
084: .getValue();
085:
086: String beanClassName = definition.getBeanClassName();
087: if (beanClassName == null)
088: continue;
089:
090: ClassLoader loader = (ClassLoader) classes
091: .get(beanClassName);
092: if (loader == null)
093: continue;
094:
095: try {
096: Class c = ClassUtils.forName(beanClassName, loader);
097: definition.setBeanClass(c);
098: } catch (Exception e) {
099: // ignore
100: }
101: }
102: }
103: }
104:
105: /**
106: * Since Spring 2.0m5 ClassUtils.forName() is not called when bean definitions are created
107: *
108: * @see org.springframework.beans.factory.support.BeanDefinitionReaderUtils#createBeanDefinition()
109: */
110: public Object disableClassForName(String className,
111: ClassLoader loader) throws Exception {
112: try {
113: AsmClassInfo.getClassInfo(className, loader);
114: // TODO this can be potential class loader clash
115: classes.put(className, loader);
116: } catch (Exception e) {
117: throw new ClassNotFoundException(className);
118: }
119: return null;
120: }
121:
122: /**
123: * Called after constructor initialization on <code>BeanDefinitionHolder</code> class
124: *
125: * @see org.springframework.beans.factory.config.BeanDefinitionHolder
126: */
127: public void saveBeanDefinition(StaticJoinPoint jp,
128: BeanDefinitionHolder holder) {
129: beanMap.put(holder.getBeanName(), holder.getBeanDefinition());
130: }
131: }
|