KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > io > ValueUtility


1 /*
2  * @(#)ValueUtility.java 1.29 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Licensed Materials - Property of IBM
9  * RMI-IIOP v1.0
10  * Copyright IBM Corp. 1998 1999 All Rights Reserved
11  *
12  * US Government Users Restricted Rights - Use, duplication or
13  * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
14  */

15
16 package com.sun.corba.se.impl.io;
17
18 import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
19 import com.sun.org.omg.CORBA.OperationDescription;
20 import com.sun.org.omg.CORBA.AttributeDescription;
21 import org.omg.CORBA.ValueMember JavaDoc;
22 import com.sun.org.omg.CORBA.Initializer;
23 import org.omg.CORBA.IDLType JavaDoc;
24 import com.sun.org.omg.CORBA._IDLTypeStub;
25 import org.omg.CORBA.ORB JavaDoc;
26 import org.omg.CORBA.TypeCodePackage.*;
27 import org.omg.CORBA.TypeCode JavaDoc;
28 import org.omg.CORBA.TCKind JavaDoc;
29 import java.lang.reflect.*;
30 import com.sun.corba.se.impl.util.RepositoryId;
31 import java.util.*;
32 import javax.rmi.CORBA.Util JavaDoc;
33 import javax.rmi.CORBA.ValueHandler JavaDoc;
34
35 /**
36  * Holds utility methods for converting from ObjectStreamClass to
37  * FullValueDescription and generating typecodes from ObjectStreamClass.
38  **/

