KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > xb > binding > sunday > unmarshalling > impl > runtime > RtUtil


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.xb.binding.sunday.unmarshalling.impl.runtime;
23
24 import java.lang.reflect.Array JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import javax.xml.namespace.NamespaceContext JavaDoc;
30 import javax.xml.namespace.QName JavaDoc;
31 import org.jboss.util.Classes;
32 import org.jboss.xb.binding.JBossXBRuntimeException;
33 import org.jboss.xb.binding.Util;
34 import org.jboss.xb.binding.introspection.FieldInfo;
35 import org.jboss.xb.binding.metadata.ValueMetaData;
36 import org.jboss.xb.binding.sunday.unmarshalling.ValueAdapter;
37
38 /**
39  * @author <a HREF="mailto:alex@jboss.org">Alexey Loubyansky</a>
40  * @version <tt>$Revision: 2045 $</tt>
41  */

42 public class RtUtil
43 {
44    private RtUtil()
45    {
46    }
47
48    public static void add(Object JavaDoc o,
49                           Object JavaDoc value,
50                           String JavaDoc prop,
51                           String JavaDoc colType,
52                           boolean ignoreNotFoundField,
53                           ValueAdapter valueAdapter)
54    {
55       FieldInfo fieldInfo = FieldInfo.getFieldInfo(o.getClass(), prop, !ignoreNotFoundField);
56       if(fieldInfo == null)
57       {
58          return;
59       }
60
61       Class JavaDoc fieldType = fieldInfo.getType();
62       boolean arrType;
63       if(fieldType.isArray())
64       {
65          arrType = true;
66       }
67       else if(Collection JavaDoc.class.isAssignableFrom(fieldType))
68       {
69          arrType = false;
70       }
71       else
72       {
73          throw new JBossXBRuntimeException(
74             "Expected type for " + prop + " in " + o.getClass() + " is an array or java.util.Collection but was " + fieldType
75          );
76       }
77
78
79       if(valueAdapter != null)
80       {
81          value = valueAdapter.cast(value, fieldType);
82       }
83
84       if(!arrType || colType != null)
85       {
86          Collection JavaDoc col = (Collection JavaDoc)fieldInfo.getValue(o);
87          if(col == null)
88          {
89             if(colType == null)
90             {
91                col = new ArrayList JavaDoc();
92             }
93             else
94             {
95                Class JavaDoc colCls;
96                try
97                {
98                   colCls = Thread.currentThread().getContextClassLoader().loadClass(colType);
99                }
100                catch(ClassNotFoundException JavaDoc e)
101                {
102                   throw new JBossXBRuntimeException("Failed to load collection type: " + colType);
103                }
104
105                try
106                {
107                   col = (Collection JavaDoc)colCls.newInstance();
108                }
109                catch(Exception JavaDoc e)
110                {
111                   throw new JBossXBRuntimeException("Failed to create an instance of " + colCls);
112                }
113             }
114
115             fieldInfo.setValue(o, col);
116          }
117
118          col.add(value);
119       }
120       else
121       {
122          Object JavaDoc arr = fieldInfo.getValue(o);
123          int length = 0;
124          if(arr == null)
125          {
126             arr = Array.newInstance(fieldType.getComponentType(), 1);
127          }
128          else
129          {
130             Object JavaDoc tmp = arr;
131             length = Array.getLength(arr);
132             arr = Array.newInstance(fieldType.getComponentType(), length + 1);
133             System.arraycopy(tmp, 0, arr, 0, length);
134             //System.out.println("copied array (1)");
135
}
136          Array.set(arr, length, value);
137          fieldInfo.setValue(o, arr);
138       }
139    }
140
141    public static void set(Object JavaDoc o,
142                           Object JavaDoc value,
143                           String JavaDoc prop,
144                           String JavaDoc colType,
145                           boolean ignoreNotFoundField,
146                           ValueAdapter valueAdapter)
147    {
148       FieldInfo fieldInfo = FieldInfo.getFieldInfo(o.getClass(), prop, !ignoreNotFoundField);
149       if(fieldInfo == null)
150       {
151          return;
152       }
153
154       Class JavaDoc fieldType = fieldInfo.getType();
155
156       if(valueAdapter != null)
157       {
158          value = valueAdapter.cast(value, fieldType);
159       }
160
161       if(Collection JavaDoc.class.isAssignableFrom(fieldType) &&
162          !Collection JavaDoc.class.isAssignableFrom(value.getClass()))
163       {
164          Collection JavaDoc col = (Collection JavaDoc)fieldInfo.getValue(o);
165          if(col == null)
166          {
167             if(colType == null)
168             {
169                col = new ArrayList JavaDoc();
170             }
171             else
172             {
173                Class JavaDoc colCls;
174                try
175                {
176                   colCls = Thread.currentThread().getContextClassLoader().loadClass(colType);
177                }
178                catch(ClassNotFoundException JavaDoc e)
179                {
180                   throw new JBossXBRuntimeException("Failed to load collection type: " + colType);
181                }
182
183                try
184                {
185                   col = (Collection JavaDoc)colCls.newInstance();
186                }
187                catch(Exception JavaDoc e)
188                {
189                   throw new JBossXBRuntimeException("Failed to create an instance of " + colCls);
190                }
191             }
192
193             fieldInfo.setValue(o, col);
194          }
195
196          //System.out.println("col.add(value): " + prop + "=" + value);
197
col.add(value);
198       }
199 /*
200       else if(fieldType.isArray() &&
201          value != null &&
202          (fieldType.getComponentType().isAssignableFrom(value.getClass()) ||
203          fieldType.getComponentType().isPrimitive() &&
204          Classes.getPrimitiveWrapper(fieldType.getComponentType()) == value.getClass()
205          ))
206       {
207          Object arr = fieldInfo.getValue(o);
208          int length = 0;
209          if(arr == null)
210          {
211             arr = Array.newInstance(fieldType.getComponentType(), 1);
212          }
213          else
214          {
215             Object tmp = arr;
216             length = Array.getLength(arr);
217             arr = Array.newInstance(fieldType.getComponentType(), length + 1);
218             System.arraycopy(tmp, 0, arr, 0, length);
219             throw new JBossXBRuntimeException("copied array (2)");
220          }
221          Array.set(arr, length, value);
222          fieldInfo.setValue(o, arr);
223       }
224 */

225       else
226       {
227          // todo: unmarshalling should produce the right type instead
228
Class JavaDoc valueClass = value == null ? null : value.getClass();
229          if (valueClass != null && fieldType.isArray() && Collection JavaDoc.class.isAssignableFrom(valueClass))
230          {
231             Collection JavaDoc col = (Collection JavaDoc) value;
232             Class JavaDoc compType = fieldType.getComponentType();
233             value = Array.newInstance(compType, col.size());
234             if (compType.isPrimitive())
235             {
236                int i = 0;
237                for (Iterator JavaDoc iter = col.iterator(); iter.hasNext();)
238                {
239                   Array.set(value, i++, iter.next());
240                }
241             }
242             else
243             {
244                value = col.toArray((Object JavaDoc[]) value);
245             }
246          }
247
248          fieldInfo.setValue(o, value);
249       }
250    }
251
252    public static void set(Object JavaDoc o, QName JavaDoc elementName, Object JavaDoc value, boolean ignoreLowLine)
253    {
254       if(o instanceof Collection JavaDoc)
255       {
256          ((Collection JavaDoc)o).add(value);
257       }
258       else
259       {
260          String JavaDoc fieldName = Util.xmlNameToFieldName(elementName.getLocalPart(), ignoreLowLine);
261          FieldInfo fieldInfo = FieldInfo.getFieldInfo(o.getClass(), fieldName, true);
262          fieldInfo.setValue(o, value);
263       }
264    }
265
266    public static Class JavaDoc loadClass(String JavaDoc clsName, boolean failIfNotFound)
267    {
268       Class JavaDoc cls = null;
269       try
270       {
271          cls = Classes.loadClass(clsName);
272       }
273       catch(ClassNotFoundException JavaDoc e)
274       {
275          if(failIfNotFound)
276          {
277             throw new JBossXBRuntimeException("Failed to load class " + clsName);
278          }
279       }
280       return cls;
281    }
282
283    public static Method JavaDoc getUnmarshalMethod(QName JavaDoc qName, ValueMetaData valueMetaData)
284    {
285       String JavaDoc unmarshalMethod = valueMetaData.getUnmarshalMethod();
286       if(unmarshalMethod == null)
287       {
288          throw new JBossXBRuntimeException(
289             "javaType annotation is specified for " + qName + " but does not contain parseMethod attribute"
290          );
291       }
292
293       int lastDot = unmarshalMethod.lastIndexOf('.');
294       String JavaDoc clsName = unmarshalMethod.substring(0, lastDot);
295       String JavaDoc methodName = unmarshalMethod.substring(lastDot + 1);
296
297       Class JavaDoc cls = RtUtil.loadClass(clsName, true);
298
299       try
300       {
301          return cls.getMethod(methodName, new Class JavaDoc[]{String JavaDoc.class});
302       }
303       catch(NoSuchMethodException JavaDoc e)
304       {
305          try
306          {
307             return cls.getMethod(methodName, new Class JavaDoc[]{String JavaDoc.class, NamespaceContext JavaDoc.class});
308          }
309          catch(NoSuchMethodException JavaDoc e1)
310          {
311             throw new JBossXBRuntimeException("Neither " +
312                methodName +
313                "(" +
314                String JavaDoc.class.getName() +
315                " p) nor " +
316                methodName +
317                "(" +
318                String JavaDoc.class.getName() +
319                " p1, " +
320                NamespaceContext JavaDoc.class.getName() +
321                " p2) were found in " + cls
322             );
323          }
324       }
325    }
326
327    public static Object JavaDoc invokeUnmarshalMethod(Class JavaDoc cls,
328                                               String JavaDoc methodName,
329                                               Object JavaDoc value,
330                                               Class JavaDoc valueType,
331                                               NamespaceContext JavaDoc nsCtx,
332                                               QName JavaDoc qName)
333    {
334       Method JavaDoc method;
335       Object JavaDoc[] args;
336       try
337       {
338          method = cls.getMethod(methodName, new Class JavaDoc[]{valueType});
339          args = new Object JavaDoc[]{value};
340       }
341       catch(NoSuchMethodException JavaDoc e)
342       {
343          try
344          {
345             method = cls.getMethod(methodName, new Class JavaDoc[]{valueType, NamespaceContext JavaDoc.class});
346             args = new Object JavaDoc[]{value, nsCtx};
347          }
348          catch(NoSuchMethodException JavaDoc e1)
349          {
350             throw new JBossXBRuntimeException("Neither " +
351                methodName +
352                "(" +
353                valueType.getName() +
354                " p) nor " +
355                methodName +
356                "(" +
357                valueType.getName() +
358                " p1, " +
359                NamespaceContext JavaDoc.class.getName() +
360                " p2) were found in " + cls
361             );
362          }
363       }
364
365       return invokeUnmarshalMethod(method, args, qName);
366    }
367
368    public static Object JavaDoc invokeUnmarshalMethod(Method JavaDoc method, Object JavaDoc[] args, QName JavaDoc qName)
369    {
370       Object JavaDoc unmarshalled;
371       try
372       {
373          unmarshalled = method.invoke(null, args);
374       }
375       catch(Exception JavaDoc e)
376       {
377          throw new JBossXBRuntimeException("Failed to invoke unmarshalMethod " +
378             method.getDeclaringClass().getName() +
379             "." +
380             method.getName() +
381             " for element " +
382             qName +
383             " and value " +
384             args[0] +
385             ": " +
386             e.getMessage(),
387             e
388          );
389       }
390       return unmarshalled;
391    }
392 }
393
Popular Tags