wrappedremote.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 235 行

JAVA
235
字号
/* * @(#)WrappedRemote.java	1.14 05/03/12 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation.  *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt).  *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA  *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions.  * */package com.sun.xlet.ixc;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.UnexpectedException;import java.lang.reflect.Method;import java.lang.reflect.InvocationTargetException;import javax.microedition.xlet.XletContext;import java.security.AccessController;import java.security.AccessControlContext;import java.security.PrivilegedActionException;import java.security.PrivilegedExceptionAction;/** * A remote object that has been wrapped to be safely accessible from * a client.  In other words, an instance of WrappedRemote is a stub * object that delegates its calls to the true remote object.  The remote * calls are executed in a thread that is in the remote ResourceDomain. * This can be done by transferring the call to a worker thread on the * remote side, or by changing the owner attribute of the thread. */public abstract class WrappedRemote implements Remote {    private Remote target;    private ImportRegistry registry;    private RegistryKey key;    private static Method hashCodeMethod;    private static Method equalsMethod;    private static Method toStringMethod;    static {        try {            Class obj = Object.class;            hashCodeMethod = obj.getMethod("hashCode", new Class[0]);            equalsMethod = obj.getMethod("equals", new Class[] { obj }                    );            toStringMethod = obj.getMethod("toString", new Class[0]);        } catch (Exception ex) {            // assert(false);            ex.printStackTrace();        }    }    protected WrappedRemote(Remote target, ImportRegistry registry,        RegistryKey key) {        this.target = target;        this.registry = registry;        this.key = key;    }    protected void finalize() {        registry.unregisterStub(key);    }    //    // Execute a remote method.  Note that this Method object must refer    // to the method loaded by the target classloader (and not the    // classloader of the stub class).    //    protected final Object     com_sun_xlet_execute(final Method remoteMethod, final Object[] args)         throws java.lang.Exception {        //XletContextImpl localXlet = registry.importer;        //XletContextImpl remoteXlet = registry.target;        XletContext localXlet = registry.importer;        XletContext remoteXlet = registry.target;        if (remoteXlet == null) {            throw new RemoteException("Remote target killed");        }        IxcRegistryImpl ixcRegis =             IxcRegistryImpl.getIxcRegistryImpl(remoteXlet);        ImportRegistry remoteIR = (ImportRegistry)            ixcRegis.getImportRegistry(localXlet);        final AccessControlContext context = ixcRegis.acc;        // Now wrap or copy arguments...        for (int i = 0; i < args.length; i++) {            args[i] = remoteIR.wrapOrCopy(args[i]);        }        final Object[] result = new Object[2];        final Remote targetNow = target;        if (targetNow == null) {            // This should never happen, but be conservative            throw new RemoteException("Remote target killed");        }        if (remoteMethod == null) {            // Stub has been destroyed in this case, must be reexported object             throw new RemoteException("Remote target killed");        }        ixcRegis.executeForClient(new Runnable() {                public void run() {		    try {		       AccessController.doPrivileged(			  new PrivilegedExceptionAction() {			     public Object run() throws RemoteException {				Throwable err = null;				try {				    result[0] = remoteMethod.invoke(targetNow, args);				} catch (InvocationTargetException ite) {				    err = ite.getTargetException();				} catch (Throwable t) {				    err = t;				}				if (err == null) {				    try {					result[0] = registry.wrapOrCopy(result[0]);				    } catch (RemoteException ex) {					result[1] = ex;				    }				} else {				    try {					result[1] = registry.wrapOrCopy(err);				    } catch (RemoteException ex) {					result[1] = ex;				    }				}				return null;			    }			}		       , context);		    } catch (PrivilegedActionException pae) {			// assert(false)			pae.getCause().printStackTrace();		    }                }            }        );        if (result[1] != null) {            // fix for 4653779, if the exception is checked, throw it            // directly, else wrap it in UnsupportedException            Class[] exceptions = remoteMethod.getExceptionTypes();            for (int i = 0; i < exceptions.length; i++) {                if (exceptions[i].isInstance(result[1])) {                    throw (Exception) result[1];                }            }            // fix for 4641529, just throw if it's a RuntimeException,            // else wrap it in RemoteException            if (result[1] instanceof RuntimeException) {                throw (RuntimeException) result[1];            } else if (result[1] instanceof RemoteException) {                throw (RemoteException) result[1];            } else {                throw new UnexpectedException("Non-declared exception", (Exception) result[1]);            }        }        return registry.wrapOrCopy(result[0]);    }    void destroy() {        target = null;    }    Remote getTarget() {        return target;    }    public int hashCode() {        try {            Object result                 = com_sun_xlet_execute(hashCodeMethod, new Object[0]);            return ((Integer) result).intValue();            //} catch (RemoteException ex) {        } catch (Exception ex) {            // Client has died.  This is the same behavior that            // java.rmi.server.RemoteObject gives.            return super.hashCode();        }    }    public boolean equals(Object obj) {        if (this == obj) {            return true;        } else if (!(obj instanceof WrappedRemote)) {            if (obj == null) {                return false;            } else {                return obj.equals(this);                // cf. bug 4099660, and java.rmi.server.RemoteObject.equals().            }        }        try {            Object result                 //= com_sun_tvimpl_execute(equalsMethod, new Object[] { obj });                = com_sun_xlet_execute(equalsMethod, new Object[] { obj }                );            return ((Boolean) result).booleanValue();        } catch (Exception ex) {            // Client has died, or o is an incompatible type.            return false;        }    }    public String toString() {        try {            String classname = this.getClass().getName();            Object result                 //= com_sun_tvimpl_execute(toStringMethod, new Object[0]);                = com_sun_xlet_execute(toStringMethod, new Object[0]);            return classname + "[" + result + "]";            //} catch (RemoteException ex) {        } catch (Exception ex) {            return super.toString();        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?