jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/StubSkeletonWriter.java
author malenkov
Tue, 29 Oct 2013 17:01:06 +0400
changeset 21278 ef8a3a2a72f2
parent 5506 202f599c92aa
child 23010 6dadb192ad81
permissions -rw-r--r--
8022746: List of spelling errors in API doc Reviewed-by: alexsch, smarks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 2003, 2005, 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: 2
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: 2
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: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
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.newrmic.jrmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import com.sun.javadoc.ClassDoc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import com.sun.javadoc.MethodDoc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import com.sun.javadoc.Type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import sun.rmi.rmic.newrmic.BatchEnvironment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import sun.rmi.rmic.newrmic.IndentingWriter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import static sun.rmi.rmic.newrmic.Constants.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import static sun.rmi.rmic.newrmic.jrmp.Constants.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * Writes the source code for the stub class and (optionally) skeleton
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * class for a particular remote implementation class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @author Peter Jones
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
class StubSkeletonWriter {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    /** rmic environment for this object */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private final BatchEnvironment env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
21278
ef8a3a2a72f2 8022746: List of spelling errors in API doc
malenkov
parents: 5506
diff changeset
    56
    /** the remote implementation class to generate code for */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    private final RemoteClass remoteClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    /** version of the JRMP stub protocol to generate code for */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    private final StubVersion version;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     * binary names of the stub and skeleton classes to generate for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * the remote class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    private final String stubClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    private final String skeletonClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    /* package name and simple names of the stub and skeleton classes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private final String packageName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    private final String stubClassSimpleName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    private final String skeletonClassSimpleName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    /** remote methods of class, indexed by operation number */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    private final RemoteClass.Method[] remoteMethods;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * Names to use for the java.lang.reflect.Method static fields in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * the generated stub class corresponding to each remote method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private final String[] methodFieldNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * Creates a StubSkeletonWriter instance for the specified remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * implementation class.  The generated code will implement the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     * specified JRMP stub protocol version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    StubSkeletonWriter(BatchEnvironment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                       RemoteClass remoteClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                       StubVersion version)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        this.env = env;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
        this.remoteClass = remoteClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        this.version = version;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        stubClassName = Util.binaryNameOf(remoteClass.classDoc()) + "_Stub";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        skeletonClassName =
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            Util.binaryNameOf(remoteClass.classDoc()) + "_Skel";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        int i = stubClassName.lastIndexOf('.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        packageName = (i != -1 ? stubClassName.substring(0, i) : "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        stubClassSimpleName = stubClassName.substring(i + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        skeletonClassSimpleName = skeletonClassName.substring(i + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
        remoteMethods = remoteClass.remoteMethods();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        methodFieldNames = nameMethodFields(remoteMethods);
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
     * Returns the binary name of the stub class to generate for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     * remote implementation class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    String stubClassName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        return stubClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * Returns the binary name of the skeleton class to generate for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * the remote implementation class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    String skeletonClassName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        return skeletonClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * Writes the stub class for the remote class to a stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    void writeStub(IndentingWriter p) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
         * Write boiler plate comment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        p.pln("// Stub class generated by rmic, do not edit.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        p.pln("// Contents subject to change without notice.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
         * If remote implementation class was in a particular package,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
         * declare the stub class to be in the same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        if (!packageName.equals("")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            p.pln("package " + packageName + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
         * Declare the stub class; implement all remote interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        p.plnI("public final class " + stubClassSimpleName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        p.pln("extends " + REMOTE_STUB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        ClassDoc[] remoteInterfaces = remoteClass.remoteInterfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (remoteInterfaces.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            p.p("implements ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            for (int i = 0; i < remoteInterfaces.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                    p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                p.p(remoteInterfaces[i].qualifiedName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        p.pOlnI("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (version == StubVersion.V1_1 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            version == StubVersion.VCOMPAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            writeOperationsArray(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            writeInterfaceHash(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        if (version == StubVersion.VCOMPAT ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            version == StubVersion.V1_2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            p.pln("private static final long serialVersionUID = " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                STUB_SERIAL_VERSION_UID + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
             * We only need to declare and initialize the static fields of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
             * Method objects for each remote method if there are any remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
             * methods; otherwise, skip this code entirely, to avoid generating
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
             * a try/catch block for a checked exception that cannot occur
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
             * (see bugid 4125181).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            if (methodFieldNames.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                    p.pln("private static boolean useNewInvoke;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                writeMethodFieldDeclarations(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                 * Initialize java.lang.reflect.Method fields for each remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                 * method in a static initializer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                p.plnI("static {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                     * Fat stubs must determine whether the API required for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                     * the JDK 1.2 stub protocol is supported in the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                     * runtime, so that it can use it if supported.  This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                     * determined by using the Reflection API to test if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                     * new invoke method on RemoteRef exists, and setting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                     * static boolean "useNewInvoke" to true if it does, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                     * to false if a NoSuchMethodException is thrown.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                    p.plnI(REMOTE_REF + ".class.getMethod(\"invoke\",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                    p.plnI("new java.lang.Class[] {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                    p.pln(REMOTE + ".class,");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                    p.pln("java.lang.reflect.Method.class,");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                    p.pln("java.lang.Object[].class,");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                    p.pln("long.class");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    p.pOln("});");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                    p.pO();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                    p.pln("useNewInvoke = true;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                writeMethodFieldInitializers(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                p.pOlnI("} catch (java.lang.NoSuchMethodException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                    p.pln("useNewInvoke = false;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                    p.plnI("throw new java.lang.NoSuchMethodError(");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                    p.pln("\"stub class initialization failed\");");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                    p.pO();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                p.pOln("}");            // end try/catch block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                p.pOln("}");            // end static initializer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                p.pln();
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
        writeStubConstructors(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
         * Write each stub method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        if (remoteMethods.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            p.pln("// methods from remote interfaces");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            for (int i = 0; i < remoteMethods.length; ++i) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                writeStubMethod(p, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        p.pOln("}");                    // end stub class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * Writes the constructors for the stub class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    private void writeStubConstructors(IndentingWriter p)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        p.pln("// constructors");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
         * Only stubs compatible with the JDK 1.1 stub protocol need
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
         * a no-arg constructor; later versions use reflection to find
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
         * the constructor that directly takes a RemoteRef argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        if (version == StubVersion.V1_1 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            version == StubVersion.VCOMPAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            p.plnI("public " + stubClassSimpleName + "() {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            p.pln("super();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        p.plnI("public " + stubClassSimpleName + "(" + REMOTE_REF + " ref) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        p.pln("super(ref);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     * Writes the stub method for the remote method with the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * operation number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    private void writeStubMethod(IndentingWriter p, int opnum)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        RemoteClass.Method method = remoteMethods[opnum];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        MethodDoc methodDoc = method.methodDoc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        String methodName = methodDoc.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        Type[] paramTypes = method.parameterTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        String paramNames[] = nameParameters(paramTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        Type returnType = methodDoc.returnType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        ClassDoc[] exceptions = method.exceptionTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
         * Declare stub method; throw exceptions declared in remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
         * interface(s).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        p.pln("// implementation of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
              Util.getFriendlyUnqualifiedSignature(methodDoc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        p.p("public " + returnType.toString() + " " + methodName + "(");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        for (int i = 0; i < paramTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            p.p(paramTypes[i].toString() + " " + paramNames[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        p.plnI(")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        if (exceptions.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            p.p("throws ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            for (int i = 0; i < exceptions.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                    p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                p.p(exceptions[i].qualifiedName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        p.pOlnI("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
         * The RemoteRef.invoke methods throw Exception, but unless
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
         * this stub method throws Exception as well, we must catch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
         * Exceptions thrown from the invocation.  So we must catch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
         * Exception and rethrow something we can throw:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
         * UnexpectedException, which is a subclass of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
         * RemoteException.  But for any subclasses of Exception that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
         * we can throw, like RemoteException, RuntimeException, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
         * any of the exceptions declared by this stub method, we want
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
         * them to pass through unmodified, so first we must catch any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
         * such exceptions and rethrow them directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
         * We have to be careful generating the rethrowing catch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
         * blocks here, because javac will flag an error if there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
         * any unreachable catch blocks, i.e. if the catch of an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
         * exception class follows a previous catch of it or of one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
         * its superclasses.  The following method invocation takes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
         * care of these details.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        List<ClassDoc> catchList = computeUniqueCatchList(exceptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
         * If we need to catch any particular exceptions (i.e. this method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
         * does not declare java.lang.Exception), put the entire stub
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
         * method in a try block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        if (catchList.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            p.plnI("if (useNewInvoke) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        if (version == StubVersion.VCOMPAT ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            version == StubVersion.V1_2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            if (!Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                p.p("Object $result = ");               // REMIND: why $?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            if (paramTypes.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
                p.p("new java.lang.Object[] {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                for (int i = 0; i < paramTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                    if (i > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                        p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                p.p("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                p.p("null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            p.pln(", " + method.methodHash() + "L);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            if (!Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                p.pln("return " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                    unwrapArgumentCode(returnType, "$result") + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            p.pOlnI("} else {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        if (version == StubVersion.V1_1 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            version == StubVersion.VCOMPAT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            p.pln(REMOTE_CALL + " call = ref.newCall((" + REMOTE_OBJECT +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                ") this, operations, " + opnum + ", interfaceHash);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            if (paramTypes.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                p.pln("java.io.ObjectOutput out = call.getOutputStream();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                writeMarshalArguments(p, "out", paramTypes, paramNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                p.pOlnI("} catch (java.io.IOException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                p.pln("throw new " + MARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                    "(\"error marshalling arguments\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            p.pln("ref.invoke(call);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            if (Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                p.pln("ref.done(call);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                p.pln(returnType.toString() + " $result;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                                                        // REMIND: why $?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
                p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                p.pln("java.io.ObjectInput in = call.getInputStream();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                boolean objectRead =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                    writeUnmarshalArgument(p, "in", returnType, "$result");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                p.pln(";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                p.pOlnI("} catch (java.io.IOException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                p.pln("throw new " + UNMARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                    "(\"error unmarshalling return\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                 * If any only if readObject has been invoked, we must catch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                 * ClassNotFoundException as well as IOException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                if (objectRead) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                    p.pln("throw new " + UNMARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                        "(\"error unmarshalling return\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                p.pOlnI("} finally {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                p.pln("ref.done(call);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                p.pln("return $result;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            p.pOln("}");                // end if/else (useNewInvoke) block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
         * If we need to catch any particular exceptions, finally write
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
         * the catch blocks for them, rethrow any other Exceptions with an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
         * UnexpectedException, and end the try block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        if (catchList.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            for (ClassDoc catchClass : catchList) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                p.pOlnI("} catch (" + catchClass.qualifiedName() + " e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                p.pln("throw e;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            p.pOlnI("} catch (java.lang.Exception e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            p.pln("throw new " + UNEXPECTED_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                "(\"undeclared checked exception\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            p.pOln("}");                // end try/catch block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        p.pOln("}");                    // end stub method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * Computes the exceptions that need to be caught and rethrown in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * a stub method before wrapping Exceptions in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     * UnexpectedExceptions, given the exceptions declared in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * throws clause of the method.  Returns a list containing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * exception to catch.  Each exception is guaranteed to be unique,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * i.e. not a subclass of any of the other exceptions in the list,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     * so the catch blocks for these exceptions may be generated in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * any order relative to each other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     * RemoteException and RuntimeException are each automatically
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * placed in the returned list (unless any of their superclasses
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     * are already present), since those exceptions should always be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
     * directly rethrown by a stub method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * The returned list will be empty if java.lang.Exception or one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     * of its superclasses is in the throws clause of the method,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
     * indicating that no exceptions need to be caught.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    private List<ClassDoc> computeUniqueCatchList(ClassDoc[] exceptions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        List<ClassDoc> uniqueList = new ArrayList<ClassDoc>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        uniqueList.add(env.docRuntimeException());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        uniqueList.add(env.docRemoteException()); // always catch/rethrow these
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        /* For each exception declared by the stub method's throws clause: */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    nextException:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        for (ClassDoc ex : exceptions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
            if (env.docException().subclassOf(ex)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                 * If java.lang.Exception (or a superclass) was declared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                 * in the throws clause of this stub method, then we don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                 * have to bother catching anything; clear the list and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                 * return.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                uniqueList.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            } else if (!ex.subclassOf(env.docException())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                 * Ignore other Throwables that do not extend Exception,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                 * because they cannot be thrown by the invoke methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
             * Compare this exception against the current list of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
             * exceptions that need to be caught:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            for (Iterator<ClassDoc> i = uniqueList.iterator(); i.hasNext();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                ClassDoc ex2 = i.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                if (ex.subclassOf(ex2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                     * If a superclass of this exception is already on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                     * the list to catch, then ignore this one and continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                    continue nextException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                } else if (ex2.subclassOf(ex)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                     * If a subclass of this exception is on the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                     * to catch, then remove it;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                    i.remove();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            /* This exception is unique: add it to the list to catch. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            uniqueList.add(ex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        return uniqueList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     * Writes the skeleton for the remote class to a stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
    void writeSkeleton(IndentingWriter p) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        if (version == StubVersion.V1_2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            throw new AssertionError(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                "should not generate skeleton for version " + version);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
         * Write boiler plate comment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        p.pln("// Skeleton class generated by rmic, do not edit.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        p.pln("// Contents subject to change without notice.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
         * If remote implementation class was in a particular package,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
         * declare the skeleton class to be in the same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        if (!packageName.equals("")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            p.pln("package " + packageName + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            p.pln();
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
         * Declare the skeleton class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        p.plnI("public final class " + skeletonClassSimpleName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        p.pln("implements " + SKELETON);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        p.pOlnI("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        writeOperationsArray(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        writeInterfaceHash(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
         * Define the getOperations() method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        p.plnI("public " + OPERATION + "[] getOperations() {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
        p.pln("return (" + OPERATION + "[]) operations.clone();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
        p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
         * Define the dispatch() method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        p.plnI("public void dispatch(" + REMOTE + " obj, " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            REMOTE_CALL + " call, int opnum, long hash)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
        p.pln("throws java.lang.Exception");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        p.pOlnI("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            p.plnI("if (opnum < 0) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            if (remoteMethods.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                    if (opnum > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                        p.pO("} else ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                    p.plnI("if (hash == " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                        remoteMethods[opnum].methodHash() + "L) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                    p.pln("opnum = " + opnum + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                p.pOlnI("} else {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
             * Skeleton throws UnmarshalException if it does not recognize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
             * the method hash; this is what UnicastServerRef.dispatch()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
             * would do.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            p.pln("throw new " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                UNMARSHAL_EXCEPTION + "(\"invalid method hash\");");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            if (remoteMethods.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
             * Ignore the validation of the interface hash if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
             * operation number was negative, since it is really a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
             * method hash instead.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            p.pOlnI("} else {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        p.plnI("if (hash != interfaceHash)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        p.pln("throw new " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            SKELETON_MISMATCH_EXCEPTION + "(\"interface hash mismatch\");");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        p.pO();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        if (version == StubVersion.VCOMPAT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            p.pOln("}");                // end if/else (opnum < 0) block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
         * Cast remote object reference to the remote implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
         * class, if it's not private.  We don't use the binary name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
         * of the class like previous implementations did because that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
         * would not compile with javac (since 1.4.1).  If the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
         * implementation class is private, then we can't cast to it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
         * like previous implementations did because that also would
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
         * not compile with javac-- so instead, we'll have to try to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
         * cast to the remote interface for each remote method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        if (!remoteClass.classDoc().isPrivate()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            p.pln(remoteClass.classDoc().qualifiedName() + " server = (" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                  remoteClass.classDoc().qualifiedName() + ") obj;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
         * Process call according to the operation number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        p.plnI("switch (opnum) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            writeSkeletonDispatchCase(p, opnum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        p.pOlnI("default:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
         * Skeleton throws UnmarshalException if it does not recognize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
         * the operation number; this is consistent with the case of an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
         * unrecognized method hash.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        p.pln("throw new " + UNMARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            "(\"invalid method number\");");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        p.pOln("}");                    // end switch statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        p.pOln("}");                    // end dispatch() method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        p.pOln("}");                    // end skeleton class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     * Writes the case block for the skeleton's dispatch method for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * the remote method with the given "opnum".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    private void writeSkeletonDispatchCase(IndentingWriter p, int opnum)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        RemoteClass.Method method = remoteMethods[opnum];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        MethodDoc methodDoc = method.methodDoc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        String methodName = methodDoc.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        Type paramTypes[] = method.parameterTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        String paramNames[] = nameParameters(paramTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        Type returnType = methodDoc.returnType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        p.pOlnI("case " + opnum + ": // " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            Util.getFriendlyUnqualifiedSignature(methodDoc));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
         * Use nested block statement inside case to provide an independent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
         * namespace for local variables used to unmarshal parameters for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
         * this remote method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        p.pOlnI("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        if (paramTypes.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
             * Declare local variables to hold arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            for (int i = 0; i < paramTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                p.pln(paramTypes[i].toString() + " " + paramNames[i] + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
             * Unmarshal arguments from call stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            p.pln("java.io.ObjectInput in = call.getInputStream();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            boolean objectsRead = writeUnmarshalArguments(p, "in",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                paramTypes, paramNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            p.pOlnI("} catch (java.io.IOException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            p.pln("throw new " + UNMARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                "(\"error unmarshalling arguments\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
             * If any only if readObject has been invoked, we must catch
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
             * ClassNotFoundException as well as IOException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
            if (objectsRead) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                p.pln("throw new " + UNMARSHAL_EXCEPTION +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
                    "(\"error unmarshalling arguments\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            p.pOlnI("} finally {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            p.pln("call.releaseInputStream();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            p.pln("call.releaseInputStream();");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        if (!Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
             * Declare variable to hold return type, if not void.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            p.p(returnType.toString() + " $result = ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                                                        // REMIND: why $?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
         * Invoke the method on the server object.  If the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
         * implementation class is private, then we don't have a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
         * reference cast to it, and so we try to cast to the remote
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
         * object reference to the method's declaring interface here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        String target = remoteClass.classDoc().isPrivate() ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            "((" + methodDoc.containingClass().qualifiedName() + ") obj)" :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            "server";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        p.p(target + "." + methodName + "(");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        for (int i = 0; i < paramNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            if (i > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
            p.p(paramNames[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        p.pln(");");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
         * Always invoke getResultStream(true) on the call object to send
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
         * the indication of a successful invocation to the caller.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
         * the return type is not void, keep the result stream and marshal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
         * the return value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        p.plnI("try {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        if (!Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            p.p("java.io.ObjectOutput out = ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        p.pln("call.getResultStream(true);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        if (!Util.isVoid(returnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            writeMarshalArgument(p, "out", returnType, "$result");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            p.pln(";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        p.pOlnI("} catch (java.io.IOException e) {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        p.pln("throw new " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            MARSHAL_EXCEPTION + "(\"error marshalling return\", e);");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        p.pOln("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        p.pln("break;");                // break from switch statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        p.pOlnI("}");                   // end nested block statement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * Writes declaration and initializer for "operations" static array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    private void writeOperationsArray(IndentingWriter p)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        p.plnI("private static final " + OPERATION + "[] operations = {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        for (int i = 0; i < remoteMethods.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            if (i > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                p.pln(",");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            p.p("new " + OPERATION + "(\"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                remoteMethods[i].operationString() + "\")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        p.pln();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        p.pOln("};");
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
     * Writes declaration and initializer for "interfaceHash" static field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    private void writeInterfaceHash(IndentingWriter p)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        p.pln("private static final long interfaceHash = " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            remoteClass.interfaceHash() + "L;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
     * Writes declaration for java.lang.reflect.Method static fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     * corresponding to each remote method in a stub.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    private void writeMethodFieldDeclarations(IndentingWriter p)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
        for (String name : methodFieldNames) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
            p.pln("private static java.lang.reflect.Method " + name + ";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
     * Writes code to initialize the static fields for each method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
     * using the Java Reflection API.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    private void writeMethodFieldInitializers(IndentingWriter p)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        for (int i = 0; i < methodFieldNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            p.p(methodFieldNames[i] + " = ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
             * Look up the Method object in the somewhat arbitrary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
             * interface that we find in the Method object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            RemoteClass.Method method = remoteMethods[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            MethodDoc methodDoc = method.methodDoc();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
            String methodName = methodDoc.name();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            Type paramTypes[] = method.parameterTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            p.p(methodDoc.containingClass().qualifiedName() + ".class.getMethod(\"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                methodName + "\", new java.lang.Class[] {");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            for (int j = 0; j < paramTypes.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                if (j > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                    p.p(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                p.p(paramTypes[j].toString() + ".class");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            p.pln("});");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     * Following are a series of static utility methods useful during
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * the code generation process:
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
     * Generates an array of names for fields correspondins to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
     * given array of remote methods.  Each name in the returned array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
     * is guaranteed to be unique.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
     * The name of a method is included in its corresponding field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
     * name to enhance readability of the generated code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    private static String[] nameMethodFields(RemoteClass.Method[] methods) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        String[] names = new String[methods.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        for (int i = 0; i < names.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            names[i] = "$method_" + methods[i].methodDoc().name() + "_" + i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        return names;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
     * Generates an array of names for parameters corresponding to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
     * given array of types for the parameters.  Each name in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
     * returned array is guaranteed to be unique.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
     * A representation of the type of a parameter is included in its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
     * corresponding parameter name to enhance the readability of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
     * generated code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
    private static String[] nameParameters(Type[] types) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        String[] names = new String[types.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        for (int i = 0; i < names.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            names[i] = "$param_" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                generateNameFromType(types[i]) + "_" + (i + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        return names;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
     * Generates a readable string representing the given type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
     * suitable for embedding within a Java identifier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    private static String generateNameFromType(Type type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        String name = type.typeName().replace('.', '$');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        int dimensions = type.dimension().length() / 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        for (int i = 0; i < dimensions; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
            name = "arrayOf_" + name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
        return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     * Writes a snippet of Java code to marshal a value named "name"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * of type "type" to the java.io.ObjectOutput stream named
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     * "stream".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
     * Primitive types are marshalled with their corresponding methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * in the java.io.DataOutput interface, and objects (including
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     * arrays) are marshalled using the writeObject method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
    private static void writeMarshalArgument(IndentingWriter p,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                                             String streamName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                                             Type type, String name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            p.p(streamName + ".writeObject(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        } else if (type.typeName().equals("boolean")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            p.p(streamName + ".writeBoolean(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
        } else if (type.typeName().equals("byte")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
            p.p(streamName + ".writeByte(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        } else if (type.typeName().equals("char")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
            p.p(streamName + ".writeChar(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        } else if (type.typeName().equals("short")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
            p.p(streamName + ".writeShort(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        } else if (type.typeName().equals("int")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            p.p(streamName + ".writeInt(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
        } else if (type.typeName().equals("long")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
            p.p(streamName + ".writeLong(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        } else if (type.typeName().equals("float")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
            p.p(streamName + ".writeFloat(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        } else if (type.typeName().equals("double")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
            p.p(streamName + ".writeDouble(" + name + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
            throw new AssertionError(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     * Writes Java statements to marshal a series of values in order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     * as named in the "names" array, with types as specified in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * "types" array, to the java.io.ObjectOutput stream named
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     * "stream".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    private static void writeMarshalArguments(IndentingWriter p,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                                              String streamName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
                                              Type[] types, String[] names)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        assert types.length == names.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        for (int i = 0; i < types.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            writeMarshalArgument(p, streamName, types[i], names[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
            p.pln(";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
     * Writes a snippet of Java code to unmarshal a value of type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
     * "type" from the java.io.ObjectInput stream named "stream" into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
     * a variable named "name" (if "name" is null, the value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
     * unmarshalled and discarded).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
     * Primitive types are unmarshalled with their corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
     * methods in the java.io.DataInput interface, and objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
     * (including arrays) are unmarshalled using the readObject
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
     * method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
     * Returns true if code to invoke readObject was written, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
     * false otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    private static boolean writeUnmarshalArgument(IndentingWriter p,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                                                  String streamName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
                                                  Type type, String name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        boolean readObject = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        if (name != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            p.p(name + " = ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            p.p("(" + type.toString() + ") " + streamName + ".readObject()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
            readObject = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        } else if (type.typeName().equals("boolean")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
            p.p(streamName + ".readBoolean()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        } else if (type.typeName().equals("byte")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
            p.p(streamName + ".readByte()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        } else if (type.typeName().equals("char")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            p.p(streamName + ".readChar()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        } else if (type.typeName().equals("short")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
            p.p(streamName + ".readShort()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
        } else if (type.typeName().equals("int")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
            p.p(streamName + ".readInt()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
        } else if (type.typeName().equals("long")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            p.p(streamName + ".readLong()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        } else if (type.typeName().equals("float")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
            p.p(streamName + ".readFloat()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        } else if (type.typeName().equals("double")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            p.p(streamName + ".readDouble()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            throw new AssertionError(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        return readObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
     * Writes Java statements to unmarshal a series of values in order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
     * of types as in the "types" array from the java.io.ObjectInput
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
     * stream named "stream" into variables as named in "names" (for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
     * any element of "names" that is null, the corresponding value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
     * unmarshalled and discarded).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    private static boolean writeUnmarshalArguments(IndentingWriter p,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                                                   String streamName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                                                   Type[] types,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                                                   String[] names)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
        assert types.length == names.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        boolean readObject = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        for (int i = 0; i < types.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            if (writeUnmarshalArgument(p, streamName, types[i], names[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                readObject = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            p.pln(";");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        return readObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
     * Returns a snippet of Java code to wrap a value named "name" of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     * type "type" into an object as appropriate for use by the Java
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
     * Reflection API.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
     * For primitive types, an appropriate wrapper class is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
     * instantiated with the primitive value.  For object types
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
     * (including arrays), no wrapping is necessary, so the value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
     * named directly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
    private static String wrapArgumentCode(Type type, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
            return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        } else if (type.typeName().equals("boolean")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
            return ("(" + name +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                    " ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
        } else if (type.typeName().equals("byte")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
            return "new java.lang.Byte(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        } else if (type.typeName().equals("char")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
            return "new java.lang.Character(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        } else if (type.typeName().equals("short")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            return "new java.lang.Short(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        } else if (type.typeName().equals("int")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            return "new java.lang.Integer(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
        } else if (type.typeName().equals("long")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            return "new java.lang.Long(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        } else if (type.typeName().equals("float")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
            return "new java.lang.Float(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
        } else if (type.typeName().equals("double")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            return "new java.lang.Double(" + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            throw new AssertionError(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
     * Returns a snippet of Java code to unwrap a value named "name"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
     * into a value of type "type", as appropriate for the Java
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
     * Reflection API.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
     * For primitive types, the value is assumed to be of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
     * corresponding wrapper class, and a method is called on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
     * wrapper to retrieve the primitive value.  For object types
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
     * (include arrays), no unwrapping is necessary; the value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
     * simply cast to the expected real object type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
    private static String unwrapArgumentCode(Type type, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        if (type.dimension().length() > 0 || type.asClassDoc() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
            return "((" + type.toString() + ") " + name + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
        } else if (type.typeName().equals("boolean")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            return "((java.lang.Boolean) " + name + ").booleanValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        } else if (type.typeName().equals("byte")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            return "((java.lang.Byte) " + name + ").byteValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
        } else if (type.typeName().equals("char")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
            return "((java.lang.Character) " + name + ").charValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
        } else if (type.typeName().equals("short")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            return "((java.lang.Short) " + name + ").shortValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
        } else if (type.typeName().equals("int")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            return "((java.lang.Integer) " + name + ").intValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
        } else if (type.typeName().equals("long")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            return "((java.lang.Long) " + name + ").longValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
        } else if (type.typeName().equals("float")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
            return "((java.lang.Float) " + name + ").floatValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        } else if (type.typeName().equals("double")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
            return "((java.lang.Double) " + name + ").doubleValue()";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
            throw new AssertionError(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
}