1 package org.codehaus.ivory.serialize;
2
3 import java.beans.Introspector;
4 import java.beans.PropertyDescriptor;
5 import java.lang.reflect.Method;
6 import java.security.AccessController;
7 import java.security.PrivilegedAction;
8 import java.util.ArrayList;
9 import java.util.Vector;
10
11 import org.apache.axis.AxisFault;
12 import org.apache.axis.InternalException;
13 import org.apache.axis.description.FieldDesc;
14 import org.apache.axis.description.TypeDesc;
15 import org.apache.axis.utils.BeanPropertyDescriptor;
16 import org.apache.axis.utils.BeanUtils;
17 import org.apache.commons.attributes.Attributes;
18 import org.apache.commons.logging.Log;
19 import org.apache.axis.components.logger.LogFactory;
20 import org.codehaus.ivory.attributes.NonWebMethod;
21
22 /***
23 *
24 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
25 * @since May 21, 2003
26 */
27 public class MetaBeanUtils extends BeanUtils
28 {
29
30 public static final Object[] noArgs = new Object[] {
31 };
32 protected static Log log = LogFactory.getLog(BeanUtils.class.getName());
33
34 /***
35 * Create a BeanPropertyDescriptor array for the indicated class.
36 * @param javaType
37 * @return an ordered array of properties
38 */
39 public static BeanPropertyDescriptor[] getPd(Class javaType)
40 {
41 return MetaBeanUtils.getPd(javaType, null);
42 }
43
44 /***
45 * Create a BeanPropertyDescriptor array for the indicated class.
46 * @param javaType
47 * @param typeDesc
48 * @return an ordered array of properties
49 */
50 public static BeanPropertyDescriptor[] getPd(
51 Class javaType,
52 TypeDesc typeDesc)
53 {
54 BeanPropertyDescriptor[] pd;
55 try
56 {
57 final Class secJavaType = javaType;
58
59
60 PropertyDescriptor[] rawPd = MetaBeanUtils.getPropertyDescriptors(secJavaType);
61 pd = MetaBeanUtils.processPropertyDescriptors(rawPd, javaType, typeDesc);
62 }
63 catch (Exception e)
64 {
65
66 throw new InternalException(e);
67 }
68 return pd;
69 }
70
71 private static PropertyDescriptor[] getPropertyDescriptors(final Class secJavaType)
72 {
73 return (
74 PropertyDescriptor[]) AccessController
75 .doPrivileged(new PrivilegedAction()
76 {
77 public Object run()
78 {
79 PropertyDescriptor[] result = null;
80
81 try
82 {
83
84 if (AxisFault.class.isAssignableFrom(secJavaType))
85 {
86
87 result =
88 Introspector
89 .getBeanInfo(secJavaType, AxisFault.class)
90 .getPropertyDescriptors();
91 }
92 else if (Throwable.class != secJavaType && Throwable.class.isAssignableFrom(secJavaType))
93 {
94
95 result =
96 Introspector
97 .getBeanInfo(secJavaType, Throwable.class)
98 .getPropertyDescriptors();
99 }
100 else
101 {
102
103 result =
104 Introspector
105 .getBeanInfo(secJavaType)
106 .getPropertyDescriptors();
107 }
108
109 }
110 catch (java.beans.IntrospectionException Iie)
111 {
112 }
113 return result;
114 }
115 });
116 }
117
118 /***
119 * Return a list of properties in the bean which should be attributes
120 */
121 public static Vector getBeanAttributes(Class javaType, TypeDesc typeDesc)
122 {
123 Vector ret = new Vector();
124
125 if (typeDesc == null)
126 {
127
128
129
130
131 try
132 {
133 Method getAttributeElements =
134 javaType.getMethod("getAttributeElements", new Class[] {
135 });
136
137 String[] array =
138 (String[]) getAttributeElements.invoke(null, noArgs);
139
140
141 ret = new Vector(array.length);
142 for (int i = 0; i < array.length; i++)
143 {
144 ret.add(array[i]);
145 }
146 }
147 catch (Exception e)
148 {
149 ret.clear();
150 }
151 }
152 else
153 {
154 FieldDesc[] fields = typeDesc.getFields();
155 if (fields != null)
156 {
157 for (int i = 0; i < fields.length; i++)
158 {
159 FieldDesc field = fields[i];
160 if (!field.isElement())
161 {
162 ret.add(field.getFieldName());
163 }
164 }
165 }
166 }
167
168 return ret;
169 }
170 /***
171 * This method attempts to sort the property descriptors using
172 * the typeDesc and order defined in the class.
173 *
174 * This routine also looks for set(i, type) and get(i) methods and adjusts the
175 * property to use these methods instead. These methods are generated by the
176 * emitter for "collection" of properties (i.e. maxOccurs="unbounded" on an element).
177 * JAX-RPC is silent on this issue, but web services depend on this kind of behaviour.
178 * The method signatures were chosen to match bean indexed properties.
179 */
180 public static BeanPropertyDescriptor[] processPropertyDescriptors(
181 PropertyDescriptor[] rawPd,
182 Class cls)
183 {
184 return MetaBeanUtils.processPropertyDescriptors(rawPd, cls, null);
185 }
186
187 public static BeanPropertyDescriptor[] processPropertyDescriptors(
188 PropertyDescriptor[] rawPd,
189 Class cls,
190 TypeDesc typeDesc)
191 {
192 ArrayList filteredPds = new ArrayList();
193
194 for (int i = 0; i < rawPd.length; i++)
195 {
196 Method m = rawPd[i].getReadMethod();
197
198 if (!Attributes.hasAttributeType(m, NonWebMethod.class))
199 {
200 filteredPds.add(rawPd[i]);
201 }
202 else
203 {
204
205 System.out.println("[ivory] skipped method " + m.getName());
206 }
207 }
208
209 return BeanUtils.processPropertyDescriptors(
210 (PropertyDescriptor[]) filteredPds.toArray( new PropertyDescriptor[0] ),
211 cls,
212 typeDesc);
213 }
214 }