39 public class ValueUtility {
40
41     public static final short PRIVATE_MEMBER = 0;
42     public static final short PUBLIC_MEMBER = 1;
43     
44     private static final String JavaDoc primitiveConstants[] = {
45     null, // tk_null 0
46
null, // tk_void 1
47
"S", // tk_short 2
48
"I", // tk_long 3
49
"S", // tk_ushort 4
50
"I", // tk_ulong 5
51
"F", // tk_float 6
52
"D", // tk_double 7
53
"Z", // tk_boolean 8
54
"C", // tk_char 9
55
"B", // tk_octet 10
56
null, // tk_any 11
57
null, // tk_typecode 12
58
null, // tk_principal 13
59
null, // tk_objref 14
60
null, // tk_struct 15
61
null, // tk_union 16
62
null, // tk_enum 17
63
null, // tk_string 18
64
null, // tk_sequence 19
65
null, // tk_array 20
66
null, // tk_alias 21
67
null, // tk_except 22
68
"J", // tk_longlong 23
69
"J", // tk_ulonglong 24
70
"D", // tk_longdouble 25
71
"C", // tk_wchar 26
72
null, // tk_wstring 27
73
null, // tk_fixed 28
74
null, // tk_value 29
75
null, // tk_value_box 30
76
null, // tk_native 31
77
null, // tk_abstract_interface 32
78
};
79
80     public static String JavaDoc getSignature(ValueMember JavaDoc member)
81     throws ClassNotFoundException JavaDoc {
82
83         // REVISIT. Can the type be something that is
84
// non-primitive yet not a value_box, value, or objref?
85
// If so, should use ObjectStreamClass or throw
86
// exception.
87

88     if (member.type.kind().value() == TCKind._tk_value_box ||
89             member.type.kind().value() == TCKind._tk_value ||
90             member.type.kind().value() == TCKind._tk_objref) {
91         Class JavaDoc c = RepositoryId.cache.getId(member.id).getClassFromType();
92             return ObjectStreamClass.getSignature(c);
93
94     } else {
95
96         return primitiveConstants[member.type.kind().value()];
97     }
98         
99     }
100
101     public static FullValueDescription translate(ORB JavaDoc orb, ObjectStreamClass osc, ValueHandler JavaDoc vh){
102         
103     // Create FullValueDescription
104
FullValueDescription result = new FullValueDescription();
105     Class JavaDoc className = osc.forClass();
106
107         ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
108         String JavaDoc repId = vhandler.createForAnyType(className);
109
110     // Set FVD name
111
result.name = vhandler.getUnqualifiedName(repId);
112         if (result.name == null)
113             result.name = "";
114
115     // Set FVD id _REVISIT_ : Manglings
116
result.id = vhandler.getRMIRepositoryID(className);
117         if (result.id == null)
118             result.id = "";
119
120     // Set FVD is_abstract
121
result.is_abstract = ObjectStreamClassCorbaExt.isAbstractInterface(className);
122         
123     // Set FVD is_custom
124
result.is_custom = osc.hasWriteObject() || osc.isExternalizable();
125
126     // Set FVD defined_in _REVISIT_ : Manglings
127
result.defined_in = vhandler.getDefinedInId(repId);
128         if (result.defined_in == null)
129             result.defined_in = "";
130
131     // Set FVD version
132
result.version = vhandler.getSerialVersionUID(repId);
133         if (result.version == null)
134             result.version = "";
135
136     // Skip FVD operations - N/A
137
result.operations = new OperationDescription[0];
138
139     // Skip FVD attributed - N/A
140
result.attributes = new AttributeDescription[0];
141
142     // Set FVD members
143
// Maps classes to repositoryIDs strings. This is used to detect recursive types.
144
IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
145         // Stores all types created for resolving indirect types at the end.
146
result.members = translateMembers(orb, osc, vh, createdIDs);
147         
148     // Skip FVD initializers - N/A
149
result.initializers = new Initializer[0];
150         
151     Class JavaDoc interfaces[] = osc.forClass().getInterfaces();
152     int abstractCount = 0;
153
154     // Skip FVD supported_interfaces
155
result.supported_interfaces = new String JavaDoc[interfaces.length];
156     for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
157          interfaceIndex++) {
158         result.supported_interfaces[interfaceIndex] =
159         vhandler.createForAnyType(interfaces[interfaceIndex]);
160             
161         if ((!(java.rmi.Remote JavaDoc.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
162         (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
163         abstractCount++;
164     }
165         
166     // Skip FVD abstract_base_values - N/A
167
result.abstract_base_values = new String JavaDoc[abstractCount];
168     for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
169          interfaceIndex++) {
170         if ((!(java.rmi.Remote JavaDoc.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
171         (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
172         result.abstract_base_values[interfaceIndex] =
173             vhandler.createForAnyType(interfaces[interfaceIndex]);
174         
175     }
176         
177     result.is_truncatable = false;
178         
179     // Set FVD base_value
180
Class JavaDoc superClass = osc.forClass().getSuperclass();
181     if (java.io.Serializable JavaDoc.class.isAssignableFrom(superClass))
182         result.base_value = vhandler.getRMIRepositoryID(superClass);
183     else
184         result.base_value = "";
185         
186     // Set FVD type
187
//result.type = createTypeCodeForClass(orb, osc.forClass());
188
result.type = orb.get_primitive_tc(TCKind.tk_value); //11638
189

190     return result;
191         
192     }
193
194     private static ValueMember JavaDoc[] translateMembers (ORB JavaDoc orb,
195                                                    ObjectStreamClass osc,
196                                                    ValueHandler JavaDoc vh,
197                                                    IdentityKeyValueStack createdIDs)
198     {
199         ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
200     ObjectStreamField fields[] = osc.getFields();
201     int fieldsLength = fields.length;
202     ValueMember JavaDoc[] members = new ValueMember JavaDoc[fieldsLength];
203     // Note : fields come out of ObjectStreamClass in correct order for
204
// writing. So, we will create the same order in the members array.
205
for (int i = 0; i < fieldsLength; i++) {
206         String JavaDoc valRepId = vhandler.getRMIRepositoryID(fields[i].getClazz());
207         members[i] = new ValueMember JavaDoc();
208         members[i].name = fields[i].getName();
209         members[i].id = valRepId; // _REVISIT_ : Manglings
210
members[i].defined_in = vhandler.getDefinedInId(valRepId);// _REVISIT_ : Manglings
211
members[i].version = "1.0";
212         members[i].type_def = new _IDLTypeStub(); // _REVISIT_ : IDLType implementation missing
213

214             if (fields[i].getField() == null) {
215                 // When using serialPersistentFields, the class may
216
// no longer have an actual Field that corresponds
217
// to one of the items. The Java to IDL spec
218
// ptc-00-01-06 1.3.5.6 says that the IDL field
219
// should be private in this case.
220
members[i].access = PRIVATE_MEMBER;
221             } else {
222                 int m = fields[i].getField().getModifiers();
223                 if (Modifier.isPublic(m))
224                     members[i].access = PUBLIC_MEMBER;
225                 else
226                     members[i].access = PRIVATE_MEMBER;
227             }
228
229         switch (fields[i].getTypeCode()) {
230         case 'B':
231         members[i].type = orb.get_primitive_tc(TCKind.tk_octet); //11638
232
break;
233         case 'C':
234         members[i].type
235                     = orb.get_primitive_tc(vhandler.getJavaCharTCKind()); // 11638
236
break;
237         case 'F':
238         members[i].type = orb.get_primitive_tc(TCKind.tk_float); //11638
239
break;
240         case 'D' :
241         members[i].type = orb.get_primitive_tc(TCKind.tk_double); //11638
242
break;
243         case 'I':
244         members[i].type = orb.get_primitive_tc(TCKind.tk_long); //11638
245
break;
246         case 'J':
247         members[i].type = orb.get_primitive_tc(TCKind.tk_longlong); //11638
248
break;
249         case 'S':
250         members[i].type = orb.get_primitive_tc(TCKind.tk_short); //11638
251
break;
252         case 'Z':
253         members[i].type = orb.get_primitive_tc(TCKind.tk_boolean); //11638
254
break;
255         // case '[':
256
// members[i].type = orb.get_primitive_tc(TCKind.tk_value_box); //11638
257
// members[i].id = RepositoryId.createForAnyType(fields[i].getType());
258
// break;
259
default:
260         members[i].type = createTypeCodeForClassInternal(orb, fields[i].getClazz(), vhandler,
261                                   createdIDs);
262         members[i].id = vhandler.createForAnyType(fields[i].getType());
263         break;
264         } // end switch
265

266     } // end for loop
267

268     return members;
269     }
270
271     private static boolean exists(String JavaDoc str, String JavaDoc strs[]){
272     for (int i = 0; i < strs.length; i++)
273         if (str.equals(strs[i]))
274         return true;
275         
276     return false;
277     }
278
279     public static boolean isAssignableFrom(String JavaDoc clzRepositoryId, FullValueDescription type,
280                        com.sun.org.omg.SendingContext.CodeBase sender){
281         
282     if (exists(clzRepositoryId, type.supported_interfaces))
283         return true;
284
285     if (clzRepositoryId.equals(type.id))
286         return true;
287         
288     if ((type.base_value != null) &&
289         (!type.base_value.equals(""))) {
290         FullValueDescription parent = sender.meta(type.base_value);
291             
292         return isAssignableFrom(clzRepositoryId, parent, sender);
293     }
294
295     return false;
296
297     }
298
299     public static TypeCode JavaDoc createTypeCodeForClass (ORB JavaDoc orb, java.lang.Class JavaDoc c, ValueHandler JavaDoc vh) {
300         // Maps classes to repositoryIDs strings. This is used to detect recursive types.
301
IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
302         // Stores all types created for resolving indirect types at the end.
303
TypeCode JavaDoc tc = createTypeCodeForClassInternal(orb, c, vh, createdIDs);
304         return tc;
305     }
306
307     private static TypeCode JavaDoc createTypeCodeForClassInternal (ORB JavaDoc orb,
308                                                             java.lang.Class JavaDoc c,
309                                                             ValueHandler JavaDoc vh,
310                                                             IdentityKeyValueStack createdIDs)
311     {
312         // This wrapper method is the protection against infinite recursion.
313
TypeCode JavaDoc tc = null;
314         String JavaDoc id = (String JavaDoc)createdIDs.get(c);
315         if (id != null) {
316             return orb.create_recursive_tc(id);
317         } else {
318             id = vh.getRMIRepositoryID(c);
319             if (id == null) id = "";
320             // cache the rep id BEFORE creating a new typecode.
321
// so that recursive tc can look up the rep id.
322
createdIDs.push(c, id);
323             tc = createTypeCodeInternal(orb, c, vh, id, createdIDs);
324             createdIDs.pop();
325             return tc;
326         }
327     }
328
329     // Maintains a stack of key-value pairs. Compares elements using == operator.
330
private static class IdentityKeyValueStack {
331         private static class KeyValuePair {
332             Object JavaDoc key;
333             Object JavaDoc value;
334             KeyValuePair(Object JavaDoc key, Object JavaDoc value) {
335                 this.key = key;
336                 this.value = value;
337             }
338             boolean equals(KeyValuePair pair) {
339                 return pair.key == this.key;
340             }
341         }
342
343         Stack pairs = null;
344
345         Object JavaDoc get(Object JavaDoc key) {
346             if (pairs == null) {
347                 return null;
348             }
349             for (Iterator i = pairs.iterator(); i.hasNext();) {
350                 KeyValuePair pair = (KeyValuePair)i.next();
351                 if (pair.key == key) {
352                     return pair.value;
353                 }
354             }
355             return null;
356         }
357
358         void push(Object JavaDoc key, Object JavaDoc value) {
359             if (pairs == null) {
360                 pairs = new Stack();
361             }
362             pairs.push(new KeyValuePair(key, value));
363         }
364
365         void pop() {
366             pairs.pop();
367         }
368     }
369
370     private static TypeCode JavaDoc createTypeCodeInternal (ORB JavaDoc orb,
371                                                     java.lang.Class JavaDoc c,
372                                                     ValueHandler JavaDoc vh,
373                                                     String JavaDoc id,
374                                                     IdentityKeyValueStack createdIDs)
375     {
376         if ( c.isArray() ) {
377         // Arrays - may recurse for multi-dimensional arrays
378
Class JavaDoc componentClass = c.getComponentType();
379         TypeCode JavaDoc embeddedType;
380         if ( componentClass.isPrimitive() ){
381         embeddedType
382                     = ValueUtility.getPrimitiveTypeCodeForClass(orb,
383                                                                 componentClass,
384                                                                 vh);
385         } else {
386         embeddedType = createTypeCodeForClassInternal(orb, componentClass, vh,
387                                                               createdIDs);
388         }
389         TypeCode JavaDoc t = orb.create_sequence_tc (0, embeddedType);
390         return orb.create_value_box_tc (id, "Sequence", t);
391     } else if ( c == java.lang.String JavaDoc.class ) {
392         // Strings
393
TypeCode JavaDoc t = orb.create_string_tc (0);
394         return orb.create_value_box_tc (id, "StringValue", t);
395     } else if (java.rmi.Remote JavaDoc.class.isAssignableFrom(c)) {
396         return orb.get_primitive_tc(TCKind.tk_objref);
397     } else if (org.omg.CORBA.Object JavaDoc.class.isAssignableFrom(c)) {
398         return orb.get_primitive_tc(TCKind.tk_objref);
399     }
400         
401     // Anything else
402

403         ObjectStreamClass osc = ObjectStreamClass.lookup(c);
404
405         if (osc == null) {
406             return orb.create_value_box_tc (id, "Value", orb.get_primitive_tc (TCKind.tk_value));
407         }
408
409         // type modifier
410
// REVISIT truncatable and abstract?
411
short modifier = (osc.isCustomMarshaled() ? org.omg.CORBA.VM_CUSTOM.value : org.omg.CORBA.VM_NONE.value);
412
413         // concrete base
414
TypeCode JavaDoc base = null;
415         Class JavaDoc superClass = c.getSuperclass();
416         if (superClass != null && java.io.Serializable JavaDoc.class.isAssignableFrom(superClass)) {
417             base = createTypeCodeForClassInternal(orb, superClass, vh, createdIDs);
418         }
419
420         // members
421
ValueMember JavaDoc[] members = translateMembers (orb, osc, vh, createdIDs);
422
423         return orb.create_value_tc(id, c.getName(), modifier, base, members);
424     }
425
426     public static TypeCode JavaDoc getPrimitiveTypeCodeForClass (ORB JavaDoc orb,
427                                                          Class JavaDoc c,
428                                                          ValueHandler JavaDoc vh) {
429         
430     if (c == Integer.TYPE) {
431         return orb.get_primitive_tc (TCKind.tk_long);
432     } else if (c == Byte.TYPE) {
433         return orb.get_primitive_tc (TCKind.tk_octet);
434     } else if (c == Long.TYPE) {
435         return orb.get_primitive_tc (TCKind.tk_longlong);
436     } else if (c == Float.TYPE) {
437         return orb.get_primitive_tc (TCKind.tk_float);
438     } else if (c == Double.TYPE) {
439         return orb.get_primitive_tc (TCKind.tk_double);
440     } else if (c == Short.TYPE) {
441         return orb.get_primitive_tc (TCKind.tk_short);
442     } else if (c == Character.TYPE) {
443             return orb.get_primitive_tc (((ValueHandlerImpl)vh).getJavaCharTCKind());
444     } else if (c == Boolean.TYPE) {
445         return orb.get_primitive_tc (TCKind.tk_boolean);
446     } else {
447         // _REVISIT_ Not sure if this is right.
448
return orb.get_primitive_tc (TCKind.tk_any);
449     }
450     }
451 }
452
Popular Tags