001/* Stub.java --
002   Copyright (C) 2004, 2004, 2005 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package javax.rmi.CORBA;
040
041import gnu.javax.rmi.CORBA.DelegateFactory;
042import gnu.javax.rmi.CORBA.StubDelegateImpl;
043
044import java.io.IOException;
045import java.io.ObjectInputStream;
046import java.io.ObjectOutputStream;
047import java.io.Serializable;
048import java.rmi.RemoteException;
049
050import javax.rmi.PortableRemoteObject;
051
052import org.omg.CORBA.ORB;
053import org.omg.CORBA_2_3.portable.ObjectImpl;
054
055/**
056 * A Stub descendants provide access to the object on the client side. This base
057 * class implements methods, required for remote or local invocation using CORBA
058 * mechanisms. The most of the functionality is forwarded to the stub delegate.
059 * This delegate can be altered by setting the system property
060 * "javax.rmi.CORBA.StubClass" to the name of the alternative class that must
061 * implement {@link StubDelegate}. Hence Stub contains two delegates, one for
062 * Stub-related operations and another inherited from the ObjectImpl.
063 * 
064 * @specnote GNU Classpath uses separate delegate per each Stub. The delegate
065 * holds information about the ORB and other data, specific for the each Stub.
066 * 
067 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
068 */
069public abstract class Stub
070  extends ObjectImpl
071  implements Serializable
072{
073  /**
074   * For compatability with Sun's JDK 1.4.2 rev. 5
075   */
076  private static final long serialVersionUID = 1087775603798577179L;
077
078  /**
079   * The hashcode, computed once (expensive operation).
080   */
081  transient int m_hash = Integer.MIN_VALUE;
082
083  /**
084   * The stringified reference, computed once (expensive operation).
085   */
086  transient String m_ior;
087
088  /**
089   * The ORB, where the stub is connected on the client side.
090   */
091  transient ORB m_orb;
092
093  /**
094   * The associated delegate, responsible for the major of the functionality of
095   * this stub.
096   */
097  static StubDelegate delegate = (StubDelegate) DelegateFactory.getInstance(DelegateFactory.STUB);
098
099  /**
100   * Returns the same hashcode for all stubs that point to the same remote
101   * object.
102   */
103  public int hashCode()
104  {
105    if (m_hash == Integer.MIN_VALUE)
106      m_hash = delegate.hashCode(this);
107    // This should finally result to the IOR comparison.
108    return m_hash;
109  }
110
111  /**
112   * The stubs are equal if they point to the same remote object.
113   */
114  public boolean equals(java.lang.Object obj)
115  {
116    return delegate.equals(this, obj);
117  }
118
119  /**
120   * Get the string representation of this Stub.
121   * 
122   * @return the CORBA IOR reference.
123   */
124  public String toString()
125  {
126    if (m_ior == null)
127      m_ior = delegate.toString(this);
128    return m_ior;
129  }
130
131  /**
132   * <p>
133   * Finds the suitable {@link Tie} for this Stub and connects it to the given
134   * ORB. The tie is found by the name pattern. If the found tie is derived from
135   * {@link org.omg.CORBA.PortableServer.Servant}, it is connected to the root
136   * POA, also activating it (if not already active).
137   * </p>
138   * <p>
139   * This method does not allow to specify, to which POA the found Tie must be
140   * connected and requires to use the deprecated method {@link ORB#connect}.
141   * Many useful POA features remain unaccessible. A better alternative it might
142   * be to generate a {@link org.omg.CORBA.PortableServer.Servant} - derived Tie
143   * (-poa key in rmic) and connect it to POA in one of the many ways, listed in
144   * the description of the {@link orb.omg.PortableServer} package). The
145   * obtained CORBA object can be narrowed into stub using
146   * {@link PortableRemoteObject#narrow}.
147   * </p>
148   * <p>
149   * It is frequently easier to call {@link PortableRemoteObject#connect} rather
150   * than this method.
151   * </p>
152   * 
153   * @param orb the ORB where the Stub must be connected.
154   * 
155   * @throws RemoteException if the stub is already connected to some other ORB.
156   * If the stub is already connected to the ORB that was passed as parameter,
157   * the method returns without action.
158   * 
159   * @throws BAD_PARAM if the name of this stub does not match the stub name
160   * pattern, "_*_Stub" or if the Tie class, "_*Impl_Tie", does not exists or an
161   * instance of this class cannot be instantiated.
162   */
163  public void connect(ORB orb)
164    throws RemoteException
165  {
166    if (m_orb != null && orb != null)
167      {
168        if (m_orb.equals(orb))
169          throw new RemoteException("Stub " + this
170            + " is connected to another ORB, " + orb);
171        else
172          return;
173      }
174    m_orb = orb;
175    delegate.connect(this, orb);
176  }
177
178  /**
179   * Required by serialized form of Java API doc.
180   */
181  private void readObject(ObjectInputStream input)
182    throws IOException, ClassNotFoundException
183  {
184    if (delegate instanceof StubDelegateImpl)
185      ((StubDelegateImpl) delegate).readObject(this, input, m_orb);
186    else
187      delegate.readObject(this, input);
188  }
189
190  /**
191   * Required by serialized form of Java API doc.
192   */
193  private void writeObject(ObjectOutputStream output)
194    throws IOException
195  {
196    // The m_orb in this case may be either known or not.
197    if (delegate instanceof StubDelegateImpl)
198      ((StubDelegateImpl) delegate).writeObject(this, output, m_orb);
199    else
200
201      delegate.writeObject(this, output);
202  }
203}