1 /*
   2  * Copyright (c) 2001, 2003, 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 /*
  27  * Licensed Materials - Property of IBM
  28  * RMI-IIOP v1.0
  29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
  30  *
  31  */
  32 
  33 package com.sun.corba.se.impl.orbutil;
  34 
  35 import java.lang.reflect.Field;
  36 import java.lang.Comparable;
  37 import java.util.Hashtable;
  38 
  39 /**
  40  * This is duplicated here somewhat in haste since we can't
  41  * expose this class outside of the com.sun.corba.se.impl.io
  42  * package for security reasons.
  43  */
  44 /**
  45  * A description of a field in a serializable class.
  46  * A array of these is used to declare the persistent fields of
  47  * a class.
  48  *
  49  */
  50 class ObjectStreamField implements Comparable {
  51     /**
  52      * Create a named field with the specified type.
  53      */
  54     ObjectStreamField(String n, Class clazz) {
  55         name = n;
  56         this.clazz = clazz;
  57 
  58         // Compute the typecode for easy switching
  59         if (clazz.isPrimitive()) {
  60             if (clazz == Integer.TYPE) {
  61                 type = 'I';
  62             } else if (clazz == Byte.TYPE) {
  63                 type = 'B';
  64             } else if (clazz == Long.TYPE) {
  65                 type = 'J';
  66             } else if (clazz == Float.TYPE) {
  67                 type = 'F';
  68             } else if (clazz == Double.TYPE) {
  69                 type = 'D';
  70             } else if (clazz == Short.TYPE) {
  71                 type = 'S';
  72             } else if (clazz == Character.TYPE) {
  73                 type = 'C';
  74             } else if (clazz == Boolean.TYPE) {
  75                 type = 'Z';
  76             }
  77         } else if (clazz.isArray()) {
  78             type = '[';
  79             typeString = ObjectStreamClass_1_3_1.getSignature(clazz);
  80         } else {
  81             type = 'L';
  82             typeString = ObjectStreamClass_1_3_1.getSignature(clazz);
  83         }
  84 
  85         if (typeString != null)
  86             signature = typeString;
  87         else
  88             signature = String.valueOf(type);
  89 
  90     }
  91 
  92     ObjectStreamField(Field field) {
  93         this(field.getName(), field.getType());
  94         this.field = field;
  95     }
  96 
  97     /**
  98      * Create an ObjectStreamField containing a reflected Field.
  99      */
 100     ObjectStreamField(String n, char t, Field f, String ts)
 101     {
 102         name = n;
 103         type = t;
 104         field = f;
 105         typeString = ts;
 106 
 107         if (typeString != null)
 108             signature = typeString;
 109         else
 110             signature = String.valueOf(type);
 111 
 112     }
 113 
 114     /**
 115      * Get the name of this field.
 116      */
 117     public String getName() {
 118         return name;
 119     }
 120 
 121     /**
 122      * Get the type of the field.
 123      */
 124     public Class getType() {
 125         if (clazz != null)
 126             return clazz;
 127         switch (type) {
 128         case 'B': clazz = Byte.TYPE;
 129             break;
 130         case 'C': clazz = Character.TYPE;
 131             break;
 132         case 'S': clazz = Short.TYPE;
 133             break;
 134         case 'I': clazz = Integer.TYPE;
 135             break;
 136         case 'J': clazz = Long.TYPE;
 137             break;
 138         case 'F': clazz = Float.TYPE;
 139             break;
 140         case 'D': clazz = Double.TYPE;
 141             break;
 142         case 'Z': clazz = Boolean.TYPE;
 143             break;
 144         case '[':
 145         case 'L':
 146             clazz = Object.class;
 147             break;
 148         }
 149 
 150         return clazz;
 151     }
 152 
 153     public char getTypeCode() {
 154         return type;
 155     }
 156 
 157     public String getTypeString() {
 158         return typeString;
 159     }
 160 
 161     Field getField() {
 162         return field;
 163     }
 164 
 165     void setField(Field field) {
 166         this.field = field;
 167         this.fieldID = -1;
 168     }
 169 
 170     /*
 171      * Default constructor creates an empty field.
 172      * Usually used just to get to the sort functions.
 173      */
 174     ObjectStreamField() {
 175     }
 176 
 177     /**
 178      * test if this field is a primitive or not.
 179      */
 180     public boolean isPrimitive() {
 181         return (type != '[' && type != 'L');
 182     }
 183 
 184     /**
 185      * Compare this with another ObjectStreamField.
 186      * return -1 if this is smaller, 0 if equal, 1 if greater
 187      * types that are primitives are "smaller" than objects.
 188      * if equal, the names are compared.
 189      */
 190     public int compareTo(Object o) {
 191         ObjectStreamField f2 = (ObjectStreamField)o;
 192         boolean thisprim = (this.typeString == null);
 193         boolean otherprim = (f2.typeString == null);
 194 
 195         if (thisprim != otherprim) {
 196             return (thisprim ? -1 : 1);
 197         }
 198         return this.name.compareTo(f2.name);
 199     }
 200 
 201     /**
 202      * Compare the types of two class descriptors.
 203      * The match if they have the same primitive types.
 204      * or if they are both objects and the object types match.
 205      */
 206     public boolean typeEquals(ObjectStreamField other) {
 207         if (other == null || type != other.type)
 208             return false;
 209 
 210         /* Return true if the primitive types matched */
 211         if (typeString == null && other.typeString == null)
 212             return true;
 213 
 214         return ObjectStreamClass_1_3_1.compareClassNames(typeString,
 215                                                          other.typeString,
 216                                                          '/');
 217     }
 218 
 219     /* Returns the signature of the Field.
 220      *
 221      */
 222     public String getSignature() {
 223 
 224         return signature;
 225 
 226     }
 227 
 228     /**
 229      * Return a string describing this field.
 230      */
 231     public String toString() {
 232         if (typeString != null)
 233             return typeString + " " + name;
 234         else
 235             return type + " " + name;
 236     }
 237 
 238     public Class getClazz() {
 239         return clazz;
 240     }
 241 
 242     /* Returns the Field ID
 243      * NOT USED, since this class is used only in ObjectStreamClass_1_3_1,
 244      * which is used only in RepositoryId_1_3_1.
 245     public long getFieldID( Class cl ) {
 246         if (fieldID == -1) {
 247             if (typeString != null)
 248                 fieldID = getFieldIDNative( cl, getName(), typeString );
 249             else
 250                 fieldID = getFieldIDNative( cl, getName(), getSignature() );
 251         }
 252         return fieldID;
 253     }
 254      */
 255 
 256     private String name;                // the name of the field
 257     private char type;                  // type first byte of the type signature
 258     private Field field;                // Reflected field
 259     private String typeString;          // iff object, typename
 260     private Class clazz;                // the type of this field, if has been resolved
 261 
 262     // the next 3 things are RMI-IIOP specific, it can be easily
 263     // removed, if we can figure out all place where there are dependencies
 264     // to this.  Signature is esentially equal to typestring. Then
 265     // essentially we can use the java.io.ObjectStreamField as such.
 266 
 267     private String signature;   // the signature of the field
 268     private long fieldID = -1;
 269     // private static native long getFieldIDNative(Class c, String fieldName, String fieldSig);
 270 }