KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > interop > rmi > iiop > GetField


1 /**
2  *
3  * Copyright 2004-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * 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  *
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.geronimo.interop.rmi.iiop;
19
20 import java.io.*;
21 import java.util.*;
22 import java.lang.reflect.*;
23
24 /**
25  ** An implementation of java.io.ObjectInputStream.GetField
26  ** Provide access to the persistent fields read from the input stream.
27  **/

28
29 public class GetField extends java.io.ObjectInputStream.GetField
30 {
31     /** class descriptor describing serializable fields */
32     private final ObjectStreamClass desc;
33     /** primitive field values */
34     private final byte[] primVals;
35     /** object field values */
36     private final Object JavaDoc[] objVals;
37     /** object field value handles */
38     private final int[] objHandles;
39
40     private int primDataSize = 0;
41     private int numObjFields = 0;
42     private ObjectStreamField[] _fields = null;
43
44     private static Method setOffsetMethod;
45
46     static
47     {
48         try
49         {
50             Class JavaDoc osFieldClass = java.io.ObjectStreamField JavaDoc.class;
51             Class JavaDoc[] params = new Class JavaDoc[1];
52             params[0] = int.class;
53             setOffsetMethod = osFieldClass.getDeclaredMethod("setOffset", params);
54             setOffsetMethod.setAccessible(true);
55         }
56         catch (Throwable JavaDoc t)
57         {
58             t.printStackTrace();
59         }
60     }
61
62     /**
63      * Creates GetFieldImpl object for reading fields defined in given
64      * class descriptor.
65      */

66     GetField(ObjectStreamClass desc)
67     {
68         this.desc = desc;
69         computeOffsets();
70         primVals = new byte[primDataSize];
71         objVals = new Object JavaDoc[numObjFields];
72         objHandles = new int[objVals.length];
73     }
74     
75     /**
76     * Get the ObjectStreamClass that describes the fields in the stream.
77     *
78     * @return the descriptor class that describes the serializable fields
79     */

80     public ObjectStreamClass getObjectStreamClass()
81     {
82         return desc;
83     }
84  
85     /**
86     * Return true if the named field is defaulted and has no value in this
87     * stream.
88     *
89     * @param name the name of the field
90     * @return true, if and only if the named field is defaulted
91     * @throws IOException if there are I/O errors while reading from
92     * the underlying <code>InputStream</code>
93     * @throws IllegalArgumentException if <code>name</code> does not
94     * correspond to a serializable field
95     */

96     public boolean defaulted(String JavaDoc name) throws IOException
97     {
98         int fieldOffset = getFieldOffset(name, null);
99         boolean result;
100         if(fieldOffset < 0)
101         {
102             result = false;
103         }
104         else
105         {
106             result = true;
107         }
108         return result;
109     }
110  
111     /**
112      * Get the value of the named boolean field from the persistent field.
113      *
114      * @param name the name of the field
115      * @param val the default value to use if <code>name</code> does not
116      * have a value
117      * @return the value of the named <code>boolean</code> field
118      * @throws IOException if there are I/O errors while reading from the
119      * underlying <code>InputStream</code>
120      * @throws IllegalArgumentException if type of <code>name</code> is
121      * not serializable or if the field type is incorrect
122      */

123     public boolean get(String JavaDoc name, boolean val) throws IOException
124     {
125         int off = getFieldOffset(name, Boolean.TYPE);
126         return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
127     }
128     
129     /**
130      * Get the value of the named byte field from the persistent field.
131      *
132      * @param name the name of the field
133      * @param val the default value to use if <code>name</code> does not
134      * have a value
135      * @return the value of the named <code>byte</code> field
136      * @throws IOException if there are I/O errors while reading from the
137      * underlying <code>InputStream</code>
138      * @throws IllegalArgumentException if type of <code>name</code> is
139      * not serializable or if the field type is incorrect
140      */

141     public byte get(String JavaDoc name, byte val) throws IOException
142     {
143         int off = getFieldOffset(name, Byte.TYPE);
144         return (off >= 0) ? primVals[off] : val;
145     }
146  
147     /**
148      * Get the value of the named char field from the persistent field.
149      *
150      * @param name the name of the field
151      * @param val the default value to use if <code>name</code> does not
152      * have a value
153      * @return the value of the named <code>char</code> field
154      * @throws IOException if there are I/O errors while reading from the
155      * underlying <code>InputStream</code>
156      * @throws IllegalArgumentException if type of <code>name</code> is
157      * not serializable or if the field type is incorrect
158      */

159     public char get(String JavaDoc name, char val) throws IOException
160     {
161         int off = getFieldOffset(name, Character.TYPE);
162         return (off >= 0) ? Bits.getChar(primVals, off) : val;
163     }
164  
165     /**
166      * Get the value of the named short field from the persistent field.
167      *
168      * @param name the name of the field
169      * @param val the default value to use if <code>name</code> does not
170      * have a value
171      * @return the value of the named <code>short</code> field
172      * @throws IOException if there are I/O errors while reading from the
173      * underlying <code>InputStream</code>
174      * @throws IllegalArgumentException if type of <code>name</code> is
175      * not serializable or if the field type is incorrect
176      */

177     public short get(String JavaDoc name, short val) throws IOException
178     {
179         int off = getFieldOffset(name, Short.TYPE);
180         return (off >= 0) ? Bits.getShort(primVals, off) : val;
181     }
182  
183     /**
184      * Get the value of the named int field from the persistent field.
185      *
186      * @param name the name of the field
187      * @param val the default value to use if <code>name</code> does not
188      * have a value
189      * @return the value of the named <code>int</code> field
190      * @throws IOException if there are I/O errors while reading from the
191      * underlying <code>InputStream</code>
192      * @throws IllegalArgumentException if type of <code>name</code> is
193      * not serializable or if the field type is incorrect
194      */

195     public int get(String JavaDoc name, int val) throws IOException
196     {
197         int off = getFieldOffset(name, Integer.TYPE);
198         return (off >= 0) ? Bits.getInt(primVals, off) : val;
199     }
200  
201     /**
202      * Get the value of the named long field from the persistent field.
203      *
204      * @param name the name of the field
205      * @param val the default value to use if <code>name</code> does not
206      * have a value
207      * @return the value of the named <code>long</code> field
208      * @throws IOException if there are I/O errors while reading from the
209      * underlying <code>InputStream</code>
210      * @throws IllegalArgumentException if type of <code>name</code> is
211      * not serializable or if the field type is incorrect
212      */

213     public long get(String JavaDoc name, long val) throws IOException
214     {
215         int off = getFieldOffset(name, Long.TYPE);
216         return (off >= 0) ? Bits.getLong(primVals, off) : val;
217     }
218     
219     /**
220      * Get the value of the named float field from the persistent field.
221      *
222      * @param name the name of the field
223      * @param val the default value to use if <code>name</code> does not
224      * have a value
225      * @return the value of the named <code>float</code> field
226      * @throws IOException if there are I/O errors while reading from the
227      * underlying <code>InputStream</code>
228      * @throws IllegalArgumentException if type of <code>name</code> is
229      * not serializable or if the field type is incorrect
230      */

231     public float get(String JavaDoc name, float val) throws IOException
232     {
233         int off = getFieldOffset(name, Float.TYPE);
234         return (off >= 0) ? Bits.getFloat(primVals, off) : val;
235     }
236  
237     /**
238      * Get the value of the named double field from the persistent field.
239      *
240      * @param name the name of the field
241      * @param val the default value to use if <code>name</code> does not
242      * have a value
243      * @return the value of the named <code>double</code> field
244      * @throws IOException if there are I/O errors while reading from the
245      * underlying <code>InputStream</code>
246      * @throws IllegalArgumentException if type of <code>name</code> is
247      * not serializable or if the field type is incorrect
248      */

249     public double get(String JavaDoc name, double val) throws IOException
250     {
251         int off = getFieldOffset(name, Double.TYPE);
252         return (off >= 0) ? Bits.getDouble(primVals, off) : val;
253     }
254  
255     /**
256      * Get the value of the named Object field from the persistent field.
257      *
258      * @param name the name of the field
259      * @param val the default value to use if <code>name</code> does not
260      * have a value
261      * @return the value of the named <code>Object</code> field
262      * @throws IOException if there are I/O errors while reading from the
263      * underlying <code>InputStream</code>
264      * @throws IllegalArgumentException if type of <code>name</code> is
265      * not serializable or if the field type is incorrect
266      */

267     public Object JavaDoc get(String JavaDoc name, Object JavaDoc val) throws IOException
268     {
269         int off = getFieldOffset(name, Object JavaDoc.class);
270         if (off >= 0)
271         {
272             return objVals[off];
273         }
274         else
275         {
276             return val;
277         }
278     }
279
280
281     /**
282      * Reads primitive and object field values from stream.
283      */

284     void readFields(ObjectInputStream oi) throws IOException
285     {
286         org.apache.geronimo.interop.rmi.iiop.ObjectInputStream in =
287             (org.apache.geronimo.interop.rmi.iiop.ObjectInputStream)oi;
288
289         in._cdrInput.read_align(4, 4);
290
291         //Read in primitive values first
292
for(int i = 0; i < primVals.length; i++)
293         {
294             primVals[i] = in.readByte();
295         }
296         
297         //Read in the object fields
298
java.io.ObjectStreamField JavaDoc[] fields = desc.getFields();
299         int numPrimFields = fields.length - objVals.length;
300         for (int i = 0; i < objVals.length; i++)
301         {
302             objVals[i] = in.readObject(ValueType.getInstance(fields[numPrimFields + i].getType()));
303         }
304     }
305
306     private int getFieldOffset(String JavaDoc name, Class JavaDoc type)
307     {
308         ObjectStreamField field = getField(name, type);
309         if (field == null)
310         {
311             throw new IllegalArgumentException JavaDoc("no such field: " + name + " of type: " + type.getName());
312         }
313         return field.getOffset();
314     }
315
316     private ObjectStreamField getField(String JavaDoc name, Class JavaDoc type)
317     {
318         if(type == null)
319         {
320             //Return match by name
321
for(int i = 0; i < _fields.length; i++)
322             {
323                 if(_fields[i].getName().equals(name))
324                 {
325                     return _fields[i];
326                 }
327             }
328             return (ObjectStreamField)null;
329         }
330         else if(type == java.lang.Object JavaDoc.class)
331         {
332             //Return match for name, and any non-primitive type
333
for(int i = 0; i < _fields.length; i++)
334             {
335                 if(_fields[i].getName().equals(name) && !_fields[i].getType().isPrimitive())
336                 {
337                     return _fields[i];
338                 }
339             }
340             return (ObjectStreamField)null;
341         }
342         else
343         {
344             for(int i = 0; i < _fields.length; i++)
345             {
346                 if(_fields[i].getName().equals(name) && _fields[i].getType().equals(type))
347                 {
348                     return _fields[i];
349                 }
350             }
351             return (ObjectStreamField)null;
352        }
353     }
354
355     private void computeOffsets()
356     {
357         try
358         {
359             computeFieldOffsets();
360         }
361         catch(Exception JavaDoc e)
362         {
363             throw new RuntimeException JavaDoc(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e));
364         }
365     }
366     
367     private void computeFieldOffsets() throws Exception JavaDoc
368     {
369         primDataSize = 0;
370         numObjFields = 0;
371         int firstObjIndex = -1;
372         java.io.ObjectStreamField JavaDoc[] fields = desc.getFields();
373         _fields = new ObjectStreamField[fields.length];
374         Object JavaDoc[] args = new Object JavaDoc[1];
375
376         for (int i = 0; i < fields.length; i++)
377         {
378             java.io.ObjectStreamField JavaDoc f = fields[i];
379             _fields[i] = new ObjectStreamField(fields[i].getName(), fields[i].getType());
380             ObjectStreamField _f = _fields[i];
381             
382             switch (f.getTypeCode())
383             {
384                 case 'Z':
385                 case 'B':
386                     args[0] = new Integer JavaDoc(primDataSize++);
387                     setOffsetMethod.invoke(_f, args);
388                     break;
389
390                 case 'C':
391                 case 'S':
392                     args[0] = new Integer JavaDoc(primDataSize);
393                     setOffsetMethod.invoke(_f, args);
394                     primDataSize += 2;
395                     break;
396
397                 case 'I':
398                 case 'F':
399                     args[0] = new Integer JavaDoc(primDataSize);
400                     setOffsetMethod.invoke(_f, args);
401                     primDataSize += 4;
402                     break;
403
404                 case 'J':
405                 case 'D':
406                     args[0] = new Integer JavaDoc(primDataSize);
407                     setOffsetMethod.invoke(_f, args);
408                     primDataSize += 8;
409                     break;
410
411                 case '[':
412                 case 'L':
413                     args[0] = new Integer JavaDoc(numObjFields++);
414                     setOffsetMethod.invoke(_f, args);
415                     if (firstObjIndex == -1)
416                     {
417                         firstObjIndex = i;
418                     }
419                     break;
420
421                 default:
422                     break;
423             }
424         }
425         if (firstObjIndex != -1 && firstObjIndex + numObjFields != fields.length)
426         {
427             //throw new InvalidClassException(name, "illegal field order");
428
}
429     }
430 }
431
Popular Tags