- /*
- * @(#)ValueUtility.java 1.29 03/12/19
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- /*
- * Licensed Materials - Property of IBM
- * RMI-IIOP v1.0
- * Copyright IBM Corp. 1998 1999 All Rights Reserved
- *
- * US Government Users Restricted Rights - Use, duplication or
- * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
-
- package com.sun.corba.se.impl.io;
-
- import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
- import com.sun.org.omg.CORBA.OperationDescription;
- import com.sun.org.omg.CORBA.AttributeDescription;
- import org.omg.CORBA.ValueMember;
- import com.sun.org.omg.CORBA.Initializer;
- import org.omg.CORBA.IDLType;
- import com.sun.org.omg.CORBA._IDLTypeStub;
- import org.omg.CORBA.ORB;
- import org.omg.CORBA.TypeCodePackage.*;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.TCKind;
- import java.lang.reflect.*;
- import com.sun.corba.se.impl.util.RepositoryId;
- import java.util.*;
- import javax.rmi.CORBA.Util;
- import javax.rmi.CORBA.ValueHandler;
-
- /**
- * Holds utility methods for converting from ObjectStreamClass to
- * FullValueDescription and generating typecodes from ObjectStreamClass.
- **/
- public class ValueUtility {
-
- public static final short PRIVATE_MEMBER = 0;
- public static final short PUBLIC_MEMBER = 1;
-
- private static final String primitiveConstants[] = {
- null, // tk_null 0
- null, // tk_void 1
- "S", // tk_short 2
- "I", // tk_long 3
- "S", // tk_ushort 4
- "I", // tk_ulong 5
- "F", // tk_float 6
- "D", // tk_double 7
- "Z", // tk_boolean 8
- "C", // tk_char 9
- "B", // tk_octet 10
- null, // tk_any 11
- null, // tk_typecode 12
- null, // tk_principal 13
- null, // tk_objref 14
- null, // tk_struct 15
- null, // tk_union 16
- null, // tk_enum 17
- null, // tk_string 18
- null, // tk_sequence 19
- null, // tk_array 20
- null, // tk_alias 21
- null, // tk_except 22
- "J", // tk_longlong 23
- "J", // tk_ulonglong 24
- "D", // tk_longdouble 25
- "C", // tk_wchar 26
- null, // tk_wstring 27
- null, // tk_fixed 28
- null, // tk_value 29
- null, // tk_value_box 30
- null, // tk_native 31
- null, // tk_abstract_interface 32
- };
-
- public static String getSignature(ValueMember member)
- throws ClassNotFoundException {
-
- // REVISIT. Can the type be something that is
- // non-primitive yet not a value_box, value, or objref?
- // If so, should use ObjectStreamClass or throw
- // exception.
-
- if (member.type.kind().value() == TCKind._tk_value_box ||
- member.type.kind().value() == TCKind._tk_value ||
- member.type.kind().value() == TCKind._tk_objref) {
- Class c = RepositoryId.cache.getId(member.id).getClassFromType();
- return ObjectStreamClass.getSignature(c);
-
- } else {
-
- return primitiveConstants[member.type.kind().value()];
- }
-
- }
-
- public static FullValueDescription translate(ORB orb, ObjectStreamClass osc, ValueHandler vh){
-
- // Create FullValueDescription
- FullValueDescription result = new FullValueDescription();
- Class className = osc.forClass();
-
- ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
- String repId = vhandler.createForAnyType(className);
-
- // Set FVD name
- result.name = vhandler.getUnqualifiedName(repId);
- if (result.name == null)
- result.name = "";
-
- // Set FVD id _REVISIT_ : Manglings
- result.id = vhandler.getRMIRepositoryID(className);
- if (result.id == null)
- result.id = "";
-
- // Set FVD is_abstract
- result.is_abstract = ObjectStreamClassCorbaExt.isAbstractInterface(className);
-
- // Set FVD is_custom
- result.is_custom = osc.hasWriteObject() || osc.isExternalizable();
-
- // Set FVD defined_in _REVISIT_ : Manglings
- result.defined_in = vhandler.getDefinedInId(repId);
- if (result.defined_in == null)
- result.defined_in = "";
-
- // Set FVD version
- result.version = vhandler.getSerialVersionUID(repId);
- if (result.version == null)
- result.version = "";
-
- // Skip FVD operations - N/A
- result.operations = new OperationDescription[0];
-
- // Skip FVD attributed - N/A
- result.attributes = new AttributeDescription[0];
-
- // Set FVD members
- // Maps classes to repositoryIDs strings. This is used to detect recursive types.
- IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
- // Stores all types created for resolving indirect types at the end.
- result.members = translateMembers(orb, osc, vh, createdIDs);
-
- // Skip FVD initializers - N/A
- result.initializers = new Initializer[0];
-
- Class interfaces[] = osc.forClass().getInterfaces();
- int abstractCount = 0;
-
- // Skip FVD supported_interfaces
- result.supported_interfaces = new String[interfaces.length];
- for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
- interfaceIndex++) {
- result.supported_interfaces[interfaceIndex] =
- vhandler.createForAnyType(interfaces[interfaceIndex]);
-
- if ((!(java.rmi.Remote.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
- (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
- abstractCount++;
- }
-
- // Skip FVD abstract_base_values - N/A
- result.abstract_base_values = new String[abstractCount];
- for (int interfaceIndex = 0; interfaceIndex < interfaces.length;
- interfaceIndex++) {
- if ((!(java.rmi.Remote.class.isAssignableFrom(interfaces[interfaceIndex]))) ||
- (!Modifier.isPublic(interfaces[interfaceIndex].getModifiers())))
- result.abstract_base_values[interfaceIndex] =
- vhandler.createForAnyType(interfaces[interfaceIndex]);
-
- }
-
- result.is_truncatable = false;
-
- // Set FVD base_value
- Class superClass = osc.forClass().getSuperclass();
- if (java.io.Serializable.class.isAssignableFrom(superClass))
- result.base_value = vhandler.getRMIRepositoryID(superClass);
- else
- result.base_value = "";
-
- // Set FVD type
- //result.type = createTypeCodeForClass(orb, osc.forClass());
- result.type = orb.get_primitive_tc(TCKind.tk_value); //11638
-
- return result;
-
- }
-
- private static ValueMember[] translateMembers (ORB orb,
- ObjectStreamClass osc,
- ValueHandler vh,
- IdentityKeyValueStack createdIDs)
- {
- ValueHandlerImpl vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
- ObjectStreamField fields[] = osc.getFields();
- int fieldsLength = fields.length;
- ValueMember[] members = new ValueMember[fieldsLength];
- // Note : fields come out of ObjectStreamClass in correct order for
- // writing. So, we will create the same order in the members array.
- for (int i = 0; i < fieldsLength; i++) {
- String valRepId = vhandler.getRMIRepositoryID(fields[i].getClazz());
- members[i] = new ValueMember();
- members[i].name = fields[i].getName();
- members[i].id = valRepId; // _REVISIT_ : Manglings
- members[i].defined_in = vhandler.getDefinedInId(valRepId);// _REVISIT_ : Manglings
- members[i].version = "1.0";
- members[i].type_def = new _IDLTypeStub(); // _REVISIT_ : IDLType implementation missing
-
- if (fields[i].getField() == null) {
- // When using serialPersistentFields, the class may
- // no longer have an actual Field that corresponds
- // to one of the items. The Java to IDL spec
- // ptc-00-01-06 1.3.5.6 says that the IDL field
- // should be private in this case.
- members[i].access = PRIVATE_MEMBER;
- } else {
- int m = fields[i].getField().getModifiers();
- if (Modifier.isPublic(m))
- members[i].access = PUBLIC_MEMBER;
- else
- members[i].access = PRIVATE_MEMBER;
- }
-
- switch (fields[i].getTypeCode()) {
- case 'B':
- members[i].type = orb.get_primitive_tc(TCKind.tk_octet); //11638
- break;
- case 'C':
- members[i].type
- = orb.get_primitive_tc(vhandler.getJavaCharTCKind()); // 11638
- break;
- case 'F':
- members[i].type = orb.get_primitive_tc(TCKind.tk_float); //11638
- break;
- case 'D' :
- members[i].type = orb.get_primitive_tc(TCKind.tk_double); //11638
- break;
- case 'I':
- members[i].type = orb.get_primitive_tc(TCKind.tk_long); //11638
- break;
- case 'J':
- members[i].type = orb.get_primitive_tc(TCKind.tk_longlong); //11638
- break;
- case 'S':
- members[i].type = orb.get_primitive_tc(TCKind.tk_short); //11638
- break;
- case 'Z':
- members[i].type = orb.get_primitive_tc(TCKind.tk_boolean); //11638
- break;
- // case '[':
- // members[i].type = orb.get_primitive_tc(TCKind.tk_value_box); //11638
- // members[i].id = RepositoryId.createForAnyType(fields[i].getType());
- // break;
- default:
- members[i].type = createTypeCodeForClassInternal(orb, fields[i].getClazz(), vhandler,
- createdIDs);
- members[i].id = vhandler.createForAnyType(fields[i].getType());
- break;
- } // end switch
-
- } // end for loop
-
- return members;
- }
-
- private static boolean exists(String str, String strs[]){
- for (int i = 0; i < strs.length; i++)
- if (str.equals(strs[i]))
- return true;
-
- return false;
- }
-
- public static boolean isAssignableFrom(String clzRepositoryId, FullValueDescription type,
- com.sun.org.omg.SendingContext.CodeBase sender){
-
- if (exists(clzRepositoryId, type.supported_interfaces))
- return true;
-
- if (clzRepositoryId.equals(type.id))
- return true;
-
- if ((type.base_value != null) &&
- (!type.base_value.equals(""))) {
- FullValueDescription parent = sender.meta(type.base_value);
-
- return isAssignableFrom(clzRepositoryId, parent, sender);
- }
-
- return false;
-
- }
-
- public static TypeCode createTypeCodeForClass (ORB orb, java.lang.Class c, ValueHandler vh) {
- // Maps classes to repositoryIDs strings. This is used to detect recursive types.
- IdentityKeyValueStack createdIDs = new IdentityKeyValueStack();
- // Stores all types created for resolving indirect types at the end.
- TypeCode tc = createTypeCodeForClassInternal(orb, c, vh, createdIDs);
- return tc;
- }
-
- private static TypeCode createTypeCodeForClassInternal (ORB orb,
- java.lang.Class c,
- ValueHandler vh,
- IdentityKeyValueStack createdIDs)
- {
- // This wrapper method is the protection against infinite recursion.
- TypeCode tc = null;
- String id = (String)createdIDs.get(c);
- if (id != null) {
- return orb.create_recursive_tc(id);
- } else {
- id = vh.getRMIRepositoryID(c);
- if (id == null) id = "";
- // cache the rep id BEFORE creating a new typecode.
- // so that recursive tc can look up the rep id.
- createdIDs.push(c, id);
- tc = createTypeCodeInternal(orb, c, vh, id, createdIDs);
- createdIDs.pop();
- return tc;
- }
- }
-
- // Maintains a stack of key-value pairs. Compares elements using == operator.
- private static class IdentityKeyValueStack {
- private static class KeyValuePair {
- Object key;
- Object value;
- KeyValuePair(Object key, Object value) {
- this.key = key;
- this.value = value;
- }
- boolean equals(KeyValuePair pair) {
- return pair.key == this.key;
- }
- }
-
- Stack pairs = null;
-
- Object get(Object key) {
- if (pairs == null) {
- return null;
- }
- for (Iterator i = pairs.iterator(); i.hasNext();) {
- KeyValuePair pair = (KeyValuePair)i.next();
- if (pair.key == key) {
- return pair.value;
- }
- }
- return null;
- }
-
- void push(Object key, Object value) {
- if (pairs == null) {
- pairs = new Stack();
- }
- pairs.push(new KeyValuePair(key, value));
- }
-
- void pop() {
- pairs.pop();
- }
- }
-
- private static TypeCode createTypeCodeInternal (ORB orb,
- java.lang.Class c,
- ValueHandler vh,
- String id,
- IdentityKeyValueStack createdIDs)
- {
- if ( c.isArray() ) {
- // Arrays - may recurse for multi-dimensional arrays
- Class componentClass = c.getComponentType();
- TypeCode embeddedType;
- if ( componentClass.isPrimitive() ){
- embeddedType
- = ValueUtility.getPrimitiveTypeCodeForClass(orb,
- componentClass,
- vh);
- } else {
- embeddedType = createTypeCodeForClassInternal(orb, componentClass, vh,
- createdIDs);
- }
- TypeCode t = orb.create_sequence_tc (0, embeddedType);
- return orb.create_value_box_tc (id, "Sequence", t);
- } else if ( c == java.lang.String.class ) {
- // Strings
- TypeCode t = orb.create_string_tc (0);
- return orb.create_value_box_tc (id, "StringValue", t);
- } else if (java.rmi.Remote.class.isAssignableFrom(c)) {
- return orb.get_primitive_tc(TCKind.tk_objref);
- } else if (org.omg.CORBA.Object.class.isAssignableFrom(c)) {
- return orb.get_primitive_tc(TCKind.tk_objref);
- }
-
- // Anything else
-
- ObjectStreamClass osc = ObjectStreamClass.lookup(c);
-
- if (osc == null) {
- return orb.create_value_box_tc (id, "Value", orb.get_primitive_tc (TCKind.tk_value));
- }
-
- // type modifier
- // REVISIT truncatable and abstract?
- short modifier = (osc.isCustomMarshaled() ? org.omg.CORBA.VM_CUSTOM.value : org.omg.CORBA.VM_NONE.value);
-
- // concrete base
- TypeCode base = null;
- Class superClass = c.getSuperclass();
- if (superClass != null && java.io.Serializable.class.isAssignableFrom(superClass)) {
- base = createTypeCodeForClassInternal(orb, superClass, vh, createdIDs);
- }
-
- // members
- ValueMember[] members = translateMembers (orb, osc, vh, createdIDs);
-
- return orb.create_value_tc(id, c.getName(), modifier, base, members);
- }
-
- public static TypeCode getPrimitiveTypeCodeForClass (ORB orb,
- Class c,
- ValueHandler vh) {
-
- if (c == Integer.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_long);
- } else if (c == Byte.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_octet);
- } else if (c == Long.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_longlong);
- } else if (c == Float.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_float);
- } else if (c == Double.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_double);
- } else if (c == Short.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_short);
- } else if (c == Character.TYPE) {
- return orb.get_primitive_tc (((ValueHandlerImpl)vh).getJavaCharTCKind());
- } else if (c == Boolean.TYPE) {
- return orb.get_primitive_tc (TCKind.tk_boolean);
- } else {
- // _REVISIT_ Not sure if this is right.
- return orb.get_primitive_tc (TCKind.tk_any);
- }
- }
- }