KickJava   Java API By Example, From Geeks To Geeks.

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


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.IOException JavaDoc;
21 import java.io.ObjectOutput JavaDoc;
22 import java.io.ObjectStreamClass JavaDoc;
23 import java.io.ObjectStreamField JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25
26 /**
27  ** An implementation of java.io.ObjectOutputStream.PutField
28  ** Provide programatic access to the persistent fields to be written
29  ** to ObjectOutput.
30  **/

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

67     PutField(ObjectStreamClass JavaDoc desc)
68     {
69         this.desc = desc;
70         computeOffsets();
71         primVals = new byte[primDataSize];
72         objVals = new Object JavaDoc[numObjFields];
73     }
74
75     /**
76      * Put the value of the named boolean field into the persistent field.
77      *
78      * @param name the name of the serializable field
79      * @param val the value to assign to the field
80      */

81     public void put(String JavaDoc name, boolean val)
82     {
83         Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
84     }
85
86     /**
87      * Put the value of the named byte field into the persistent field.
88      *
89      * @param name the name of the serializable field
90      * @param val the value to assign to the field
91      */

92     public void put(String JavaDoc name, byte val)
93     {
94         primVals[getFieldOffset(name, Byte.TYPE)] = val;
95     }
96
97     /**
98      * Put the value of the named char field into the persistent field.
99      *
100      * @param name the name of the serializable field
101      * @param val the value to assign to the field
102      */

103     public void put(String JavaDoc name, char val)
104     {
105         Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
106     }
107
108     /**
109      * Put the value of the named short field into the persistent field.
110      *
111      * @param name the name of the serializable field
112      * @param val the value to assign to the field
113      */

114     public void put(String JavaDoc name, short val)
115     {
116         Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
117     }
118
119     /**
120      * Put the value of the named int field into the persistent field.
121      *
122      * @param name the name of the serializable field
123      * @param val the value to assign to the field
124      */

125     public void put(String JavaDoc name, int val)
126     {
127         Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
128     }
129
130     /**
131      * Put the value of the named long field into the persistent field.
132      *
133      * @param name the name of the serializable field
134      * @param val the value to assign to the field
135      */

136     public void put(String JavaDoc name, long val)
137     {
138         Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
139     }
140
141     /**
142      * Put the value of the named float field into the persistent field.
143      *
144      * @param name the name of the serializable field
145      * @param val the value to assign to the field
146      */

147     public void put(String JavaDoc name, float val)
148     {
149         Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
150     }
151
152     /**
153      * Put the value of the named double field into the persistent field.
154      *
155      * @param name the name of the serializable field
156      * @param val the value to assign to the field
157      */

158     public void put(String JavaDoc name, double val)
159     {
160         Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
161     }
162
163     /**
164      * Put the value of the named Object field into the persistent field.
165      *
166      * @param name the name of the serializable field
167      * @param val the value to assign to the field
168      */

169     public void put(String JavaDoc name, Object JavaDoc val)
170     {
171         objVals[getFieldOffset(name, Object JavaDoc.class)] = val;
172     }
173
174     /**
175      * Write the data and fields to the specified ObjectOutput stream.
176      *
177      * @param out the stream to write the data and fields to
178      * @throws IOException if I/O errors occur while writing to the
179      * underlying stream
180      * @deprecated This method does not write the values contained by this
181      * <code>PutField</code> object in a proper format, and may
182      * result in corruption of the serialization stream. The
183      * correct way to write <code>PutField</code> data is by
184      * calling the {@link java.io.ObjectOutputStream#writeFields()}
185      * method.
186      */

187     public void write(ObjectOutput JavaDoc out) throws IOException JavaDoc
188     {
189         /*
190          * Applications should *not* use this method to write PutField
191          * data, as it will lead to stream corruption if the PutField
192          * object writes any primitive data (since block data mode is not
193          * unset/set properly, as is done in OOS.writeFields()). This
194          * broken implementation is being retained solely for behavioral
195          * compatibility, in order to support applications which use
196          * OOS.PutField.write() for writing only non-primitive data.
197          *
198          * Serialization of unshared objects is not implemented here since
199          * it is not necessary for backwards compatibility; also, unshared
200          * semantics may not be supported by the given ObjectOutput
201          * instance. Applications which write unshared objects using the
202          * PutField API must use OOS.writeFields().
203          */

204         throw new IOException JavaDoc("PutField.write(ObjectOutput) - not supported for RMI/IIOP");
205     }
206
207     /**
208      * Writes buffered primitive data and object fields to stream.
209      */

