corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
author ohair
Tue, 25 May 2010 15:52:11 -0700
changeset 5555 b2b5ed3f0d0d
parent 3291 805a72a26925
child 7588 cdc4ca035126
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
02bb8761fcce Initial load
duke
parents:
diff changeset
     1
/*
5555
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
     2
 * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
4
02bb8761fcce Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
02bb8761fcce Initial load
duke
parents:
diff changeset
     4
 *
02bb8761fcce Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
02bb8761fcce Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5555
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
4
02bb8761fcce Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5555
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
4
02bb8761fcce Initial load
duke
parents:
diff changeset
    10
 *
02bb8761fcce Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
02bb8761fcce Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
02bb8761fcce Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
02bb8761fcce Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
02bb8761fcce Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
02bb8761fcce Initial load
duke
parents:
diff changeset
    16
 *
02bb8761fcce Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
02bb8761fcce Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
02bb8761fcce Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
02bb8761fcce Initial load
duke
parents:
diff changeset
    20
 *
5555
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
b2b5ed3f0d0d 6943119: Rebrand source copyright notices
ohair
parents: 3291
diff changeset
    23
 * questions.
4
02bb8761fcce Initial load
duke
parents:
diff changeset
    24
 */
02bb8761fcce Initial load
duke
parents:
diff changeset
    25
/*
02bb8761fcce Initial load
duke
parents:
diff changeset
    26
 * Licensed Materials - Property of IBM
02bb8761fcce Initial load
duke
parents:
diff changeset
    27
 * RMI-IIOP v1.0
02bb8761fcce Initial load
duke
parents:
diff changeset
    28
 * Copyright IBM Corp. 1998 1999  All Rights Reserved
02bb8761fcce Initial load
duke
parents:
diff changeset
    29
 *
02bb8761fcce Initial load
duke
parents:
diff changeset
    30
 */
02bb8761fcce Initial load
duke
parents:
diff changeset
    31
02bb8761fcce Initial load
duke
parents:
diff changeset
    32
package com.sun.corba.se.impl.io;
02bb8761fcce Initial load
duke
parents:
diff changeset
    33
02bb8761fcce Initial load
duke
parents:
diff changeset
    34
import java.security.MessageDigest;
02bb8761fcce Initial load
duke
parents:
diff changeset
    35
import java.security.NoSuchAlgorithmException;
02bb8761fcce Initial load
duke
parents:
diff changeset
    36
import java.security.DigestOutputStream;
02bb8761fcce Initial load
duke
parents:
diff changeset
    37
import java.security.AccessController;
02bb8761fcce Initial load
duke
parents:
diff changeset
    38
import java.security.PrivilegedExceptionAction;
02bb8761fcce Initial load
duke
parents:
diff changeset
    39
import java.security.PrivilegedActionException;
02bb8761fcce Initial load
duke
parents:
diff changeset
    40
import java.security.PrivilegedAction;
02bb8761fcce Initial load
duke
parents:
diff changeset
    41
02bb8761fcce Initial load
duke
parents:
diff changeset
    42
import java.lang.reflect.Modifier;
02bb8761fcce Initial load
duke
parents:
diff changeset
    43
import java.lang.reflect.Array;
02bb8761fcce Initial load
duke
parents:
diff changeset
    44
import java.lang.reflect.Field;
02bb8761fcce Initial load
duke
parents:
diff changeset
    45
import java.lang.reflect.Member;
02bb8761fcce Initial load
duke
parents:
diff changeset
    46
import java.lang.reflect.Method;
02bb8761fcce Initial load
duke
parents:
diff changeset
    47
import java.lang.reflect.Constructor;
02bb8761fcce Initial load
duke
parents:
diff changeset
    48
import java.lang.reflect.Proxy;
02bb8761fcce Initial load
duke
parents:
diff changeset
    49
import java.lang.reflect.InvocationTargetException;
02bb8761fcce Initial load
duke
parents:
diff changeset
    50
02bb8761fcce Initial load
duke
parents:
diff changeset
    51
import java.io.IOException;
02bb8761fcce Initial load
duke
parents:
diff changeset
    52
import java.io.DataOutputStream;
02bb8761fcce Initial load
duke
parents:
diff changeset
    53
import java.io.ByteArrayOutputStream;
02bb8761fcce Initial load
duke
parents:
diff changeset
    54
import java.io.InvalidClassException;
02bb8761fcce Initial load
duke
parents:
diff changeset
    55
import java.io.Serializable;
02bb8761fcce Initial load
duke
parents:
diff changeset
    56
02bb8761fcce Initial load
duke
parents:
diff changeset
    57
import java.util.Arrays;
02bb8761fcce Initial load
duke
parents:
diff changeset
    58
import java.util.Comparator;
02bb8761fcce Initial load
duke
parents:
diff changeset
    59
import java.util.Hashtable;
02bb8761fcce Initial load
duke
parents:
diff changeset
    60
02bb8761fcce Initial load
duke
parents:
diff changeset
    61
import com.sun.corba.se.impl.util.RepositoryId;
02bb8761fcce Initial load
duke
parents:
diff changeset
    62
02bb8761fcce Initial load
duke
parents:
diff changeset
    63
import org.omg.CORBA.ValueMember;
02bb8761fcce Initial load
duke
parents:
diff changeset
    64
02bb8761fcce Initial load
duke
parents:
diff changeset
    65
import sun.corba.Bridge;
02bb8761fcce Initial load
duke
parents:
diff changeset
    66
02bb8761fcce Initial load
duke
parents:
diff changeset
    67
/**
02bb8761fcce Initial load
duke
parents:
diff changeset
    68
 * A ObjectStreamClass describes a class that can be serialized to a stream
02bb8761fcce Initial load
duke
parents:
diff changeset
    69
 * or a class that was serialized to a stream.  It contains the name
02bb8761fcce Initial load
duke
parents:
diff changeset
    70
 * and the serialVersionUID of the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
    71
 * <br>
02bb8761fcce Initial load
duke
parents:
diff changeset
    72
 * The ObjectStreamClass for a specific class loaded in this Java VM can
02bb8761fcce Initial load
duke
parents:
diff changeset
    73
 * be found using the lookup method.
02bb8761fcce Initial load
duke
parents:
diff changeset
    74
 *
02bb8761fcce Initial load
duke
parents:
diff changeset
    75
 * @author  Roger Riggs
02bb8761fcce Initial load
duke
parents:
diff changeset
    76
 * @since   JDK1.1
02bb8761fcce Initial load
duke
parents:
diff changeset
    77
 */
02bb8761fcce Initial load
duke
parents:
diff changeset
    78
