1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.snamespaces.config;
18
19 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
20 import org.springframework.beans.factory.support.AbstractBeanDefinition;
21 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
22 import org.springframework.beans.factory.support.RootBeanDefinition;
23 import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
24 import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
25 import org.springframework.beans.factory.xml.ParserContext;
26 import org.springframework.beans.factory.xml.XmlReaderContext;
27 import org.springframework.util.Assert;
28 import org.springframework.util.ClassUtils;
29 import org.springframework.util.StringUtils;
30 import org.w3c.dom.Element;
31
32 /**
33 * TODO make doc
34 *
35 * @author Jonhnny Weslley
36 * @version 1.00, 13/09/2007
37 * @since 1.0
38 */
39 public class BeanDefinitionParserDependentFromFactoryPostProcessor extends
40 AbstractBeanDefinitionParser {
41
42 /** Constant for the class attribute */
43 private static final String CLASS_ATTRIBUTE = "class";
44
45 private final String prefix;
46 private final Class<?> expectedBeanClass;
47 private final Class<?> factoryPostProcessorClass;
48
49 BeanDefinitionParserDependentFromFactoryPostProcessor(
50 final String prefix, final Class<?> expectedBeanClass, final Class<?> factoryPostProcessorClass) {
51 Assert.hasText(prefix);
52 Assert.notNull(expectedBeanClass);
53 Assert.isAssignable(BeanFactoryPostProcessor.class, factoryPostProcessorClass);
54 this.prefix = prefix;
55 this.expectedBeanClass = expectedBeanClass;
56 this.factoryPostProcessorClass = factoryPostProcessorClass;
57 }
58
59 @Override
60 protected final AbstractBeanDefinition parseInternal(final Element element,
61 final ParserContext parserContext) {
62
63 final XmlReaderContext readerContext = parserContext.getReaderContext();
64 final BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
65
66 final String className = getBeanClassName(element);
67 try {
68 registerFactoryPostProcessorIfNecessary(parserContext.getRegistry());
69
70 final Class<?> beanClass = ClassUtils.forName(className);
71 Assert.isAssignable(expectedBeanClass, beanClass);
72
73 final AbstractBeanDefinition bd = new RootBeanDefinition(beanClass);
74
75
76 delegate.parseMetaElements(element, bd);
77 delegate.parseLookupOverrideSubElements(element, bd.getMethodOverrides());
78 delegate.parseReplacedMethodSubElements(element, bd.getMethodOverrides());
79
80 delegate.parseConstructorArgElements(element, bd);
81 delegate.parsePropertyElements(element, bd);
82
83 bd.setResourceDescription(readerContext.getResource().getDescription());
84 bd.setSource(parserContext.extractSource(element));
85 return bd;
86
87 } catch (final ClassNotFoundException ex) {
88 readerContext.error("Bean class [" + className + "] not found", element, null, ex);
89
90 } catch (final NoClassDefFoundError err) {
91 readerContext.error("Class that bean class [" + className + "] depends on not found", element, null, err);
92
93 } catch (final Throwable ex) {
94 readerContext.error("Unexpected failure during bean definition parsing", element, null, ex);
95 }
96 return null;
97 }
98
99 /**
100 * Determine the bean class name corresponding to the supplied {@link Element}.
101 * @param element the <code>Element</code> that is being parsed
102 * @return the class name of the bean that is being defined via parsing the supplied <code>Element</code>
103 * (must <b>not</b> be <code>null</code>)
104 * @see #parseInternal(Element, ParserContext)
105 */
106 protected String getBeanClassName(final Element element) {
107 return element.getAttribute(CLASS_ATTRIBUTE);
108 }
109
110 @Override
111 protected final String resolveId(final Element element,
112 final AbstractBeanDefinition definition, final ParserContext parserContext) {
113 return prefix + resolveName(element, definition, parserContext);
114 }
115
116 protected String resolveName(final Element element,
117 final AbstractBeanDefinition definition, final ParserContext parserContext) {
118 return getBeanClassName(element);
119 }
120
121 protected String getFactoryPostProcessorBeanName() {
122 return factoryPostProcessorClass.getPackage().getName() + "."
123 + StringUtils.uncapitalize(factoryPostProcessorClass.getSimpleName());
124 }
125
126 private void registerFactoryPostProcessorIfNecessary(final BeanDefinitionRegistry registry) {
127 final String factoryPostProcessorBeanName = getFactoryPostProcessorBeanName();
128 if (!registry.containsBeanDefinition(factoryPostProcessorBeanName)) {
129 final RootBeanDefinition beanDefinition = new RootBeanDefinition(factoryPostProcessorClass);
130 registry.registerBeanDefinition(factoryPostProcessorBeanName, beanDefinition);
131 }
132 }
133
134 }