123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /* PortableRemoteObjectDelegateImpl.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath 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 for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package gnu.javax.rmi.CORBA;
- import gnu.CORBA.SimpleDelegate;
- import gnu.CORBA.Unexpected;
- import gnu.CORBA.Poa.LocalDelegate;
- import gnu.CORBA.Poa.ORB_1_4;
- import gnu.CORBA.Poa.AOM;
- import java.rmi.NoSuchObjectException;
- import java.rmi.Remote;
- import java.rmi.RemoteException;
- import java.rmi.server.RMIClassLoader;
- import javax.rmi.CORBA.PortableRemoteObjectDelegate;
- import javax.rmi.CORBA.Stub;
- import javax.rmi.CORBA.Tie;
- import javax.rmi.CORBA.Util;
- import org.omg.CORBA.BAD_PARAM;
- import org.omg.CORBA.ORB;
- import org.omg.CORBA.portable.Delegate;
- import org.omg.CORBA.portable.ObjectImpl;
- import org.omg.PortableServer.POA;
- import org.omg.PortableServer.POAHelper;
- import org.omg.PortableServer.Servant;
- import org.omg.PortableServer.POAManagerPackage.State;
- /**
- * Implements PortableRemoteObjectDelegate.
- *
- * @author Wu Gansha (gansha.wu@intel.com) (stub)
- * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
- */
- public class PortableRemoteObjectDelegateImpl
- implements PortableRemoteObjectDelegate
- {
- /**
- * <p>
- * Makes the remote object <code>a_target</code> ready for remote
- * communication using the same communications runtime as for the passed
- * <code>a_source</code> parameter. The a_target is connected to the same
- * ORB (and, if applicable, to the same POA) as the a_source.
- *
- * @param a_target the target to connect to ORB, must be an instance of either
- * {@link ObjectImpl} (Stubs and old-style ties) or {@link Servant} (POA-bases
- * ties).
- *
- * @param a_source the object, providing the connection information, must be
- * an instance of either {@link ObjectImpl} (Stubs and old-style ties) or
- * {@link Servant} (POA-bases ties).
- *
- * @throws RemoteException if the target is already connected to another ORB.
- */
- public void connect(Remote a_target, Remote a_source)
- throws RemoteException
- {
- ORB orb = null;
- POA poa = null;
- boolean ok = false;
- try
- {
- if (a_source instanceof Servant)
- {
- Servant s = (Servant) a_source;
- orb = s._orb();
- poa = s._poa();
- ok = true;
- }
- if (!ok && a_source instanceof ObjectImpl)
- {
- ObjectImpl o = (ObjectImpl) a_source;
- orb = o._orb();
- ok = true;
- try
- {
- if (orb instanceof ORB_1_4)
- {
- // POA information available.
- ORB_1_4 xorb = (ORB_1_4) orb;
- Delegate d = o._get_delegate();
- if (d instanceof LocalDelegate)
- {
- LocalDelegate l = (LocalDelegate) d;
- poa = l.poa;
- }
- else if (d instanceof SimpleDelegate)
- {
- byte[] ior_key = ((SimpleDelegate) d).getIor().key;
- AOM.Obj ref = xorb.rootPOA.findIorKey(ior_key);
- if (ref != null)
- poa = ref.poa;
- }
- }
- }
- catch (Exception ex)
- {
- // OK, POA info is not available, but as ORB is available, we
- // will connect in a default way.
- }
- }
- }
- catch (Exception ex)
- {
- RuntimeException rex = new RuntimeException("Unable to get info from "
- + a_source);
- rex.initCause(ex);
- throw rex;
- }
- if (!ok && a_source instanceof Tie)
- {
- Tie t = (Tie) a_source;
- orb = t.orb();
- poa = null;
- ok = true;
- }
- if (orb == null)
- throw new RemoteException("Unable to determine ORB from " + a_source);
- if (a_target instanceof Stub)
- {
- StubDelegateImpl.connect((Stub) a_target, orb, poa);
- }
- else if (a_target instanceof Servant)
- {
- try
- {
- if (poa == null)
- {
- poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
- // Activate if not active.
- if (poa.the_POAManager().get_state().value() == State._HOLDING)
- poa.the_POAManager().activate();
- }
- poa.servant_to_reference((Servant) a_target);
- }
- catch (Exception ex)
- {
- throw new Unexpected(ex);
- }
- }
- else if (a_target instanceof org.omg.CORBA.Object)
- {
- // Connect as object.
- orb.connect((org.omg.CORBA.Object) a_target);
- }
- else if (a_target instanceof Tie)
- {
- // We avoid calling this because it will aways connect to the root poa.
- ((Tie) a_target).orb(orb);
- }
- }
- /**
- * Narrow the given object to the instance of the given class. The currently
- * supported narrowing types are:
- *
- * 1. Simple widening conversion.<br>
- * 2. ObjectImpl -> RMI interface.<br>
- * 3. ObjectImpl -> ObjectImpl.<br>
- * 4. Tie -> Remote (implementation)<br>
- * 5. Remote (implementation) -> Tie.<br>
- *
- * The narrowing has sense only for derived classes.
- */
- public Object narrow(Object narrowFrom, Class narrowTo)
- throws ClassCastException
- {
- if (narrowTo == null)
- throw new ClassCastException("Can't narrow to null class");
- else if (narrowFrom == null)
- return null;
- else
- // Simple narrowing case.
- if (narrowTo.isAssignableFrom(narrowFrom.getClass()))
- return narrowFrom;
- else if (narrowTo.isInterface() || narrowFrom instanceof ObjectImpl)
- {
- // Narrow CORBA object to passed interface.
- String interf = narrowTo.getName();
- String stubClassName;
- stubClassName = getStubClassName(interf);
- try
- {
- // Replace the interface class by the stub class.
- narrowTo = Util.loadClass(stubClassName, null,
- narrowTo.getClassLoader());
- }
- catch (ClassNotFoundException e)
- {
- ClassCastException cex = new ClassCastException("Class not found: "
- + stubClassName);
- cex.initCause(e);
- throw cex;
- }
- }
- else if (narrowFrom instanceof Tie)
- {
- // Try to substitute the return tie target as a return value.
- Remote target = ((Tie) narrowFrom).getTarget();
- if (target != null && narrowTo.isAssignableFrom(target.getClass()))
- return target;
- }
- Object narrowed;
- try
- {
- narrowed = narrowTo.newInstance();
- }
- catch (Exception e)
- {
- ClassCastException cex = new ClassCastException("Cannot instantiate "
- + narrowTo.getName());
- cex.initCause(e);
- throw cex;
- }
- if (narrowed instanceof ObjectImpl)
- {
- // This also works for the instances of the Stub.
- ObjectImpl target = (ObjectImpl) narrowed;
- // Set the delegate, as is done in *Helper.narrow(..).
- target._set_delegate(((ObjectImpl) narrowFrom)._get_delegate());
- }
- else if (narrowed instanceof Tie && narrowFrom instanceof Remote)
- {
- // Try to set the narrowing object as a target for the Tie.
- ((Tie) narrowed).setTarget((Remote) narrowFrom);
- }
- else
- throw new ClassCastException("Narrowing of " + narrowFrom.getClass()
- + " to " + narrowTo + " is either not possible or not implemented.");
- return narrowed;
- }
- /**
- * Get the Stub class name for the name, representing the given interface.
- */
- static String getStubClassName(String interf)
- {
- String stubClassName;
- int p = interf.lastIndexOf('.');
- if (p < 0)
- // The interface is defined in the default package.
- stubClassName = "_" + interf + "_Stub";
- else
- stubClassName = interf.substring(0, p + 1) + "_"
- + interf.substring(p + 1) + "_Stub";
- return stubClassName;
- }
- /**
- * Get stub for the given implementation, searching by class name pattern. The
- * found stub must implement Remote for this method to succeed.
- */
- public Remote toStub(Remote ObjImpl)
- throws NoSuchObjectException
- {
- String icn = ObjImpl.getClass().getName();
- if (!icn.endsWith("Impl"))
- throw new BAD_PARAM("Invalid class name '" + icn
- + "', must end with 'Impl'");
- String sn = "_" + icn.substring(0, icn.length() - "Impl".length())
- + "_Stub";
- Class stubClass;
- Object o_stub;
- try
- {
- stubClass = RMIClassLoader.loadClass(sn);
- o_stub = stubClass.newInstance();
- }
- catch (Exception e)
- {
- NoSuchObjectException n = new NoSuchObjectException(sn);
- n.initCause(e);
- throw n;
- }
- if (!Remote.class.isAssignableFrom(stubClass))
- throw new ClassCastException(stubClass.getName()
- + " exists but cannot be returned as it does not inherit from "
- + Remote.class.getName());
- return (Remote) o_stub;
- }
- /**
- * If the object tie is no longer in use, disconnet it from the orb.
- */
- public void unexportObject(Remote obj)
- throws NoSuchObjectException
- {
- Util.unexportObject(obj);
- }
- /**
- * Find or create a tie for this target and mark it as being used by the given
- * object.
- */
- public void exportObject(Remote obj)
- throws RemoteException
- {
- if (obj instanceof Stub)
- Util.registerTarget(StubDelegateImpl.getTieFromStub((Stub) obj), obj);
- else if (obj instanceof Tie)
- {
- Tie t = (Tie) obj;
- Util.registerTarget(t, null);
- }
- }
- }
|