KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > utils > BeanUtils


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

16 package org.apache.axis.utils;
17
18 import org.apache.axis.AxisFault;
19 import org.apache.axis.Constants;
20 import org.apache.axis.InternalException;
21 import org.apache.axis.components.logger.LogFactory;
22 import org.apache.axis.description.FieldDesc;
23 import org.apache.axis.description.TypeDesc;
24 import org.apache.commons.logging.Log;
25
26 import java.beans.Introspector JavaDoc;
27 import java.beans.PropertyDescriptor JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.lang.reflect.Modifier JavaDoc;
31 import java.security.AccessController JavaDoc;
32 import java.security.PrivilegedAction JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.Vector JavaDoc;
35
36 public class BeanUtils {
37
38     public static final Object JavaDoc[] noArgs = new Object JavaDoc[] {};
39     protected static Log log =
40         LogFactory.getLog(BeanUtils.class.getName());
41
42     /**
43      * Create a BeanPropertyDescriptor array for the indicated class.
44      * @param javaType
45      * @return an ordered array of properties
46      */

47     public static BeanPropertyDescriptor[] getPd(Class JavaDoc javaType) {
48         return getPd(javaType, null);
49     }
50
51     /**
52      * Create a BeanPropertyDescriptor array for the indicated class.
53      * @param javaType
54      * @param typeDesc
55      * @return an ordered array of properties
56      */

57     public static BeanPropertyDescriptor[] getPd(Class JavaDoc javaType, TypeDesc typeDesc) {
58         BeanPropertyDescriptor[] pd;
59         try {
60             final Class JavaDoc secJavaType = javaType;
61
62             // Need doPrivileged access to do introspection.
63
PropertyDescriptor JavaDoc[] rawPd = getPropertyDescriptors(secJavaType);
64             pd = processPropertyDescriptors(rawPd,javaType,typeDesc);
65         } catch (Exception JavaDoc e) {
66             // this should never happen
67
throw new InternalException(e);
68         }
69         return pd;
70     }
71
72     private static PropertyDescriptor JavaDoc[] getPropertyDescriptors(final Class JavaDoc secJavaType) {
73         return (PropertyDescriptor JavaDoc[])AccessController.doPrivileged(
74                 new PrivilegedAction JavaDoc() {
75                     public Object JavaDoc run() {
76                         PropertyDescriptor JavaDoc[] result = null;
77 // START FIX http://nagoya.apache.org/bugzilla/showattachment.cgi?attach_id=4937
78
try {
79                             // privileged code goes here
80
if (AxisFault.class.isAssignableFrom(secJavaType)) {
81                                 // Don't include AxisFault data
82
result = Introspector.
83                                         getBeanInfo(secJavaType,AxisFault.class).
84                                         getPropertyDescriptors();
85                             } else if (Throwable JavaDoc.class != secJavaType && Throwable JavaDoc.class.isAssignableFrom(secJavaType)) {
86                                 // Don't include Throwable data
87
result = Introspector.
88                                         getBeanInfo(secJavaType,Throwable JavaDoc.class).
89                                         getPropertyDescriptors();
90                             } else {
91                                 // privileged code goes here
92
result = Introspector.
93                                         getBeanInfo(secJavaType).
94                                         getPropertyDescriptors();
95                             }
96 // END FIX http://nagoya.apache.org/bugzilla/showattachment.cgi?attach_id=4937
97
} catch (java.beans.IntrospectionException JavaDoc Iie) {
98                         }
99                         return result;
100                     }
101                 });
102     }
103
104     /**
105      * Return a list of properties in the bean which should be attributes
106      */

107     public static Vector JavaDoc getBeanAttributes(Class JavaDoc javaType, TypeDesc typeDesc) {
108         Vector JavaDoc ret = new Vector JavaDoc();
109
110         if (typeDesc == null) {
111             // !!! Support old-style beanAttributeNames for now
112

113             // See if this object defined the 'getAttributeElements' function
114
// which returns a Vector of property names that are attributes
115
try {
116                 Method JavaDoc getAttributeElements =
117                         javaType.getMethod("getAttributeElements",
118                                            new Class JavaDoc [] {});
119                 // get string array
120
String JavaDoc[] array = (String JavaDoc[])getAttributeElements.invoke(null, noArgs);
121
122                 // convert it to a Vector
123
ret = new Vector JavaDoc(array.length);
124                 for (int i = 0; i < array.length; i++) {
125                     ret.add(array[i]);
126                 }
127             } catch (Exception JavaDoc e) {
128                 ret.clear();
129             }
130         } else {
131             FieldDesc [] fields = typeDesc.getFields();
132             if (fields != null) {
133                 for (int i = 0; i < fields.length; i++) {
134                     FieldDesc field = fields[i];
135                     if (!field.isElement()) {
136                         ret.add(field.getFieldName());
137                     }
138                 }
139             }
140         }
141
142         return ret;
143     }
144     /**
145      * This method attempts to sort the property descriptors using
146      * the typeDesc and order defined in the class.
147      *
148      * This routine also looks for set(i, type) and get(i) methods and adjusts the
149      * property to use these methods instead. These methods are generated by the
150      * emitter for "collection" of properties (i.e. maxOccurs="unbounded" on an element).
151      * JAX-RPC is silent on this issue, but web services depend on this kind of behaviour.
152      * The method signatures were chosen to match bean indexed properties.
153      */

154     public static BeanPropertyDescriptor[] processPropertyDescriptors(
155                   PropertyDescriptor JavaDoc[] rawPd, Class JavaDoc cls) {
156         return processPropertyDescriptors(rawPd, cls, null);
157     }
158
159     public static BeanPropertyDescriptor[] processPropertyDescriptors(
160                   PropertyDescriptor JavaDoc[] rawPd, Class JavaDoc cls, TypeDesc typeDesc) {
161
162         // Create a copy of the rawPd called myPd
163
BeanPropertyDescriptor[] myPd = new BeanPropertyDescriptor[rawPd.length];
164
165         ArrayList JavaDoc pd = new ArrayList JavaDoc();
166
167         try {
168             for (int i=0; i < rawPd.length; i++) {
169                 // Skip the special "any" field
170
if (rawPd[i].getName().equals(Constants.ANYCONTENT))
171                     continue;
172                 pd.add(new BeanPropertyDescriptor(rawPd[i]));
173             }
174
175             // Now look for public fields
176
Field JavaDoc fields[] = cls.getFields();
177             if (fields != null && fields.length > 0) {
178                 // See if the field is in the list of properties
179
// add it if not.
180
for (int i=0; i < fields.length; i++) {
181                     Field JavaDoc f = fields[i];
182                     // skip if field come from a java.* or javax.* package
183
// WARNING: Is this going to make bad things happen for
184
// users JavaBeans? Do they WANT these fields serialzed?
185
String JavaDoc clsName = f.getDeclaringClass().getName();
186                     if (clsName.startsWith("java.") ||
187                             clsName.startsWith("javax.")) {
188                         continue;
189                     }
190                     // skip field if it is final, transient, or static
191
if (!(Modifier.isStatic(f.getModifiers()) ||
192                             Modifier.isFinal(f.getModifiers()) ||
193                             Modifier.isTransient(f.getModifiers()))) {
194                         String JavaDoc fName = f.getName();
195                         boolean found = false;
196                         for (int j=0; j< rawPd.length && !found; j++) {
197                             String JavaDoc pName =
198                                     ((BeanPropertyDescriptor)pd.get(j)).getName();
199                             if (pName.length() == fName.length() &&
200                                     pName.substring(0,1).equalsIgnoreCase(
201                                             fName.substring(0,1))) {
202
203                                 found = pName.length() == 1 ||
204                                         pName.substring(1).equals(fName.substring(1));
205                             }
206                         }
207
208                         if (!found) {
209                             pd.add(new FieldPropertyDescriptor(f.getName(), f));
210                         }
211                     }
212                 }
213             }
214
215             // If typeDesc meta data exists, re-order according to the fields
216
if (typeDesc != null &&
217                     typeDesc.getFields(true) != null) {
218                 ArrayList JavaDoc ordered = new ArrayList JavaDoc();
219                 // Add the TypeDesc elements first
220
FieldDesc[] fds = typeDesc.getFields(true);
221                 for (int i=0; i<fds.length; i++) {
222                     FieldDesc field = fds[i];
223                     if (field.isElement()) {
224                         boolean found = false;
225                         for (int j=0;
226                              j<pd.size() && !found;
227                              j++) {
228                             if (field.getFieldName().equals(
229                                     ((BeanPropertyDescriptor)pd.get(j)).getName())) {
230                                 ordered.add(pd.remove(j));
231                                 found = true;
232                             }
233                         }
234                     }
235                 }
236                 // Add the remaining elements
237
while (pd.size() > 0) {
238                     ordered.add(pd.remove(0));
239                 }
240                 // Use the ordered list
241
pd = ordered;
242             }
243
244             myPd = new BeanPropertyDescriptor[pd.size()];
245             for (int i=0; i <pd.size(); i++) {
246                 myPd[i] = (BeanPropertyDescriptor) pd.get(i);
247             }
248         } catch (Exception JavaDoc e) {
249             log.error(Messages.getMessage("badPropertyDesc00",
250                                            cls.getName()), e);
251             throw new InternalException(e);
252         }
253
254         return myPd;
255     }
256
257     public static BeanPropertyDescriptor getAnyContentPD(Class JavaDoc javaType) {
258         PropertyDescriptor JavaDoc [] pds = getPropertyDescriptors(javaType);
259         return getSpecificPD(pds, Constants.ANYCONTENT);
260     }
261
262     public static BeanPropertyDescriptor getSpecificPD(PropertyDescriptor JavaDoc[] pds,
263                                                        String JavaDoc name) {
264         for (int i = 0; i < pds.length; i++) {
265             PropertyDescriptor JavaDoc pd = pds[i];
266             if (pd.getName().equals(name))
267                 return new BeanPropertyDescriptor(pd);
268         }
269         return null;
270     }
271
272     public static BeanPropertyDescriptor getSpecificPD(BeanPropertyDescriptor[] pds,
273                                                        String JavaDoc name) {
274         for (int i = 0; i < pds.length; i++) {
275             BeanPropertyDescriptor pd = pds[i];
276             if (pd.getName().equals(name))
277                 return pd;
278         }
279         return null;
280     }
281 }
282
Popular Tags