src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java

Tue, 25 May 2010 15:52:11 -0700

author
ohair
date
Tue, 25 May 2010 15:52:11 -0700
changeset 158
91006f157c46
parent 1
55540e827aef
child 443
3c73273667ae
permissions
-rw-r--r--

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 }

mercurial