210     void writeFields(ObjectOutputStream o) throws IOException JavaDoc
211     {
212         org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream out = (org.apache.geronimo.interop.rmi.iiop.ObjectOutputStream)o;
213
214         out._cdrOutput.write_align(4, 4); // write any necessary padding
215

216         //Write out the primitive values first
217
for(int i = 0; i < primVals.length; i++)
218         {
219             out.writeByte(primVals[i]);
220         }
221
222         //Write out the object fields
223
java.io.ObjectStreamField JavaDoc[] fields = desc.getFields();
224         int numPrimFields = fields.length - objVals.length;
225         for (int i = 0; i < objVals.length; i++)
226         {
227             out.writeObject(ValueType.getInstance(objVals[i].getClass()), objVals[i]);
228         }
229     }
230
231     /**
232      * Returns offset of field with given name and type. A specified type
233      * of null matches all types, Object.class matches all non-primitive
234      * types, and any other non-null type matches assignable types only.
235      * Throws IllegalArgumentException if no matching field found.
236      */

237     private int getFieldOffset(String JavaDoc name, Class JavaDoc type)
238     {
239         ObjectStreamField JavaDoc field = getField(name, type);
240         if (field == null)
241         {
242             throw new IllegalArgumentException JavaDoc("no such field");
243         }
244         return field.getOffset();
245     }
246
247     private ObjectStreamField JavaDoc getField(String JavaDoc name, Class JavaDoc type)
248     {
249         if(type == null)
250         {
251             //Return match by name
252
for(int i = 0; i < _fields.length; i++)
253             {
254                 if(_fields[i].getName().equals(name))
255                 {
256                     return _fields[i];
257                 }
258             }
259             return (ObjectStreamField JavaDoc)null;
260         }
261         else if(type == java.lang.Object JavaDoc.class)
262         {
263             //Return match for name, and any non-primitive type
264
for(int i = 0; i < _fields.length; i++)
265             {
266                 if(_fields[i].getName().equals(name) && !_fields[i].getType().isPrimitive())
267                 {
268                     return _fields[i];
269                 }
270             }
271             return (ObjectStreamField JavaDoc)null;
272         }
273         else
274         {
275             for(int i = 0; i < _fields.length; i++)
276             {
277                 if(_fields[i].getName().equals(name) && _fields[i].getType().equals(type))
278                 {
279                     return _fields[i];
280                 }
281             }
282             return (ObjectStreamField JavaDoc)null;
283         }
284     }
285
286     private void computeOffsets()
287     {
288         try
289         {
290             computeFieldOffsets();
291         }
292         catch(Exception JavaDoc e)
293         {
294             throw new RuntimeException JavaDoc(org.apache.geronimo.interop.util.ExceptionUtil.causedBy(e));
295         }
296     }
297
298     private void computeFieldOffsets() throws Exception JavaDoc
299     {
300         primDataSize = 0;
301         numObjFields = 0;
302         int firstObjIndex = -1;
303         java.io.ObjectStreamField JavaDoc[] fields = desc.getFields();
304         _fields = new ObjectStreamField JavaDoc[fields.length];
305         Object JavaDoc[] args = new Object JavaDoc[1];
306
307         for (int i = 0; i < fields.length; i++)
308         {
309             java.io.ObjectStreamField JavaDoc f = fields[i];
310             _fields[i] = new ObjectStreamField JavaDoc(fields[i].getName(), fields[i].getType());
311             ObjectStreamField JavaDoc _f = _fields[i];
312
313             switch (f.getTypeCode())
314             {
315                 case 'Z':
316                 case 'B':
317                     args[0] = new Integer JavaDoc(primDataSize++);
318                     setOffsetMethod.invoke(_f, args);
319                     break;
320
321                 case 'C':
322                 case 'S':
323                     args[0] = new Integer JavaDoc(primDataSize);
324                     setOffsetMethod.invoke(_f, args);
325                     primDataSize += 2;
326                     break;
327
328                 case 'I':
329                 case 'F':
330                     args[0] = new Integer JavaDoc(primDataSize);
331                     setOffsetMethod.invoke(_f, args);
332                     primDataSize += 4;
333                     break;
334
335                 case 'J':
336                 case 'D':
337                     args[0] = new Integer JavaDoc(primDataSize);
338                     setOffsetMethod.invoke(_f, args);
339                     primDataSize += 8;
340                     break;
341
342                 case '[':
343                 case 'L':
344                     args[0] = new Integer JavaDoc(numObjFields++);
345                     setOffsetMethod.invoke(_f, args);
346                     if (firstObjIndex == -1)
347                     {
348                         firstObjIndex = i;
349                     }
350                     break;
351
352                 default:
353                     break;
354             }
355         }
356         if (firstObjIndex != -1 && firstObjIndex + numObjFields != fields.length)
357         {
358             //throw new InvalidClassException(name, "illegal field order");
359
}
360     }
361
362 }
363
Popular Tags