public class ObjectStreamClass implements java.io.Serializable {
02bb8761fcce Initial load
duke
parents:
diff changeset
    79
    private static final boolean DEBUG_SVUID = false ;
02bb8761fcce Initial load
duke
parents:
diff changeset
    80
02bb8761fcce Initial load
duke
parents:
diff changeset
    81
    public static final long kDefaultUID = -1;
02bb8761fcce Initial load
duke
parents:
diff changeset
    82
02bb8761fcce Initial load
duke
parents:
diff changeset
    83
    private static Object noArgsList[] = {};
02bb8761fcce Initial load
duke
parents:
diff changeset
    84
    private static Class noTypesList[] = {};
02bb8761fcce Initial load
duke
parents:
diff changeset
    85
02bb8761fcce Initial load
duke
parents:
diff changeset
    86
    private static Hashtable translatedFields;
02bb8761fcce Initial load
duke
parents:
diff changeset
    87
02bb8761fcce Initial load
duke
parents:
diff changeset
    88
    private static final Bridge bridge =
02bb8761fcce Initial load
duke
parents:
diff changeset
    89
        (Bridge)AccessController.doPrivileged(
02bb8761fcce Initial load
duke
parents:
diff changeset
    90
            new PrivilegedAction() {
02bb8761fcce Initial load
duke
parents:
diff changeset
    91
                public Object run() {
02bb8761fcce Initial load
duke
parents:
diff changeset
    92
                    return Bridge.get() ;
02bb8761fcce Initial load
duke
parents:
diff changeset
    93
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
    94
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
    95
        ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
    96
02bb8761fcce Initial load
duke
parents:
diff changeset
    97
    /** Find the descriptor for a class that can be serialized.  Null
02bb8761fcce Initial load
duke
parents:
diff changeset
    98
     * is returned if the specified class does not implement
02bb8761fcce Initial load
duke
parents:
diff changeset
    99
     * java.io.Serializable or java.io.Externalizable.
02bb8761fcce Initial load
duke
parents:
diff changeset
   100
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   101
    static final ObjectStreamClass lookup(Class cl)
02bb8761fcce Initial load
duke
parents:
diff changeset
   102
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   103
        ObjectStreamClass desc = lookupInternal(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   104
        if (desc.isSerializable() || desc.isExternalizable())
02bb8761fcce Initial load
duke
parents:
diff changeset
   105
            return desc;
02bb8761fcce Initial load
duke
parents:
diff changeset
   106
        return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   107
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   108
02bb8761fcce Initial load
duke
parents:
diff changeset
   109
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   110
     * Find the class descriptor for the specified class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   111
     * Package access only so it can be called from ObjectIn/OutStream.
02bb8761fcce Initial load
duke
parents:
diff changeset
   112
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   113
    static ObjectStreamClass lookupInternal(Class cl)
02bb8761fcce Initial load
duke
parents:
diff changeset
   114
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   115
        /* Synchronize on the hashtable so no two threads will do
02bb8761fcce Initial load
duke
parents:
diff changeset
   116
         * this at the same time.
02bb8761fcce Initial load
duke
parents:
diff changeset
   117
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   118
        ObjectStreamClass desc = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   119
        synchronized (descriptorFor) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   120
            /* Find the matching descriptor if it already known */
02bb8761fcce Initial load
duke
parents:
diff changeset
   121
            desc = findDescriptorFor(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   122
            if (desc == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   123
                /* Check if it's serializable */
02bb8761fcce Initial load
duke
parents:
diff changeset
   124
                boolean serializable = classSerializable.isAssignableFrom(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   125
02bb8761fcce Initial load
duke
parents:
diff changeset
   126
                /* If the class is only Serializable,
02bb8761fcce Initial load
duke
parents:
diff changeset
   127
                 * lookup the descriptor for the superclass.
02bb8761fcce Initial load
duke
parents:
diff changeset
   128
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
   129
                ObjectStreamClass superdesc = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   130
                if (serializable) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   131
                    Class superclass = cl.getSuperclass();
02bb8761fcce Initial load
duke
parents:
diff changeset
   132
                    if (superclass != null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   133
                        superdesc = lookup(superclass);
02bb8761fcce Initial load
duke
parents:
diff changeset
   134
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   135
02bb8761fcce Initial load
duke
parents:
diff changeset
   136
                /* Check if its' externalizable.
02bb8761fcce Initial load
duke
parents:
diff changeset
   137
                 * If it's Externalizable, clear the serializable flag.
02bb8761fcce Initial load
duke
parents:
diff changeset
   138
                 * Only one or the other may be set in the protocol.
02bb8761fcce Initial load
duke
parents:
diff changeset
   139
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
   140
                boolean externalizable = false;
02bb8761fcce Initial load
duke
parents:
diff changeset
   141
                if (serializable) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   142
                    externalizable =
02bb8761fcce Initial load
duke
parents:
diff changeset
   143
                        ((superdesc != null) && superdesc.isExternalizable()) ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   144
                        classExternalizable.isAssignableFrom(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   145
                    if (externalizable) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   146
                        serializable = false;
02bb8761fcce Initial load
duke
parents:
diff changeset
   147
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   148
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   149
02bb8761fcce Initial load
duke
parents:
diff changeset
   150
                /* Create a new version descriptor,
02bb8761fcce Initial load
duke
parents:
diff changeset
   151
                 * it put itself in the known table.
02bb8761fcce Initial load
duke
parents:
diff changeset
   152
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
   153
                desc = new ObjectStreamClass(cl, superdesc,
02bb8761fcce Initial load
duke
parents:
diff changeset
   154
                                             serializable, externalizable);
02bb8761fcce Initial load
duke
parents:
diff changeset
   155
            }
2664
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   156
            // Must always call init.  See bug 4488137.  This code was
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   157
            // incorrectly changed to return immediately on a non-null
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   158
            // cache result.  That allowed threads to gain access to
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   159
            // unintialized instances.
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   160
            //
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   161
            // History: Note, the following init() call was originally within
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   162
            // the synchronization block, as it currently is now. Later, the
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   163
            // init() call was moved outside the synchronization block, and
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   164
            // the init() method used a private member variable lock, to
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   165
            // avoid performance problems. See bug 4165204. But that lead to
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   166
            // a deadlock situation, see bug 5104239. Hence, the init() method
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   167
            // has now been moved back into the synchronization block. The
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   168
            // right approach to solving these problems would be to rewrite
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   169
            // this class, based on the latest java.io.ObjectStreamClass.
a0a22a8f16bd 6372405: Server thread hangs when fragments don't complete because of connection abort
tbell
parents: 4
diff changeset
   170
            desc.init();
4
02bb8761fcce Initial load
duke
parents:
diff changeset
   171
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   172
        return desc;
02bb8761fcce Initial load
duke
parents:
diff changeset
   173
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   174
02bb8761fcce Initial load
duke
parents:
diff changeset
   175
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   176
     * The name of the class described by this descriptor.
02bb8761fcce Initial load
duke
parents:
diff changeset
   177
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   178
    public final String getName() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   179
        return name;
02bb8761fcce Initial load
duke
parents:
diff changeset
   180
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   181
02bb8761fcce Initial load
duke
parents:
diff changeset
   182
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   183
     * Return the serialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   184
     * The serialVersionUID defines a set of classes all with the same name
02bb8761fcce Initial load
duke
parents:
diff changeset
   185
     * that have evolved from a common root class and agree to be serialized
02bb8761fcce Initial load
duke
parents:
diff changeset
   186
     * and deserialized using a common format.
02bb8761fcce Initial load
duke
parents:
diff changeset
   187
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   188
    public static final long getSerialVersionUID( java.lang.Class clazz) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   189
        ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz );
02bb8761fcce Initial load
duke
parents:
diff changeset
   190
        if( theosc != null )
02bb8761fcce Initial load
duke
parents:
diff changeset
   191
        {
02bb8761fcce Initial load
duke
parents:
diff changeset
   192
                return theosc.getSerialVersionUID( );
02bb8761fcce Initial load
duke
parents:
diff changeset
   193
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   194
        return 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   195
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   196
02bb8761fcce Initial load
duke
parents:
diff changeset
   197
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   198
     * Return the serialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   199
     * The serialVersionUID defines a set of classes all with the same name
02bb8761fcce Initial load
duke
parents:
diff changeset
   200
     * that have evolved from a common root class and agree to be serialized
02bb8761fcce Initial load
duke
parents:
diff changeset
   201
     * and deserialized using a common format.
02bb8761fcce Initial load
duke
parents:
diff changeset
   202
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   203
    public final long getSerialVersionUID() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   204
        return suid;
02bb8761fcce Initial load
duke
parents:
diff changeset
   205
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   206
02bb8761fcce Initial load
duke
parents:
diff changeset
   207
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   208
     * Return the serialVersionUID string for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   209
     * The serialVersionUID defines a set of classes all with the same name
02bb8761fcce Initial load
duke
parents:
diff changeset
   210
     * that have evolved from a common root class and agree to be serialized
02bb8761fcce Initial load
duke
parents:
diff changeset
   211
     * and deserialized using a common format.
02bb8761fcce Initial load
duke
parents:
diff changeset
   212
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   213
    public final String getSerialVersionUIDStr() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   214
        if (suidStr == null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   215
            suidStr = Long.toHexString(suid).toUpperCase();
02bb8761fcce Initial load
duke
parents:
diff changeset
   216
        return suidStr;
02bb8761fcce Initial load
duke
parents:
diff changeset
   217
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   218
02bb8761fcce Initial load
duke
parents:
diff changeset
   219
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   220
     * Return the actual (computed) serialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   221
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   222
    public static final long getActualSerialVersionUID( java.lang.Class clazz )
02bb8761fcce Initial load
duke
parents:
diff changeset
   223
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   224
        ObjectStreamClass theosc = ObjectStreamClass.lookup( clazz );
02bb8761fcce Initial load
duke
parents:
diff changeset
   225
        if( theosc != null )
02bb8761fcce Initial load
duke
parents:
diff changeset
   226
        {
02bb8761fcce Initial load
duke
parents:
diff changeset
   227
                return theosc.getActualSerialVersionUID( );
02bb8761fcce Initial load
duke
parents:
diff changeset
   228
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   229
        return 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   230
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   231
02bb8761fcce Initial load
duke
parents:
diff changeset
   232
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   233
     * Return the actual (computed) serialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   234
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   235
    public final long getActualSerialVersionUID() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   236
        return actualSuid;
02bb8761fcce Initial load
duke
parents:
diff changeset
   237
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   238
02bb8761fcce Initial load
duke
parents:
diff changeset
   239
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   240
     * Return the actual (computed) serialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   241
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   242
    public final String getActualSerialVersionUIDStr() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   243
        if (actualSuidStr == null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   244
            actualSuidStr = Long.toHexString(actualSuid).toUpperCase();
02bb8761fcce Initial load
duke
parents:
diff changeset
   245
        return actualSuidStr;
02bb8761fcce Initial load
duke
parents:
diff changeset
   246
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   247
02bb8761fcce Initial load
duke
parents:
diff changeset
   248
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   249
     * Return the class in the local VM that this version is mapped to.
02bb8761fcce Initial load
duke
parents:
diff changeset
   250
     * Null is returned if there is no corresponding local class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   251
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   252
    public final Class forClass() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   253
        return ofClass;
02bb8761fcce Initial load
duke
parents:
diff changeset
   254
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   255
02bb8761fcce Initial load
duke
parents:
diff changeset
   256
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   257
     * Return an array of the fields of this serializable class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   258
     * @return an array containing an element for each persistent
02bb8761fcce Initial load
duke
parents:
diff changeset
   259
     * field of this class. Returns an array of length zero if
02bb8761fcce Initial load
duke
parents:
diff changeset
   260
     * there are no fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
   261
     * @since JDK1.2
02bb8761fcce Initial load
duke
parents:
diff changeset
   262
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   263
    public ObjectStreamField[] getFields() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   264
        // Return a copy so the caller can't change the fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
   265
        if (fields.length > 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   266
            ObjectStreamField[] dup = new ObjectStreamField[fields.length];
02bb8761fcce Initial load
duke
parents:
diff changeset
   267
            System.arraycopy(fields, 0, dup, 0, fields.length);
02bb8761fcce Initial load
duke
parents:
diff changeset
   268
            return dup;
02bb8761fcce Initial load
duke
parents:
diff changeset
   269
        } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   270
            return fields;
02bb8761fcce Initial load
duke
parents:
diff changeset
   271
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   272
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   273
02bb8761fcce Initial load
duke
parents:
diff changeset
   274
    public boolean hasField(ValueMember field)
02bb8761fcce Initial load
duke
parents:
diff changeset
   275
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   276
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   277
            for (int i = 0; i < fields.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   278
                if (fields[i].getName().equals(field.name)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   279
                    if (fields[i].getSignature().equals(
02bb8761fcce Initial load
duke
parents:
diff changeset
   280
                        ValueUtility.getSignature(field)))
02bb8761fcce Initial load
duke
parents:
diff changeset
   281
                        return true;
02bb8761fcce Initial load
duke
parents:
diff changeset
   282
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   283
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   284
        } catch (Exception exc) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   285
            // Ignore this; all we want to do is return false
02bb8761fcce Initial load
duke
parents:
diff changeset
   286
            // Note that ValueUtility.getSignature can throw checked exceptions.
02bb8761fcce Initial load
duke
parents:
diff changeset
   287
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   288
02bb8761fcce Initial load
duke
parents:
diff changeset
   289
        return false;
02bb8761fcce Initial load
duke
parents:
diff changeset
   290
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   291
02bb8761fcce Initial load
duke
parents:
diff changeset
   292
    /* Avoid unnecessary allocations. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   293
    final ObjectStreamField[] getFieldsNoCopy() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   294
        return fields;
02bb8761fcce Initial load
duke
parents:
diff changeset
   295
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   296
02bb8761fcce Initial load
duke
parents:
diff changeset
   297
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   298
     * Get the field of this class by name.
02bb8761fcce Initial load
duke
parents:
diff changeset
   299
     * @return The ObjectStreamField object of the named field or null if there
02bb8761fcce Initial load
duke
parents:
diff changeset
   300
     * is no such named field.
02bb8761fcce Initial load
duke
parents:
diff changeset
   301
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   302
    public final ObjectStreamField getField(String name) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   303
        /* Binary search of fields by name.
02bb8761fcce Initial load
duke
parents:
diff changeset
   304
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   305
        for (int i = fields.length-1; i >= 0; i--) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   306
            if (name.equals(fields[i].getName())) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   307
                return fields[i];
02bb8761fcce Initial load
duke
parents:
diff changeset
   308
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   309
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   310
        return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   311
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   312
02bb8761fcce Initial load
duke
parents:
diff changeset
   313
    public Serializable writeReplace(Serializable value) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   314
        if (writeReplaceObjectMethod != null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   315
            try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   316
                return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList);
02bb8761fcce Initial load
duke
parents:
diff changeset
   317
            } catch(Throwable t) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   318
                throw new RuntimeException(t);
02bb8761fcce Initial load
duke
parents:
diff changeset
   319
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   320
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   321
        else return value;
02bb8761fcce Initial load
duke
parents:
diff changeset
   322
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   323
02bb8761fcce Initial load
duke
parents:
diff changeset
   324
    public Object readResolve(Object value) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   325
        if (readResolveObjectMethod != null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   326
            try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   327
                return readResolveObjectMethod.invoke(value,noArgsList);
02bb8761fcce Initial load
duke
parents:
diff changeset
   328
            } catch(Throwable t) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   329
                throw new RuntimeException(t);
02bb8761fcce Initial load
duke
parents:
diff changeset
   330
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   331
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   332
        else return value;
02bb8761fcce Initial load
duke
parents:
diff changeset
   333
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   334
02bb8761fcce Initial load
duke
parents:
diff changeset
   335
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   336
     * Return a string describing this ObjectStreamClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
   337
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   338
    public final String toString() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   339
        StringBuffer sb = new StringBuffer();
02bb8761fcce Initial load
duke
parents:
diff changeset
   340
02bb8761fcce Initial load
duke
parents:
diff changeset
   341
        sb.append(name);
02bb8761fcce Initial load
duke
parents:
diff changeset
   342
        sb.append(": static final long serialVersionUID = ");
02bb8761fcce Initial load
duke
parents:
diff changeset
   343
        sb.append(Long.toString(suid));
02bb8761fcce Initial load
duke
parents:
diff changeset
   344
        sb.append("L;");
02bb8761fcce Initial load
duke
parents:
diff changeset
   345
        return sb.toString();
02bb8761fcce Initial load
duke
parents:
diff changeset
   346
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   347
02bb8761fcce Initial load
duke
parents:
diff changeset
   348
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   349
     * Create a new ObjectStreamClass from a loaded class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   350
     * Don't call this directly, call lookup instead.
02bb8761fcce Initial load
duke
parents:
diff changeset
   351
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   352
    private ObjectStreamClass(java.lang.Class cl, ObjectStreamClass superdesc,
02bb8761fcce Initial load
duke
parents:
diff changeset
   353
                              boolean serial, boolean extern)
02bb8761fcce Initial load
duke
parents:
diff changeset
   354
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   355
        ofClass = cl;           /* created from this class */
02bb8761fcce Initial load
duke
parents:
diff changeset
   356
02bb8761fcce Initial load
duke
parents:
diff changeset
   357
        if (Proxy.isProxyClass(cl)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   358
            forProxyClass = true;
02bb8761fcce Initial load
duke
parents:
diff changeset
   359
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   360
02bb8761fcce Initial load
duke
parents:
diff changeset
   361
        name = cl.getName();
02bb8761fcce Initial load
duke
parents:
diff changeset
   362
        superclass = superdesc;
02bb8761fcce Initial load
duke
parents:
diff changeset
   363
        serializable = serial;
02bb8761fcce Initial load
duke
parents:
diff changeset
   364
        if (!forProxyClass) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   365
            // proxy classes are never externalizable
02bb8761fcce Initial load
duke
parents:
diff changeset
   366
            externalizable = extern;
02bb8761fcce Initial load
duke
parents:
diff changeset
   367
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   368
02bb8761fcce Initial load
duke
parents:
diff changeset
   369
        /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   370
         * Enter this class in the table of known descriptors.
02bb8761fcce Initial load
duke
parents:
diff changeset
   371
         * Otherwise, when the fields are read it may recurse
02bb8761fcce Initial load
duke
parents:
diff changeset
   372
         * trying to find the descriptor for itself.
02bb8761fcce Initial load
duke
parents:
diff changeset
   373
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   374
        insertDescriptorFor(this);
02bb8761fcce Initial load
duke
parents:
diff changeset
   375
02bb8761fcce Initial load
duke
parents:
diff changeset
   376
        /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   377
         * The remainder of initialization occurs in init(), which is called
02bb8761fcce Initial load
duke
parents:
diff changeset
   378
         * after the lock on the global class descriptor table has been
02bb8761fcce Initial load
duke
parents:
diff changeset
   379
         * released.
02bb8761fcce Initial load
duke
parents:
diff changeset
   380
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   381
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   382
02bb8761fcce Initial load
duke
parents:
diff changeset
   383
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   384
     * Initialize class descriptor.  This method is only invoked on class
02bb8761fcce Initial load
duke
parents:
diff changeset
   385
     * descriptors created via calls to lookupInternal().  This method is kept
02bb8761fcce Initial load
duke
parents:
diff changeset
   386
     * separate from the ObjectStreamClass constructor so that lookupInternal
02bb8761fcce Initial load
duke
parents:
diff changeset
   387
     * does not have to hold onto a global class descriptor table lock while the
02bb8761fcce Initial load
duke
parents:
diff changeset
   388
     * class descriptor is being initialized (see bug 4165204).
02bb8761fcce Initial load
duke
parents:
diff changeset
   389
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   390
02bb8761fcce Initial load
duke
parents:
diff changeset
   391
02bb8761fcce Initial load
duke
parents:
diff changeset
   392
    private void init() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   393
      synchronized (lock) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   394
02bb8761fcce Initial load
duke
parents:
diff changeset
   395
        // See description at definition of initialized.
02bb8761fcce Initial load
duke
parents:
diff changeset
   396
        if (initialized)
02bb8761fcce Initial load
duke
parents:
diff changeset
   397
            return;
02bb8761fcce Initial load
duke
parents:
diff changeset
   398
02bb8761fcce Initial load
duke
parents:
diff changeset
   399
        final Class cl = ofClass;
02bb8761fcce Initial load
duke
parents:
diff changeset
   400
02bb8761fcce Initial load
duke
parents:
diff changeset
   401
        if (!serializable ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   402
            externalizable ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   403
            forProxyClass ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   404
            name.equals("java.lang.String")) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   405
            fields = NO_FIELDS;
02bb8761fcce Initial load
duke
parents:
diff changeset
   406
        } else if (serializable) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   407
            /* Ask for permission to override field access checks.
02bb8761fcce Initial load
duke
parents:
diff changeset
   408
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
   409
            AccessController.doPrivileged(new PrivilegedAction() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   410
                public Object run() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   411
                /* Fill in the list of persistent fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
   412
                 * If it is declared, use the declared serialPersistentFields.
02bb8761fcce Initial load
duke
parents:
diff changeset
   413
                 * Otherwise, extract the fields from the class itself.
02bb8761fcce Initial load
duke
parents:
diff changeset
   414
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
   415
                try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   416
                    Field pf = cl.getDeclaredField("serialPersistentFields");
02bb8761fcce Initial load
duke
parents:
diff changeset
   417
                    // serial bug 7; the serialPersistentFields were not
02bb8761fcce Initial load
duke
parents:
diff changeset
   418
                    // being read and stored as Accessible bit was not set
02bb8761fcce Initial load
duke
parents:
diff changeset
   419
                    pf.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   420
                    // serial bug 7; need to find if the field is of type
02bb8761fcce Initial load
duke
parents:
diff changeset
   421
                    // java.io.ObjectStreamField
02bb8761fcce Initial load
duke
parents:
diff changeset
   422
                    java.io.ObjectStreamField[] f =
02bb8761fcce Initial load
duke
parents:
diff changeset
   423
                           (java.io.ObjectStreamField[])pf.get(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   424
                    int mods = pf.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
   425
                    if ((Modifier.isPrivate(mods)) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   426
                        (Modifier.isStatic(mods)) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   427
                        (Modifier.isFinal(mods)))
02bb8761fcce Initial load
duke
parents:
diff changeset
   428
                    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   429
                        fields = (ObjectStreamField[])translateFields((Object[])pf.get(cl));
02bb8761fcce Initial load
duke
parents:
diff changeset
   430
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   431
                } catch (NoSuchFieldException e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   432
                    fields = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   433
                } catch (IllegalAccessException e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   434
                    fields = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   435
                } catch (IllegalArgumentException e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   436
                    fields = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   437
                } catch (ClassCastException e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   438
                    /* Thrown if a field serialPersistentField exists
02bb8761fcce Initial load
duke
parents:
diff changeset
   439
                     * but it is not of type ObjectStreamField.
02bb8761fcce Initial load
duke
parents:
diff changeset
   440
                     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   441
                    fields = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   442
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   443
02bb8761fcce Initial load
duke
parents:
diff changeset
   444
02bb8761fcce Initial load
duke
parents:
diff changeset
   445
                if (fields == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   446
                    /* Get all of the declared fields for this
02bb8761fcce Initial load
duke
parents:
diff changeset
   447
                     * Class. setAccessible on all fields so they
02bb8761fcce Initial load
duke
parents:
diff changeset
   448
                     * can be accessed later.  Create a temporary
02bb8761fcce Initial load
duke
parents:
diff changeset
   449
                     * ObjectStreamField array to hold each
02bb8761fcce Initial load
duke
parents:
diff changeset
   450
                     * non-static, non-transient field. Then copy the
02bb8761fcce Initial load
duke
parents:
diff changeset
   451
                     * temporary array into an array of the correct
02bb8761fcce Initial load
duke
parents:
diff changeset
   452
                     * size once the number of fields is known.
02bb8761fcce Initial load
duke
parents:
diff changeset
   453
                     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   454
                    Field[] actualfields = cl.getDeclaredFields();
02bb8761fcce Initial load
duke
parents:
diff changeset
   455
02bb8761fcce Initial load
duke
parents:
diff changeset
   456
                    int numFields = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   457
                    ObjectStreamField[] tempFields =
02bb8761fcce Initial load
duke
parents:
diff changeset
   458
                        new ObjectStreamField[actualfields.length];
02bb8761fcce Initial load
duke
parents:
diff changeset
   459
                    for (int i = 0; i < actualfields.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   460
                        Field fld = actualfields[i] ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   461
                        int modifiers = fld.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
   462
                        if (!Modifier.isStatic(modifiers) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   463
                            !Modifier.isTransient(modifiers)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   464
                            fld.setAccessible(true) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   465
                            tempFields[numFields++] = new ObjectStreamField(fld);
02bb8761fcce Initial load
duke
parents:
diff changeset
   466
                        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   467
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   468
02bb8761fcce Initial load
duke
parents:
diff changeset
   469
                    fields = new ObjectStreamField[numFields];
02bb8761fcce Initial load
duke
parents:
diff changeset
   470
                    System.arraycopy(tempFields, 0, fields, 0, numFields);
02bb8761fcce Initial load
duke
parents:
diff changeset
   471
02bb8761fcce Initial load
duke
parents:
diff changeset
   472
                } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   473
                    // For each declared persistent field, look for an actual
02bb8761fcce Initial load
duke
parents:
diff changeset
   474
                    // reflected Field. If there is one, make sure it's the correct
02bb8761fcce Initial load
duke
parents:
diff changeset
   475
                    // type and cache it in the ObjectStreamClass for that field.
02bb8761fcce Initial load
duke
parents:
diff changeset
   476
                    for (int j = fields.length-1; j >= 0; j--) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   477
                        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   478
                            Field reflField = cl.getDeclaredField(fields[j].getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
   479
                            if (fields[j].getType() == reflField.getType()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   480
                                reflField.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   481
                                fields[j].setField(reflField);
02bb8761fcce Initial load
duke
parents:
diff changeset
   482
                            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   483
                        } catch (NoSuchFieldException e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   484
                            // Nothing to do
02bb8761fcce Initial load
duke
parents:
diff changeset
   485
                        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   486
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   487
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   488
                return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   489
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   490
            });
02bb8761fcce Initial load
duke
parents:
diff changeset
   491
02bb8761fcce Initial load
duke
parents:
diff changeset
   492
            if (fields.length > 1)
02bb8761fcce Initial load
duke
parents:
diff changeset
   493
                Arrays.sort(fields);
02bb8761fcce Initial load
duke
parents:
diff changeset
   494
02bb8761fcce Initial load
duke
parents:
diff changeset
   495
            /* Set up field data for use while writing using the API api. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   496
            computeFieldInfo();
02bb8761fcce Initial load
duke
parents:
diff changeset
   497
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   498
02bb8761fcce Initial load
duke
parents:
diff changeset
   499
        /* Get the serialVersionUID from the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   500
         * It uses the access override mechanism so make sure
02bb8761fcce Initial load
duke
parents:
diff changeset
   501
         * the field objects is only used here.
02bb8761fcce Initial load
duke
parents:
diff changeset
   502
         *
02bb8761fcce Initial load
duke
parents:
diff changeset
   503
         * NonSerializable classes have a serialVerisonUID of 0L.
02bb8761fcce Initial load
duke
parents:
diff changeset
   504
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   505
         if (isNonSerializable()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   506
             suid = 0L;
02bb8761fcce Initial load
duke
parents:
diff changeset
   507
         } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   508
             // Lookup special Serializable members using reflection.
02bb8761fcce Initial load
duke
parents:
diff changeset
   509
             AccessController.doPrivileged(new PrivilegedAction() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   510
                public Object run() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   511
                if (forProxyClass) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   512
                    // proxy classes always have serialVersionUID of 0L
02bb8761fcce Initial load
duke
parents:
diff changeset
   513
                    suid = 0L;
02bb8761fcce Initial load
duke
parents:
diff changeset
   514
                } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   515
                    try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   516
                        final Field f = cl.getDeclaredField("serialVersionUID");
02bb8761fcce Initial load
duke
parents:
diff changeset
   517
                        int mods = f.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
   518
                        // SerialBug 5:  static final SUID should be read
02bb8761fcce Initial load
duke
parents:
diff changeset
   519
                        if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   520
                            f.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   521
                            suid = f.getLong(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   522
                            // SerialBug 2: should be computed after writeObject
02bb8761fcce Initial load
duke
parents:
diff changeset
   523
                            // actualSuid = computeStructuralUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   524
                        } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   525
                            suid = _computeSerialVersionUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   526
                            // SerialBug 2: should be computed after writeObject
02bb8761fcce Initial load
duke
parents:
diff changeset
   527
                            // actualSuid = computeStructuralUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   528
                        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   529
                    } catch (NoSuchFieldException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   530
                        suid = _computeSerialVersionUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   531
                        // SerialBug 2: should be computed after writeObject
02bb8761fcce Initial load
duke
parents:
diff changeset
   532
                        // actualSuid = computeStructuralUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   533
                    } catch (IllegalAccessException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   534
                        suid = _computeSerialVersionUID(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   535
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   536
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   537
02bb8761fcce Initial load
duke
parents:
diff changeset
   538
                writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
02bb8761fcce Initial load
duke
parents:
diff changeset
   539
                    "writeReplace", noTypesList, Object.class);
02bb8761fcce Initial load
duke
parents:
diff changeset
   540
02bb8761fcce Initial load
duke
parents:
diff changeset
   541
                readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
02bb8761fcce Initial load
duke
parents:
diff changeset
   542
                    "readResolve", noTypesList, Object.class);
02bb8761fcce Initial load
duke
parents:
diff changeset
   543
02bb8761fcce Initial load
duke
parents:
diff changeset
   544
                if (externalizable)
02bb8761fcce Initial load
duke
parents:
diff changeset
   545
                    cons = getExternalizableConstructor(cl) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   546
                else
02bb8761fcce Initial load
duke
parents:
diff changeset
   547
                    cons = getSerializableConstructor(cl) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   548
02bb8761fcce Initial load
duke
parents:
diff changeset
   549
                if (serializable && !forProxyClass) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   550
                    /* Look for the writeObject method
02bb8761fcce Initial load
duke
parents:
diff changeset
   551
                     * Set the accessible flag on it here. ObjectOutputStream
02bb8761fcce Initial load
duke
parents:
diff changeset
   552
                     * will call it as necessary.
02bb8761fcce Initial load
duke
parents:
diff changeset
   553
                     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   554
                    writeObjectMethod = getPrivateMethod( cl, "writeObject",
02bb8761fcce Initial load
duke
parents:
diff changeset
   555
                        new Class[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   556
                    readObjectMethod = getPrivateMethod( cl, "readObject",
02bb8761fcce Initial load
duke
parents:
diff changeset
   557
                        new Class[] { java.io.ObjectInputStream.class }, Void.TYPE ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   558
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   559
                return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   560
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   561
          });
02bb8761fcce Initial load
duke
parents:
diff changeset
   562
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   563
02bb8761fcce Initial load
duke
parents:
diff changeset
   564
        // This call depends on a lot of information computed above!
02bb8761fcce Initial load
duke
parents:
diff changeset
   565
        actualSuid = ObjectStreamClass.computeStructuralUID(this, cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   566
02bb8761fcce Initial load
duke
parents:
diff changeset
   567
        // If we have a write object method, precompute the
02bb8761fcce Initial load
duke
parents:
diff changeset
   568
        // RMI-IIOP stream format version 2 optional data
02bb8761fcce Initial load
duke
parents:
diff changeset
   569
        // repository ID.
02bb8761fcce Initial load
duke
parents:
diff changeset
   570
        if (hasWriteObject())
02bb8761fcce Initial load
duke
parents:
diff changeset
   571
            rmiiiopOptionalDataRepId = computeRMIIIOPOptionalDataRepId();
02bb8761fcce Initial load
duke
parents:
diff changeset
   572
02bb8761fcce Initial load
duke
parents:
diff changeset
   573
        // This must be done last.
02bb8761fcce Initial load
duke
parents:
diff changeset
   574
        initialized = true;
02bb8761fcce Initial load
duke
parents:
diff changeset
   575
      }
02bb8761fcce Initial load
duke
parents:
diff changeset
   576
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   577
02bb8761fcce Initial load
duke
parents:
diff changeset
   578
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   579
     * Returns non-static private method with given signature defined by given
02bb8761fcce Initial load
duke
parents:
diff changeset
   580
     * class, or null if none found.  Access checks are disabled on the
02bb8761fcce Initial load
duke
parents:
diff changeset
   581
     * returned method (if any).
02bb8761fcce Initial load
duke
parents:
diff changeset
   582
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   583
    private static Method getPrivateMethod(Class cl, String name,
02bb8761fcce Initial load
duke
parents:
diff changeset
   584
                                           Class[] argTypes,
02bb8761fcce Initial load
duke
parents:
diff changeset
   585
                                           Class returnType)
02bb8761fcce Initial load
duke
parents:
diff changeset
   586
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   587
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   588
            Method meth = cl.getDeclaredMethod(name, argTypes);
02bb8761fcce Initial load
duke
parents:
diff changeset
   589
            meth.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   590
            int mods = meth.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
   591
            return ((meth.getReturnType() == returnType) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   592
                    ((mods & Modifier.STATIC) == 0) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   593
                    ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   594
        } catch (NoSuchMethodException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   595
            return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   596
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   597
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   598
02bb8761fcce Initial load
duke
parents:
diff changeset
   599
    // Specific to RMI-IIOP
02bb8761fcce Initial load
duke
parents:
diff changeset
   600
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   601
     * Java to IDL ptc-02-01-12 1.5.1
02bb8761fcce Initial load
duke
parents:
diff changeset
   602
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   603
     * "The rep_id string passed to the start_value method must be
02bb8761fcce Initial load
duke
parents:
diff changeset
   604
     * 'RMI:org.omg.custom.class:hashcode:suid' where class is the
02bb8761fcce Initial load
duke
parents:
diff changeset
   605
     * fully-qualified name of the class whose writeObject method
02bb8761fcce Initial load
duke
parents:
diff changeset
   606
     * is being invoked and hashcode and suid are the class's hashcode
02bb8761fcce Initial load
duke
parents:
diff changeset
   607
     * and SUID."
02bb8761fcce Initial load
duke
parents:
diff changeset
   608
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   609
    private String computeRMIIIOPOptionalDataRepId() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   610
02bb8761fcce Initial load
duke
parents:
diff changeset
   611
        StringBuffer sbuf = new StringBuffer("RMI:org.omg.custom.");
02bb8761fcce Initial load
duke
parents:
diff changeset
   612
        sbuf.append(RepositoryId.convertToISOLatin1(this.getName()));
02bb8761fcce Initial load
duke
parents:
diff changeset
   613
        sbuf.append(':');
02bb8761fcce Initial load
duke
parents:
diff changeset
   614
        sbuf.append(this.getActualSerialVersionUIDStr());
02bb8761fcce Initial load
duke
parents:
diff changeset
   615
        sbuf.append(':');
02bb8761fcce Initial load
duke
parents:
diff changeset
   616
        sbuf.append(this.getSerialVersionUIDStr());
02bb8761fcce Initial load
duke
parents:
diff changeset
   617
02bb8761fcce Initial load
duke
parents:
diff changeset
   618
        return sbuf.toString();
02bb8761fcce Initial load
duke
parents:
diff changeset
   619
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   620
02bb8761fcce Initial load
duke
parents:
diff changeset
   621
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   622
     * This will return null if there is no writeObject method.
02bb8761fcce Initial load
duke
parents:
diff changeset
   623
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   624
    public final String getRMIIIOPOptionalDataRepId() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   625
        return rmiiiopOptionalDataRepId;
02bb8761fcce Initial load
duke
parents:
diff changeset
   626
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   627
02bb8761fcce Initial load
duke
parents:
diff changeset
   628
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   629
     * Create an empty ObjectStreamClass for a class about to be read.
02bb8761fcce Initial load
duke
parents:
diff changeset
   630
     * This is separate from read so ObjectInputStream can assign the
02bb8761fcce Initial load
duke
parents:
diff changeset
   631
     * wire handle early, before any nested ObjectStreamClass might
02bb8761fcce Initial load
duke
parents:
diff changeset
   632
     * be read.
02bb8761fcce Initial load
duke
parents:
diff changeset
   633
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   634
    ObjectStreamClass(String n, long s) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   635
        name = n;
02bb8761fcce Initial load
duke
parents:
diff changeset
   636
        suid = s;
02bb8761fcce Initial load
duke
parents:
diff changeset
   637
        superclass = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   638
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   639
02bb8761fcce Initial load
duke
parents:
diff changeset
   640
    private static Object[] translateFields(Object objs[])
02bb8761fcce Initial load
duke
parents:
diff changeset
   641
        throws NoSuchFieldException {
02bb8761fcce Initial load
duke
parents:
diff changeset
   642
        try{
02bb8761fcce Initial load
duke
parents:
diff changeset
   643
            java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField[])objs;
02bb8761fcce Initial load
duke
parents:
diff changeset
   644
            Object translation[] = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   645
02bb8761fcce Initial load
duke
parents:
diff changeset
   646
            if (translatedFields == null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   647
                translatedFields = new Hashtable();
02bb8761fcce Initial load
duke
parents:
diff changeset
   648
02bb8761fcce Initial load
duke
parents:
diff changeset
   649
            translation = (Object[])translatedFields.get(fields);
02bb8761fcce Initial load
duke
parents:
diff changeset
   650
02bb8761fcce Initial load
duke
parents:
diff changeset
   651
            if (translation != null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   652
                return translation;
02bb8761fcce Initial load
duke
parents:
diff changeset
   653
            else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   654
                Class osfClass = Class.forName("com.sun.corba.se.impl.io.ObjectStreamField");
02bb8761fcce Initial load
duke
parents:
diff changeset
   655
                translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length);
02bb8761fcce Initial load
duke
parents:
diff changeset
   656
                Object arg[] = new Object[2];
02bb8761fcce Initial load
duke
parents:
diff changeset
   657
                Class types[] = {String.class, Class.class};
02bb8761fcce Initial load
duke
parents:
diff changeset
   658
                Constructor constructor = osfClass.getDeclaredConstructor(types);
02bb8761fcce Initial load
duke
parents:
diff changeset
   659
                for (int i = fields.length -1; i >= 0; i--){
02bb8761fcce Initial load
duke
parents:
diff changeset
   660
                    arg[0] = fields[i].getName();
02bb8761fcce Initial load
duke
parents:
diff changeset
   661
                    arg[1] = fields[i].getType();
02bb8761fcce Initial load
duke
parents:
diff changeset
   662
02bb8761fcce Initial load
duke
parents:
diff changeset
   663
                    translation[i] = constructor.newInstance(arg);
02bb8761fcce Initial load
duke
parents:
diff changeset
   664
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   665
                translatedFields.put(fields, translation);
02bb8761fcce Initial load
duke
parents:
diff changeset
   666
02bb8761fcce Initial load
duke
parents:
diff changeset
   667
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   668
02bb8761fcce Initial load
duke
parents:
diff changeset
   669
            return (Object[])translation;
02bb8761fcce Initial load
duke
parents:
diff changeset
   670
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   671
        catch(Throwable t){
02bb8761fcce Initial load
duke
parents:
diff changeset
   672
            NoSuchFieldException nsfe = new NoSuchFieldException();
02bb8761fcce Initial load
duke
parents:
diff changeset
   673
            nsfe.initCause( t ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   674
            throw nsfe ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   675
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   676
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   677
02bb8761fcce Initial load
duke
parents:
diff changeset
   678
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   679
     * Set the class this version descriptor matches.
02bb8761fcce Initial load
duke
parents:
diff changeset
   680
     * The base class name and serializable hash must match.
02bb8761fcce Initial load
duke
parents:
diff changeset
   681
     * Fill in the reflected Fields that will be used
02bb8761fcce Initial load
duke
parents:
diff changeset
   682
     * for reading.
02bb8761fcce Initial load
duke
parents:
diff changeset
   683
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   684
    final void setClass(Class cl) throws InvalidClassException {
02bb8761fcce Initial load
duke
parents:
diff changeset
   685
02bb8761fcce Initial load
duke
parents:
diff changeset
   686
        if (cl == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   687
            localClassDesc = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   688
            ofClass = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   689
            computeFieldInfo();
02bb8761fcce Initial load
duke
parents:
diff changeset
   690
            return;
02bb8761fcce Initial load
duke
parents:
diff changeset
   691
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   692
02bb8761fcce Initial load
duke
parents:
diff changeset
   693
        localClassDesc = lookupInternal(cl);
02bb8761fcce Initial load
duke
parents:
diff changeset
   694
        if (localClassDesc == null)
02bb8761fcce Initial load
duke
parents:
diff changeset
   695
            // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
   696
            throw new InvalidClassException(cl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   697
                                            "Local class not compatible");
02bb8761fcce Initial load
duke
parents:
diff changeset
   698
        if (suid != localClassDesc.suid) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   699
02bb8761fcce Initial load
duke
parents:
diff changeset
   700
            /* Check for exceptional cases that allow mismatched suid. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   701
02bb8761fcce Initial load
duke
parents:
diff changeset
   702
            /* Allow adding Serializable or Externalizable
02bb8761fcce Initial load
duke
parents:
diff changeset
   703
             * to a later release of the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
   704
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
   705
            boolean addedSerialOrExtern =
02bb8761fcce Initial load
duke
parents:
diff changeset
   706
                isNonSerializable() || localClassDesc.isNonSerializable();
02bb8761fcce Initial load
duke
parents:
diff changeset
   707
02bb8761fcce Initial load
duke
parents:
diff changeset
   708
            /* Disregard the serialVersionUID of an array
02bb8761fcce Initial load
duke
parents:
diff changeset
   709
             * when name and cl.Name differ. If resolveClass() returns
02bb8761fcce Initial load
duke
parents:
diff changeset
   710
             * an array with a different package name,
02bb8761fcce Initial load
duke
parents:
diff changeset
   711
             * the serialVersionUIDs will not match since the fully
02bb8761fcce Initial load
duke
parents:
diff changeset
   712
             * qualified array class is used in the
02bb8761fcce Initial load
duke
parents:
diff changeset
   713
             * computation of the array's serialVersionUID. There is
02bb8761fcce Initial load
duke
parents:
diff changeset
   714
             * no way to set a permanent serialVersionUID for an array type.
02bb8761fcce Initial load
duke
parents:
diff changeset
   715
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
   716
02bb8761fcce Initial load
duke
parents:
diff changeset
   717
            boolean arraySUID = (cl.isArray() && ! cl.getName().equals(name));
02bb8761fcce Initial load
duke
parents:
diff changeset
   718
02bb8761fcce Initial load
duke
parents:
diff changeset
   719
            if (! arraySUID && ! addedSerialOrExtern ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   720
                // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
   721
                throw new InvalidClassException(cl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   722
                                                "Local class not compatible:" +
02bb8761fcce Initial load
duke
parents:
diff changeset
   723
                                                " stream classdesc serialVersionUID=" + suid +
02bb8761fcce Initial load
duke
parents:
diff changeset
   724
                                                " local class serialVersionUID=" + localClassDesc.suid);
02bb8761fcce Initial load
duke
parents:
diff changeset
   725
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   726
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   727
02bb8761fcce Initial load
duke
parents:
diff changeset
   728
        /* compare the class names, stripping off package names. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   729
        if (! compareClassNames(name, cl.getName(), '.'))
02bb8761fcce Initial load
duke
parents:
diff changeset
   730
            // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
   731
            throw new InvalidClassException(cl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   732
                         "Incompatible local class name. " +
02bb8761fcce Initial load
duke
parents:
diff changeset
   733
                         "Expected class name compatible with " +
02bb8761fcce Initial load
duke
parents:
diff changeset
   734
                         name);
02bb8761fcce Initial load
duke
parents:
diff changeset
   735
02bb8761fcce Initial load
duke
parents:
diff changeset
   736
        /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   737
         * Test that both implement either serializable or externalizable.
02bb8761fcce Initial load
duke
parents:
diff changeset
   738
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   739
02bb8761fcce Initial load
duke
parents:
diff changeset
   740
        // The next check is more generic, since it covers the
02bb8761fcce Initial load
duke
parents:
diff changeset
   741
        // Proxy case, the JDK 1.3 serialization code has
02bb8761fcce Initial load
duke
parents:
diff changeset
   742
        // both checks
02bb8761fcce Initial load
duke
parents:
diff changeset
   743
        //if ((serializable && localClassDesc.externalizable) ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   744
        //    (externalizable && localClassDesc.serializable))
02bb8761fcce Initial load
duke
parents:
diff changeset
   745
        //    throw new InvalidClassException(localCl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   746
        //            "Serializable is incompatible with Externalizable");
02bb8761fcce Initial load
duke
parents:
diff changeset
   747
02bb8761fcce Initial load
duke
parents:
diff changeset
   748
        if ((serializable != localClassDesc.serializable) ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   749
            (externalizable != localClassDesc.externalizable) ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   750
            (!serializable && !externalizable))
02bb8761fcce Initial load
duke
parents:
diff changeset
   751
02bb8761fcce Initial load
duke
parents:
diff changeset
   752
            // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
   753
            throw new InvalidClassException(cl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   754
                                            "Serialization incompatible with Externalization");
02bb8761fcce Initial load
duke
parents:
diff changeset
   755
02bb8761fcce Initial load
duke
parents:
diff changeset
   756
        /* Set up the reflected Fields in the class where the value of each
02bb8761fcce Initial load
duke
parents:
diff changeset
   757
         * field in this descriptor should be stored.
02bb8761fcce Initial load
duke
parents:
diff changeset
   758
         * Each field in this ObjectStreamClass (the source) is located (by
02bb8761fcce Initial load
duke
parents:
diff changeset
   759
         * name) in the ObjectStreamClass of the class(the destination).
02bb8761fcce Initial load
duke
parents:
diff changeset
   760
         * In the usual (non-versioned case) the field is in both
02bb8761fcce Initial load
duke
parents:
diff changeset
   761
         * descriptors and the types match, so the reflected Field is copied.
02bb8761fcce Initial load
duke
parents:
diff changeset
   762
         * If the type does not match, a InvalidClass exception is thrown.
02bb8761fcce Initial load
duke
parents:
diff changeset
   763
         * If the field is not present in the class, the reflected Field
02bb8761fcce Initial load
duke
parents:
diff changeset
   764
         * remains null so the field will be read but discarded.
02bb8761fcce Initial load
duke
parents:
diff changeset
   765
         * If extra fields are present in the class they are ignored. Their
02bb8761fcce Initial load
duke
parents:
diff changeset
   766
         * values will be set to the default value by the object allocator.
02bb8761fcce Initial load
duke
parents:
diff changeset
   767
         * Both the src and dest field list are sorted by type and name.
02bb8761fcce Initial load
duke
parents:
diff changeset
   768
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   769
02bb8761fcce Initial load
duke
parents:
diff changeset
   770
        ObjectStreamField[] destfield =
02bb8761fcce Initial load
duke
parents:
diff changeset
   771
            (ObjectStreamField[])localClassDesc.fields;
02bb8761fcce Initial load
duke
parents:
diff changeset
   772
        ObjectStreamField[] srcfield =
02bb8761fcce Initial load
duke
parents:
diff changeset
   773
            (ObjectStreamField[])fields;
02bb8761fcce Initial load
duke
parents:
diff changeset
   774
02bb8761fcce Initial load
duke
parents:
diff changeset
   775
        int j = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   776
    nextsrc:
02bb8761fcce Initial load
duke
parents:
diff changeset
   777
        for (int i = 0; i < srcfield.length; i++ ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   778
            /* Find this field in the dest*/
02bb8761fcce Initial load
duke
parents:
diff changeset
   779
            for (int k = j; k < destfield.length; k++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   780
                if (srcfield[i].getName().equals(destfield[k].getName())) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   781
                    /* found match */
02bb8761fcce Initial load
duke
parents:
diff changeset
   782
                    if (srcfield[i].isPrimitive() &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   783
                        !srcfield[i].typeEquals(destfield[k])) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   784
                        // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
   785
                        throw new InvalidClassException(cl.getName(),
02bb8761fcce Initial load
duke
parents:
diff changeset
   786
                                                        "The type of field " +
02bb8761fcce Initial load
duke
parents:
diff changeset
   787
                                                        srcfield[i].getName() +
02bb8761fcce Initial load
duke
parents:
diff changeset
   788
                                                        " of class " + name +
02bb8761fcce Initial load
duke
parents:
diff changeset
   789
                                                        " is incompatible.");
02bb8761fcce Initial load
duke
parents:
diff changeset
   790
                    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   791
02bb8761fcce Initial load
duke
parents:
diff changeset
   792
                    /* Skip over any fields in the dest that are not in the src */
02bb8761fcce Initial load
duke
parents:
diff changeset
   793
                    j = k;
02bb8761fcce Initial load
duke
parents:
diff changeset
   794
02bb8761fcce Initial load
duke
parents:
diff changeset
   795
                    srcfield[i].setField(destfield[j].getField());
02bb8761fcce Initial load
duke
parents:
diff changeset
   796
                    // go on to the next source field
02bb8761fcce Initial load
duke
parents:
diff changeset
   797
                    continue nextsrc;
02bb8761fcce Initial load
duke
parents:
diff changeset
   798
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
   799
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   800
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   801
02bb8761fcce Initial load
duke
parents:
diff changeset
   802
        /* Set up field data for use while reading from the input stream. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   803
        computeFieldInfo();
02bb8761fcce Initial load
duke
parents:
diff changeset
   804
02bb8761fcce Initial load
duke
parents:
diff changeset
   805
        /* Remember the class this represents */
02bb8761fcce Initial load
duke
parents:
diff changeset
   806
        ofClass = cl;
02bb8761fcce Initial load
duke
parents:
diff changeset
   807
02bb8761fcce Initial load
duke
parents:
diff changeset
   808
        /* get the cache of these methods from the local class
02bb8761fcce Initial load
duke
parents:
diff changeset
   809
         * implementation.
02bb8761fcce Initial load
duke
parents:
diff changeset
   810
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
   811
        readObjectMethod = localClassDesc.readObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
   812
        readResolveObjectMethod = localClassDesc.readResolveObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
   813
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   814
02bb8761fcce Initial load
duke
parents:
diff changeset
   815
    /* Compare the base class names of streamName and localName.
02bb8761fcce Initial load
duke
parents:
diff changeset
   816
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   817
     * @return  Return true iff the base class name compare.
02bb8761fcce Initial load
duke
parents:
diff changeset
   818
     * @parameter streamName    Fully qualified class name.
02bb8761fcce Initial load
duke
parents:
diff changeset
   819
     * @parameter localName     Fully qualified class name.
02bb8761fcce Initial load
duke
parents:
diff changeset
   820
     * @parameter pkgSeparator  class names use either '.' or '/'.
02bb8761fcce Initial load
duke
parents:
diff changeset
   821
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   822
     * Only compare base class name to allow package renaming.
02bb8761fcce Initial load
duke
parents:
diff changeset
   823
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   824
    static boolean compareClassNames(String streamName,
02bb8761fcce Initial load
duke
parents:
diff changeset
   825
                                     String localName,
02bb8761fcce Initial load
duke
parents:
diff changeset
   826
                                     char pkgSeparator) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   827
        /* compare the class names, stripping off package names. */
02bb8761fcce Initial load
duke
parents:
diff changeset
   828
        int streamNameIndex = streamName.lastIndexOf(pkgSeparator);
02bb8761fcce Initial load
duke
parents:
diff changeset
   829
        if (streamNameIndex < 0)
02bb8761fcce Initial load
duke
parents:
diff changeset
   830
            streamNameIndex = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   831
02bb8761fcce Initial load
duke
parents:
diff changeset
   832
        int localNameIndex = localName.lastIndexOf(pkgSeparator);
02bb8761fcce Initial load
duke
parents:
diff changeset
   833
        if (localNameIndex < 0)
02bb8761fcce Initial load
duke
parents:
diff changeset
   834
            localNameIndex = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
   835
02bb8761fcce Initial load
duke
parents:
diff changeset
   836
        return streamName.regionMatches(false, streamNameIndex,
02bb8761fcce Initial load
duke
parents:
diff changeset
   837
                                        localName, localNameIndex,
02bb8761fcce Initial load
duke
parents:
diff changeset
   838
                                        streamName.length() - streamNameIndex);
02bb8761fcce Initial load
duke
parents:
diff changeset
   839
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   840
02bb8761fcce Initial load
duke
parents:
diff changeset
   841
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   842
     * Compare the types of two class descriptors.
02bb8761fcce Initial load
duke
parents:
diff changeset
   843
     * They match if they have the same class name and suid
02bb8761fcce Initial load
duke
parents:
diff changeset
   844
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   845
    final boolean typeEquals(ObjectStreamClass other) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   846
        return (suid == other.suid) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   847
            compareClassNames(name, other.name, '.');
02bb8761fcce Initial load
duke
parents:
diff changeset
   848
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   849
02bb8761fcce Initial load
duke
parents:
diff changeset
   850
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   851
     * Return the superclass descriptor of this descriptor.
02bb8761fcce Initial load
duke
parents:
diff changeset
   852
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   853
    final void setSuperclass(ObjectStreamClass s) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   854
        superclass = s;
02bb8761fcce Initial load
duke
parents:
diff changeset
   855
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   856
02bb8761fcce Initial load
duke
parents:
diff changeset
   857
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   858
     * Return the superclass descriptor of this descriptor.
02bb8761fcce Initial load
duke
parents:
diff changeset
   859
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   860
    final ObjectStreamClass getSuperclass() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   861
        return superclass;
02bb8761fcce Initial load
duke
parents:
diff changeset
   862
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   863
02bb8761fcce Initial load
duke
parents:
diff changeset
   864
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   865
     * Return whether the class has a readObject method
02bb8761fcce Initial load
duke
parents:
diff changeset
   866
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   867
    final boolean hasReadObject() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   868
        return readObjectMethod != null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   869
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   870
02bb8761fcce Initial load
duke
parents:
diff changeset
   871
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   872
     * Return whether the class has a writeObject method
02bb8761fcce Initial load
duke
parents:
diff changeset
   873
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   874
    final boolean hasWriteObject() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   875
        return writeObjectMethod != null ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   876
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   877
02bb8761fcce Initial load
duke
parents:
diff changeset
   878
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   879
     * Returns when or not this class should be custom
02bb8761fcce Initial load
duke
parents:
diff changeset
   880
     * marshaled (use chunking).  This should happen if
02bb8761fcce Initial load
duke
parents:
diff changeset
   881
     * it is Externalizable OR if it or
02bb8761fcce Initial load
duke
parents:
diff changeset
   882
     * any of its superclasses has a writeObject method,
02bb8761fcce Initial load
duke
parents:
diff changeset
   883
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   884
    final boolean isCustomMarshaled() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   885
        return (hasWriteObject() || isExternalizable())
02bb8761fcce Initial load
duke
parents:
diff changeset
   886
            || (superclass != null && superclass.isCustomMarshaled());
02bb8761fcce Initial load
duke
parents:
diff changeset
   887
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   888
02bb8761fcce Initial load
duke
parents:
diff changeset
   889
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   890
     * Return true if all instances of 'this' Externalizable class
02bb8761fcce Initial load
duke
parents:
diff changeset
   891
     * are written in block-data mode from the stream that 'this' was read
02bb8761fcce Initial load
duke
parents:
diff changeset
   892
     * from. <p>
02bb8761fcce Initial load
duke
parents:
diff changeset
   893
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   894
     * In JDK 1.1, all Externalizable instances are not written
02bb8761fcce Initial load
duke
parents:
diff changeset
   895
     * in block-data mode.
02bb8761fcce Initial load
duke
parents:
diff changeset
   896
     * In JDK 1.2, all Externalizable instances, by default, are written
02bb8761fcce Initial load
duke
parents:
diff changeset
   897
     * in block-data mode and the Externalizable instance is terminated with
02bb8761fcce Initial load
duke
parents:
diff changeset
   898
     * tag TC_ENDBLOCKDATA. Change enabled the ability to skip Externalizable
02bb8761fcce Initial load
duke
parents:
diff changeset
   899
     * instances.
02bb8761fcce Initial load
duke
parents:
diff changeset
   900
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   901
     * IMPLEMENTATION NOTE:
02bb8761fcce Initial load
duke
parents:
diff changeset
   902
     *   This should have been a mode maintained per stream; however,
02bb8761fcce Initial load
duke
parents:
diff changeset
   903
     *   for compatibility reasons, it was only possible to record
02bb8761fcce Initial load
duke
parents:
diff changeset
   904
     *   this change per class. All Externalizable classes within
02bb8761fcce Initial load
duke
parents:
diff changeset
   905
     *   a given stream should either have this mode enabled or
02bb8761fcce Initial load
duke
parents:
diff changeset
   906
     *   disabled. This is enforced by not allowing the PROTOCOL_VERSION
02bb8761fcce Initial load
duke
parents:
diff changeset
   907
     *   of a stream to he changed after any objects have been written.
02bb8761fcce Initial load
duke
parents:
diff changeset
   908
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   909
     * @see ObjectOutputStream#useProtocolVersion
02bb8761fcce Initial load
duke
parents:
diff changeset
   910
     * @see ObjectStreamConstants#PROTOCOL_VERSION_1
02bb8761fcce Initial load
duke
parents:
diff changeset
   911
     * @see ObjectStreamConstants#PROTOCOL_VERSION_2
02bb8761fcce Initial load
duke
parents:
diff changeset
   912
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
   913
     * @since JDK 1.2
02bb8761fcce Initial load
duke
parents:
diff changeset
   914
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   915
    boolean hasExternalizableBlockDataMode() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   916
        return hasExternalizableBlockData;
02bb8761fcce Initial load
duke
parents:
diff changeset
   917
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   918
02bb8761fcce Initial load
duke
parents:
diff changeset
   919
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   920
     * Creates a new instance of the represented class.  If the class is
02bb8761fcce Initial load
duke
parents:
diff changeset
   921
     * externalizable, invokes its public no-arg constructor; otherwise, if the
02bb8761fcce Initial load
duke
parents:
diff changeset
   922
     * class is serializable, invokes the no-arg constructor of the first
02bb8761fcce Initial load
duke
parents:
diff changeset
   923
     * non-serializable superclass.  Throws UnsupportedOperationException if
02bb8761fcce Initial load
duke
parents:
diff changeset
   924
     * this class descriptor is not associated with a class, if the associated
02bb8761fcce Initial load
duke
parents:
diff changeset
   925
     * class is non-serializable or if the appropriate no-arg constructor is
02bb8761fcce Initial load
duke
parents:
diff changeset
   926
     * inaccessible/unavailable.
02bb8761fcce Initial load
duke
parents:
diff changeset
   927
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   928
    Object newInstance()
02bb8761fcce Initial load
duke
parents:
diff changeset
   929
        throws InstantiationException, InvocationTargetException,
02bb8761fcce Initial load
duke
parents:
diff changeset
   930
               UnsupportedOperationException
02bb8761fcce Initial load
duke
parents:
diff changeset
   931
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
   932
        if (cons != null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   933
            try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   934
                return cons.newInstance(new Object[0]);
02bb8761fcce Initial load
duke
parents:
diff changeset
   935
            } catch (IllegalAccessException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   936
                // should not occur, as access checks have been suppressed
02bb8761fcce Initial load
duke
parents:
diff changeset
   937
                InternalError ie = new InternalError();
02bb8761fcce Initial load
duke
parents:
diff changeset
   938
                ie.initCause( ex ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   939
                throw ie ;
02bb8761fcce Initial load
duke
parents:
diff changeset
   940
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   941
        } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
   942
            throw new UnsupportedOperationException();
02bb8761fcce Initial load
duke
parents:
diff changeset
   943
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   944
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   945
02bb8761fcce Initial load
duke
parents:
diff changeset
   946
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   947
     * Returns public no-arg constructor of given class, or null if none found.
02bb8761fcce Initial load
duke
parents:
diff changeset
   948
     * Access checks are disabled on the returned constructor (if any), since
02bb8761fcce Initial load
duke
parents:
diff changeset
   949
     * the defining class may still be non-public.
02bb8761fcce Initial load
duke
parents:
diff changeset
   950
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   951
    private static Constructor getExternalizableConstructor(Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   952
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   953
            Constructor cons = cl.getDeclaredConstructor(new Class[0]);
02bb8761fcce Initial load
duke
parents:
diff changeset
   954
            cons.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   955
            return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
02bb8761fcce Initial load
duke
parents:
diff changeset
   956
                cons : null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   957
        } catch (NoSuchMethodException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   958
            return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   959
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   960
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   961
02bb8761fcce Initial load
duke
parents:
diff changeset
   962
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
   963
     * Returns subclass-accessible no-arg constructor of first non-serializable
02bb8761fcce Initial load
duke
parents:
diff changeset
   964
     * superclass, or null if none found.  Access checks are disabled on the
02bb8761fcce Initial load
duke
parents:
diff changeset
   965
     * returned constructor (if any).
02bb8761fcce Initial load
duke
parents:
diff changeset
   966
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   967
    private static Constructor getSerializableConstructor(Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   968
        Class initCl = cl;
02bb8761fcce Initial load
duke
parents:
diff changeset
   969
        while (Serializable.class.isAssignableFrom(initCl)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   970
            if ((initCl = initCl.getSuperclass()) == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   971
                return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   972
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   973
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   974
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
   975
            Constructor cons = initCl.getDeclaredConstructor(new Class[0]);
02bb8761fcce Initial load
duke
parents:
diff changeset
   976
            int mods = cons.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
   977
            if ((mods & Modifier.PRIVATE) != 0 ||
02bb8761fcce Initial load
duke
parents:
diff changeset
   978
                ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
02bb8761fcce Initial load
duke
parents:
diff changeset
   979
                 !packageEquals(cl, initCl)))
02bb8761fcce Initial load
duke
parents:
diff changeset
   980
            {
02bb8761fcce Initial load
duke
parents:
diff changeset
   981
                return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   982
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
   983
            cons = bridge.newConstructorForSerialization(cl, cons);
02bb8761fcce Initial load
duke
parents:
diff changeset
   984
            cons.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
   985
            return cons;
02bb8761fcce Initial load
duke
parents:
diff changeset
   986
        } catch (NoSuchMethodException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
   987
            return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
   988
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
   989
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   990
02bb8761fcce Initial load
duke
parents:
diff changeset
   991
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   992
     * Return the ObjectStreamClass of the local class this one is based on.
02bb8761fcce Initial load
duke
parents:
diff changeset
   993
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
   994
    final ObjectStreamClass localClassDescriptor() {
02bb8761fcce Initial load
duke
parents:
diff changeset
   995
        return localClassDesc;
02bb8761fcce Initial load
duke
parents:
diff changeset
   996
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
   997
02bb8761fcce Initial load
duke
parents:
diff changeset
   998
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
   999
     * Get the Serializability of the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1000
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1001
    boolean isSerializable() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1002
        return serializable;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1003
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1004
02bb8761fcce Initial load
duke
parents:
diff changeset
  1005
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1006
     * Get the externalizability of the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1007
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1008
    boolean isExternalizable() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1009
        return externalizable;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1010
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1011
02bb8761fcce Initial load
duke
parents:
diff changeset
  1012
    boolean isNonSerializable() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1013
        return ! (externalizable || serializable);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1014
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1015
02bb8761fcce Initial load
duke
parents:
diff changeset
  1016
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1017
     * Calculate the size of the array needed to store primitive data and the
02bb8761fcce Initial load
duke
parents:
diff changeset
  1018
     * number of object references to read when reading from the input
02bb8761fcce Initial load
duke
parents:
diff changeset
  1019
     * stream.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1020
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1021
    private void computeFieldInfo() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1022
        primBytes = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1023
        objFields = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1024
02bb8761fcce Initial load
duke
parents:
diff changeset
  1025
        for (int i = 0; i < fields.length; i++ ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1026
            switch (fields[i].getTypeCode()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1027
            case 'B':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1028
            case 'Z':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1029
                primBytes += 1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1030
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1031
            case 'C':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1032
            case 'S':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1033
                primBytes += 2;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1034
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1035
02bb8761fcce Initial load
duke
parents:
diff changeset
  1036
            case 'I':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1037
            case 'F':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1038
                primBytes += 4;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1039
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1040
            case 'J':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1041
            case 'D' :
02bb8761fcce Initial load
duke
parents:
diff changeset
  1042
                primBytes += 8;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1043
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1044
02bb8761fcce Initial load
duke
parents:
diff changeset
  1045
            case 'L':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1046
            case '[':
02bb8761fcce Initial load
duke
parents:
diff changeset
  1047
                objFields += 1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1048
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1049
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1050
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1051
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1052
02bb8761fcce Initial load
duke
parents:
diff changeset
  1053
    private static void msg( String str )
02bb8761fcce Initial load
duke
parents:
diff changeset
  1054
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1055
        System.out.println( str ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1056
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1057
02bb8761fcce Initial load
duke
parents:
diff changeset
  1058
    /* JDK 1.5 has introduced some new modifier bits (such as SYNTHETIC)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1059
     * that can affect the SVUID computation (see bug 4897937).  These bits
02bb8761fcce Initial load
duke
parents:
diff changeset
  1060
     * must be ignored, as otherwise interoperability with ORBs in earlier
02bb8761fcce Initial load
duke
parents:
diff changeset
  1061
     * JDK versions can be compromised.  I am adding these masks for this
02bb8761fcce Initial load
duke
parents:
diff changeset
  1062
     * purpose as discussed in the CCC for this bug (see http://ccc.sfbay/4897937).
02bb8761fcce Initial load
duke
parents:
diff changeset
  1063
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1064
02bb8761fcce Initial load
duke
parents:
diff changeset
  1065
    public static final int CLASS_MASK = Modifier.PUBLIC | Modifier.FINAL |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1066
        Modifier.INTERFACE | Modifier.ABSTRACT ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1067
    public static final int FIELD_MASK = Modifier.PUBLIC | Modifier.PRIVATE |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1068
        Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1069
        Modifier.TRANSIENT | Modifier.VOLATILE ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1070
    public static final int METHOD_MASK = Modifier.PUBLIC | Modifier.PRIVATE |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1071
        Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1072
        Modifier.SYNCHRONIZED | Modifier.NATIVE | Modifier.ABSTRACT |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1073
        Modifier.STRICT ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1074
02bb8761fcce Initial load
duke
parents:
diff changeset
  1075
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1076
     * Compute a hash for the specified class.  Incrementally add
02bb8761fcce Initial load
duke
parents:
diff changeset
  1077
     * items to the hash accumulating in the digest stream.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1078
     * Fold the hash into a long.  Use the SHA secure hash function.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1079
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1080
    private static long _computeSerialVersionUID(Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1081
        if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1082
            msg( "Computing SerialVersionUID for " + cl ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1083
        ByteArrayOutputStream devnull = new ByteArrayOutputStream(512);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1084
02bb8761fcce Initial load
duke
parents:
diff changeset
  1085
        long h = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1086
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1087
            MessageDigest md = MessageDigest.getInstance("SHA");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1088
            DigestOutputStream mdo = new DigestOutputStream(devnull, md);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1089
            DataOutputStream data = new DataOutputStream(mdo);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1090
02bb8761fcce Initial load
duke
parents:
diff changeset
  1091
            if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1092
                msg( "\twriteUTF( \"" + cl.getName() + "\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1093
            data.writeUTF(cl.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1094
02bb8761fcce Initial load
duke
parents:
diff changeset
  1095
            int classaccess = cl.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1096
            classaccess &= (Modifier.PUBLIC | Modifier.FINAL |
02bb8761fcce Initial load
duke
parents:
diff changeset
  1097
                            Modifier.INTERFACE | Modifier.ABSTRACT);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1098
02bb8761fcce Initial load
duke
parents:
diff changeset
  1099
            /* Workaround for javac bug that only set ABSTRACT for
02bb8761fcce Initial load
duke
parents:
diff changeset
  1100
             * interfaces if the interface had some methods.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1101
             * The ABSTRACT bit reflects that the number of methods > 0.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1102
             * This is required so correct hashes can be computed
02bb8761fcce Initial load
duke
parents:
diff changeset
  1103
             * for existing class files.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1104
             * Previously this hack was previously present in the VM.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1105
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1106
            Method[] method = cl.getDeclaredMethods();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1107
            if ((classaccess & Modifier.INTERFACE) != 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1108
                classaccess &= (~Modifier.ABSTRACT);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1109
                if (method.length > 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1110
                    classaccess |= Modifier.ABSTRACT;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1111
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1112
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1113
02bb8761fcce Initial load
duke
parents:
diff changeset
  1114
            // Mask out any post-1.4 attributes
02bb8761fcce Initial load
duke
parents:
diff changeset
  1115
            classaccess &= CLASS_MASK ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1116
02bb8761fcce Initial load
duke
parents:
diff changeset
  1117
            if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1118
                msg( "\twriteInt( " + classaccess + " ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1119
            data.writeInt(classaccess);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1120
02bb8761fcce Initial load
duke
parents:
diff changeset
  1121
            /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1122
             * Get the list of interfaces supported,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1123
             * Accumulate their names their names in Lexical order
02bb8761fcce Initial load
duke
parents:
diff changeset
  1124
             * and add them to the hash
02bb8761fcce Initial load
duke
parents:
diff changeset
  1125
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1126
            if (!cl.isArray()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1127
                /* In 1.2fcs, getInterfaces() was modified to return
02bb8761fcce Initial load
duke
parents:
diff changeset
  1128
                 * {java.lang.Cloneable, java.io.Serializable} when
02bb8761fcce Initial load
duke
parents:
diff changeset
  1129
                 * called on array classes.  These values would upset
02bb8761fcce Initial load
duke
parents:
diff changeset
  1130
                 * the computation of the hash, so we explicitly omit
02bb8761fcce Initial load
duke
parents:
diff changeset
  1131
                 * them from its computation.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1132
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1133
02bb8761fcce Initial load
duke
parents:
diff changeset
  1134
                Class interfaces[] = cl.getInterfaces();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1135
                Arrays.sort(interfaces, compareClassByName);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1136
02bb8761fcce Initial load
duke
parents:
diff changeset
  1137
                for (int i = 0; i < interfaces.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1138
                    if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1139
                        msg( "\twriteUTF( \"" + interfaces[i].getName() + "\" ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1140
                    data.writeUTF(interfaces[i].getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1141
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1142
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1143
02bb8761fcce Initial load
duke
parents:
diff changeset
  1144
            /* Sort the field names to get a deterministic order */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1145
            Field[] field = cl.getDeclaredFields();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1146
            Arrays.sort(field, compareMemberByName);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1147
02bb8761fcce Initial load
duke
parents:
diff changeset
  1148
            for (int i = 0; i < field.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1149
                Field f = field[i];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1150
02bb8761fcce Initial load
duke
parents:
diff changeset
  1151
                /* Include in the hash all fields except those that are
02bb8761fcce Initial load
duke
parents:
diff changeset
  1152
                 * private transient and private static.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1153
                 */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1154
                int m = f.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1155
                if (Modifier.isPrivate(m) &&
02bb8761fcce Initial load
duke
parents:
diff changeset
  1156
                    (Modifier.isTransient(m) || Modifier.isStatic(m)))
02bb8761fcce Initial load
duke
parents:
diff changeset
  1157
                    continue;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1158
02bb8761fcce Initial load
duke
parents:
diff changeset
  1159
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1160
                    msg( "\twriteUTF( \"" + f.getName() + "\" ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1161
                data.writeUTF(f.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1162
02bb8761fcce Initial load
duke
parents:
diff changeset
  1163
                // Mask out any post-1.4 bits
02bb8761fcce Initial load
duke
parents:
diff changeset
  1164
                m &= FIELD_MASK ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1165
02bb8761fcce Initial load
duke
parents:
diff changeset
  1166
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1167
                    msg( "\twriteInt( " + m + " ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1168
                data.writeInt(m);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1169
02bb8761fcce Initial load
duke
parents:
diff changeset
  1170
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1171
                    msg( "\twriteUTF( \"" + getSignature(f.getType()) + "\" ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1172
                data.writeUTF(getSignature(f.getType()));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1173
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1174
02bb8761fcce Initial load
duke
parents:
diff changeset
  1175
            if (hasStaticInitializer(cl)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1176
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1177
                    msg( "\twriteUTF( \"<clinit>\" ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1178
                data.writeUTF("<clinit>");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1179
02bb8761fcce Initial load
duke
parents:
diff changeset
  1180
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1181
                    msg( "\twriteInt( " + Modifier.STATIC + " )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1182
                data.writeInt(Modifier.STATIC); // TBD: what modifiers does it have
02bb8761fcce Initial load
duke
parents:
diff changeset
  1183
02bb8761fcce Initial load
duke
parents:
diff changeset
  1184
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1185
                    msg( "\twriteUTF( \"()V\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1186
                data.writeUTF("()V");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1187
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1188
02bb8761fcce Initial load
duke
parents:
diff changeset
  1189
            /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1190
             * Get the list of constructors including name and signature
02bb8761fcce Initial load
duke
parents:
diff changeset
  1191
             * Sort lexically, add all except the private constructors
02bb8761fcce Initial load
duke
parents:
diff changeset
  1192
             * to the hash with their access flags
02bb8761fcce Initial load
duke
parents:
diff changeset
  1193
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1194
02bb8761fcce Initial load
duke
parents:
diff changeset
  1195
            MethodSignature[] constructors =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1196
                MethodSignature.removePrivateAndSort(cl.getDeclaredConstructors());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1197
            for (int i = 0; i < constructors.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1198
                MethodSignature c = constructors[i];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1199
                String mname = "<init>";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1200
                String desc = c.signature;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1201
                desc = desc.replace('/', '.');
02bb8761fcce Initial load
duke
parents:
diff changeset
  1202
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1203
                    msg( "\twriteUTF( \"" + mname + "\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1204
                data.writeUTF(mname);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1205
02bb8761fcce Initial load
duke
parents:
diff changeset
  1206
                // mask out post-1.4 modifiers
02bb8761fcce Initial load
duke
parents:
diff changeset
  1207
                int modifier = c.member.getModifiers() & METHOD_MASK ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1208
02bb8761fcce Initial load
duke
parents:
diff changeset
  1209
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1210
                    msg( "\twriteInt( " + modifier + " ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1211
                data.writeInt( modifier ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1212
02bb8761fcce Initial load
duke
parents:
diff changeset
  1213
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1214
                    msg( "\twriteUTF( \"" + desc+ "\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1215
                data.writeUTF(desc);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1216
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1217
02bb8761fcce Initial load
duke
parents:
diff changeset
  1218
            /* Include in the hash all methods except those that are
02bb8761fcce Initial load
duke
parents:
diff changeset
  1219
             * private transient and private static.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1220
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1221
            MethodSignature[] methods =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1222
                MethodSignature.removePrivateAndSort(method);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1223
            for (int i = 0; i < methods.length; i++ ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1224
                MethodSignature m = methods[i];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1225
                String desc = m.signature;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1226
                desc = desc.replace('/', '.');
02bb8761fcce Initial load
duke
parents:
diff changeset
  1227
02bb8761fcce Initial load
duke
parents:
diff changeset
  1228
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1229
                    msg( "\twriteUTF( \"" + m.member.getName()+ "\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1230
                data.writeUTF(m.member.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1231
02bb8761fcce Initial load
duke
parents:
diff changeset
  1232
                // mask out post-1.4 modifiers
02bb8761fcce Initial load
duke
parents:
diff changeset
  1233
                int modifier = m.member.getModifiers() & METHOD_MASK ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1234
02bb8761fcce Initial load
duke
parents:
diff changeset
  1235
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1236
                    msg( "\twriteInt( " + modifier + " ) " ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1237
                data.writeInt( modifier ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1238
02bb8761fcce Initial load
duke
parents:
diff changeset
  1239
                if (DEBUG_SVUID)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1240
                    msg( "\twriteUTF( \"" + desc + "\" )" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1241
                data.writeUTF(desc);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1242
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1243
02bb8761fcce Initial load
duke
parents:
diff changeset
  1244
            /* Compute the hash value for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1245
             * Use only the first 64 bits of the hash.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1246
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1247
            data.flush();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1248
            byte hasharray[] = md.digest();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1249
            for (int i = 0; i < Math.min(8, hasharray.length); i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1250
                h += (long)(hasharray[i] & 255) << (i * 8);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1251
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1252
        } catch (IOException ignore) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1253
            /* can't happen, but be deterministic anyway. */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1254
            h = -1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1255
        } catch (NoSuchAlgorithmException complain) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1256
            SecurityException se = new SecurityException() ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1257
            se.initCause( complain ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1258
            throw se ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1259
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1260
02bb8761fcce Initial load
duke
parents:
diff changeset
  1261
        return h;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1262
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1263
02bb8761fcce Initial load
duke
parents:
diff changeset
  1264
    private static long computeStructuralUID(com.sun.corba.se.impl.io.ObjectStreamClass osc, Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1265
        ByteArrayOutputStream devnull = new ByteArrayOutputStream(512);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1266
02bb8761fcce Initial load
duke
parents:
diff changeset
  1267
        long h = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1268
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1269
02bb8761fcce Initial load
duke
parents:
diff changeset
  1270
            if ((!java.io.Serializable.class.isAssignableFrom(cl)) ||
02bb8761fcce Initial load
duke
parents:
diff changeset
  1271
                (cl.isInterface())){
02bb8761fcce Initial load
duke
parents:
diff changeset
  1272
                return 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1273
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1274
02bb8761fcce Initial load
duke
parents:
diff changeset
  1275
            if (java.io.Externalizable.class.isAssignableFrom(cl)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1276
                return 1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1277
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1278
02bb8761fcce Initial load
duke
parents:
diff changeset
  1279
            MessageDigest md = MessageDigest.getInstance("SHA");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1280
            DigestOutputStream mdo = new DigestOutputStream(devnull, md);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1281
            DataOutputStream data = new DataOutputStream(mdo);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1282
02bb8761fcce Initial load
duke
parents:
diff changeset
  1283
            // Get SUID of parent
02bb8761fcce Initial load
duke
parents:
diff changeset
  1284
            Class parent = cl.getSuperclass();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1285
            if ((parent != null))
02bb8761fcce Initial load
duke
parents:
diff changeset
  1286
            // SerialBug 1; acc. to spec the one for
02bb8761fcce Initial load
duke
parents:
diff changeset
  1287
            // java.lang.object
02bb8761fcce Initial load
duke
parents:
diff changeset
  1288
            // should be computed and put
02bb8761fcce Initial load
duke
parents:
diff changeset
  1289
            //     && (parent != java.lang.Object.class))
02bb8761fcce Initial load
duke
parents:
diff changeset
  1290
            {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1291
                                //data.writeLong(computeSerialVersionUID(null,parent));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1292
                data.writeLong(computeStructuralUID(lookup(parent), parent));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1293
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1294
02bb8761fcce Initial load
duke
parents:
diff changeset
  1295
            if (osc.hasWriteObject())
02bb8761fcce Initial load
duke
parents:
diff changeset
  1296
                data.writeInt(2);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1297
            else
02bb8761fcce Initial load
duke
parents:
diff changeset
  1298
                data.writeInt(1);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1299
02bb8761fcce Initial load
duke
parents:
diff changeset
  1300
            // CORBA formal 00-11-03 10.6.2:  For each field of the
02bb8761fcce Initial load
duke
parents:
diff changeset
  1301
            // class that is mapped to IDL, sorted lexicographically
02bb8761fcce Initial load
duke
parents:
diff changeset
  1302
            // by Java field name, in increasing order...
02bb8761fcce Initial load
duke
parents:
diff changeset
  1303
            ObjectStreamField[] field = osc.getFields();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1304
            if (field.length > 1) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1305
                Arrays.sort(field, compareObjStrFieldsByName);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1306
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1307
02bb8761fcce Initial load
duke
parents:
diff changeset
  1308
            // ...Java field name in UTF encoding, field
02bb8761fcce Initial load
duke
parents:
diff changeset
  1309
            // descriptor, as defined by the JVM spec...
02bb8761fcce Initial load
duke
parents:
diff changeset
  1310
            for (int i = 0; i < field.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1311
                data.writeUTF(field[i].getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1312
                data.writeUTF(field[i].getSignature());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1313
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1314
02bb8761fcce Initial load
duke
parents:
diff changeset
  1315
            /* Compute the hash value for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1316
             * Use only the first 64 bits of the hash.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1317
             */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1318
            data.flush();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1319
            byte hasharray[] = md.digest();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1320
            // int minimum = Math.min(8, hasharray.length);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1321
            // SerialBug 3: SHA computation is wrong; for loop reversed
02bb8761fcce Initial load
duke
parents:
diff changeset
  1322
            //for (int i = minimum; i > 0; i--)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1323
            for (int i = 0; i < Math.min(8, hasharray.length); i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1324
                h += (long)(hasharray[i] & 255) << (i * 8);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1325
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1326
        } catch (IOException ignore) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1327
            /* can't happen, but be deterministic anyway. */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1328
            h = -1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1329
        } catch (NoSuchAlgorithmException complain) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1330
            SecurityException se = new SecurityException();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1331
            se.initCause( complain ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1332
            throw se ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1333
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1334
        return h;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1335
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1336
02bb8761fcce Initial load
duke
parents:
diff changeset
  1337
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1338
     * Compute the JVM signature for the class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1339
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1340
    static String getSignature(Class clazz) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1341
        String type = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1342
        if (clazz.isArray()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1343
            Class cl = clazz;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1344
            int dimensions = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1345
            while (cl.isArray()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1346
                dimensions++;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1347
                cl = cl.getComponentType();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1348
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1349
            StringBuffer sb = new StringBuffer();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1350
            for (int i = 0; i < dimensions; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1351
                sb.append("[");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1352
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1353
            sb.append(getSignature(cl));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1354
            type = sb.toString();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1355
        } else if (clazz.isPrimitive()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1356
            if (clazz == Integer.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1357
                type = "I";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1358
            } else if (clazz == Byte.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1359
                type = "B";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1360
            } else if (clazz == Long.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1361
                type = "J";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1362
            } else if (clazz == Float.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1363
                type = "F";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1364
            } else if (clazz == Double.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1365
                type = "D";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1366
            } else if (clazz == Short.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1367
                type = "S";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1368
            } else if (clazz == Character.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1369
                type = "C";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1370
            } else if (clazz == Boolean.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1371
                type = "Z";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1372
            } else if (clazz == Void.TYPE) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1373
                type = "V";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1374
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1375
        } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1376
            type = "L" + clazz.getName().replace('.', '/') + ";";
02bb8761fcce Initial load
duke
parents:
diff changeset
  1377
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1378
        return type;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1379
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1380
02bb8761fcce Initial load
duke
parents:
diff changeset
  1381
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1382
     * Compute the JVM method descriptor for the method.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1383
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1384
    static String getSignature(Method meth) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1385
        StringBuffer sb = new StringBuffer();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1386
02bb8761fcce Initial load
duke
parents:
diff changeset
  1387
        sb.append("(");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1388
02bb8761fcce Initial load
duke
parents:
diff changeset
  1389
        Class[] params = meth.getParameterTypes(); // avoid clone
02bb8761fcce Initial load
duke
parents:
diff changeset
  1390
        for (int j = 0; j < params.length; j++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1391
            sb.append(getSignature(params[j]));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1392
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1393
        sb.append(")");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1394
        sb.append(getSignature(meth.getReturnType()));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1395
        return sb.toString();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1396
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1397
02bb8761fcce Initial load
duke
parents:
diff changeset
  1398
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1399
     * Compute the JVM constructor descriptor for the constructor.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1400
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1401
    static String getSignature(Constructor cons) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1402
        StringBuffer sb = new StringBuffer();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1403
02bb8761fcce Initial load
duke
parents:
diff changeset
  1404
        sb.append("(");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1405
02bb8761fcce Initial load
duke
parents:
diff changeset
  1406
        Class[] params = cons.getParameterTypes(); // avoid clone
02bb8761fcce Initial load
duke
parents:
diff changeset
  1407
        for (int j = 0; j < params.length; j++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1408
            sb.append(getSignature(params[j]));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1409
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1410
        sb.append(")V");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1411
        return sb.toString();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1412
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1413
02bb8761fcce Initial load
duke
parents:
diff changeset
  1414
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1415
     * Cache of Class -> ClassDescriptor Mappings.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1416
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1417
    static private ObjectStreamClassEntry[] descriptorFor = new ObjectStreamClassEntry[61];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1418
02bb8761fcce Initial load
duke
parents:
diff changeset
  1419
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1420
     * findDescriptorFor a Class.  This looks in the cache for a
02bb8761fcce Initial load
duke
parents:
diff changeset
  1421
     * mapping from Class -> ObjectStreamClass mappings.  The hashCode
02bb8761fcce Initial load
duke
parents:
diff changeset
  1422
     * of the Class is used for the lookup since the Class is the key.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1423
     * The entries are extended from java.lang.ref.SoftReference so the
02bb8761fcce Initial load
duke
parents:
diff changeset
  1424
     * gc will be able to free them if needed.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1425
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1426
    private static ObjectStreamClass findDescriptorFor(Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1427
02bb8761fcce Initial load
duke
parents:
diff changeset
  1428
        int hash = cl.hashCode();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1429
        int index = (hash & 0x7FFFFFFF) % descriptorFor.length;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1430
        ObjectStreamClassEntry e;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1431
        ObjectStreamClassEntry prev;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1432
02bb8761fcce Initial load
duke
parents:
diff changeset
  1433
        /* Free any initial entries whose refs have been cleared */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1434
        while ((e = descriptorFor[index]) != null && e.get() == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1435
            descriptorFor[index] = e.next;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1436
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1437
02bb8761fcce Initial load
duke
parents:
diff changeset
  1438
        /* Traverse the chain looking for a descriptor with ofClass == cl.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1439
         * unlink entries that are unresolved.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1440
         */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1441
        prev = e;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1442
        while (e != null ) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1443
            ObjectStreamClass desc = (ObjectStreamClass)(e.get());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1444
            if (desc == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1445
                // This entry has been cleared,  unlink it
02bb8761fcce Initial load
duke
parents:
diff changeset
  1446
                prev.next = e.next;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1447
            } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1448
                if (desc.ofClass == cl)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1449
                    return desc;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1450
                prev = e;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1451
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1452
            e = e.next;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1453
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1454
        return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1455
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1456
02bb8761fcce Initial load
duke
parents:
diff changeset
  1457
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1458
     * insertDescriptorFor a Class -> ObjectStreamClass mapping.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1459
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1460
    private static void insertDescriptorFor(ObjectStreamClass desc) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1461
        // Make sure not already present
02bb8761fcce Initial load
duke
parents:
diff changeset
  1462
        if (findDescriptorFor(desc.ofClass) != null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1463
            return;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1464
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1465
02bb8761fcce Initial load
duke
parents:
diff changeset
  1466
        int hash = desc.ofClass.hashCode();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1467
        int index = (hash & 0x7FFFFFFF) % descriptorFor.length;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1468
        ObjectStreamClassEntry e = new ObjectStreamClassEntry(desc);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1469
        e.next = descriptorFor[index];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1470
        descriptorFor[index] = e;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1471
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1472
02bb8761fcce Initial load
duke
parents:
diff changeset
  1473
    private static Field[] getDeclaredFields(final Class clz) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1474
        return (Field[]) AccessController.doPrivileged(new PrivilegedAction() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1475
            public Object run() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1476
                return clz.getDeclaredFields();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1477
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1478
        });
02bb8761fcce Initial load
duke
parents:
diff changeset
  1479
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1480
02bb8761fcce Initial load
duke
parents:
diff changeset
  1481
02bb8761fcce Initial load
duke
parents:
diff changeset
  1482
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1483
     * The name of this descriptor
02bb8761fcce Initial load
duke
parents:
diff changeset
  1484
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1485
    private String name;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1486
02bb8761fcce Initial load
duke
parents:
diff changeset
  1487
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1488
     * The descriptor of the supertype.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1489
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1490
    private ObjectStreamClass superclass;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1491
02bb8761fcce Initial load
duke
parents:
diff changeset
  1492
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1493
     * Flags for Serializable and Externalizable.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1494
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1495
    private boolean serializable;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1496
    private boolean externalizable;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1497
02bb8761fcce Initial load
duke
parents:
diff changeset
  1498
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1499
     * Array of persistent fields of this class, sorted by
02bb8761fcce Initial load
duke
parents:
diff changeset
  1500
     * type and name.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1501
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1502
    private ObjectStreamField[] fields;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1503
02bb8761fcce Initial load
duke
parents:
diff changeset
  1504
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1505
     * Class that is a descriptor for in this virtual machine.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1506
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1507
    private Class ofClass;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1508
02bb8761fcce Initial load
duke
parents:
diff changeset
  1509
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1510
     * True if descriptor for a proxy class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1511
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1512
    boolean forProxyClass;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1513
02bb8761fcce Initial load
duke
parents:
diff changeset
  1514
02bb8761fcce Initial load
duke
parents:
diff changeset
  1515
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1516
     * SerialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1517
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1518
    private long suid = kDefaultUID;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1519
    private String suidStr = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1520
02bb8761fcce Initial load
duke
parents:
diff changeset
  1521
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1522
     * Actual (computed) SerialVersionUID for this class.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1523
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1524
    private long actualSuid = kDefaultUID;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1525
    private String actualSuidStr = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1526
02bb8761fcce Initial load
duke
parents:
diff changeset
  1527
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1528
     * The total number of bytes of primitive fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1529
     * The total number of object fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1530
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1531
    int primBytes;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1532
    int objFields;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1533
02bb8761fcce Initial load
duke
parents:
diff changeset
  1534
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1535
     * Flag indicating whether or not this instance has
02bb8761fcce Initial load
duke
parents:
diff changeset
  1536
     * successfully completed initialization.  This is to
02bb8761fcce Initial load
duke
parents:
diff changeset
  1537
     * try to fix bug 4373844.  Working to move to
02bb8761fcce Initial load
duke
parents:
diff changeset
  1538
     * reusing java.io.ObjectStreamClass for JDK 1.5.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1539
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1540
    private boolean initialized = false;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1541
02bb8761fcce Initial load
duke
parents:
diff changeset
  1542
    /* Internal lock object. */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1543
    private Object lock = new Object();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1544
02bb8761fcce Initial load
duke
parents:
diff changeset
  1545
    /* In JDK 1.1, external data was not written in block mode.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1546
     * As of JDK 1.2, external data is written in block data mode. This
02bb8761fcce Initial load
duke
parents:
diff changeset
  1547
     * flag enables JDK 1.2 to be able to read JDK 1.1 written external data.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1548
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
  1549
     * @since JDK 1.2
02bb8761fcce Initial load
duke
parents:
diff changeset
  1550
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1551
    private boolean hasExternalizableBlockData;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1552
    Method writeObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1553
    Method readObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1554
    private Method writeReplaceObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1555
    private Method readResolveObjectMethod;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1556
    private Constructor cons ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1557
02bb8761fcce Initial load
duke
parents:
diff changeset
  1558
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1559
     * Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
02bb8761fcce Initial load
duke
parents:
diff changeset
  1560
     * stream format version 2 which puts a fake valuetype around
02bb8761fcce Initial load
duke
parents:
diff changeset
  1561
     * a Serializable's optional custom data.  This valuetype has
02bb8761fcce Initial load
duke
parents:
diff changeset
  1562
     * a special repository ID made from the Serializable's
02bb8761fcce Initial load
duke
parents:
diff changeset
  1563
     * information which we are pre-computing and
02bb8761fcce Initial load
duke
parents:
diff changeset
  1564
     * storing here.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1565
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1566
    private String rmiiiopOptionalDataRepId = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1567
02bb8761fcce Initial load
duke
parents:
diff changeset
  1568
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1569
     * ObjectStreamClass that this one was built from.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1570
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1571
    private ObjectStreamClass localClassDesc;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1572
02bb8761fcce Initial load
duke
parents:
diff changeset
  1573
    /* Find out if the class has a static class initializer <clinit> */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1574
    private static Method hasStaticInitializerMethod = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1575
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1576
     * Returns true if the given class defines a static initializer method,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1577
     * false otherwise.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1578
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1579
    private static boolean hasStaticInitializer(Class cl) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1580
        if (hasStaticInitializerMethod == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1581
            Class classWithThisMethod = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1582
02bb8761fcce Initial load
duke
parents:
diff changeset
  1583
            try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1584
                try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1585
                    // When using rip-int with Merlin or when this is a Merlin
02bb8761fcce Initial load
duke
parents:
diff changeset
  1586
                    // workspace, the method we want is in sun.misc.ClassReflector
02bb8761fcce Initial load
duke
parents:
diff changeset
  1587
                    // and absent from java.io.ObjectStreamClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1588
                    //
02bb8761fcce Initial load
duke
parents:
diff changeset
  1589
                    // When compiling rip-int with JDK 1.3.x, we have to get it
02bb8761fcce Initial load
duke
parents:
diff changeset
  1590
                    // from java.io.ObjectStreamClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1591
                    classWithThisMethod = Class.forName("sun.misc.ClassReflector");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1592
                } catch (ClassNotFoundException cnfe) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1593
                    // Do nothing.  This is either not a Merlin workspace,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1594
                    // or rip-int is being compiled with something other than
02bb8761fcce Initial load
duke
parents:
diff changeset
  1595
                    // Merlin, probably JDK 1.3.  Fall back on java.io.ObjectStreaClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1596
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1597
                if (classWithThisMethod == null)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1598
                    classWithThisMethod = java.io.ObjectStreamClass.class;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1599
02bb8761fcce Initial load
duke
parents:
diff changeset
  1600
                hasStaticInitializerMethod =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1601
                    classWithThisMethod.getDeclaredMethod("hasStaticInitializer",
02bb8761fcce Initial load
duke
parents:
diff changeset
  1602
                                                          new Class[] { Class.class });
02bb8761fcce Initial load
duke
parents:
diff changeset
  1603
            } catch (NoSuchMethodException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1604
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1605
02bb8761fcce Initial load
duke
parents:
diff changeset
  1606
            if (hasStaticInitializerMethod == null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1607
                // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
  1608
                throw new InternalError("Can't find hasStaticInitializer method on "
02bb8761fcce Initial load
duke
parents:
diff changeset
  1609
                                        + classWithThisMethod.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1610
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1611
            hasStaticInitializerMethod.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1612
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1613
02bb8761fcce Initial load
duke
parents:
diff changeset
  1614
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1615
            Boolean retval = (Boolean)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1616
                hasStaticInitializerMethod.invoke(null, new Object[] { cl });
02bb8761fcce Initial load
duke
parents:
diff changeset
  1617
            return retval.booleanValue();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1618
        } catch (Exception ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1619
            // XXX I18N, logging needed
02bb8761fcce Initial load
duke
parents:
diff changeset
  1620
            InternalError ie = new InternalError( "Error invoking hasStaticInitializer" ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1621
            ie.initCause( ex ) ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1622
            throw ie ;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1623
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1624
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1625
02bb8761fcce Initial load
duke
parents:
diff changeset
  1626
02bb8761fcce Initial load
duke
parents:
diff changeset
  1627
    /* The Class Object for java.io.Serializable */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1628
    private static Class classSerializable = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1629
    private static Class classExternalizable = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1630
02bb8761fcce Initial load
duke
parents:
diff changeset
  1631
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1632
     * Resolve java.io.Serializable at load time.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1633
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1634
    static {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1635
        try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1636
            classSerializable = Class.forName("java.io.Serializable");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1637
            classExternalizable = Class.forName("java.io.Externalizable");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1638
        } catch (Throwable e) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1639
            System.err.println("Could not load java.io.Serializable or java.io.Externalizable.");
02bb8761fcce Initial load
duke
parents:
diff changeset
  1640
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1641
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1642
02bb8761fcce Initial load
duke
parents:
diff changeset
  1643
    /** use serialVersionUID from JDK 1.1. for interoperability */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1644
    private static final long serialVersionUID = -6120832682080437368L;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1645
02bb8761fcce Initial load
duke
parents:
diff changeset
  1646
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1647
     * Set serialPersistentFields of a Serializable class to this value to
02bb8761fcce Initial load
duke
parents:
diff changeset
  1648
     * denote that the class has no Serializable fields.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1649
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1650
    public static final ObjectStreamField[] NO_FIELDS =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1651
        new ObjectStreamField[0];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1652
02bb8761fcce Initial load
duke
parents:
diff changeset
  1653
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1654
     * Entries held in the Cache of known ObjectStreamClass objects.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1655
     * Entries are chained together with the same hash value (modulo array size).
02bb8761fcce Initial load
duke
parents:
diff changeset
  1656
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1657
    private static class ObjectStreamClassEntry // extends java.lang.ref.SoftReference
02bb8761fcce Initial load
duke
parents:
diff changeset
  1658
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1659
        ObjectStreamClassEntry(ObjectStreamClass c) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1660
            //super(c);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1661
            this.c = c;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1662
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1663
        ObjectStreamClassEntry next;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1664
02bb8761fcce Initial load
duke
parents:
diff changeset
  1665
        public Object get()
02bb8761fcce Initial load
duke
parents:
diff changeset
  1666
        {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1667
            return c;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1668
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1669
        private ObjectStreamClass c;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1670
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1671
02bb8761fcce Initial load
duke
parents:
diff changeset
  1672
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1673
     * Comparator object for Classes and Interfaces
02bb8761fcce Initial load
duke
parents:
diff changeset
  1674
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1675
    private static Comparator compareClassByName =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1676
        new CompareClassByName();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1677
02bb8761fcce Initial load
duke
parents:
diff changeset
  1678
    private static class CompareClassByName implements Comparator {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1679
        public int compare(Object o1, Object o2) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1680
            Class c1 = (Class)o1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1681
            Class c2 = (Class)o2;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1682
            return (c1.getName()).compareTo(c2.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1683
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1684
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1685
02bb8761fcce Initial load
duke
parents:
diff changeset
  1686
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1687
     * Comparator for ObjectStreamFields by name
02bb8761fcce Initial load
duke
parents:
diff changeset
  1688
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1689
    private final static Comparator compareObjStrFieldsByName
02bb8761fcce Initial load
duke
parents:
diff changeset
  1690
        = new CompareObjStrFieldsByName();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1691
02bb8761fcce Initial load
duke
parents:
diff changeset
  1692
    private static class CompareObjStrFieldsByName implements Comparator {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1693
        public int compare(Object o1, Object o2) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1694
            ObjectStreamField osf1 = (ObjectStreamField)o1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1695
            ObjectStreamField osf2 = (ObjectStreamField)o2;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1696
02bb8761fcce Initial load
duke
parents:
diff changeset
  1697
            return osf1.getName().compareTo(osf2.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1698
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1699
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1700
02bb8761fcce Initial load
duke
parents:
diff changeset
  1701
    /*
02bb8761fcce Initial load
duke
parents:
diff changeset
  1702
     * Comparator object for Members, Fields, and Methods
02bb8761fcce Initial load
duke
parents:
diff changeset
  1703
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1704
    private static Comparator compareMemberByName =
02bb8761fcce Initial load
duke
parents:
diff changeset
  1705
        new CompareMemberByName();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1706
02bb8761fcce Initial load
duke
parents:
diff changeset
  1707
    private static class CompareMemberByName implements Comparator {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1708
        public int compare(Object o1, Object o2) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1709
            String s1 = ((Member)o1).getName();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1710
            String s2 = ((Member)o2).getName();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1711
02bb8761fcce Initial load
duke
parents:
diff changeset
  1712
            if (o1 instanceof Method) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1713
                s1 += getSignature((Method)o1);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1714
                s2 += getSignature((Method)o2);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1715
            } else if (o1 instanceof Constructor) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1716
                s1 += getSignature((Constructor)o1);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1717
                s2 += getSignature((Constructor)o2);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1718
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1719
            return s1.compareTo(s2);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1720
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1721
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1722
02bb8761fcce Initial load
duke
parents:
diff changeset
  1723
    /* It is expensive to recompute a method or constructor signature
02bb8761fcce Initial load
duke
parents:
diff changeset
  1724
       many times, so compute it only once using this data structure. */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1725
    private static class MethodSignature implements Comparator {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1726
        Member member;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1727
        String signature;      // cached parameter signature
02bb8761fcce Initial load
duke
parents:
diff changeset
  1728
02bb8761fcce Initial load
duke
parents:
diff changeset
  1729
        /* Given an array of Method or Constructor members,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1730
           return a sorted array of the non-private members.*/
02bb8761fcce Initial load
duke
parents:
diff changeset
  1731
        /* A better implementation would be to implement the returned data
02bb8761fcce Initial load
duke
parents:
diff changeset
  1732
           structure as an insertion sorted link list.*/
02bb8761fcce Initial load
duke
parents:
diff changeset
  1733
        static MethodSignature[] removePrivateAndSort(Member[] m) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1734
            int numNonPrivate = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1735
            for (int i = 0; i < m.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1736
                if (! Modifier.isPrivate(m[i].getModifiers())) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1737
                    numNonPrivate++;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1738
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1739
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1740
            MethodSignature[] cm = new MethodSignature[numNonPrivate];
02bb8761fcce Initial load
duke
parents:
diff changeset
  1741
            int cmi = 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1742
            for (int i = 0; i < m.length; i++) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1743
                if (! Modifier.isPrivate(m[i].getModifiers())) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1744
                    cm[cmi] = new MethodSignature(m[i]);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1745
                    cmi++;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1746
                }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1747
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1748
            if (cmi > 0)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1749
                Arrays.sort(cm, cm[0]);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1750
            return cm;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1751
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1752
02bb8761fcce Initial load
duke
parents:
diff changeset
  1753
        /* Assumes that o1 and o2 are either both methods
02bb8761fcce Initial load
duke
parents:
diff changeset
  1754
           or both constructors.*/
02bb8761fcce Initial load
duke
parents:
diff changeset
  1755
        public int compare(Object o1, Object o2) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1756
            /* Arrays.sort calls compare when o1 and o2 are equal.*/
02bb8761fcce Initial load
duke
parents:
diff changeset
  1757
            if (o1 == o2)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1758
                return 0;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1759
02bb8761fcce Initial load
duke
parents:
diff changeset
  1760
            MethodSignature c1 = (MethodSignature)o1;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1761
            MethodSignature c2 = (MethodSignature)o2;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1762
02bb8761fcce Initial load
duke
parents:
diff changeset
  1763
            int result;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1764
            if (isConstructor()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1765
                result = c1.signature.compareTo(c2.signature);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1766
            } else { // is a Method.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1767
                result = c1.member.getName().compareTo(c2.member.getName());
02bb8761fcce Initial load
duke
parents:
diff changeset
  1768
                if (result == 0)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1769
                    result = c1.signature.compareTo(c2.signature);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1770
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1771
            return result;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1772
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1773
02bb8761fcce Initial load
duke
parents:
diff changeset
  1774
        final private boolean isConstructor() {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1775
            return member instanceof Constructor;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1776
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1777
        private MethodSignature(Member m) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1778
            member = m;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1779
            if (isConstructor()) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1780
                signature = ObjectStreamClass.getSignature((Constructor)m);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1781
            } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1782
                signature = ObjectStreamClass.getSignature((Method)m);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1783
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1784
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1785
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1786
02bb8761fcce Initial load
duke
parents:
diff changeset
  1787
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1788
     * Returns non-static, non-abstract method with given signature provided it
02bb8761fcce Initial load
duke
parents:
diff changeset
  1789
     * is defined by or accessible (via inheritance) by the given class, or
02bb8761fcce Initial load
duke
parents:
diff changeset
  1790
     * null if no match found.  Access checks are disabled on the returned
02bb8761fcce Initial load
duke
parents:
diff changeset
  1791
     * method (if any).
02bb8761fcce Initial load
duke
parents:
diff changeset
  1792
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
  1793
     * Copied from the Merlin java.io.ObjectStreamClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1794
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1795
    private static Method getInheritableMethod(Class cl, String name,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1796
                                               Class[] argTypes,
02bb8761fcce Initial load
duke
parents:
diff changeset
  1797
                                               Class returnType)
02bb8761fcce Initial load
duke
parents:
diff changeset
  1798
    {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1799
        Method meth = null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1800
        Class defCl = cl;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1801
        while (defCl != null) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1802
            try {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1803
                meth = defCl.getDeclaredMethod(name, argTypes);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1804
                break;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1805
            } catch (NoSuchMethodException ex) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1806
                defCl = defCl.getSuperclass();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1807
            }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1808
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1809
02bb8761fcce Initial load
duke
parents:
diff changeset
  1810
        if ((meth == null) || (meth.getReturnType() != returnType)) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1811
            return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1812
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1813
        meth.setAccessible(true);
02bb8761fcce Initial load
duke
parents:
diff changeset
  1814
        int mods = meth.getModifiers();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1815
        if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1816
            return null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1817
        } else if ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1818
            return meth;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1819
        } else if ((mods & Modifier.PRIVATE) != 0) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1820
            return (cl == defCl) ? meth : null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1821
        } else {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1822
            return packageEquals(cl, defCl) ? meth : null;
02bb8761fcce Initial load
duke
parents:
diff changeset
  1823
        }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1824
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1825
02bb8761fcce Initial load
duke
parents:
diff changeset
  1826
    /**
02bb8761fcce Initial load
duke
parents:
diff changeset
  1827
     * Returns true if classes are defined in the same package, false
02bb8761fcce Initial load
duke
parents:
diff changeset
  1828
     * otherwise.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1829
     *
02bb8761fcce Initial load
duke
parents:
diff changeset
  1830
     * Copied from the Merlin java.io.ObjectStreamClass.
02bb8761fcce Initial load
duke
parents:
diff changeset
  1831
     */
02bb8761fcce Initial load
duke
parents:
diff changeset
  1832
    private static boolean packageEquals(Class cl1, Class cl2) {
02bb8761fcce Initial load
duke
parents:
diff changeset
  1833
        Package pkg1 = cl1.getPackage(), pkg2 = cl2.getPackage();
02bb8761fcce Initial load
duke
parents:
diff changeset
  1834
        return ((pkg1 == pkg2) || ((pkg1 != null) && (pkg1.equals(pkg2))));
02bb8761fcce Initial load
duke
parents:
diff changeset
  1835
    }
02bb8761fcce Initial load
duke
parents:
diff changeset
  1836
}