001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.beans.factory.xml;
018:
019: import org.w3c.dom.Element;
020:
021: import org.springframework.beans.factory.support.AbstractBeanDefinition;
022: import org.springframework.beans.factory.support.BeanDefinitionBuilder;
023:
024: /**
025: * Base class for those {@link BeanDefinitionParser} implementations that
026: * need to parse and define just a <i>single</i> <code>BeanDefinition</code>.
027: *
028: * <p>Extend this parser class when you want to create a single bean definition
029: * from an arbitrarily complex XML element. You may wish to consider extending
030: * the {@link AbstractSimpleBeanDefinitionParser} when you want to create a
031: * single bean definition from a relatively simple custom XML element.
032: *
033: * <p>The resulting <code>BeanDefinition</code> will be automatically registered
034: * with the {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}.
035: * Your job simply is to {@link #doParse parse} the custom XML {@link Element}
036: * into a single <code>BeanDefinition</code>.
037: *
038: * @author Rob Harrop
039: * @author Juergen Hoeller
040: * @author Rick Evans
041: * @since 2.0
042: * @see #getBeanClass
043: * @see #getBeanClassName
044: * @see #doParse
045: */
046: public abstract class AbstractSingleBeanDefinitionParser extends
047: AbstractBeanDefinitionParser {
048:
049: /**
050: * Creates a {@link BeanDefinitionBuilder} instance for the
051: * {@link #getBeanClass bean Class} and passes it to the
052: * {@link #doParse} strategy method.
053: * @param element the element that is to be parsed into a single BeanDefinition
054: * @param parserContext the object encapsulating the current state of the parsing process
055: * @return the BeanDefinition resulting from the parsing of the supplied {@link Element}
056: * @throws IllegalStateException if the bean {@link Class} returned from
057: * {@link #getBeanClass(org.w3c.dom.Element)} is <code>null</code>
058: * @see #doParse
059: */
060: protected final AbstractBeanDefinition parseInternal(
061: Element element, ParserContext parserContext) {
062: BeanDefinitionBuilder builder = BeanDefinitionBuilder
063: .genericBeanDefinition();
064: String parentName = getParentName(element);
065: if (parentName != null) {
066: builder.getRawBeanDefinition().setParentName(parentName);
067: }
068: Class beanClass = getBeanClass(element);
069: if (beanClass != null) {
070: builder.getRawBeanDefinition().setBeanClass(beanClass);
071: } else {
072: String beanClassName = getBeanClassName(element);
073: if (beanClassName != null) {
074: builder.getRawBeanDefinition().setBeanClassName(
075: beanClassName);
076: }
077: }
078: builder.setSource(parserContext.extractSource(element));
079: if (parserContext.isNested()) {
080: // Inner bean definition must receive same scope as containing bean.
081: builder.setScope(parserContext
082: .getContainingBeanDefinition().getScope());
083: }
084: if (parserContext.isDefaultLazyInit()) {
085: // Default-lazy-init applies to custom bean definitions as well.
086: builder.setLazyInit(true);
087: }
088: doParse(element, parserContext, builder);
089: return builder.getBeanDefinition();
090: }
091:
092: /**
093: * Determine the name for the parent of the currently parsed bean,
094: * in case of the current bean being defined as a child bean.
095: * <p>The default implementation returns <code>null</code>,
096: * indicating a root bean definition.
097: * @param element the <code>Element</code> that is being parsed
098: * @return the name of the parent bean for the currently parsed bean,
099: * or <code>null</code> if none
100: */
101: protected String getParentName(Element element) {
102: return null;
103: }
104:
105: /**
106: * Determine the bean class corresponding to the supplied {@link Element}.
107: * <p>Note that, for application classes, it is generally preferable to
108: * override {@link #getBeanClassName} instead, in order to avoid a direct
109: * dependence on the bean implementation class. The BeanDefinitionParser
110: * and its NamespaceHandler can be used within an IDE plugin then, even
111: * if the application classes are not available on the plugin's classpath.
112: * @param element the <code>Element</code> that is being parsed
113: * @return the {@link Class} of the bean that is being defined via parsing
114: * the supplied <code>Element</code>, or <code>null</code> if none
115: * @see #getBeanClassName
116: */
117: protected Class getBeanClass(Element element) {
118: return null;
119: }
120:
121: /**
122: * Determine the bean class name corresponding to the supplied {@link Element}.
123: * @param element the <code>Element</code> that is being parsed
124: * @return the class name of the bean that is being defined via parsing
125: * the supplied <code>Element</code>, or <code>null</code> if none
126: * @see #getBeanClass
127: */
128: protected String getBeanClassName(Element element) {
129: return null;
130: }
131:
132: /**
133: * Parse the supplied {@link Element} and populate the supplied
134: * {@link BeanDefinitionBuilder} as required.
135: * <p>The default implementation delegates to the <code>doParse</code>
136: * version without ParserContext argument.
137: * @param element the XML element being parsed
138: * @param parserContext the object encapsulating the current state of the parsing process
139: * @param builder used to define the <code>BeanDefinition</code>
140: * @see #doParse(Element, BeanDefinitionBuilder)
141: */
142: protected void doParse(Element element,
143: ParserContext parserContext, BeanDefinitionBuilder builder) {
144: doParse(element, builder);
145: }
146:
147: /**
148: * Parse the supplied {@link Element} and populate the supplied
149: * {@link BeanDefinitionBuilder} as required.
150: * <p>The default implementation does nothing.
151: * @param element the XML element being parsed
152: * @param builder used to define the <code>BeanDefinition</code>
153: */
154: protected void doParse(Element element,
155: BeanDefinitionBuilder builder) {
156: }
157:
158: }
|