01: /*
02: * Copyright 2002-2007 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.springframework.beans.factory.xml;
18:
19: import org.w3c.dom.Attr;
20: import org.w3c.dom.Element;
21: import org.w3c.dom.Node;
22:
23: import org.springframework.beans.MutablePropertyValues;
24: import org.springframework.beans.factory.config.BeanDefinition;
25: import org.springframework.beans.factory.config.BeanDefinitionHolder;
26: import org.springframework.beans.factory.config.RuntimeBeanReference;
27: import org.springframework.core.Conventions;
28:
29: /**
30: * Simple <code>NamespaceHandler</code> implementation that maps custom attributes
31: * directly through to bean properties. An important point to note is that this
32: * <code>NamespaceHandler</code> does not have a corresponding schema since there
33: * is no way to know in advance all possible attribute names.
34: *
35: * <p>An example of the usage of this <code>NamespaceHandler</code> is shown below:
36: *
37: * <pre class="code">
38: * <bean id="rob" class="..TestBean" p:name="Rob Harrop" p:spouse-ref="sally"/></pre>
39: *
40: * Here the '<code>p:name</code>' corresponds directly to the '<code>name</code>'
41: * property on class '<code>TestBean</code>'. The '<code>p:spouse-ref</code>'
42: * attributes corresponds to the '<code>spouse</code>' property and, rather
43: * than being the concrete value, it contains the name of the bean that will
44: * be injected into that property.
45: *
46: * @author Rob Harrop
47: * @since 2.0
48: */
49: public class SimplePropertyNamespaceHandler implements NamespaceHandler {
50:
51: private static final String REF_SUFFIX = "-ref";
52:
53: public void init() {
54: }
55:
56: public BeanDefinition parse(Element element,
57: ParserContext parserContext) {
58: parserContext.getReaderContext().error(
59: "Class [" + getClass().getName()
60: + "] does not support custom elements.",
61: element);
62: return null;
63: }
64:
65: public BeanDefinitionHolder decorate(Node node,
66: BeanDefinitionHolder definition, ParserContext parserContext) {
67: if (node instanceof Attr) {
68: Attr attr = (Attr) node;
69: String propertyName = attr.getLocalName();
70: String propertyValue = attr.getValue();
71: MutablePropertyValues pvs = definition.getBeanDefinition()
72: .getPropertyValues();
73: if (pvs.contains(propertyName)) {
74: parserContext
75: .getReaderContext()
76: .error(
77: "Property '"
78: + propertyName
79: + "' is already defined using "
80: + "both <property> and inline syntax. Only one approach may be used per property.",
81: attr);
82: }
83: if (propertyName.endsWith(REF_SUFFIX)) {
84: propertyName = propertyName.substring(0, propertyName
85: .length()
86: - REF_SUFFIX.length());
87: pvs.addPropertyValue(Conventions
88: .attributeNameToPropertyName(propertyName),
89: new RuntimeBeanReference(propertyValue));
90: } else {
91: pvs.addPropertyValue(Conventions
92: .attributeNameToPropertyName(propertyName),
93: propertyValue);
94: }
95: }
96: return definition;
97: }
98:
99: }
|