jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/RemoteClass.java
author ysuenaga
Fri, 11 Dec 2015 21:58:28 +0900
changeset 34493 c68e0ab807d8
parent 30655 d83f50188ca9
permissions -rw-r--r--
8036003: Add --with-debug-symbols=[none|internal|external|zipped] Reviewed-by: ihse, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 21278
diff changeset
     2
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.rmi.rmic;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.Hashtable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.ByteArrayOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.DataOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.security.MessageDigest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.security.DigestOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.security.NoSuchAlgorithmException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import sun.tools.java.Type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.tools.java.ClassDefinition;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.tools.java.ClassDeclaration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import sun.tools.java.MemberDefinition;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.tools.java.Identifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.tools.java.ClassNotFound;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * A RemoteClass object encapsulates RMI-specific information about
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * a remote implementation class, i.e. a class that implements
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * one or more remote interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * @author      Peter Jones
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
public class RemoteClass implements sun.rmi.rmic.RMIConstants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     * Create a RemoteClass object representing the remote meta-information
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     * of the given class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     * Returns true if successful.  If the class is not a properly formed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * remote implementation class or if some other error occurs, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     * return value will be null, and errors will have been reported to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * the supplied BatchEnvironment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    public static RemoteClass forClass(BatchEnvironment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
                                       ClassDefinition implClassDef)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
        RemoteClass rc = new RemoteClass(env, implClassDef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        if (rc.initialize()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
            return rc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * Return the ClassDefinition for this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    public ClassDefinition getClassDefinition() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        return implClassDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * Return the name of the class represented by this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    public Identifier getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        return implClassDef.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * Return an array of ClassDefinitions representing all of the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * interfaces implemented by this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * A remote interface is any interface that extends Remote,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * directly or indirectly.  The remote interfaces of a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * are the interfaces directly listed in either the class's
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     * "implements" clause, or the "implements" clause of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * of its superclasses, that are remote interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     * The order of the array returned is arbitrary, and some elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * may be superfluous (i.e., superinterfaces of other interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * in the array).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public ClassDefinition[] getRemoteInterfaces() {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   106
        return remoteInterfaces.clone();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * Return an array of RemoteClass.Method objects representing all of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * the remote methods implemented by this class, i.e. all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * methods in the class's remote interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     *
30655
d83f50188ca9 8080422: some docs cleanup for core libs
avstepan
parents: 25859
diff changeset
   114
     * The methods in the array are ordered according to the comparison
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * of the strings consisting of their method name followed by their
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * type signature, so each method's index in the array corresponds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * to its "operation number" in the JDK 1.1 version of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * stub/skeleton protocol.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public Method[] getRemoteMethods() {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   121
        return remoteMethods.clone();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Return the "interface hash" used to match a stub/skeleton pair for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * this class in the JDK 1.1 version of the stub/skeleton protocol.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    public long getInterfaceHash() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        return interfaceHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * Return string representation of this object, consisting of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * the string "remote class " followed by the class name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        return "remote class " + implClassDef.getName().toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    /** rmic environment for this object */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    private BatchEnvironment env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    /** the remote implementation class this object corresponds to */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    private ClassDefinition implClassDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /** remote interfaces implemented by this class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    private ClassDefinition[] remoteInterfaces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    /** all the remote methods of this class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    private Method[] remoteMethods;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    /** stub/skeleton "interface hash" for this class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    private long interfaceHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    /** cached definition for certain classes used in this environment */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    private ClassDefinition defRemote;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    private ClassDefinition defException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    private ClassDefinition defRemoteException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * Create a RemoteClass instance for the given class.  The resulting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     * object is not yet initialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    private RemoteClass(BatchEnvironment env, ClassDefinition implClassDef) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        this.env = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        this.implClassDef = implClassDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * Validate that the remote implementation class is properly formed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * and fill in the data structures required by the public interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    private boolean initialize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         * Verify that the "impl" is really a class, not an interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (implClassDef.isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            env.error(0, "rmic.cant.make.stubs.for.interface",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                      implClassDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
         * Initialize cached definitions for the Remote interface and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
         * the RemoteException class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            defRemote =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                env.getClassDeclaration(idRemote).getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            defException =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                env.getClassDeclaration(idJavaLangException).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            defRemoteException =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                env.getClassDeclaration(idRemoteException).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            env.error(0, "rmic.class.not.found", e.name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
         * Here we find all of the remote interfaces of our remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
         * implementation class.  For each class up the superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
         * chain, add each directly-implemented interface that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
         * somehow extends Remote to a list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
         */
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   207
        Vector<ClassDefinition> remotesImplemented = // list of remote interfaces found
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   208
            new Vector<ClassDefinition>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        for (ClassDefinition classDef = implClassDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
             classDef != null;)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                    ClassDeclaration[] interfaces = classDef.getInterfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                    for (int i = 0; i < interfaces.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                        ClassDefinition interfaceDef =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                            interfaces[i].getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                         * Add interface to the list if it extends Remote and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                         * it is not already there.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                        if (!remotesImplemented.contains(interfaceDef) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                            defRemote.implementedBy(env, interfaces[i]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                                remotesImplemented.addElement(interfaceDef);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                                /***** <DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                                if (env.verbose()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                                    System.out.println("[found remote interface: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                                                       interfaceDef.getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                                    /***** </DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                     * Verify that the candidate remote implementation class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                     * implements at least one remote interface directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                    if (classDef == implClassDef && remotesImplemented.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                        if (defRemote.implementedBy(env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                                                    implClassDef.getClassDeclaration()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                                 * This error message is used if the class does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                                 * implement a remote interface through one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                                 * its superclasses, but not directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                                env.error(0, "rmic.must.implement.remote.directly",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                                          implClassDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                                 * This error message is used if the class never
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                                 * implements a remote interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                                env.error(0, "rmic.must.implement.remote",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                                          implClassDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                     * Get definition for next superclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                    classDef = (classDef.getSuperClass() != null ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                                classDef.getSuperClass().getClassDefinition(env) :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                                null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                    env.error(0, "class.not.found", e.name, classDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
         * The "remotesImplemented" vector now contains all of the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
         * interfaces directly implemented by the remote class or by any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
         * of its superclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         * At this point, we could optimize the list by removing superfluous
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
         * entries, i.e. any interfaces that are implemented by some other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
         * interface in the list anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
         * This should be correct; would it be worthwhile?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
         *      for (int i = 0; i < remotesImplemented.size();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
         *          ClassDefinition interfaceDef =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
         *              (ClassDefinition) remotesImplemented.elementAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
         *          boolean isOtherwiseImplemented = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
         *          for (int j = 0; j < remotesImplemented.size; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
         *              if (j != i &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
         *                  interfaceDef.implementedBy(env, (ClassDefinition)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
         *                  remotesImplemented.elementAt(j).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
         *                      getClassDeclaration()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
         *              {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
         *                  isOtherwiseImplemented = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
         *                  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
         *              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
         *          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
         *          if (isOtherwiseImplemented) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
         *              remotesImplemented.removeElementAt(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
         *          } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
         *              ++i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
         *          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
         *      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
         * Now we collect the methods from all of the remote interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
         * into a hashtable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
         */
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   310
        Hashtable<String, Method> methods = new Hashtable<String, Method>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        boolean errors = false;
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   312
        for (Enumeration<ClassDefinition> enumeration
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   313
                 = remotesImplemented.elements();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
             enumeration.hasMoreElements();)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   316
                ClassDefinition interfaceDef = enumeration.nextElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                if (!collectRemoteMethods(interfaceDef, methods))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                    errors = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        if (errors)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
         * Convert vector of remote interfaces to an array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
         * (order is not important for this array).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        remoteInterfaces = new ClassDefinition[remotesImplemented.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        remotesImplemented.copyInto(remoteInterfaces);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
         * Sort table of remote methods into an array.  The elements are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
         * sorted in ascending order of the string of the method's name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
         * and type signature, so that each elements index is equal to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
         * its operation number of the JDK 1.1 version of the stub/skeleton
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
         * protocol.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        String[] orderedKeys = new String[methods.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        int count = 0;
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   339
        for (Enumeration<Method> enumeration = methods.elements();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
             enumeration.hasMoreElements();)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   342
                Method m = enumeration.nextElement();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                String key = m.getNameAndDescriptor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                int i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                for (i = count; i > 0; --i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                    if (key.compareTo(orderedKeys[i - 1]) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                    orderedKeys[i] = orderedKeys[i - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                orderedKeys[i] = key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                ++count;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        remoteMethods = new Method[methods.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        for (int i = 0; i < remoteMethods.length; i++) {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   356
            remoteMethods[i] = methods.get(orderedKeys[i]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            /***** <DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            if (env.verbose()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                System.out.print("[found remote method <" + i + ">: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                                 remoteMethods[i].getOperationString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                ClassDeclaration[] exceptions =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                    remoteMethods[i].getExceptions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                if (exceptions.length > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    System.out.print(" throws ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                for (int j = 0; j < exceptions.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    if (j > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                        System.out.print(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    System.out.print(exceptions[j].getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                System.out.println("]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            /***** </DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
         * Finally, pre-compute the interface hash to be used by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
         * stubs/skeletons for this remote class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        interfaceHash = computeInterfaceHash();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * Collect and validate all methods from given interface and all of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * its superinterfaces as remote methods.  Remote methods are added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     * to the supplied hashtable.  Returns true if successful,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * or false if an error occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    private boolean collectRemoteMethods(ClassDefinition interfaceDef,
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   391
                                         Hashtable<String, Method> table)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        if (!interfaceDef.isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            throw new Error(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                            "expected interface, not class: " + interfaceDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
         * rmic used to enforce that a remote interface could not extend
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
         * a non-remote interface, i.e. an interface that did not itself
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
         * extend from Remote.  The current version of rmic does not have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
         * this restriction, so the following code is now commented out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
         * Verify that this interface extends Remote, since all interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
         * extended by a remote interface must implement Remote.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
         *      try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
         *          if (!defRemote.implementedBy(env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
         *              interfaceDef.getClassDeclaration()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
         *          {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
         *              env.error(0, "rmic.can.mix.remote.nonremote",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
         *                  interfaceDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
         *              return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
         *          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
         *      } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
         *          env.error(0, "class.not.found", e.name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
         *              interfaceDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
         *          return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
         *      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        boolean errors = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
         * Search interface's members for methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    nextMember:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        for (MemberDefinition member = interfaceDef.getFirstMember();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
             member != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
             member = member.getNextMember())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                if (member.isMethod() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                    !member.isConstructor() && !member.isInitializer())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                         * Verify that each method throws RemoteException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                        ClassDeclaration[] exceptions = member.getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                        boolean hasRemoteException = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                        for (int i = 0; i < exceptions.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                             * rmic used to enforce that a remote method had to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                             * explicitly list RemoteException in its "throws"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                             * clause; i.e., just throwing Exception was not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                             * acceptable.  The current version of rmic does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                             * have this restriction, so the following code is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                             * now commented out.  Instead, the method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                             * considered valid if RemoteException is a subclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                             * of any of the methods declared exceptions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                             *  if (exceptions[i].getName().equals(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                             *      idRemoteException))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                             *  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                             *      hasRemoteException = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                             *      break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                             *  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                                if (defRemoteException.subClassOf(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                                                                  env, exceptions[i]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                                        hasRemoteException = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                            } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                                env.error(0, "class.not.found", e.name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                                          interfaceDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                                continue nextMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                         * If this method did not throw RemoteException as required,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                         * generate the error but continue, so that multiple such
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                         * errors can be reported.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                        if (!hasRemoteException) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                            env.error(0, "rmic.must.throw.remoteexception",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                                      interfaceDef.getName(), member.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                            errors = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                            continue nextMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                         * Verify that the implementation of this method throws only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                         * java.lang.Exception or its subclasses (fix bugid 4092486).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                         * JRMP does not support remote methods throwing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                         * java.lang.Throwable or other subclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                            MemberDefinition implMethod = implClassDef.findMethod(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                                                                                  env, member.getName(), member.getType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                            if (implMethod != null) {           // should not be null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                                exceptions = implMethod.getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                                for (int i = 0; i < exceptions.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                                    if (!defException.superClassOf(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                                                                   env, exceptions[i]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                                        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                                            env.error(0, "rmic.must.only.throw.exception",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                                                      implMethod.toString(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                                                      exceptions[i].getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                                            errors = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                                            continue nextMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                        } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                            env.error(0, "class.not.found", e.name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                                      implClassDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                            continue nextMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                         * Create RemoteClass.Method object to represent this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                         * found in a remote interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                        Method newMethod = new Method(member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                         * Store remote method's representation in the table of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                         * remote methods found, keyed by its name and parameter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                         * signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                         * If the table already contains an entry with the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                         * method name and parameter signature, then we must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                         * replace the old entry with a Method object that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
                         * represents a legal combination of the old and the new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                         * methods; specifically, the combined method must have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                         * a throws list that contains (only) all of the checked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                         * exceptions that can be thrown by both the old or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                         * the new method (see bugid 4070653).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                        String key = newMethod.getNameAndDescriptor();
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   532
                        Method oldMethod = table.get(key);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                        if (oldMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                            newMethod = newMethod.mergeWith(oldMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                            if (newMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                                errors = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                                continue nextMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                        table.put(key, newMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
         * Recursively collect methods for all superinterfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            ClassDeclaration[] superDefs = interfaceDef.getInterfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            for (int i = 0; i < superDefs.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                ClassDefinition superDef =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                    superDefs[i].getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                if (!collectRemoteMethods(superDef, table))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                    errors = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            env.error(0, "class.not.found", e.name, interfaceDef.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        return !errors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * Compute the "interface hash" of the stub/skeleton pair for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * remote implementation class.  This is the 64-bit value used to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * enforce compatibility between a stub and a skeleton using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * JDK 1.1 version of the stub/skeleton protocol.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * It is calculated using the first 64 bits of a SHA digest.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * digest is from a stream consisting of the following data:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     *     (int) stub version number, always 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     *     for each remote method, in order of operation number:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     *         (UTF) method name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     *         (UTF) method type signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     *         for each declared exception, in alphabetical name order:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     *             (UTF) name of exception class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    private long computeInterfaceHash() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        long hash = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            MessageDigest md = MessageDigest.getInstance("SHA");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            DataOutputStream out = new DataOutputStream(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                                                        new DigestOutputStream(sink, md));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            out.writeInt(INTERFACE_HASH_STUB_VERSION);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            for (int i = 0; i < remoteMethods.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                MemberDefinition m = remoteMethods[i].getMemberDefinition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                Identifier name = m.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                Type type = m.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                out.writeUTF(name.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                // type signatures already use mangled class names
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                out.writeUTF(type.getTypeSignature());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                ClassDeclaration exceptions[] = m.getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                sortClassDeclarations(exceptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                for (int j = 0; j < exceptions.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                    out.writeUTF(Names.mangleClass(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                                                   exceptions[j].getName()).toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            out.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            // use only the first 64 bits of the digest for the hash
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            byte hashArray[] = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            for (int i = 0; i < Math.min(8, hashArray.length); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            throw new Error(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                            "unexpected exception computing intetrface hash: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            throw new Error(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                            "unexpected exception computing intetrface hash: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        return hash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
     * Sort array of class declarations alphabetically by their mangled
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 5506
diff changeset
   624
     * fully-qualified class name.  This is used to feed a method's exceptions
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     * in a canonical order into the digest stream for the interface hash
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * computation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
    private void sortClassDeclarations(ClassDeclaration[] decl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        for (int i = 1; i < decl.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            ClassDeclaration curr = decl[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            String name = Names.mangleClass(curr.getName()).toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            int j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            for (j = i; j > 0; j--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                if (name.compareTo(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                                   Names.mangleClass(decl[j - 1].getName()).toString()) >= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                decl[j] = decl[j - 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            decl[j] = curr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * A RemoteClass.Method object encapsulates RMI-specific information
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * about a particular remote method in the remote implementation class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * represented by the outer instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    public class Method implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
         * Return the definition of the actual class member corresponing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
         * to this method of a remote interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
         * REMIND: Can this method be removed?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        public MemberDefinition getMemberDefinition() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            return memberDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
         * Return the name of this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        public Identifier getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            return memberDef.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
         * Return the type of this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        public Type getType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            return memberDef.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
         * Return an array of the exception classes declared to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
         * thrown by this remote method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
         * For methods with the same name and type signature inherited
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
         * from multiple remote interfaces, the array will contain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
         * the set of exceptions declared in all of the interfaces'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
         * methods that can be legally thrown in each of them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        public ClassDeclaration[] getExceptions() {
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   687
            return exceptions.clone();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
         * Return the "method hash" used to identify this remote method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
         * in the JDK 1.2 version of the stub protocol.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        public long getMethodHash() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            return methodHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
         * Return the string representation of this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            return memberDef.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
         * Return the string representation of this method appropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
         * for the construction of a java.rmi.server.Operation object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        public String getOperationString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            return memberDef.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
         * Return a string consisting of this method's name followed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
         * its method descriptor, using the Java VM's notation for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
         * method descriptors (see section 4.3.3 of The Java Virtual
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
         * Machine Specification).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        public String getNameAndDescriptor() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
            return memberDef.getName().toString() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                memberDef.getType().getTypeSignature();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
         * Member definition for this method, from one of the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
         * interfaces that this method was found in.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
         * Note that this member definition may be only one of several
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
         * member defintions that correspond to this remote method object,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
         * if several of this class's remote interfaces contain methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
         * with the same name and type signature.  Therefore, this member
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
         * definition may declare more exceptions thrown that this remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
         * method does.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        private MemberDefinition memberDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        /** stub "method hash" to identify this method */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        private long methodHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
         * Exceptions declared to be thrown by this remote method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
         * This list can include superfluous entries, such as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
         * unchecked exceptions and subclasses of other entries.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        private ClassDeclaration[] exceptions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
         * Create a new Method object corresponding to the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
         * method definition.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
         * Temporarily comment out the private modifier until
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
         * the VM allows outer class to access inner class's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
         * private constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        /* private */ Method(MemberDefinition memberDef) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            this.memberDef = memberDef;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            exceptions = memberDef.getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
            methodHash = computeMethodHash();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
         * Cloning is supported by returning a shallow copy of this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                return super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            } catch (CloneNotSupportedException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                throw new Error("clone failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
         * Return a new Method object that is a legal combination of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
         * this method object and another one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
         * This requires determining the exceptions declared by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
         * combined method, which must be (only) all of the exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
         * declared in both old Methods that may thrown in either of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
         * them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        private Method mergeWith(Method other) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            if (!getName().equals(other.getName()) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                !getType().equals(other.getType()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                    throw new Error("attempt to merge method \"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                                    other.getNameAndDescriptor() + "\" with \"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                                    getNameAndDescriptor());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   792
            Vector<ClassDeclaration> legalExceptions
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   793
                = new Vector<ClassDeclaration>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                collectCompatibleExceptions(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                                            other.exceptions, exceptions, legalExceptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                collectCompatibleExceptions(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                                            exceptions, other.exceptions, legalExceptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
            } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                env.error(0, "class.not.found", e.name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                          getClassDefinition().getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            Method merged = (Method) clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            merged.exceptions = new ClassDeclaration[legalExceptions.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            legalExceptions.copyInto(merged.exceptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            return merged;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
         * Add to the supplied list all exceptions in the "from" array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
         * that are subclasses of an exception in the "with" array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        private void collectCompatibleExceptions(ClassDeclaration[] from,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                                                 ClassDeclaration[] with,
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   818
                                                 Vector<ClassDeclaration> list)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            throws ClassNotFound
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            for (int i = 0; i < from.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                ClassDefinition exceptionDef = from[i].getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                if (!list.contains(from[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                    for (int j = 0; j < with.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                        if (exceptionDef.subClassOf(env, with[j])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                            list.addElement(from[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
         * Compute the "method hash" of this remote method.  The method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
         * hash is a long containing the first 64 bits of the SHA digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
         * from the UTF encoded string of the method name and descriptor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
         * REMIND: Should this method share implementation code with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
         * the outer class's computeInterfaceHash() method?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        private long computeMethodHash() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            long hash = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                MessageDigest md = MessageDigest.getInstance("SHA");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                DataOutputStream out = new DataOutputStream(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                                                            new DigestOutputStream(sink, md));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                String methodString = getNameAndDescriptor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                /***** <DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                if (env.verbose()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                    System.out.println("[string used for method hash: \"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                                       methodString + "\"]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                /***** </DEBUG> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                out.writeUTF(methodString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                // use only the first 64 bits of the digest for the hash
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                out.flush();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                byte hashArray[] = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                for (int i = 0; i < Math.min(8, hashArray.length); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                throw new Error(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                                "unexpected exception computing intetrface hash: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
            } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                throw new Error(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                                "unexpected exception computing intetrface hash: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
            return hash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
}