1 package org.apache.commons.beanutils2;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static org.apache.commons.beanutils2.Argument.getParameterTypes;
23 import static org.apache.commons.beanutils2.Assertions.checkNoneIsNull;
24 import static org.apache.commons.beanutils2.Assertions.checkNotNull;
25
26 import static java.lang.reflect.Modifier.isAbstract;
27
28 import java.lang.reflect.Constructor;
29 import java.lang.reflect.InvocationTargetException;
30
31 final class DefaultClassAccessor<B>
32 implements ClassAccessor<B>
33 {
34
35 private final AccessibleObjectsRegistry<Constructor<?>> constructorRegistry =
36 AccessibleObjectsRegistry.getConstructorsRegistry();
37
38 private final BeanProperties<B> beanProperties;
39
40 private final Class<B> beanClass;
41
42 public DefaultClassAccessor( Class<B> beanClass )
43 {
44 this.beanClass = beanClass;
45 beanProperties = new DefaultBeanProperties<B>( beanClass );
46 }
47
48
49
50
51
52
53 public BeanAccessor<B> newInstance()
54 {
55 return invokeConstructor();
56 }
57
58
59
60
61
62
63 public BeanAccessor<B> invokeConstructor( Argument<?>... arguments )
64 {
65 arguments = checkNotNull( arguments,
66 "Null arguments not admitted - don't pass any argument to use %s empty constructor",
67 beanClass );
68 arguments = checkNoneIsNull( arguments );
69 return invokeConstructor( false, arguments );
70 }
71
72
73
74
75 public BeanAccessor<B> invokeExactConstructor( Argument<?>... arguments )
76 {
77 arguments = checkNotNull( arguments,
78 "Null arguments not admitted - don't pass any argument to use %s empty constructor",
79 beanClass );
80 arguments = checkNoneIsNull( arguments );
81 return invokeConstructor( true, arguments );
82 }
83
84 private BeanAccessor<B> invokeConstructor( boolean exact, Argument<?>... arguments )
85 {
86 checkInstantiable();
87 @SuppressWarnings( "unchecked" )
88 Constructor<B> constructor = (Constructor<B>) constructorRegistry.get( exact,
89 beanClass,
90 getParameterTypes( arguments ) );
91
92 if ( null == constructor )
93 {
94 throw new NoSuchConstructorException( beanClass, null );
95 }
96
97 int argumentsLength = arguments.length;
98 Object[] parameterObjects = new Object[argumentsLength];
99 for ( int i = 0; i < argumentsLength; i++ )
100 {
101 parameterObjects[i] = arguments[i].getValue();
102 }
103
104 B bean = doInvokeConstructor( constructor, parameterObjects );
105 return new DefaultBeanAccessor<B>( bean );
106 }
107
108
109
110
111
112 private void checkInstantiable()
113 {
114 if ( beanClass.isInterface() )
115 {
116 throw new BeanInstantiationException( beanClass, "Type is an interface." );
117 }
118 if ( beanClass.isArray() )
119 {
120 throw new BeanInstantiationException( beanClass, "Type is an array class." );
121 }
122 if ( beanClass.isPrimitive() )
123 {
124 throw new BeanInstantiationException( beanClass, "Type is primitive." );
125 }
126 if ( beanClass.equals( Void.TYPE ) )
127 {
128 throw new BeanInstantiationException( beanClass, "Type represents void." );
129 }
130
131 if ( isAbstract( beanClass.getModifiers() ) )
132 {
133 throw new BeanInstantiationException( beanClass, "Type is abstract." );
134 }
135 }
136
137 private B doInvokeConstructor( Constructor<B> constructor, Object[] parameterObjects )
138 {
139 try
140 {
141 return constructor.newInstance( parameterObjects );
142 }
143 catch ( InstantiationException e )
144 {
145 throw new BeanInstantiationException( beanClass, e );
146 }
147 catch ( IllegalAccessException e )
148 {
149 throw new ConstructorNotAccessibleException( beanClass, e );
150 }
151 catch ( InvocationTargetException e )
152 {
153 throw new ConstructorInvocationException( beanClass, e );
154 }
155 }
156
157
158
159 public BeanProperties<B> getProperties()
160 {
161 return beanProperties;
162 }
163
164
165
166
167
168
169 public ArgumentsAccessor invokeStatic( String methodName )
170 {
171 methodName = checkNotNull( methodName, "Impossible to execute null static method in %s", beanClass );
172 return new DefaultArgumentsAccessor( beanClass, false, methodName, null );
173 }
174
175
176
177
178 public ArgumentsAccessor invokeExactStatic( String methodName )
179 {
180 methodName = checkNotNull( methodName, "Impossible to execute null static method in %s", beanClass );
181 return new DefaultArgumentsAccessor( beanClass, true, methodName, null );
182 }
183
184 }