Package org.apache.harmony.rmi.remoteref

Source Code of org.apache.harmony.rmi.remoteref.UnicastRef

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @author  Mikhail A. Markov
* @version $Revision: 1.1.2.2 $
*/
package org.apache.harmony.rmi.remoteref;

import java.lang.reflect.Method;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.rmi.MarshalException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.UnmarshalException;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteCall;
import java.rmi.server.Operation;

import org.apache.harmony.rmi.client.ClientConnection;
import org.apache.harmony.rmi.client.ClientConnectionManager;
import org.apache.harmony.rmi.client.ClientRemoteCall;
import org.apache.harmony.rmi.common.RMILog;
import org.apache.harmony.rmi.internal.nls.Messages;
import org.apache.harmony.rmi.server.RemoteRefBase;
import org.apache.harmony.rmi.transport.Endpoint;
import org.apache.harmony.rmi.transport.RMIObjectInputStream;
import org.apache.harmony.rmi.transport.RMIObjectOutputStream;
import org.apache.harmony.rmi.transport.RMIProtocolConstants;


/**
* Implementation of handle for remote objects.
*
* @author  Mikhail A. Markov
* @version $Revision: 1.1.2.2 $
*/
public class UnicastRef extends RemoteRefBase {

    private static final long serialVersionUID = -2637470287094993242L;

    /** Logger where to write client-side log of remote calls. */
    public static final RMILog clientCallsLog = RMILog.getClientCallsLog();

    // Log where to write server-side log of remote reference activity
    private static final RMILog clientRefLog = RMILog.getClientRefLog();

    /**
     * Default constructor: constructs an empty instance of this class.
     */
    public UnicastRef() {
        ep = null;
        objId = null;
    }

    /**
     * Constructs UnicastRef.
     *
     * @param host host name where remote object impl. is located.
     * @param port port on remote host where remote object accepts RMI calls
     * @param objId Object ID of remoteObject
     */
    public UnicastRef(String host,
                      int port,
                      ObjID objId) {
        this(new Endpoint(host, port, null, null), objId);
    }

    /**
     * Constructs UnicastRef using specified Endpoint and objId.
     *
     * @param ep Endpoint for remote calls
     * @param objId Object ID of remote object
     */
    public UnicastRef(Endpoint ep, ObjID objId) {
        this(ep, objId, false);
    }

    /**
     * Constructs UnicastRef using specified Endpoint and objId.
     *
     * @param ep Endpoint for remote calls
     * @param objId Object ID of remote object
     * @param isLocal if true this UnicastRef belongs to local object
     */
    public UnicastRef(Endpoint ep, ObjID objId, boolean isLocal) {
        this.ep = ep;
        this.objId = objId;
        this.isLocal = isLocal;
    }


    /**
     * @see RemoteRef.invoke(Remote, Method, Object[], long)
     */
    public Object invoke(Remote obj,
                         Method m,
                         Object[] params,
                         long h) throws Exception {
        Object toReturn = null;
        logClientCall(obj, m.toString());

        if (clientRefLog.isLoggable(RMILog.BRIEF)) {
            // rmi.log.100=New call: method = [{0}], hash = {1}
            clientRefLog.log(RMILog.BRIEF, Messages.getString("rmi.log.100", //$NON-NLS-1$
                m, h));
        }

        // initiate a new call
        RemoteCall call = newCall(null, null, -1, h);
        ((ClientRemoteCall) call).setMethod(m);


        try {
            // write arguments for the method called
            RMIObjectOutputStream oout =
                    (RMIObjectOutputStream) call.getOutputStream();
            Class[] paramTypes = m.getParameterTypes();

            try {
                if (params != null) {
                    for (int i = 0; i < params.length; ++i) {
                        oout.writeRMIObject(params[i], paramTypes[i]);
                    }
                }
            } catch (IOException ioe) {
                // rmi.6F=I/O error occurred while marshalling arguments
                throw new MarshalException(Messages.getString("rmi.6F"), ioe); //$NON-NLS-1$
            }

            // execute the call
            invoke(call);

            // read return value
            // if we pass here then server produced no exceptions
            if (m.getReturnType() != Void.TYPE) {
                RMIObjectInputStream oin =
                        (RMIObjectInputStream) call.getInputStream();

                try {
                    toReturn = oin.readRMIObject(m.getReturnType());
                } catch (IOException ioe) {
                    // rmi.70=IOException occurred while unmarshalling return value
                    throw new UnmarshalException(Messages.getString("rmi.70"), ioe); //$NON-NLS-1$
                } catch (ClassNotFoundException cnfe) {
                    // rmi.71=ClassNotFoundException occurred while unmarshalling return value
                    throw new UnmarshalException(Messages.getString("rmi.71"), cnfe); //$NON-NLS-1$
                }
            }
        } catch (IOException ioe) {
            ((ClientRemoteCall) call).close();
            throw ioe;
        }
        done(call);
        return toReturn;
    }

