001    /* PortableRemoteObject.java --
002       Copyright (C) 2004, 2004, 2005 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.rmi;
040    
041    import gnu.javax.rmi.CORBA.DelegateFactory;
042    
043    import org.omg.CORBA.BAD_PARAM;
044    import org.omg.CORBA.ORB;
045    import org.omg.CORBA.portable.ObjectImpl;
046    import org.omg.PortableServer.POA;
047    import org.omg.PortableServer.Servant;
048    
049    import java.rmi.NoSuchObjectException;
050    import java.rmi.Remote;
051    import java.rmi.RemoteException;
052    
053    import javax.rmi.CORBA.PortableRemoteObjectDelegate;
054    import javax.rmi.CORBA.Stub;
055    import javax.rmi.CORBA.Tie;
056    import javax.rmi.CORBA.Util;
057    
058    /**
059     * <p>
060     * An utility class for RMI/IDL server side object implementations. Server side
061     * implementation objects may inherit from this class, but this is not
062     * mandatory, as the needed methds are static. Server side implementations may
063     * choose to inherit from {@link ObjectImpl} or {@link Servant} instead.
064     * </p>
065     * <p>
066     * The functionality of methods in this class is forwarded to the enclosed
067     * PortableRemoteObjectDelegate. This delegate can be altered by setting the
068     * system property "javax.rmi.CORBA.PortableRemoteObjectClass" to the name of
069     * the alternative class that must implement
070     * {@link PortableRemoteObjectDelegate}.
071     * </p>
072     *
073     * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
074     */
075    public class PortableRemoteObject
076    {
077      /**
078       * A delegate where the functionality is forwarded.
079       */
080      static PortableRemoteObjectDelegate delegate = (PortableRemoteObjectDelegate) DelegateFactory.getInstance(DelegateFactory.PORTABLE_REMOTE_OBJECT);
081    
082      /**
083       * The protected constructor calls {@link exportObject} (this).
084       *
085       * @throws RemoteException if the exportObject(this) throws one.
086       */
087      protected PortableRemoteObject()
088        throws RemoteException
089      {
090        exportObject((Remote) this);
091      }
092    
093      /**
094       * <p>
095       * Makes the remote object <code>a_target</code> ready for remote
096       * communication using the same communications runtime as for the passed
097       * <code>a_source</code> parameter. The a_target is connected to the same
098       * ORB (and, if applicable, to the same {@link POA}) as the a_source.
099       *
100       * @param target the target to connect to ORB, must be an instance of either
101       * {@link ObjectImpl} (Stubs and old-style ties) or {@link Tie}.
102       *
103       * @param source the object, providing the connection information, must be
104       * an instance of either {@link ObjectImpl} (Stubs and old-style ties) or
105       * {@link Servant} (the next-generation Ties supporting {@link POA}).
106       *
107       * @throws RemoteException if the target is already connected to another ORB.
108       */
109      public static void connect(Remote target, Remote source)
110        throws RemoteException
111      {
112        delegate.connect(target, source);
113      }
114    
115      /**
116       * <p>
117       * Makes a server object ready for remote calls. The subclasses of
118       * PortableRemoteObject do not need to call this method, as it is called by
119       * the constructor.
120       * </p>
121       * <p>
122       * This method only creates a tie object and caches it for future usage. The
123       * created tie does not have a delegate or an ORB associated.
124       * </p>
125       *
126       * @param object the object to export.
127       *
128       * @throws RemoteException if export fails due any reason.
129       */
130      public static void exportObject(Remote object)
131        throws RemoteException
132      {
133        delegate.exportObject(object);
134      }
135    
136      /**
137       * Narrows the passed object to conform to the given interface or IDL type. In
138       * RMI-IIOP, this method replaces the narrow(org.omg.CORBA.Object) method that
139       * was present in the CORBA Helpers. This method frequently returns different
140       * instance and cannot be replaced by the direct cast. The typical narrowing
141       * cases (all supported by GNU Classpath) are:
142       * <ul>
143       * <li>A CORBA object (for instance, returned by the
144       * {@link ORB#string_to_object} or from the naming service) can be narrowed
145       * into interface, derived from Remote. The method will try to locate an
146       * appropriate {@link Stub} by the name pattern (_*_Stub). If the object being
147       * narrowed is connected to an ORB, the returned instance will inherit that
148       * connection, representing the same remote (or local) object, but now with
149       * the possibility to invoke remote methods. </li>
150       * <li>A CORBA object may be directly narrowed into the appropriate
151       * {@link Stub} class, if it is and passed as a second parameter. This allows
152       * to use non-standard stubs without parameterless constructors.</li>
153       * <li>Any two classes, derived from the {@link ObjectImpl} (may be Stub's)
154       * can be narrowed one into another (a delegate is transferred). </li>
155       * <li>An implementation of Remote can be narrowed into {@link Tie} that can
156       * later connected to an ORB, making the methods accessible remotely. The
157       * Remote being narrowed normally provides a local implementation, but you can
158       * also narrow remote Stub, creating "forwarding Tie".</li>
159       * <li>null is narrowed into null regardless of the second parameter.</li>
160       * <li>A {@link Tie} can be narrowed into Remote, representing the
161       * implementation for this Tie (if one is set).</li>
162       * </ul>
163       *
164       * @param object the object like CORBA Object, Stub or Remote that must be
165       * narrowed to the given interface.
166       *
167       * @param narrowToInstaceOf the class of the interface to that the object must
168       * be narrowed.
169       *
170       * @return On success, an object of type narrowTo or null, if narrowFrom =
171       * null.
172       *
173       * @throws ClassCastException if no narrowing is possible.
174       */
175      public static Object narrow(Object object, Class narrowToInstaceOf)
176        throws ClassCastException
177      {
178        return delegate.narrow(object, narrowToInstaceOf);
179      }
180    
181      /**
182       * <p>
183       * Takes a server implementation object (name pattern *imp) and returns a stub
184       * object that can be used to access that server object (target), name
185       * (pattern _*_Stub).
186       *
187       * The returned stub is not connected to any ORB and must be explicitly
188       * connected using {@link #connect}.
189       * </p>
190       * <p>
191       * The method signature prevents it from returning stubs that does not
192       * implement Remote (ClassCastException will be thrown).
193       * </p>
194       *
195       * @param target a server side object implementation.
196       * @return a stub object that can be used to access that server object.
197       *
198       * @throws NoSuchObjectException if a stub class cannot be located by supposed
199       * name pattern, or an instance of stub fails to be instantiated.
200       *
201       * @throws ClassCastException if the stub class can be located, but it does
202       * not inherit from Remote.
203       *
204       * @throws BAD_PARAM if the name of the passed class does not match the
205       * implementation name pattern (does not end by 'Impl').
206       */
207      public static Remote toStub(Remote targetImpl)
208        throws NoSuchObjectException
209      {
210        return delegate.toStub(targetImpl);
211      }
212    
213      /**
214       * Deregister a currently exported server object from the ORB runtimes. The
215       * object to becomes available for garbage collection. This is usually
216       * impemented via {@link Util#unexportObject}
217       *
218       * @param object the object to unexport.
219       *
220       * @throws NoSuchObjectException if the passed object is not currently
221       * exported.
222       */
223      public static void unexportObject(Remote object)
224        throws NoSuchObjectException
225      {
226        delegate.unexportObject(object);
227      }
228    }