ObjectStreamField.java revision 608:7e06bf1dcb09
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
33package com.sun.corba.se.impl.io;
34
35import java.lang.reflect.Field;
36import java.lang.Comparable;
37import java.util.Hashtable;
38
39import sun.corba.Bridge ;
40import java.security.AccessController ;
41import 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 */
49public 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}
272