    /**
     * @see RemoteRef.getRefClass(ObjectOutput)
     */
    public String getRefClass(ObjectOutput out) {
        return "UnicastRef"; //$NON-NLS-1$
    }

    /**
     * Writes this UnicastRef object to the specified output stream.
     *
     * @param out the stream to write the object to
     *
     * @throws IOException if any I/O error occurred or class is not serializable
     */
    public void writeExternal(ObjectOutput out) throws IOException {
        ep.writeExternal(out, false);
        writeCommon(out);
    }

    /**
     * Reads data for creating RemoteRef object from the specified input stream.
     *
     * @param in the stream to read data from
     *
     * @throws IOException if any I/O error occurred
     * @throws ClassNotFoundException if class could not be loaded by current
     *         class loader
     */
    public void readExternal(ObjectInput in)
            throws IOException, ClassNotFoundException {
        ep = Endpoint.readExternal(in, false);
        readCommon(in);
    }

    /**
     * @see RemoteRef.newCall(RemoteObject, Operation[], int, long)
     */
    public RemoteCall newCall(RemoteObject obj,
                              Operation[] op,
                              int opnum,
                              long hash)
            throws RemoteException {
        if (opnum != -1) {
            if (clientRefLog.isLoggable(RMILog.BRIEF)) {
                // rmi.log.101=New call: method = [{0}], opnum = {1}, hash = {2}
                clientRefLog.log(RMILog.BRIEF, Messages.getString("rmi.log.101", //$NON-NLS-1$
                        new Object[]{op[opnum].toString(), opnum, hash}));
            }
            logClientCall(obj, op[opnum].toString());
        }
        ClientConnection conn = ClientConnectionManager.getConnection(ep);
        RemoteCall call = new ClientRemoteCall(conn);

        if (clientRefLog.isLoggable(RMILog.VERBOSE)) {
            //rmi.log.102=Created new call {0}
            clientRefLog.log(RMILog.VERBOSE, Messages.getString("rmi.log.102", call)); //$NON-NLS-1$
        }

        try {
            // write method signature
            DataOutputStream dout = new DataOutputStream(conn.getOutputStream());
            dout.writeByte(RMIProtocolConstants.CALL_MSG);
            ObjectOutputStream oout =
                    (ObjectOutputStream) call.getOutputStream();
            objId.write(oout);
            oout.writeInt(opnum);
            oout.writeLong(hash);
            return call;
        } catch (IOException ioe) {
            done(call);
            // rmi.72=Unable to marshal call header
            throw new MarshalException(Messages.getString("rmi.72"), ioe); //$NON-NLS-1$
        }
    }

    /**
     * @see RemoteRef.invoke(RemoteCall)
     */
    public void invoke(RemoteCall call) throws Exception {
        if (clientRefLog.isLoggable(RMILog.VERBOSE)) {
            // rmi.log.103=Execute call {0}
            clientRefLog.log(RMILog.VERBOSE, Messages.getString("rmi.log.103", call)); //$NON-NLS-1$
        }
        call.releaseOutputStream();
        call.executeCall();
    }

    /**
     * @see RemoteRef.done(RemoteCall)
     */
    public void done(RemoteCall call) throws RemoteException {
        if (clientRefLog.isLoggable(RMILog.VERBOSE)) {
            // rmi.log.104=Finalize call {0}
            clientRefLog.log(RMILog.VERBOSE, Messages.getString("rmi.log.104", call)); //$NON-NLS-1$
        }

        try {
            call.done();
        } catch (Exception ex) {
        }
    }

    // Logs remote method call on client side.
    private void logClientCall(Remote obj, String m) {
        if (clientCallsLog.isLoggable(RMILog.VERBOSE)) {
            // rmi.log.105=Outbound remote call to endpoint:{0}: method:[{1}], obj:[{2}].
            clientCallsLog.log(RMILog.VERBOSE,Messages.getString("rmi.log.105", //$NON-NLS-1$
                    new Object[]{ ep, m, obj}));
        }
    }
}
TOP

Related Classes of org.apache.harmony.rmi.remoteref.UnicastRef

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.