View Javadoc

1   /*
2    Spring-Annotation, an easy way to configre Spring-Framework without all that XML.
3    Copyright (C) 2007 Rodrigo Urubatan Ferreira Jardim (http://www.urubatan.com.br)
4   
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9   
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14  
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  
19   <a href="http://www.gnu.org/licenses/lgpl.html">http://www.gnu.org/licenses/lgpl.html</a>
20   */
21  package net.sourceforge.sannotations.utils;
22  
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.Field;
25  import java.lang.reflect.Method;
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import javax.annotation.PostConstruct;
29  import javax.annotation.PreDestroy;
30  
31  import net.sourceforge.sannotations.annotation.Alias;
32  import net.sourceforge.sannotations.annotation.Bean;
33  import net.sourceforge.sannotations.annotation.ConstructorArgs;
34  import net.sourceforge.sannotations.annotation.Property;
35  import net.sourceforge.sannotations.annotation.Scope;
36  
37  import org.springframework.beans.MutablePropertyValues;
38  import org.springframework.beans.factory.config.ConstructorArgumentValues;
39  import org.springframework.beans.factory.config.RuntimeBeanReference;
40  import org.springframework.beans.factory.support.BeanDefinitionRegistry;
41  import org.springframework.beans.factory.support.RootBeanDefinition;
42  
43  /***
44   * Default instance of {@link IBeanReader} that knows how to handle the following annotations: 
45   * {@link net.sourceforge.sannotations.annotation.Alias},{@link net.sourceforge.sannotations.annotation.Bean},{@link net.sourceforge.sannotations.annotation.ConstructorArgs},{@link net.sourceforge.sannotations.annotation.Property},{@link net.sourceforge.sannotations.annotation.Scope}.
46   * TODO document 
47   * @author Urubatan
48   */
49  public class BeanReader implements IBeanReader {
50  	//TODO document
51  	public void register(BeanDefinitionRegistry registry, Class<?> c) {
52  		final Bean b = c.getAnnotation(Bean.class);
53  		final Alias al = c.getAnnotation(Alias.class);
54  		final RootBeanDefinition rbd = new RootBeanDefinition();
55  		rbd.setAbstract(false);
56  		rbd.setBeanClass(c);
57  		// rbd.setBeanClassName(classname);
58  		rbd.setSingleton(b.singleton());
59  		rbd.setLazyInit(b.lazy());
60  		if (!"".equals(b.initMethod().trim())) {
61  			rbd.setInitMethodName(b.initMethod());
62  		}
63  		if (!"".equals(b.destroyMethod().trim())) {
64  			rbd.setDestroyMethodName(b.destroyMethod());
65  		}
66  		if (!"".equals(b.factoryMethod().trim())) {
67  			rbd.setFactoryMethodName(b.factoryMethod());
68  		}
69  		rbd.setAutowireCandidate(true);
70  		rbd.setAutowireMode(b.autoWire().value());
71  		this.readProperties(c, b, rbd);
72  		this.readConstructors(c, b, rbd);
73  		if (!Scope.DEFAULT.equals(b.scope())) {
74  			rbd.setScope(b.scope().getScopeName());
75  		} else if (!"".equals(b.scopeName().trim())) {
76  			rbd.setScope(b.scopeName());
77  		}
78  		String name = b.name();
79  		if ((name == null) || "".equals(name.trim())) {
80  			name = c.getName();
81  		}
82  		for (final Method m : c.getMethods()) {
83  			if (m.getAnnotation(PreDestroy.class) != null) {
84  				rbd.setDestroyMethodName(m.getName());
85  			}
86  			if (m.getAnnotation(PostConstruct.class) != null) {
87  				rbd.setInitMethodName(m.getName());
88  			}
89  		}
90  		registry.registerBeanDefinition(name, rbd);
91  		if (al != null) {
92  			for (final String alias : al.value()) {
93  				registry.registerAlias(name, alias);
94  			}
95  		}
96  	}
97  	//TODO document
98  	private void readConstructors(final Class<?> cl, final Bean b, final RootBeanDefinition rbd) {
99  		for (final Constructor<?> c : cl.getConstructors()) {
100 			ConstructorArgs args;
101 			if ((args = c.getAnnotation(ConstructorArgs.class)) != null) {
102 				final ConstructorArgumentValues cav = new ConstructorArgumentValues();
103 				for (final Property p : args.value()) {
104 					if (!"".equals(p.bean())) {
105 						cav.addGenericArgumentValue(new RuntimeBeanReference(p.bean()));
106 					} else {
107 						cav.addGenericArgumentValue(p.value());
108 					}
109 				}
110 				rbd.setConstructorArgumentValues(cav);
111 				break;
112 			}
113 		}
114 	}
115 	//TODO document
116 	private void readProperties(final Class<?> c, final Bean b, final RootBeanDefinition rbd) {
117 		Class<?> currentClass = c;
118 		final ArrayList<Field> fields = new ArrayList<Field>();
119 		while (currentClass != null) {
120 			Collections.addAll(fields, currentClass.getDeclaredFields());
121 			currentClass = currentClass.getSuperclass();
122 		}
123 		final MutablePropertyValues mpv = new MutablePropertyValues();
124 		for (final Field f : fields) {
125 			final Property prop = f.getAnnotation(Property.class);
126 			if (prop != null) {
127 				if (!"".equals(prop.bean())) {
128 					mpv.addPropertyValue(f.getName(), new RuntimeBeanReference(prop.bean()));
129 				} else {
130 					mpv.addPropertyValue(f.getName(), prop.value());
131 				}
132 			}
133 		}
134 		if (!mpv.isEmpty()) {
135 			rbd.setPropertyValues(mpv);
136 		}
137 	}
138 }