KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > gbean > runtime > GBeanAttribute


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.gbean.runtime;
19
20 import java.lang.reflect.Method JavaDoc;
21
22 import org.apache.geronimo.gbean.DynamicGAttributeInfo;
23 import org.apache.geronimo.gbean.DynamicGBean;
24 import org.apache.geronimo.gbean.GAttributeInfo;
25 import org.apache.geronimo.gbean.InvalidConfigurationException;
26 import org.apache.geronimo.kernel.ClassLoading;
27
28 /**
29  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
30  */

31 public class GBeanAttribute {
32     private final GBeanInstance gbeanInstance;
33
34     private final String JavaDoc name;
35
36     private final Class JavaDoc type;
37
38     private final boolean readable;
39
40     private final MethodInvoker getInvoker;
41
42     private final boolean writable;
43
44     private final MethodInvoker setInvoker;
45
46     private final boolean isConstructorArg;
47
48     private final boolean persistent;
49
50     private final boolean manageable;
51
52     private Object JavaDoc persistentValue;
53
54     /**
55      * Is this a special attribute like objectName, classLoader or gbeanContext?
56      * Special attributes are injected at startup just like persistent attrubutes, but are
57      * otherwise unmodifiable.
58      */

59     private final boolean special;
60
61     private final boolean framework;
62
63     private final boolean dynamic;
64
65     private final GAttributeInfo attributeInfo;
66
67     static GBeanAttribute createSpecialAttribute(GBeanAttribute attribute, GBeanInstance gbeanInstance, String JavaDoc name, Class JavaDoc type, Object JavaDoc value) {
68         return new GBeanAttribute(attribute, gbeanInstance, name, type, value);
69     }
70
71     private GBeanAttribute(GBeanAttribute attribute, GBeanInstance gbeanInstance, String JavaDoc name, Class JavaDoc type, Object JavaDoc value) {
72         this.special = true;
73         this.framework = false;
74         this.dynamic = false;
75
76         if (gbeanInstance == null || name == null || type == null) {
77             throw new IllegalArgumentException JavaDoc("null param(s) supplied");
78         }
79
80         // if we have an attribute verify the gbean instance, name and types match
81
if (attribute != null) {
82             assert (gbeanInstance == attribute.gbeanInstance);
83             assert (name.equals(attribute.name));
84             if (type != attribute.type) {
85                 throw new InvalidConfigurationException("Special attribute " + name +
86                         " must have the type " + type.getName() + ", but is " +
87                         attribute.type.getName() + ": targetClass=" + gbeanInstance.getType().getName());
88             }
89             if (attribute.isPersistent()) {
90                 throw new InvalidConfigurationException("Special attributes must not be persistent:" +
91                         " name=" + name + ", targetClass=" + gbeanInstance.getType().getName());
92             }
93         }
94
95         this.gbeanInstance = gbeanInstance;
96         this.name = name;
97         this.type = type;
98
99         // getter
100
this.getInvoker = null;
101         this.readable = true;
102
103         // setter
104
if (attribute != null) {
105             this.setInvoker = attribute.setInvoker;
106             this.isConstructorArg = attribute.isConstructorArg;
107         } else {
108             this.setInvoker = null;
109             this.isConstructorArg = false;
110         }
111         this.writable = false;
112
113         // persistence
114
this.persistent = false;
115         initializePersistentValue(value);
116
117         // not manageable
118
this.manageable = false;
119
120         // create an attribute info for this gbean
121
if (attribute != null) {
122             GAttributeInfo attributeInfo = attribute.getAttributeInfo();
123             this.attributeInfo = new GAttributeInfo(this.name,
124                     this.type.getName(),
125                     this.persistent,
126                     this.manageable,
127                     this.readable,
128                     this.writable,
129                     attributeInfo.getGetterName(),
130                     attributeInfo.getSetterName());
131         } else {
132             this.attributeInfo = new GAttributeInfo(this.name,
133                     this.type.getName(),
134                     this.persistent,
135                     this.manageable,
136                     this.readable,
137                     this.writable,
138                     null,
139                     null);
140         }
141     }
142
143     static GBeanAttribute createFrameworkAttribute(GBeanInstance gbeanInstance, String JavaDoc name, Class JavaDoc type, MethodInvoker getInvoker) {
144         return new GBeanAttribute(gbeanInstance, name, type, getInvoker, null, false, null, true);
145     }
146
147     static GBeanAttribute createFrameworkAttribute(GBeanInstance gbeanInstance, String JavaDoc name, Class JavaDoc type, MethodInvoker getInvoker, MethodInvoker setInvoker, boolean persistent, Object JavaDoc persistentValue, boolean manageable) {
148         return new GBeanAttribute(gbeanInstance, name, type, getInvoker, setInvoker, persistent, persistentValue, manageable);
149     }
150
151     private GBeanAttribute(GBeanInstance gbeanInstance, String JavaDoc name, Class JavaDoc type, MethodInvoker getInvoker, MethodInvoker setInvoker, boolean persistent, Object JavaDoc persistentValue, boolean manageable) {
152         this.special = false;
153         this.framework = true;
154         this.dynamic = false;
155
156         if (gbeanInstance == null || name == null || type == null) {
157             throw new IllegalArgumentException JavaDoc("null param(s) supplied");
158         }
159
160         this.gbeanInstance = gbeanInstance;
161         this.name = name;
162         this.type = type;
163
164         // getter
165
this.getInvoker = getInvoker;
166         this.readable = (this.getInvoker != null);
167
168         // setter
169
this.setInvoker = setInvoker;
170         this.isConstructorArg = false;
171         this.writable = (this.setInvoker != null);
172
173         // persistence
174
this.persistent = persistent;
175         initializePersistentValue(persistentValue);
176
177         // manageable
178
this.manageable = manageable;
179
180         // create an attribute info for this gbean
181
attributeInfo = new GAttributeInfo(this.name,
182                 this.type.getName(),
183                 this.persistent,
184                 this.manageable,
185                 this.readable,
186                 this.writable,
187                 null,
188                 null);
189     }
190
191     public GBeanAttribute(GBeanInstance gbeanInstance, GAttributeInfo attributeInfo, boolean isConstructorArg) throws InvalidConfigurationException {
192         this.special = false;
193         this.framework = false;
194
195         if (gbeanInstance == null || attributeInfo == null) {
196             throw new IllegalArgumentException JavaDoc("null param(s) supplied");
197         }
198         if (!attributeInfo.isReadable() && !attributeInfo.isWritable() && !attributeInfo.isPersistent() && !isConstructorArg)
199         {
200             throw new InvalidConfigurationException("An attribute must be readable, writable, persistent or a constructor arg: " +
201                     " name=" + attributeInfo.getName() + " targetClass=" + gbeanInstance.getType().getName());
202         }
203         this.gbeanInstance = gbeanInstance;
204         this.attributeInfo = attributeInfo;
205         this.name = attributeInfo.getName();
206         this.isConstructorArg = isConstructorArg;
207         try {
208             this.type = ClassLoading.loadClass(attributeInfo.getType(), gbeanInstance.getClassLoader());
209         } catch (ClassNotFoundException JavaDoc e) {
210             throw new InvalidConfigurationException("Could not load attribute class: " + attributeInfo.getType());
211         }
212         this.persistent = attributeInfo.isPersistent();
213         this.manageable = attributeInfo.isManageable();
214
215         readable = attributeInfo.isReadable();
216         writable = attributeInfo.isWritable();
217
218         // If attribute is persistent or not tagged as unreadable, search for a
219
// getter method
220
if (attributeInfo instanceof DynamicGAttributeInfo) {
221             this.dynamic = true;
222             if (readable) {
223                 getInvoker = new DynamicGetterMethodInvoker(name);
224             } else {
225                 getInvoker = null;
226             }
227             if (writable) {
228                 setInvoker = new DynamicSetterMethodInvoker(name);
229             } else {
230                 setInvoker = null;
231             }
232         } else {
233             this.dynamic = false;
234             if (attributeInfo.getGetterName() != null) {
235                 try {
236                     String JavaDoc getterName = attributeInfo.getGetterName();
237                     Method JavaDoc getterMethod = gbeanInstance.getType().getMethod(getterName, null);
238
239                     if (!getterMethod.getReturnType().equals(type)) {
240                         if (getterMethod.getReturnType().getName().equals(type.getName())) {
241                             throw new InvalidConfigurationException("Getter return type in wrong classloader: type: " + type + " wanted in classloader: " + type.getClassLoader() + " actual: " + getterMethod.getReturnType().getClassLoader());
242                         } else {
243                             throw new InvalidConfigurationException("Getter method of wrong type: " + getterMethod.getReturnType() + " expected " + getDescription());
244                         }
245                     }
246                     if (AbstractGBeanReference.NO_PROXY) {
247                         getInvoker = new ReflectionMethodInvoker(getterMethod);
248                     } else {
249                         getInvoker = new FastMethodInvoker(getterMethod);
250                     }
251                 } catch (NoSuchMethodException JavaDoc e) {
252                     throw new InvalidConfigurationException("Getter method not found " + getDescription());
253                 }
254             } else {
255                 getInvoker = null;
256             }
257
258             // If attribute is persistent or not tagged as unwritable, search
259
// for a setter method
260
if (attributeInfo.getSetterName() != null) {
261                 try {
262                     String JavaDoc setterName = attributeInfo.getSetterName();
263                     Method JavaDoc setterMethod = gbeanInstance.getType().getMethod(setterName, new Class JavaDoc[]{type});
264                     if (AbstractGBeanReference.NO_PROXY) {
265                         setInvoker = new ReflectionMethodInvoker(setterMethod);
266                     } else {
267                         setInvoker = new FastMethodInvoker(setterMethod);
268                     }
269                 } catch (NoSuchMethodException JavaDoc e) {
270                     throw new InvalidConfigurationException("Setter method not found " + getDescription());
271                 }
272             } else {
273                 setInvoker = null;
274             }
275         }
276
277         initializePersistentValue(null);
278     }
279
280     private void initializePersistentValue(Object JavaDoc value) {
281         if (persistent || special) {
282             if (value == null && type.isPrimitive() && isConstructorArg) {
283                 if (type == Boolean.TYPE) {
284                     value = Boolean.FALSE;
285                 } else if (type == Byte.TYPE) {
286                     value = new Byte JavaDoc((byte) 0);
287                 } else if (type == Short.TYPE) {
288                     value = new Short JavaDoc((short) 0);
289                 } else if (type == Integer.TYPE) {
290                     value = new Integer JavaDoc(0);
291                 } else if (type == Long.TYPE) {
292                     value = new Long JavaDoc(0);
293                 } else if (type == Character.TYPE) {
294                     value = new Character JavaDoc((char) 0);
295                 } else if (type == Float.TYPE) {
296                     value = new Float JavaDoc(0);
297                 } else /** if (type == Double.TYPE) */ {
298                     value = new Double JavaDoc(0);
299                 }
300             }
301             persistentValue = value;
302         }
303     }
304
305     public String JavaDoc getName() {
306         return name;
307     }
308
309     public GAttributeInfo getAttributeInfo() {
310         return attributeInfo;
311     }
312
313     public boolean isReadable() {
314         return readable;
315     }
316
317     public boolean isWritable() {
318         return writable;
319     }
320
321     public Class JavaDoc getType() {
322         return type;
323     }
324
325     public boolean isFramework() {
326         return framework;
327     }
328
329     public boolean isDynamic() {
330         return dynamic;
331     }
332
333     public boolean isPersistent() {
334         return persistent;
335     }
336
337     public boolean isManageable() {
338         return manageable;
339     }
340
341     public boolean isSpecial() {
342         return special;
343     }
344
345     public void inject(Object JavaDoc target) throws Exception JavaDoc {
346         if ((persistent || special) && !isConstructorArg && writable && persistentValue != null) {
347             setValue(target, persistentValue);
348         }
349     }
350
351     public Object JavaDoc getPersistentValue() {
352         if (!persistent && !special) {
353             throw new IllegalStateException JavaDoc("Attribute is not persistent " + getDescription());
354         }
355         return persistentValue;
356     }
357
358     public void setPersistentValue(Object JavaDoc persistentValue) {
359         if (!persistent && !special) {
360             throw new IllegalStateException JavaDoc("Attribute is not persistent " + getDescription());
361         }
362
363         if (persistentValue == null && type.isPrimitive()) {
364             throw new IllegalArgumentException JavaDoc("Cannot assign null to a primitive attribute. " + getDescription());
365         }
366
367         // @todo actually check type
368
this.persistentValue = persistentValue;
369     }
370
371     public Object JavaDoc getValue(Object JavaDoc target) throws Exception JavaDoc {
372         if (!readable) {
373             if (persistent) {
374                 return persistentValue;
375             } else {
376                 throw new IllegalStateException JavaDoc("This attribute is not readable. " + getDescription());
377             }
378         }
379
380         if (special) {
381             return persistentValue;
382         }
383
384         // get the target to invoke
385
if (target == null && !framework) {
386             throw new IllegalStateException JavaDoc("GBean does not have a target instance to invoke. " + getDescription());
387         }
388
389         // call the getter
390
Object JavaDoc value = getInvoker.invoke(target, null);
391         return value;
392     }
393
394     public void setValue(Object JavaDoc target, Object JavaDoc value) throws Exception JavaDoc {
395         if (!writable) {
396             if (persistent) {
397                 throw new IllegalStateException JavaDoc("This persistent attribute is not modifable while the gbean is running. " + getDescription());
398             } else {
399                 throw new IllegalStateException JavaDoc("This attribute is not writable. " + getDescription());
400             }
401         }
402
403         // the value can not be null for primitives
404
if (value == null && type.isPrimitive()) {
405             throw new IllegalArgumentException JavaDoc("Cannot assign null to a primitive attribute. " + getDescription());
406         }
407
408         // @todo actually check type
409

410         // get the target to invoke
411
if (target == null && !framework) {
412             throw new IllegalStateException JavaDoc("GBean does not have a target instance to invoke. " + getDescription());
413         }
414
415         // call the setter
416
setInvoker.invoke(target, new Object JavaDoc[]{value});
417     }
418
419     public String JavaDoc getDescription() {
420         return "Attribute Name: " + getName() + ", Type: " + getType() + ", GBeanInstance: " + gbeanInstance.getName();
421     }
422
423     private static final class DynamicGetterMethodInvoker implements MethodInvoker {
424         private final String JavaDoc name;
425
426         public DynamicGetterMethodInvoker(String JavaDoc name) {
427             this.name = name;
428         }
429
430         public Object JavaDoc invoke(Object JavaDoc target, Object JavaDoc[] arguments) throws Exception JavaDoc {
431             return ((DynamicGBean) target).getAttribute(name);
432         }
433     }
434
435     private static final class DynamicSetterMethodInvoker implements MethodInvoker {
436         private final String JavaDoc name;
437
438         public DynamicSetterMethodInvoker(String JavaDoc name) {
439             this.name = name;
440         }
441
442         public Object JavaDoc invoke(Object JavaDoc target, Object JavaDoc[] arguments) throws Exception JavaDoc {
443             ((DynamicGBean) target).setAttribute(name, arguments[0]);
444             return null;
445         }
446     }
447 }
448
Popular Tags