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.support;
018:
019: import org.springframework.beans.PropertyValue;
020: import org.springframework.beans.factory.config.RuntimeBeanReference;
021: import org.springframework.util.ObjectUtils;
022:
023: /**
024: * Programmatic means of constructing
025: * {@link org.springframework.beans.factory.config.BeanDefinition BeanDefinitions}
026: * using the builder pattern. Intended primarily for use when implementing Spring 2.0
027: * {@link org.springframework.beans.factory.xml.NamespaceHandler NamespaceHandlers}.
028: *
029: * @author Rod Johnson
030: * @author Rob Harrop
031: * @author Juergen Hoeller
032: * @since 2.0
033: */
034: public class BeanDefinitionBuilder {
035:
036: /**
037: * Create a new <code>BeanDefinitionBuilder</code> used to construct a {@link RootBeanDefinition}.
038: * @param beanClass the <code>Class</code> of the bean that the definition is being created for
039: */
040: public static BeanDefinitionBuilder rootBeanDefinition(
041: Class beanClass) {
042: return rootBeanDefinition(beanClass, null);
043: }
044:
045: /**
046: * Create a new <code>BeanDefinitionBuilder</code> used to construct a {@link RootBeanDefinition}.
047: * @param beanClass the <code>Class</code> of the bean that the definition is being created for
048: * @param factoryMethodName the name of the method to use to construct the bean instance
049: */
050: public static BeanDefinitionBuilder rootBeanDefinition(
051: Class beanClass, String factoryMethodName) {
052: BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
053: builder.beanDefinition = new RootBeanDefinition();
054: builder.beanDefinition.setBeanClass(beanClass);
055: builder.beanDefinition.setFactoryMethodName(factoryMethodName);
056: return builder;
057: }
058:
059: /**
060: * Create a new <code>BeanDefinitionBuilder</code> used to construct a {@link RootBeanDefinition}.
061: * @param beanClassName the class name for the bean that the definition is being created for
062: */
063: public static BeanDefinitionBuilder rootBeanDefinition(
064: String beanClassName) {
065: return rootBeanDefinition(beanClassName, null);
066: }
067:
068: /**
069: * Create a new <code>BeanDefinitionBuilder</code> used to construct a {@link RootBeanDefinition}.
070: * @param beanClassName the class name for the bean that the definition is being created for
071: * @param factoryMethodName the name of the method to use to construct the bean instance
072: */
073: public static BeanDefinitionBuilder rootBeanDefinition(
074: String beanClassName, String factoryMethodName) {
075: BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
076: builder.beanDefinition = new RootBeanDefinition();
077: builder.beanDefinition.setBeanClassName(beanClassName);
078: builder.beanDefinition.setFactoryMethodName(factoryMethodName);
079: return builder;
080: }
081:
082: /**
083: * Create a new <code>BeanDefinitionBuilder</code> used to construct a {@link ChildBeanDefinition}.
084: * @param parentBeanName the name of the parent bean
085: */
086: public static BeanDefinitionBuilder childBeanDefinition(
087: String parentBeanName) {
088: BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
089: builder.beanDefinition = new ChildBeanDefinition(parentBeanName);
090: return builder;
091: }
092:
093: /**
094: * The <code>BeanDefinition</code> instance we are creating.
095: */
096: private AbstractBeanDefinition beanDefinition;
097:
098: /**
099: * Our current position with respect to constructor args.
100: */
101: private int constructorArgIndex;
102:
103: /**
104: * Enforce the use of factory methods.
105: */
106: private BeanDefinitionBuilder() {
107: }
108:
109: /**
110: * Return the current BeanDefinition object in its raw (unvalidated) form.
111: * @see #getBeanDefinition()
112: */
113: public AbstractBeanDefinition getRawBeanDefinition() {
114: return this .beanDefinition;
115: }
116:
117: /**
118: * Validate and return the created BeanDefinition object.
119: */
120: public AbstractBeanDefinition getBeanDefinition() {
121: this .beanDefinition.validate();
122: return this .beanDefinition;
123: }
124:
125: /**
126: * Add the supplied property value under the given name.
127: */
128: public BeanDefinitionBuilder addPropertyValue(String name,
129: Object value) {
130: this .beanDefinition.getPropertyValues().addPropertyValue(
131: new PropertyValue(name, value));
132: return this ;
133: }
134:
135: /**
136: * Add a reference to the specified bean name under the property specified.
137: * @param name the name of the property to add the reference to
138: * @param beanName the name of the bean being referenced
139: */
140: public BeanDefinitionBuilder addPropertyReference(String name,
141: String beanName) {
142: return addPropertyValue(name,
143: new RuntimeBeanReference(beanName));
144: }
145:
146: /**
147: * Add an indexed constructor arg value. The current index is tracked internally and all
148: * additions are at the present point.
149: */
150: public BeanDefinitionBuilder addConstructorArg(Object value) {
151: this .beanDefinition.getConstructorArgumentValues()
152: .addIndexedArgumentValue(constructorArgIndex++, value);
153: return this ;
154: }
155:
156: /**
157: * Add a reference to a named bean as a constructor arg.
158: * @see #addConstructorArg(Object)
159: */
160: public BeanDefinitionBuilder addConstructorArgReference(
161: String beanName) {
162: return addConstructorArg(new RuntimeBeanReference(beanName));
163: }
164:
165: /**
166: * Set the name of the factory method to use for this definition.
167: */
168: public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
169: this .beanDefinition.setFactoryMethodName(factoryMethod);
170: return this ;
171: }
172:
173: /**
174: * Set the name of the factory bean to use for this definition.
175: */
176: public BeanDefinitionBuilder setFactoryBean(String factoryBean,
177: String factoryMethod) {
178: this .beanDefinition.setFactoryBeanName(factoryBean);
179: this .beanDefinition.setFactoryMethodName(factoryMethod);
180: return this ;
181: }
182:
183: /**
184: * Set the scope of this definition.
185: * @see org.springframework.beans.factory.config.BeanDefinition#SCOPE_SINGLETON
186: * @see org.springframework.beans.factory.config.BeanDefinition#SCOPE_PROTOTYPE
187: */
188: public BeanDefinitionBuilder setScope(String scope) {
189: this .beanDefinition.setScope(scope);
190: return this ;
191: }
192:
193: /**
194: * Set whether or not this definition describes a singleton bean,
195: * as alternative to <code>setScope</code>.
196: * @see #setScope
197: */
198: public BeanDefinitionBuilder setSingleton(boolean singleton) {
199: this .beanDefinition.setSingleton(singleton);
200: return this ;
201: }
202:
203: /**
204: * Set whether or not this definition is abstract.
205: */
206: public BeanDefinitionBuilder setAbstract(boolean flag) {
207: this .beanDefinition.setAbstract(flag);
208: return this ;
209: }
210:
211: /**
212: * Set whether beans for this definition should be lazily initialized or not.
213: */
214: public BeanDefinitionBuilder setLazyInit(boolean lazy) {
215: this .beanDefinition.setLazyInit(lazy);
216: return this ;
217: }
218:
219: /**
220: * Set the autowire mode for this definition.
221: */
222: public BeanDefinitionBuilder setAutowireMode(int autowireMode) {
223: beanDefinition.setAutowireMode(autowireMode);
224: return this ;
225: }
226:
227: /**
228: * Set the depency check mode for this definition.
229: */
230: public BeanDefinitionBuilder setDependencyCheck(int dependencyCheck) {
231: beanDefinition.setDependencyCheck(dependencyCheck);
232: return this ;
233: }
234:
235: /**
236: * Set the destroy method for this definition.
237: */
238: public BeanDefinitionBuilder setDestroyMethodName(String methodName) {
239: beanDefinition.setDestroyMethodName(methodName);
240: return this ;
241: }
242:
243: /**
244: * Set the init method for this definition.
245: */
246: public BeanDefinitionBuilder setInitMethodName(String methodName) {
247: beanDefinition.setInitMethodName(methodName);
248: return this ;
249: }
250:
251: /**
252: * Set the description associated with this definition.
253: */
254: public BeanDefinitionBuilder setResourceDescription(
255: String resourceDescription) {
256: this .beanDefinition.setResourceDescription(resourceDescription);
257: return this ;
258: }
259:
260: /**
261: * Append the specified bean name to the list of beans that this definition
262: * depends on.
263: */
264: public BeanDefinitionBuilder addDependsOn(String beanName) {
265: if (this .beanDefinition.getDependsOn() == null) {
266: this .beanDefinition.setDependsOn(new String[] { beanName });
267: } else {
268: String[] added = (String[]) ObjectUtils.addObjectToArray(
269: beanDefinition.getDependsOn(), beanName);
270: this .beanDefinition.setDependsOn(added);
271: }
272: return this ;
273: }
274:
275: /**
276: * Set the source of this definition.
277: * @see AbstractBeanDefinition#setSource
278: */
279: public BeanDefinitionBuilder setSource(Object source) {
280: this .beanDefinition.setSource(source);
281: return this ;
282: }
283:
284: /**
285: * Set the role of this definition.
286: * @see AbstractBeanDefinition#setRole
287: */
288: public BeanDefinitionBuilder setRole(int role) {
289: this.beanDefinition.setRole(role);
290: return this;
291: }
292:
293: }
|