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