Tue, 25 May 2010 15:52:11 -0700
6943119: Rebrand source copyright notices
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 /*
26 * Licensed Materials - Property of IBM
27 * RMI-IIOP v1.0
28 * Copyright IBM Corp. 1998 1999 All Rights Reserved
29 *
30 */
32 package com.sun.corba.se.impl.io;
34 import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
35 import com.sun.org.omg.CORBA.OperationDescription;
36 import com.sun.org.omg.CORBA.AttributeDescription;
37 import org.omg.CORBA.ValueMember;
38 import com.sun.org.omg.CORBA.Initializer;
39 import org.omg.CORBA.IDLType;
40 import com.sun.org.omg.CORBA._IDLTypeStub;
41 import org.omg.CORBA.ORB;
42 import org.omg.CORBA.TypeCodePackage.*;
43 import org.omg.CORBA.TypeCode;
44 import org.omg.CORBA.TCKind;
45 import java.lang.reflect.*;
46 import com.sun.corba.se.impl.util.RepositoryId;
47 import java.util.*;
48 import javax.rmi.CORBA.Util;
49 import javax.rmi.CORBA.ValueHandler;
51 /**
52 * Holds utility methods for converting from ObjectStreamClass to
53 * FullValueDescription and generating typecodes from ObjectStreamClass.
54 **/
55 public class ValueUtility {
57 public static final short PRIVATE_MEMBER = 0;
58 public static final short PUBLIC_MEMBER = 1;
60 private static final String primitiveConstants[] = {
61 null, // tk_null 0
62 null, // tk_void 1
63 "S", // tk_short 2
64 "I", // tk_long 3
65 "S", // tk_ushort 4
66 "I", // tk_ulong 5
67 "F", // tk_float 6
68 "D", // tk_double 7
69 "Z", // tk_boolean 8
70 "C", // tk_char 9
71 "B", // tk_octet 10
72 null, // tk_any 11
73 null, // tk_typecode 12
74 null, // tk_principal 13
75 null, // tk_objref 14
76 null, // tk_struct 15
77 null, // tk_union 16
78 null, // tk_enum 17
79 null, // tk_string 18
80 null, // tk_sequence 19
81 null, // tk_array 20
82 null, // tk_alias 21
83 null, // tk_except 22
84 "J", // tk_longlong 23
85 "J", // tk_ulonglong 24
86 "D", // tk_longdouble 25
87 "C", // tk_wchar 26
88 null, // tk_wstring 27
89 null, // tk_fixed 28
90 null, // tk_value 29
91 null, // tk_value_box 30
92 null, // tk_native 31
93 null, // tk_abstract_interface 32
94 };
96 public static String getSignature(ValueMember member)
97 throws ClassNotFoundException {
99 // REVISIT. Can the type be something that is
100 // non-primitive yet not a value_box, value, or objref?
101 // If so, should use ObjectStreamClass or throw
102 // exception.
104 if (member.type.kind().value() == TCKind._tk_value_box ||
105 member.type.kind().value() == TCKind._tk_value ||
106 member.type.kind().value() == TCKind._tk_objref) {
107 Class c = RepositoryId.cache.getId(member.id).getClassFromType();
108 return ObjectStreamClass.getSignature(c);
110 } else {
112 return primitiveConstants[member.type.kind().value()];
113 }
115 }
117 public static FullValueDescription translate(ORB orb, ObjectStreamClass osc, ValueHandler vh){
119 // Create FullValueDescription
120 FullValueDescription result = new FullValueDescription();
121 Class className = osc.forClass();
123 ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
124 String repId = vhandler.createForAnyType(className);
126 // Set FVD name
127 result.name = vhandler.getUnqualifiedName(repId);
128 if (result.name == null)
129 result.name = "";
131 // Set FVD id _REVISIT_ : Manglings
132 result.id = vhandler.getRMIRepositoryID(className);
133 if (result.id == null)
134 result.id = "";
136 // Set FVD is_abstract
137 result.is_abstract = ObjectStreamClassCorbaExt.isAbstractInterface(className);
139 // Set FVD is_custom
140 result.is_custom = osc.hasWriteObject() || osc.isExternalizable();
142 // Set FVD defined_in _REVISIT_ : Manglings
143 result.defined_in = vhandler.getDefinedInId(repId);
144 if (result.defined_in == null)
145 result.defined_in = "";
147 // Set FVD version
148 result.version = vhandler.getSerialVersionUID(repId);
149 if (result.version == null)
150 result.version = "";
152 // Skip FVD operations - N/A
153 result.operations = new OperationDescription[0];
155 // Skip FVD attributed - N/A
156 result.attributes = new AttributeDescription[0];
158 // Set FVD members
159 // Maps classes to repositoryIDs strings. This is used to detect recursive types.
160 IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
161 // Stores all types created for resolving indirect types at the end.
162 result.members = translateMembers(orb, osc, vh, createdIDs);
164 // Skip FVD initializers - N/A
165 result.initializers = new Initializer[0];
167 Class interfaces[] = osc.forClass().getInterfaces();
168 int abstractCount = 0;
170 // Skip FVD supported_interfaces
171 result.supported_interfaces = new String[interfaces.length];
172 for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
173 interfaceIndex++) {
174 result.supported_interfaces[interfaceIndex] =
175 vhandler.createForAnyType(interfaces[interfaceIndex]);
177 if ((!(java.rmi.Remote.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
178 (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
179 abstractCount++;
180 }
182 // Skip FVD abstract_base_values - N/A
183 result.abstract_base_values = new String[abstractCount];
184 for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
185 interfaceIndex++) {
186 if ((!(java.rmi.Remote.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
187 (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
188 result.abstract_base_values[interfaceIndex] =
189 vhandler.createForAnyType(interfaces[interfaceIndex]);
191 }
193 result.is_truncatable = false;
195 // Set FVD base_value
196 Class superClass = osc.forClass().getSuperclass();
197 if (java.io.Serializable.class.isAssignableFrom(superClass))
198 result.base_value = vhandler.getRMIRepositoryID(superClass);
199 else
200 result.base_value = "";
202 // Set FVD type
203 //result.type = createTypeCodeForClass(orb, osc.forClass());
204 result.type = orb.get_primitive_tc(TCKind.tk_value); //11638
206 return result;
208 }
210 private static ValueMember[] translateMembers (ORB orb,
211 ObjectStreamClass osc,
212 ValueHandler vh,
213 IdentityKeyValueStack createdIDs)
214 {
215 ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
216 ObjectStreamField fields[] = osc.getFields();
217 int fieldsLength = fields.length;
218 ValueMember[] members = new ValueMember[fieldsLength];
219 // Note : fields come out of ObjectStreamClass in correct order for
220 // writing. So, we will create the same order in the members array.
221 for (int i = 0; i < fieldsLength; i++) {
222 String valRepId = vhandler.getRMIRepositoryID(fields[i].getClazz());
223 members[i] = new ValueMember();
224 members[i].name = fields[i].getName();
225 members[i].id = valRepId; // _REVISIT_ : Manglings
226 members[i].defined_in = vhandler.getDefinedInId(valRepId);// _REVISIT_ : Manglings
227 members[i].version = "1.0";
228 members[i].type_def = new _IDLTypeStub(); // _REVISIT_ : IDLType implementation missing
230 if (fields[i].getField() == null) {
231 // When using serialPersistentFields, the class may
232 // no longer have an actual Field that corresponds
233 // to one of the items. The Java to IDL spec
234 // ptc-00-01-06 1.3.5.6 says that the IDL field
235 // should be private in this case.
236 members[i].access = PRIVATE_MEMBER;
237 } else {
238 int m = fields[i].getField().getModifiers();
239 if (Modifier.isPublic(m))
240 members[i].access = PUBLIC_MEMBER;
241 else
242 members[i].access = PRIVATE_MEMBER;
243 }
245 switch (fields[i].getTypeCode()) {
246 case 'B':
247 members[i].type = orb.get_primitive_tc(TCKind.tk_octet); //11638
248 break;
249 case 'C':
250 members[i].type
251 = orb.get_primitive_tc(vhandler.getJavaCharTCKind()); // 11638
252 break;
253 case 'F':
254 members[i].type = orb.get_primitive_tc(TCKind.tk_float); //11638
255 break;
256 case 'D' :
257 members[i].type = orb.get_primitive_tc(TCKind.tk_double); //11638
258 break;
259 case 'I':
260 members[i].type = orb.get_primitive_tc(TCKind.tk_long); //11638
261 break;
262 case 'J':
263 members[i].type = orb.get_primitive_tc(TCKind.tk_longlong); //11638
264 break;
265 case 'S':
266 members[i].type = orb.get_primitive_tc(TCKind.tk_short); //11638
267 break;
268 case 'Z':
269 members[i].type = orb.get_primitive_tc(TCKind.tk_boolean); //11638
270 break;
271 // case '[':
272 // members[i].type = orb.get_primitive_tc(TCKind.tk_value_box); //11638
273 // members[i].id = RepositoryId.createForAnyType(fields[i].getType());
274 // break;
275 default:
276 members[i].type = createTypeCodeForClassInternal(orb, fields[i].getClazz(), vhandler,
277 createdIDs);
278 members[i].id = vhandler.createForAnyType(fields[i].getType());
279 break;
280 } // end switch
282 } // end for loop
284 return members;
285 }
287 private static boolean exists(String str, String strs[]){
288 for (int i = 0; i < strs.length; i++)
289 if (str.equals(strs[i]))
290 return true;
292 return false;
293 }
295 public static boolean isAssignableFrom(String clzRepositoryId, FullValueDescription type,
296 com.sun.org.omg.SendingContext.CodeBase sender){
298 if (exists(clzRepositoryId, type.supported_interfaces))
299 return true;
301 if (clzRepositoryId.equals(type.id))
302 return true;
304 if ((type.base_value != null) &&
305 (!type.base_value.equals(""))) {
306 FullValueDescription parent = sender.meta(type.base_value);
308 return isAssignableFrom(clzRepositoryId, parent, sender);
309 }
311 return false;
313 }
315 public static TypeCode createTypeCodeForClass (ORB orb, java.lang.Class c, ValueHandler vh) {
316 // Maps classes to repositoryIDs strings. This is used to detect recursive types.
317 IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
318 // Stores all types created for resolving indirect types at the end.
319 TypeCode tc = createTypeCodeForClassInternal(orb, c, vh, createdIDs);
320 return tc;
321 }
323 private static TypeCode createTypeCodeForClassInternal (ORB orb,
324 java.lang.Class c,
325 ValueHandler vh,
326 IdentityKeyValueStack createdIDs)
327 {
328 // This wrapper method is the protection against infinite recursion.
329 TypeCode tc = null;
330 String id = (String)createdIDs.get(c);
331 if (id != null) {
332 return orb.create_recursive_tc(id);
333 } else {
334 id = vh.getRMIRepositoryID(c);
335 if (id == null) id = "";
336 // cache the rep id BEFORE creating a new typecode.
337 // so that recursive tc can look up the rep id.
338 createdIDs.push(c, id);
339 tc = createTypeCodeInternal(orb, c, vh, id, createdIDs);
340 createdIDs.pop();
341 return tc;
342 }
343 }
345 // Maintains a stack of key-value pairs. Compares elements using == operator.
346 private static class IdentityKeyValueStack {
347 private static class KeyValuePair {
348 Object key;
349 Object value;
350 KeyValuePair(Object key, Object value) {
351 this.key = key;
352 this.value = value;
353 }
354 boolean equals(KeyValuePair pair) {
355 return pair.key == this.key;
356 }
357 }
359 Stack pairs = null;
361 Object get(Object key) {
362 if (pairs == null) {
363 return null;
364 }
365 for (Iterator i = pairs.iterator(); i.hasNext();) {
366 KeyValuePair pair = (KeyValuePair)i.next();
367 if (pair.key == key) {
368 return pair.value;
369 }
370 }
371 return null;
372 }
374 void push(Object key, Object value) {
375 if (pairs == null) {
376 pairs = new Stack();
377 }
378 pairs.push(new KeyValuePair(key, value));
379 }
381 void pop() {
382 pairs.pop();
383 }
384 }
386 private static TypeCode createTypeCodeInternal (ORB orb,
387 java.lang.Class c,
388 ValueHandler vh,
389 String id,
390 IdentityKeyValueStack createdIDs)
391 {
392 if ( c.isArray() ) {
393 // Arrays - may recurse for multi-dimensional arrays
394 Class componentClass = c.getComponentType();
395 TypeCode embeddedType;
396 if ( componentClass.isPrimitive() ){
397 embeddedType
398 = ValueUtility.getPrimitiveTypeCodeForClass(orb,
399 componentClass,
400 vh);
401 } else {
402 embeddedType = createTypeCodeForClassInternal(orb, componentClass, vh,
403 createdIDs);
404 }
405 TypeCode t = orb.create_sequence_tc (0, embeddedType);
406 return orb.create_value_box_tc (id, "Sequence", t);
407 } else if ( c == java.lang.String.class ) {
408 // Strings
409 TypeCode t = orb.create_string_tc (0);
410 return orb.create_value_box_tc (id, "StringValue", t);
411 } else if (java.rmi.Remote.class.isAssignableFrom(c)) {
412 return orb.get_primitive_tc(TCKind.tk_objref);
413 } else if (org.omg.CORBA.Object.class.isAssignableFrom(c)) {
414 return orb.get_primitive_tc(TCKind.tk_objref);
415 }
417 // Anything else
419 ObjectStreamClass osc = ObjectStreamClass.lookup(c);
421 if (osc == null) {
422 return orb.create_value_box_tc (id, "Value", orb.get_primitive_tc (TCKind.tk_value));
423 }
425 // type modifier
426 // REVISIT truncatable and abstract?
427 short modifier = (osc.isCustomMarshaled() ? org.omg.CORBA.VM_CUSTOM.value : org.omg.CORBA.VM_NONE.value);
429 // concrete base
430 TypeCode base = null;
431 Class superClass = c.getSuperclass();
432 if (superClass != null && java.io.Serializable.class.isAssignableFrom(superClass)) {
433 base = createTypeCodeForClassInternal(orb, superClass, vh, createdIDs);
434 }
436 // members
437 ValueMember[] members = translateMembers (orb, osc, vh, createdIDs);
439 return orb.create_value_tc(id, c.getName(), modifier, base, members);
440 }
442 public static TypeCode getPrimitiveTypeCodeForClass (ORB orb,
443 Class c,
444 ValueHandler vh) {
446 if (c == Integer.TYPE) {
447 return orb.get_primitive_tc (TCKind.tk_long);
448 } else if (c == Byte.TYPE) {
449 return orb.get_primitive_tc (TCKind.tk_octet);
450 } else if (c == Long.TYPE) {
451 return orb.get_primitive_tc (TCKind.tk_longlong);
452 } else if (c == Float.TYPE) {
453 return orb.get_primitive_tc (TCKind.tk_float);
454 } else if (c == Double.TYPE) {
455 return orb.get_primitive_tc (TCKind.tk_double);
456 } else if (c == Short.TYPE) {
457 return orb.get_primitive_tc (TCKind.tk_short);
458 } else if (c == Character.TYPE) {
459 return orb.get_primitive_tc (((ValueHandlerImpl)vh).getJavaCharTCKind());
460 } else if (c == Boolean.TYPE) {
461 return orb.get_primitive_tc (TCKind.tk_boolean);
462 } else {
463 // _REVISIT_ Not sure if this is right.
464 return orb.get_primitive_tc (TCKind.tk_any);
465 }
466 }
467 }