mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1795 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1795 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			Java
		
	
	
	
/* OrbFunctional.java --
 | 
						|
   Copyright (C) 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.CORBA;
 | 
						|
 | 
						|
import gnu.CORBA.CDR.UnknownExceptionCtxHandler;
 | 
						|
import gnu.CORBA.CDR.BufferredCdrInput;
 | 
						|
import gnu.CORBA.CDR.BufferedCdrOutput;
 | 
						|
import gnu.CORBA.GIOP.CloseMessage;
 | 
						|
import gnu.CORBA.GIOP.ErrorMessage;
 | 
						|
import gnu.CORBA.GIOP.MessageHeader;
 | 
						|
import gnu.CORBA.GIOP.ReplyHeader;
 | 
						|
import gnu.CORBA.GIOP.RequestHeader;
 | 
						|
import gnu.CORBA.NamingService.NameParser;
 | 
						|
import gnu.CORBA.NamingService.NamingServiceTransient;
 | 
						|
import gnu.CORBA.Poa.gnuForwardRequest;
 | 
						|
import gnu.CORBA.interfaces.SocketFactory;
 | 
						|
 | 
						|
import org.omg.CORBA.BAD_OPERATION;
 | 
						|
import org.omg.CORBA.BAD_PARAM;
 | 
						|
import org.omg.CORBA.CompletionStatus;
 | 
						|
import org.omg.CORBA.MARSHAL;
 | 
						|
import org.omg.CORBA.NO_RESOURCES;
 | 
						|
import org.omg.CORBA.OBJECT_NOT_EXIST;
 | 
						|
import org.omg.CORBA.Request;
 | 
						|
import org.omg.CORBA.SystemException;
 | 
						|
import org.omg.CORBA.UNKNOWN;
 | 
						|
import org.omg.CORBA.WrongTransaction;
 | 
						|
import org.omg.CORBA.ORBPackage.InvalidName;
 | 
						|
import org.omg.CORBA.portable.Delegate;
 | 
						|
import org.omg.CORBA.portable.InvokeHandler;
 | 
						|
import org.omg.CORBA.portable.ObjectImpl;
 | 
						|
import org.omg.CORBA.portable.UnknownException;
 | 
						|
import org.omg.CosNaming.NamingContextExt;
 | 
						|
import org.omg.CosNaming.NamingContextExtHelper;
 | 
						|
 | 
						|
import java.applet.Applet;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.OutputStream;
 | 
						|
import java.net.InetAddress;
 | 
						|
import java.net.ServerSocket;
 | 
						|
import java.net.Socket;
 | 
						|
import java.net.SocketException;
 | 
						|
import java.net.UnknownHostException;
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Enumeration;
 | 
						|
import java.util.Hashtable;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.LinkedList;
 | 
						|
import java.util.Map;
 | 
						|
import java.util.Properties;
 | 
						|
import java.util.Random;
 | 
						|
import java.util.StringTokenizer;
 | 
						|
import java.util.TreeMap;
 | 
						|
 | 
						|
/**
 | 
						|
 * The ORB implementation, capable to handle remote invocations on the
 | 
						|
 * registered object. This class implements all features, required till the jdk
 | 
						|
 * 1.3 inclusive, but does not support the POA that appears since 1.4. The POA
 | 
						|
 * is supported by {@link gnu.CORBA.Poa.ORB_1_4}.
 | 
						|
 *
 | 
						|
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 | 
						|
 */
 | 
						|
public class OrbFunctional extends OrbRestricted
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * A server, responsible for listening on requests on some local port. The ORB
 | 
						|
   * may listen on multiple ports and process the requests in separate threads.
 | 
						|
   * Normally the server takes one port per object being served.
 | 
						|
   */
 | 
						|
  protected class portServer
 | 
						|
    extends Thread
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The number of the currently running parallel threads.
 | 
						|
     */
 | 
						|
    int running_threads;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The port on that this portServer is listening for requests.
 | 
						|
     */
 | 
						|
    int s_port;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The server socket of this portServer.
 | 
						|
     */
 | 
						|
    ServerSocket service;
 | 
						|
 | 
						|
    /**
 | 
						|
     * True if the serving node must shutdown due call of the close_now().
 | 
						|
     */
 | 
						|
    boolean terminated;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new portServer, serving on specific port.
 | 
						|
     */
 | 
						|
    portServer(int _port)
 | 
						|
    {
 | 
						|
      s_port = _port;
 | 
						|
      setDaemon(true);
 | 
						|
      try
 | 
						|
        {
 | 
						|
          service = socketFactory.createServerSocket(s_port);
 | 
						|
        }
 | 
						|
      catch (IOException ex)
 | 
						|
        {
 | 
						|
          BAD_OPERATION bad = new BAD_OPERATION(
 | 
						|
            "Unable to open the server socket at " + s_port);
 | 
						|
          bad.minor = Minor.Socket;
 | 
						|
          bad.initCause(ex);
 | 
						|
          throw bad;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Enter the serving loop (get request/process it). All portServer normally
 | 
						|
     * terminate thy threads when the OrbFunctional.running is set to false.
 | 
						|
     */
 | 
						|
    public void run()
 | 
						|
    {
 | 
						|
      while (running)
 | 
						|
        {
 | 
						|
          try
 | 
						|
            {
 | 
						|
              tick();
 | 
						|
            }
 | 
						|
          catch (SocketException ex)
 | 
						|
            {
 | 
						|
              // May be thrown when the service is closed by
 | 
						|
              // the close_now().
 | 
						|
              if (terminated)
 | 
						|
                return;
 | 
						|
            }
 | 
						|
          catch (Exception iex)
 | 
						|
            {
 | 
						|
              // Wait. Do not terminate the
 | 
						|
              // service due potentially transient error.
 | 
						|
              try
 | 
						|
                {
 | 
						|
                  Thread.sleep(TWAIT_SERVER_ERROR_PAUSE);
 | 
						|
                }
 | 
						|
              catch (InterruptedException ex)
 | 
						|
                {
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Perform a single serving step.
 | 
						|
     *
 | 
						|
     * @throws java.lang.Exception
 | 
						|
     */
 | 
						|
    void tick()
 | 
						|
      throws Exception
 | 
						|
    {
 | 
						|
      serve(this, service);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Forcibly close the server socket and mark this port as free.
 | 
						|
     */
 | 
						|
    public void close_now()
 | 
						|
    {
 | 
						|
      try
 | 
						|
        {
 | 
						|
          terminated = true;
 | 
						|
          service.close();
 | 
						|
        }
 | 
						|
      catch (Exception ex)
 | 
						|
        {
 | 
						|
          // This may happen if the service has not been opened or
 | 
						|
          // cannot be closed. Return without action.
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * If the thread is no longer in use, close the socket (if opened).
 | 
						|
     */
 | 
						|
    protected void finalize()
 | 
						|
    {
 | 
						|
      close_now();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * A server, responsible for listening on requests on some local port and
 | 
						|
   * serving multiple requests (probably to the different objects) on the same
 | 
						|
   * thread.
 | 
						|
   */
 | 
						|
  protected class sharedPortServer extends portServer
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * Create a new portServer, serving on specific port.
 | 
						|
     */
 | 
						|
    sharedPortServer(int _port)
 | 
						|
    {
 | 
						|
      super(_port);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Perform a single serving step.
 | 
						|
     *
 | 
						|
     * @throws java.lang.Exception
 | 
						|
     */
 | 
						|
    void tick() throws Exception
 | 
						|
    {
 | 
						|
      Socket request = service.accept();
 | 
						|
      serveStep(request, false);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * The default value where the first instance of this ORB will start looking
 | 
						|
   * for a free port.
 | 
						|
   */
 | 
						|
  public static int DEFAULT_INITIAL_PORT = 1126;
 | 
						|
 | 
						|
  /**
 | 
						|
   * When trying to open the socket on a random port, start of the interval to
 | 
						|
   * try.
 | 
						|
   */
 | 
						|
  public static int RANDOM_PORT_FROM = 1024;
 | 
						|
 | 
						|
  /**
 | 
						|
   * When trying to open the socket on a random port, end of the interval to
 | 
						|
   * try.
 | 
						|
   */
 | 
						|
  public static int RANDOM_PORT_TO = 4024;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The number of attempts to try when opening random port.
 | 
						|
   */
 | 
						|
  public static int RANDOM_PORT_ATTEMPTS = 64;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The property of port, on that this ORB is listening for requests from
 | 
						|
   * clients. This class supports one port per ORB only.
 | 
						|
   */
 | 
						|
  public static final String LISTEN_ON = "gnu.classpath.CORBA.ListenOn";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The property, defining the IOR of the intial reference to resolve.
 | 
						|
   */
 | 
						|
  public static final String REFERENCE = "org.omg.CORBA.ORBInitRef";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The property, defining the port on that the default name service is
 | 
						|
   * running.
 | 
						|
   */
 | 
						|
  public static final String NS_PORT = "org.omg.CORBA.ORBInitialPort";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The property, defining the host on that the default name service is
 | 
						|
   * running.
 | 
						|
   */
 | 
						|
  public static final String NS_HOST = "org.omg.CORBA.ORBInitialHost";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The string, defining the naming service initial reference.
 | 
						|
   */
 | 
						|
  public static final String NAME_SERVICE = "NameService";
 | 
						|
 | 
						|
  /**
 | 
						|
   * Defines the ORB ID that is accessible by IOR interceptors.
 | 
						|
   */
 | 
						|
  public static final String ORB_ID = "org.omg.CORBA.ORBid";
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Defines the SERVER ID that is accessible by IOR interceptors.
 | 
						|
   */
 | 
						|
  public static final String SERVER_ID = "org.omg.CORBA.ServerId";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The if the client has once opened a socket, it should start sending the
 | 
						|
   * message header in a given time. Otherwise the server will close the socket.
 | 
						|
   * This prevents server hang when the client opens the socket, but does not
 | 
						|
   * send any message, usually due crash on the client side.
 | 
						|
   */
 | 
						|
  public static String START_READING_MESSAGE =
 | 
						|
    "gnu.classpath.CORBA.TOUT_START_READING_MESSAGE";
 | 
						|
 | 
						|
  /**
 | 
						|
   * If the client has started to send the request message, the socket time out
 | 
						|
   * changes to the specified value.
 | 
						|
   */
 | 
						|
  public static String WHILE_READING =
 | 
						|
    "gnu.classpath.CORBA.TOUT_WHILE_READING";
 | 
						|
 | 
						|
  /**
 | 
						|
   * If the message body is received, the time out changes to the specifice
 | 
						|
   * value. This must be longer, as includes time, required to process the
 | 
						|
   * received task. We make it 40 minutes.
 | 
						|
   */
 | 
						|
  public static String AFTER_RECEIVING =
 | 
						|
    "gnu.classpath.CORBA.TOUT_AFTER_RECEIVING";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The server waits for this duration after the potentially transient error
 | 
						|
   * during its servicing cycle.
 | 
						|
   */
 | 
						|
  public static String SERVER_ERROR_PAUSE =
 | 
						|
    "gnu.classpath.CORBA.SERVER_ERROR_PAUSE";
 | 
						|
 | 
						|
  /**
 | 
						|
   * The address of the local host.
 | 
						|
   */
 | 
						|
  public final String LOCAL_HOST;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The if the client has once opened a socket, it should start sending the
 | 
						|
   * message header in a given time. Otherwise the server will close the socket.
 | 
						|
   * This prevents server hang when the client opens the socket, but does not
 | 
						|
   * send any message, usually due crash on the client side.
 | 
						|
   */
 | 
						|
  public int TOUT_START_READING_MESSAGE = 20 * 1000;
 | 
						|
 | 
						|
  // (Here and below, we use * to make the meaning of the constant clearler).
 | 
						|
 | 
						|
  /**
 | 
						|
   * If the client has started to send the request message, the socket time out
 | 
						|
   * changes to the specified value.
 | 
						|
   */
 | 
						|
  public int TOUT_WHILE_READING = 2 * 60 * 1000;
 | 
						|
 | 
						|
  /**
 | 
						|
   * If the message body is received, the time out changes to the specifice
 | 
						|
   * value. This must be longer, as includes time, required to process the
 | 
						|
   * received task. We make it 40 minutes.
 | 
						|
   */
 | 
						|
  public int TOUT_AFTER_RECEIVING = 40 * 60 * 1000;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The server waits for this duration after the potentially transient error
 | 
						|
   * during its servicing cycle.
 | 
						|
   */
 | 
						|
  public int TWAIT_SERVER_ERROR_PAUSE = 5000;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Some clients tend to submit multiple requests over the same socket. The
 | 
						|
   * server waits for the next request on the same socket for the duration,
 | 
						|
   * specified below. In additions, the request of this implementation also
 | 
						|
   * waits for the same duration before closing the socket. The default time is
 | 
						|
   * seven seconds.
 | 
						|
   */
 | 
						|
  public static int TANDEM_REQUESTS = 7000;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The Id of this ORB.
 | 
						|
   */
 | 
						|
  public String orb_id = "orb_"+hashCode();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The Id of this Server. This field is defined static to ensure it has
 | 
						|
   * the same value over all ORB's in this machine.
 | 
						|
   */
 | 
						|
  public static String server_id = "server_"+OrbFunctional.class.hashCode();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The map of the already conncted objects.
 | 
						|
   */
 | 
						|
  protected final Connected_objects connected_objects =
 | 
						|
    new Connected_objects();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The maximal CORBA version, supported by this ORB. The default value 0 means
 | 
						|
   * that the ORB will not check the request version while trying to respond.
 | 
						|
   */
 | 
						|
  protected Version max_version;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Setting this value to false causes the ORB to shutdown after the latest
 | 
						|
   * serving operation is complete.
 | 
						|
   */
 | 
						|
  protected boolean running;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The map of the initial references.
 | 
						|
   */
 | 
						|
  protected Map initial_references = new TreeMap();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The currently active portServers.
 | 
						|
   */
 | 
						|
  protected ArrayList portServers = new ArrayList();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The host, on that the name service is expected to be running.
 | 
						|
   */
 | 
						|
  private String ns_host;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Probably free port, under that the ORB will try listening for remote
 | 
						|
   * requests first. When the new object is connected, this port is used first,
 | 
						|
   * then it is incremented by 1, etc. If the given port is not available, up to
 | 
						|
   * 20 subsequent values are tried and then the parameterless server socket
 | 
						|
   * contructor is called. The constant is shared between multiple instances of
 | 
						|
   * this ORB.
 | 
						|
   */
 | 
						|
  private static int Port = DEFAULT_INITIAL_PORT;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The port, on that the name service is expected to be running.
 | 
						|
   */
 | 
						|
  private int ns_port = 900;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The name parser.
 | 
						|
   */
 | 
						|
  NameParser nameParser = new NameParser();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The instance, stored in this field, handles the asynchronous dynamic
 | 
						|
   * invocations.
 | 
						|
   */
 | 
						|
  protected Asynchron asynchron = new Asynchron();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The list of the freed ports. The ORB reuses ports, when possible.
 | 
						|
   */
 | 
						|
  protected LinkedList freed_ports = new LinkedList();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Maps a single-threaded POAs to they sharedPortServants.
 | 
						|
   */
 | 
						|
  protected Hashtable identities = new Hashtable();
 | 
						|
 | 
						|
  /**
 | 
						|
   * The maximal allowed number of the currently running parallel threads per
 | 
						|
   * object. For security reasons, this is made private and unchangeable. After
 | 
						|
   * exceeding this limit, the NO_RESOURCES is thrown back to the client.
 | 
						|
   */
 | 
						|
  private int MAX_RUNNING_THREADS = 256;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The producer of the client and server sockets for this ORB.
 | 
						|
   */
 | 
						|
  public SocketFactory socketFactory = DefaultSocketFactory.Singleton;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Create the instance of the Functional ORB.
 | 
						|
   */
 | 
						|
  public OrbFunctional()
 | 
						|
  {
 | 
						|
    try
 | 
						|
      {
 | 
						|
        LOCAL_HOST = ns_host = InetAddress.getLocalHost().getHostAddress();
 | 
						|
        initial_references.put("CodecFactory", new gnuCodecFactory(this));
 | 
						|
      }
 | 
						|
    catch (UnknownHostException ex)
 | 
						|
      {
 | 
						|
        BAD_OPERATION bad =
 | 
						|
          new BAD_OPERATION("Unable to open the server socket.");
 | 
						|
        bad.initCause(ex);
 | 
						|
        throw bad;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * If the max version is assigned, the orb replies with the error message if
 | 
						|
   * the request version is above the supported 1.2 version. This behavior is
 | 
						|
   * recommended by OMG, but not all implementations respond that error message
 | 
						|
   * by re-sending the request, encoded in the older version.
 | 
						|
   */
 | 
						|
  public void setMaxVersion(Version max_supported)
 | 
						|
  {
 | 
						|
    max_version = max_supported;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the maximal supported GIOP version or null if the version is not
 | 
						|
   * checked.
 | 
						|
   */
 | 
						|
  public Version getMaxVersion()
 | 
						|
  {
 | 
						|
    return max_version;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the currently free port, starting from the initially set port and going
 | 
						|
   * up max 20 steps, then trying to bind into any free address.
 | 
						|
   *
 | 
						|
   * @return the currently available free port.
 | 
						|
   *
 | 
						|
   * @throws NO_RESOURCES if the server socked cannot be opened on the local
 | 
						|
   * host.
 | 
						|
   */
 | 
						|
  public int getFreePort()
 | 
						|
    throws BAD_OPERATION
 | 
						|
  {
 | 
						|
    ServerSocket s;
 | 
						|
    int a_port;
 | 
						|
 | 
						|
    try
 | 
						|
      {
 | 
						|
        // If there are some previously freed ports, use them first.
 | 
						|
        if (!freed_ports.isEmpty())
 | 
						|
          {
 | 
						|
            Integer free = (Integer) freed_ports.getLast();
 | 
						|
            freed_ports.removeLast();
 | 
						|
            s = socketFactory.createServerSocket(free.intValue());
 | 
						|
            s.close();
 | 
						|
            return free.intValue();
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (Exception ex)
 | 
						|
      {
 | 
						|
        // This may be thrown if the request for the new port has arrived
 | 
						|
        // before the current service is completly shutdown.
 | 
						|
        // OK then, use a new port.
 | 
						|
      }
 | 
						|
 | 
						|
    for (a_port = Port; a_port < Port + 20; a_port++)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            s = socketFactory.createServerSocket(a_port);
 | 
						|
            s.close();
 | 
						|
            Port = a_port + 1;
 | 
						|
            return a_port;
 | 
						|
          }
 | 
						|
        catch (IOException ex)
 | 
						|
          {
 | 
						|
            // Repeat the loop if this exception has been thrown.
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    Random rand = new Random();
 | 
						|
    // Try any random port in the interval RANDOM_PORT_FROM.RANDOM_PORT_TO.
 | 
						|
    int range = RANDOM_PORT_TO - RANDOM_PORT_FROM;
 | 
						|
    IOException ioex = null;
 | 
						|
    for (int i = 0; i < RANDOM_PORT_ATTEMPTS; i++)
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            a_port = RANDOM_PORT_FROM + rand.nextInt(range);
 | 
						|
            s = socketFactory.createServerSocket(a_port);
 | 
						|
            s.close();
 | 
						|
            return a_port;
 | 
						|
          }
 | 
						|
        catch (IOException ex)
 | 
						|
          {
 | 
						|
            // Repeat the loop if this exception has been thrown.
 | 
						|
            ioex = ex;
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    NO_RESOURCES bad = new NO_RESOURCES("Unable to open the server socket.");
 | 
						|
    bad.minor = Minor.Ports;
 | 
						|
    if (ioex != null)
 | 
						|
      bad.initCause(ioex);
 | 
						|
    throw bad;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the port, on that the server is listening for the client requests. If
 | 
						|
   * only one object is connected to the orb, the server will be try listening
 | 
						|
   * on this port first. It the port is busy, or if more objects are connected,
 | 
						|
   * the subsequent object will receive a larger port values, skipping
 | 
						|
   * unavailable ports, if required. The change applies globally.
 | 
						|
   *
 | 
						|
   * @param a_Port a port, on that the server is listening for requests.
 | 
						|
   */
 | 
						|
  public static void setPort(int a_Port)
 | 
						|
  {
 | 
						|
    Port = a_Port;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Connect the given CORBA object to this ORB. After the object is connected,
 | 
						|
   * it starts receiving remote invocations via this ORB.
 | 
						|
   *
 | 
						|
   * The ORB tries to connect the object to the port, that has been previously
 | 
						|
   * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger
 | 
						|
   * values and then calls the parameterless server socked constructor to get
 | 
						|
   * any free local port. If this fails, the {@link NO_RESOURCES} is thrown.
 | 
						|
   *
 | 
						|
   * @param object the object, must implement the {@link InvokeHandler})
 | 
						|
   * interface.
 | 
						|
   *
 | 
						|
   * @throws BAD_PARAM if the object does not implement the
 | 
						|
   * {@link InvokeHandler}).
 | 
						|
   */
 | 
						|
  public void connect(org.omg.CORBA.Object object)
 | 
						|
  {
 | 
						|
    int a_port = getFreePort();
 | 
						|
 | 
						|
    Connected_objects.cObject ref = connected_objects.add(object, a_port);
 | 
						|
    IOR ior = createIOR(ref);
 | 
						|
    prepareObject(object, ior);
 | 
						|
    if (running)
 | 
						|
      startService(ior);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Connect the given CORBA object to this ORB, explicitly specifying the
 | 
						|
   * object key.
 | 
						|
   *
 | 
						|
   * The ORB tries to connect the object to the port, that has been previously
 | 
						|
   * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger
 | 
						|
   * values and then calls the parameterless server socked constructor to get
 | 
						|
   * any free local port. If this fails, the {@link NO_RESOURCES} is thrown.
 | 
						|
   *
 | 
						|
   * @param object the object, must implement the {@link InvokeHandler})
 | 
						|
   * interface.
 | 
						|
   * @param key the object key, usually used to identify the object from remote
 | 
						|
   * side.
 | 
						|
   *
 | 
						|
   * @throws BAD_PARAM if the object does not implement the
 | 
						|
   * {@link InvokeHandler}).
 | 
						|
   */
 | 
						|
  public void connect(org.omg.CORBA.Object object, byte[] key)
 | 
						|
  {
 | 
						|
    int a_port = getFreePort();
 | 
						|
 | 
						|
    Connected_objects.cObject ref =
 | 
						|
      connected_objects.add(key, object, a_port, null);
 | 
						|
    IOR ior = createIOR(ref);
 | 
						|
    prepareObject(object, ior);
 | 
						|
    if (running)
 | 
						|
      startService(ior);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Connect the given CORBA object to this ORB, explicitly specifying the
 | 
						|
   * object key and the identity of the thread (and port), where the object must
 | 
						|
   * be served. The identity is normally the POA.
 | 
						|
   *
 | 
						|
   * The new port server will be started only if there is no one already running
 | 
						|
   * for the same identity. Otherwise, the task of the existing port server will
 | 
						|
   * be widened, including duty to serve the given object. All objects,
 | 
						|
   * connected to a single identity by this method, will process they requests
 | 
						|
   * subsequently in the same thread. The method is used when the expected
 | 
						|
   * number of the objects is too large to have a single port and thread per
 | 
						|
   * object. This method is used by POAs, having a single thread policy.
 | 
						|
   *
 | 
						|
   * @param object the object, must implement the {@link InvokeHandler})
 | 
						|
   * interface.
 | 
						|
   * @param key the object key, usually used to identify the object from remote
 | 
						|
   * side.
 | 
						|
   * @param port the port, where the object must be connected.
 | 
						|
   *
 | 
						|
   * @throws BAD_PARAM if the object does not implement the
 | 
						|
   * {@link InvokeHandler}).
 | 
						|
   */
 | 
						|
  public void connect_1_thread(org.omg.CORBA.Object object, byte[] key,
 | 
						|
    java.lang.Object identity
 | 
						|
  )
 | 
						|
  {
 | 
						|
    sharedPortServer shared = (sharedPortServer) identities.get(identity);
 | 
						|
    if (shared == null)
 | 
						|
      {
 | 
						|
        int a_port = getFreePort();
 | 
						|
        shared = new sharedPortServer(a_port);
 | 
						|
        identities.put(identity, shared);
 | 
						|
        if (running)
 | 
						|
          {
 | 
						|
            portServers.add(shared);
 | 
						|
            shared.start();
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    Connected_objects.cObject ref =
 | 
						|
      connected_objects.add(key, object, shared.s_port, identity);
 | 
						|
    IOR ior = createIOR(ref);
 | 
						|
    prepareObject(object, ior);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Start the service on the given port of this IOR.
 | 
						|
   *
 | 
						|
   * @param ior the ior (only Internet.port is used).
 | 
						|
   */
 | 
						|
  public void startService(IOR ior)
 | 
						|
  {
 | 
						|
    portServer p = new portServer(ior.Internet.port);
 | 
						|
    portServers.add(p);
 | 
						|
    p.start();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Destroy this server, releasing the occupied resources.
 | 
						|
   */
 | 
						|
  public void destroy()
 | 
						|
  {
 | 
						|
    portServer p;
 | 
						|
    for (int i = 0; i < portServers.size(); i++)
 | 
						|
      {
 | 
						|
        p = (portServer) portServers.get(i);
 | 
						|
        p.close_now();
 | 
						|
      }
 | 
						|
    super.destroy();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Disconnect the given CORBA object from this ORB. The object will be no
 | 
						|
   * longer receiving the remote invocations. In response to the remote
 | 
						|
   * invocation on this object, the ORB will send the exception
 | 
						|
   * {@link OBJECT_NOT_EXIST}. The object, however, is not destroyed and can
 | 
						|
   * receive the local invocations.
 | 
						|
   *
 | 
						|
   * @param object the object to disconnect.
 | 
						|
   */
 | 
						|
  public void disconnect(org.omg.CORBA.Object object)
 | 
						|
  {
 | 
						|
    Connected_objects.cObject rmKey = null;
 | 
						|
 | 
						|
    // Handle the case when it is possible to get the object key.
 | 
						|
    // Handle the case when the object is known, but not local.
 | 
						|
    if (object instanceof ObjectImpl)
 | 
						|
      {
 | 
						|
        Delegate delegate = ((ObjectImpl) object)._get_delegate();
 | 
						|
        if (delegate instanceof SimpleDelegate)
 | 
						|
          {
 | 
						|
            byte[] key = ((SimpleDelegate) delegate).getIor().key;
 | 
						|
            rmKey = connected_objects.get(key);
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    // Try to find and disconned the object that is not an instance of the
 | 
						|
    // object implementation.
 | 
						|
    if (rmKey == null)
 | 
						|
      rmKey = connected_objects.getKey(object);
 | 
						|
    if (rmKey != null)
 | 
						|
      {
 | 
						|
        // Find and stop the corresponding portServer.
 | 
						|
        portServer p;
 | 
						|
        StopService:
 | 
						|
        for (int i = 0; i < portServers.size(); i++)
 | 
						|
          {
 | 
						|
            p = (portServer) portServers.get(i);
 | 
						|
            if (p.s_port == rmKey.port && !(p instanceof sharedPortServer))
 | 
						|
              {
 | 
						|
                p.close_now();
 | 
						|
                freed_ports.addFirst(new Integer(rmKey.port));
 | 
						|
                break StopService;
 | 
						|
              }
 | 
						|
            connected_objects.remove(rmKey.key);
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Notifies ORB that the shared service indentity (usually POA) is destroyed.
 | 
						|
   * The matching shared port server is terminated and the identity table entry
 | 
						|
   * is deleted. If this identity is not known for this ORB, the method returns
 | 
						|
   * without action.
 | 
						|
   *
 | 
						|
   * @param identity the identity that has been destroyed.
 | 
						|
   */
 | 
						|
  public void identityDestroyed(java.lang.Object identity)
 | 
						|
  {
 | 
						|
    if (identity == null)
 | 
						|
      return;
 | 
						|
 | 
						|
    sharedPortServer ise = (sharedPortServer) identities.get(identity);
 | 
						|
    if (ise != null)
 | 
						|
      {
 | 
						|
        synchronized (connected_objects)
 | 
						|
          {
 | 
						|
            ise.close_now();
 | 
						|
            identities.remove(identity);
 | 
						|
 | 
						|
            Connected_objects.cObject obj;
 | 
						|
            Map.Entry m;
 | 
						|
            Iterator iter = connected_objects.entrySet().iterator();
 | 
						|
            while (iter.hasNext())
 | 
						|
              {
 | 
						|
                m = (Map.Entry) iter.next();
 | 
						|
                obj = (Connected_objects.cObject) m.getValue();
 | 
						|
                if (obj.identity == identity)
 | 
						|
                  iter.remove();
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find the local object, connected to this ORB.
 | 
						|
   *
 | 
						|
   * @param ior the ior of the potentially local object.
 | 
						|
   *
 | 
						|
   * @return the local object, represented by the given IOR, or null if this is
 | 
						|
   * not a local connected object.
 | 
						|
   */
 | 
						|
  public org.omg.CORBA.Object find_local_object(IOR ior)
 | 
						|
  {
 | 
						|
    // Must be the same host.
 | 
						|
    if (!ior.Internet.host.equals(LOCAL_HOST))
 | 
						|
      return null;
 | 
						|
 | 
						|
    return find_connected_object(ior.key, ior.Internet.port);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * List the initially available CORBA objects (services).
 | 
						|
   *
 | 
						|
   * @return a list of services.
 | 
						|
   *
 | 
						|
   * @see resolve_initial_references(String)
 | 
						|
   */
 | 
						|
  public String[] list_initial_services()
 | 
						|
  {
 | 
						|
    String[] refs = new String[ initial_references.size() ];
 | 
						|
    int p = 0;
 | 
						|
 | 
						|
    Iterator iter = initial_references.keySet().iterator();
 | 
						|
    while (iter.hasNext())
 | 
						|
      {
 | 
						|
        refs [ p++ ] = (String) iter.next();
 | 
						|
      }
 | 
						|
    return refs;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the IOR reference string for the given object. The string embeds
 | 
						|
   * information about the object repository Id, its access key and the server
 | 
						|
   * internet address and port. With this information, the object can be found
 | 
						|
   * by another ORB, possibly located on remote computer.
 | 
						|
   *
 | 
						|
   * @param forObject CORBA object
 | 
						|
   * @return the object IOR representation.
 | 
						|
   *
 | 
						|
   * @throws BAD_PARAM if the object has not been previously connected to this
 | 
						|
   * ORB.
 | 
						|
   *
 | 
						|
   * @throws BAD_OPERATION in the unlikely case if the local host address cannot
 | 
						|
   * be resolved.
 | 
						|
   *
 | 
						|
   * @see string_to_object(String)
 | 
						|
   */
 | 
						|
  public String object_to_string(org.omg.CORBA.Object forObject)
 | 
						|
  {
 | 
						|
    // Handle the case when the object is known, but not local.
 | 
						|
    if (forObject instanceof ObjectImpl)
 | 
						|
      {
 | 
						|
        Delegate delegate = ((ObjectImpl) forObject)._get_delegate();
 | 
						|
        if (delegate instanceof SimpleDelegate)
 | 
						|
          return ((SimpleDelegate) delegate).getIor().toStringifiedReference();
 | 
						|
      }
 | 
						|
 | 
						|
    // Handle the case when the object is local.
 | 
						|
    Connected_objects.cObject rec = connected_objects.getKey(forObject);
 | 
						|
 | 
						|
    if (rec == null)
 | 
						|
      throw new BAD_PARAM("The object " + forObject +
 | 
						|
        " has not been previously connected to this ORB"
 | 
						|
      );
 | 
						|
 | 
						|
    IOR ior = createIOR(rec);
 | 
						|
 | 
						|
    return ior.toStringifiedReference();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the local IOR for the given object, null if the object is not local.
 | 
						|
   */
 | 
						|
  public IOR getLocalIor(org.omg.CORBA.Object forObject)
 | 
						|
  {
 | 
						|
    Connected_objects.cObject rec = connected_objects.getKey(forObject);
 | 
						|
    if (rec == null)
 | 
						|
      return null;
 | 
						|
    else
 | 
						|
      return createIOR(rec);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find and return the easily accessible CORBA object, addressed by name.
 | 
						|
   *
 | 
						|
   * @param name the object name.
 | 
						|
   * @return the object
 | 
						|
   *
 | 
						|
   * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name is not
 | 
						|
   * associated with the known object.
 | 
						|
   */
 | 
						|
  public org.omg.CORBA.Object resolve_initial_references(String name)
 | 
						|
    throws InvalidName
 | 
						|
  {
 | 
						|
    org.omg.CORBA.Object object = null;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        object = (org.omg.CORBA.Object) initial_references.get(name);
 | 
						|
        if (object == null && name.equals(NAME_SERVICE))
 | 
						|
          {
 | 
						|
            object = getDefaultNameService();
 | 
						|
            if (object != null)
 | 
						|
              initial_references.put(NAME_SERVICE, object);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (Exception ex)
 | 
						|
      {
 | 
						|
        InvalidName err = new InvalidName(name);
 | 
						|
        err.initCause(ex);
 | 
						|
        throw err;
 | 
						|
      }
 | 
						|
    if (object != null)
 | 
						|
      return object;
 | 
						|
    else
 | 
						|
      throw new InvalidName("Not found: '" + name + "'");
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Start the ORBs main working cycle (receive invocation - invoke on the local
 | 
						|
   * object - send response - wait for another invocation). The method only
 | 
						|
   * returns after calling {@link #shutdown(boolean)}.
 | 
						|
   */
 | 
						|
  public void run()
 | 
						|
  {
 | 
						|
    CollocatedOrbs.registerOrb(this);
 | 
						|
    try
 | 
						|
      {
 | 
						|
        running = true;
 | 
						|
 | 
						|
        // Instantiate the port server for each socket.
 | 
						|
        Iterator iter = connected_objects.entrySet().iterator();
 | 
						|
        Map.Entry m;
 | 
						|
        Connected_objects.cObject obj;
 | 
						|
 | 
						|
        while (iter.hasNext())
 | 
						|
          {
 | 
						|
            m = (Map.Entry) iter.next();
 | 
						|
            obj = (Connected_objects.cObject) m.getValue();
 | 
						|
 | 
						|
            portServer subserver;
 | 
						|
 | 
						|
            if (obj.identity == null)
 | 
						|
              {
 | 
						|
                subserver = new portServer(obj.port);
 | 
						|
                portServers.add(subserver);
 | 
						|
              }
 | 
						|
            else
 | 
						|
              subserver = (portServer) identities.get(obj.identity);
 | 
						|
 | 
						|
            if (! subserver.isAlive())
 | 
						|
              {
 | 
						|
                // Reuse the current thread for the last portServer.
 | 
						|
                if (! iter.hasNext())
 | 
						|
                  {
 | 
						|
                    // Discard the iterator, eliminating lock checks.
 | 
						|
                    iter = null;
 | 
						|
                    subserver.run();
 | 
						|
                    return;
 | 
						|
                  }
 | 
						|
                else
 | 
						|
                  subserver.start();
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
    finally
 | 
						|
      {
 | 
						|
        CollocatedOrbs.unregisterOrb(this);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Start the server in a new thread, if not already running. This method is
 | 
						|
   * used to ensure that the objects being transfered will be served from the
 | 
						|
   * remote side, if required. If the ORB is started using this method, it
 | 
						|
   * starts as a daemon thread.
 | 
						|
   */
 | 
						|
  public void ensureRunning()
 | 
						|
  {
 | 
						|
    final OrbFunctional THIS = this;
 | 
						|
 | 
						|
    if (!running)
 | 
						|
      {
 | 
						|
        Thread t = new Thread()
 | 
						|
        {
 | 
						|
          public void run()
 | 
						|
          {
 | 
						|
            THIS.run();
 | 
						|
          }
 | 
						|
        };
 | 
						|
        t.setDaemon(true);
 | 
						|
        t.start();
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Shutdown the ORB server.
 | 
						|
   *
 | 
						|
   * @param wait_for_completion if true, the current thread is suspended until
 | 
						|
   * the shutdown process is complete.
 | 
						|
   */
 | 
						|
  public void shutdown(boolean wait_for_completion)
 | 
						|
  {
 | 
						|
    super.shutdown(wait_for_completion);
 | 
						|
    running = false;
 | 
						|
 | 
						|
    if (!wait_for_completion)
 | 
						|
      {
 | 
						|
        for (int i = 0; i < portServers.size(); i++)
 | 
						|
          {
 | 
						|
            portServer p = (portServer) portServers.get(i);
 | 
						|
            p.close_now();
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find and return the CORBA object, addressed by the given IOR string
 | 
						|
   * representation. The object can (an usually is) located on a remote
 | 
						|
   * computer, possibly running a different (not necessary java) CORBA
 | 
						|
   * implementation.
 | 
						|
   *
 | 
						|
   * @param an_ior the object IOR representation string.
 | 
						|
   *
 | 
						|
   * @return the found CORBA object.
 | 
						|
   * @see object_to_string(org.omg.CORBA.Object)
 | 
						|
   */
 | 
						|
  public org.omg.CORBA.Object string_to_object(String an_ior)
 | 
						|
  {
 | 
						|
    return nameParser.corbaloc(an_ior, this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Convert ior reference to CORBA object.
 | 
						|
   */
 | 
						|
  public org.omg.CORBA.Object ior_to_object(IOR ior)
 | 
						|
  {
 | 
						|
    org.omg.CORBA.Object object = find_local_object(ior);
 | 
						|
    if (object == null)
 | 
						|
      {
 | 
						|
        // Check maybe the local object on another ORB, but same VM.
 | 
						|
        object = CollocatedOrbs.searchLocalObject(ior);
 | 
						|
        if (object == null)
 | 
						|
          {
 | 
						|
            // Surely remote object.
 | 
						|
            ObjectImpl impl = StubLocator.search(this, ior);
 | 
						|
            try
 | 
						|
              {
 | 
						|
                if (impl._get_delegate() == null)
 | 
						|
                  impl._set_delegate(new IorDelegate(this, ior));
 | 
						|
              }
 | 
						|
            catch (BAD_OPERATION ex)
 | 
						|
              {
 | 
						|
                // Some colaborants may throw this exception
 | 
						|
                // in response to the attempt to get the unset delegate.
 | 
						|
                impl._set_delegate(new IorDelegate(this, ior));
 | 
						|
              }
 | 
						|
 | 
						|
            object = impl;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return object;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the default naming service for the case when there no NameService
 | 
						|
   * entries.
 | 
						|
   */
 | 
						|
  protected org.omg.CORBA.Object getDefaultNameService()
 | 
						|
  {
 | 
						|
    if (initial_references.containsKey(NAME_SERVICE))
 | 
						|
      return (org.omg.CORBA.Object) initial_references.get(NAME_SERVICE);
 | 
						|
 | 
						|
    IOR ior = new IOR();
 | 
						|
    ior.Id = NamingContextExtHelper.id();
 | 
						|
    ior.Internet.host = ns_host;
 | 
						|
    ior.Internet.port = ns_port;
 | 
						|
    ior.key = NamingServiceTransient.getDefaultKey();
 | 
						|
 | 
						|
    IorObject iorc = new IorObject(this, ior);
 | 
						|
    NamingContextExt namer = NamingContextExtHelper.narrow(iorc);
 | 
						|
    initial_references.put(NAME_SERVICE, namer);
 | 
						|
    return namer;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find and return the object, that must be previously connected to this ORB.
 | 
						|
   * Return null if no such object is available.
 | 
						|
   *
 | 
						|
   * @param key the object key.
 | 
						|
   * @param port the port where the object is connected.
 | 
						|
   *
 | 
						|
   * @return the connected object, null if none.
 | 
						|
   */
 | 
						|
  protected org.omg.CORBA.Object find_connected_object(byte[] key, int port)
 | 
						|
  {
 | 
						|
    Connected_objects.cObject ref = connected_objects.get(key);
 | 
						|
    if (ref == null)
 | 
						|
      return null;
 | 
						|
    if (port >= 0 && ref.port != port)
 | 
						|
      return null;
 | 
						|
    else
 | 
						|
      return ref.object;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the ORB parameters. This method is normally called from
 | 
						|
   * {@link #init(Applet, Properties)}.
 | 
						|
   *
 | 
						|
   * @param app the current applet.
 | 
						|
   *
 | 
						|
   * @param props application specific properties, passed as the second
 | 
						|
   * parameter in {@link #init(Applet, Properties)}. Can be <code>null</code>.
 | 
						|
   */
 | 
						|
  protected void set_parameters(Applet app, Properties props)
 | 
						|
  {
 | 
						|
    useProperties(props);
 | 
						|
 | 
						|
    String[][] para = app.getParameterInfo();
 | 
						|
    if (para != null)
 | 
						|
      {
 | 
						|
        for (int i = 0; i < para.length; i++)
 | 
						|
          {
 | 
						|
            if (para[i][0].equals(LISTEN_ON))
 | 
						|
              Port = Integer.parseInt(para[i][1]);
 | 
						|
            if (para[i][0].equals(REFERENCE))
 | 
						|
              {
 | 
						|
                StringTokenizer st = new StringTokenizer(para[i][1], "=");
 | 
						|
                initial_references.put(st.nextToken(),
 | 
						|
                  string_to_object(st.nextToken()));
 | 
						|
              }
 | 
						|
 | 
						|
            if (para[i][0].equals(ORB_ID))
 | 
						|
              orb_id = para[i][1];
 | 
						|
 | 
						|
            if (para[i][0].equals(SERVER_ID))
 | 
						|
              server_id = para[i][1];
 | 
						|
 | 
						|
            if (para[i][0].equals(NS_HOST))
 | 
						|
              ns_host = para[i][1];
 | 
						|
            if (para[i][0].equals(START_READING_MESSAGE))
 | 
						|
              TOUT_START_READING_MESSAGE = Integer.parseInt(para[i][1]);
 | 
						|
            if (para[i][0].equals(WHILE_READING))
 | 
						|
              TOUT_WHILE_READING = Integer.parseInt(para[i][1]);
 | 
						|
            if (para[i][0].equals(AFTER_RECEIVING))
 | 
						|
              TOUT_AFTER_RECEIVING = Integer.parseInt(para[i][1]);
 | 
						|
            try
 | 
						|
              {
 | 
						|
                if (para[i][0].equals(NS_PORT))
 | 
						|
                  ns_port = Integer.parseInt(para[i][1]);
 | 
						|
              }
 | 
						|
            catch (NumberFormatException ex)
 | 
						|
              {
 | 
						|
                BAD_PARAM bad = new BAD_PARAM("Invalid " + NS_PORT
 | 
						|
                  + "property, unable to parse '" + props.getProperty(NS_PORT)
 | 
						|
                  + "'");
 | 
						|
                bad.initCause(ex);
 | 
						|
                throw bad;
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the ORB parameters. This method is normally called from
 | 
						|
   * {@link #init(String[], Properties)}.
 | 
						|
   *
 | 
						|
   * @param para the parameters, that were passed as the parameters to the
 | 
						|
   * <code>main(String[] args)</code> method of the current standalone
 | 
						|
   * application.
 | 
						|
   *
 | 
						|
   * @param props application specific properties that were passed as a second
 | 
						|
   * parameter in {@link init(String[], Properties)}). Can be <code>null</code>.
 | 
						|
   */
 | 
						|
  protected void set_parameters(String[] para, Properties props)
 | 
						|
  {
 | 
						|
    if ((para != null) && para.length > 1)
 | 
						|
      {
 | 
						|
        for (int i = 0; i < para.length - 1; i++)
 | 
						|
          {
 | 
						|
            if (para[i].endsWith("ListenOn"))
 | 
						|
              Port = Integer.parseInt(para[i + 1]);
 | 
						|
            if (para[i].endsWith("ORBInitRef"))
 | 
						|
              {
 | 
						|
                StringTokenizer st = new StringTokenizer(para[i + 1], "=");
 | 
						|
                initial_references.put(st.nextToken(),
 | 
						|
                  string_to_object(st.nextToken()));
 | 
						|
              }
 | 
						|
 | 
						|
            if (para[i].endsWith("ORBInitialHost"))
 | 
						|
              ns_host = para[i + 1];
 | 
						|
 | 
						|
            if (para[i].endsWith("ServerId"))
 | 
						|
              server_id = para[i++];
 | 
						|
            else if (para[i].endsWith("ORBid"))
 | 
						|
              orb_id = para[i++];
 | 
						|
 | 
						|
            try
 | 
						|
              {
 | 
						|
                if (para[i].endsWith("ORBInitialPort"))
 | 
						|
                  ns_port = Integer.parseInt(para[i + 1]);
 | 
						|
              }
 | 
						|
            catch (NumberFormatException ex)
 | 
						|
              {
 | 
						|
                throw new BAD_PARAM("Invalid " + para[i]
 | 
						|
                  + "parameter, unable to parse '"
 | 
						|
                  + props.getProperty(para[i + 1]) + "'");
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    useProperties(props);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Create IOR for the given object references.
 | 
						|
   */
 | 
						|
  protected IOR createIOR(Connected_objects.cObject ref)
 | 
						|
    throws BAD_OPERATION
 | 
						|
  {
 | 
						|
    IOR ior = new IOR();
 | 
						|
    ior.key = ref.key;
 | 
						|
    ior.Internet.port = ref.port;
 | 
						|
 | 
						|
    if (ref.object instanceof ObjectImpl)
 | 
						|
      {
 | 
						|
        ObjectImpl imp = (ObjectImpl) ref.object;
 | 
						|
        if (imp._ids().length > 0)
 | 
						|
          ior.Id = imp._ids() [ 0 ];
 | 
						|
      }
 | 
						|
    if (ior.Id == null)
 | 
						|
      ior.Id = ref.object.getClass().getName();
 | 
						|
 | 
						|
    ior.Internet.host = CollocatedOrbs.localHost;
 | 
						|
    ior.Internet.port = ref.port;
 | 
						|
 | 
						|
    return ior;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Prepare object for connecting it to this ORB.
 | 
						|
   *
 | 
						|
   * @param object the object being connected.
 | 
						|
   *
 | 
						|
   * @throws BAD_PARAM if the object does not implement the
 | 
						|
   * {@link InvokeHandler}).
 | 
						|
   */
 | 
						|
  protected void prepareObject(org.omg.CORBA.Object object, IOR ior)
 | 
						|
    throws BAD_PARAM
 | 
						|
  {
 | 
						|
    /*
 | 
						|
     * if (!(object instanceof InvokeHandler)) throw new
 | 
						|
     * BAD_PARAM(object.getClass().getName() + " does not implement
 | 
						|
     * InvokeHandler. " );
 | 
						|
     */
 | 
						|
 | 
						|
    // If no delegate is set, set the default delegate.
 | 
						|
    if (object instanceof ObjectImpl)
 | 
						|
      {
 | 
						|
        ObjectImpl impl = (ObjectImpl) object;
 | 
						|
        try
 | 
						|
          {
 | 
						|
            if (impl._get_delegate() == null)
 | 
						|
              impl._set_delegate(new SimpleDelegate(this, ior));
 | 
						|
          }
 | 
						|
        catch (BAD_OPERATION ex)
 | 
						|
          {
 | 
						|
            // Some colaborants may throw this exception.
 | 
						|
            impl._set_delegate(new SimpleDelegate(this, ior));
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Write the response message.
 | 
						|
   *
 | 
						|
   * @param net_out the stream to write response into
 | 
						|
   * @param msh_request the request message header
 | 
						|
   * @param rh_request the request header
 | 
						|
   * @param handler the invocation handler that has been used to invoke the
 | 
						|
   * operation
 | 
						|
   * @param sysEx the system exception, thrown during the invocation, null if
 | 
						|
   * none.
 | 
						|
   *
 | 
						|
   * @throws IOException
 | 
						|
   */
 | 
						|
  private void respond_to_client(OutputStream net_out,
 | 
						|
    MessageHeader msh_request, RequestHeader rh_request,
 | 
						|
    ResponseHandlerImpl handler, SystemException sysEx
 | 
						|
  ) throws IOException
 | 
						|
  {
 | 
						|
    // Set the reply header properties.
 | 
						|
    ReplyHeader reply = handler.reply_header;
 | 
						|
 | 
						|
    if (sysEx != null)
 | 
						|
      reply.reply_status = ReplyHeader.SYSTEM_EXCEPTION;
 | 
						|
    else if (handler.isExceptionReply())
 | 
						|
      reply.reply_status = ReplyHeader.USER_EXCEPTION;
 | 
						|
    else
 | 
						|
      reply.reply_status = ReplyHeader.NO_EXCEPTION;
 | 
						|
    reply.request_id = rh_request.request_id;
 | 
						|
 | 
						|
    BufferedCdrOutput out =
 | 
						|
      new BufferedCdrOutput(50 + handler.getBuffer().buffer.size());
 | 
						|
    out.setOrb(this);
 | 
						|
 | 
						|
    out.setOffset(msh_request.getHeaderSize());
 | 
						|
 | 
						|
    reply.write(out);
 | 
						|
 | 
						|
    if (msh_request.version.since_inclusive(1, 2))
 | 
						|
      {
 | 
						|
        out.align(8);
 | 
						|
 | 
						|
        // Write the reply data from the handler. The handler data already
 | 
						|
        // include the necessary heading zeroes for alignment.
 | 
						|
      }
 | 
						|
    handler.getBuffer().buffer.writeTo(out);
 | 
						|
 | 
						|
    MessageHeader msh_reply = new MessageHeader();
 | 
						|
 | 
						|
    msh_reply.version = msh_request.version;
 | 
						|
    msh_reply.message_type = MessageHeader.REPLY;
 | 
						|
    msh_reply.message_size = out.buffer.size();
 | 
						|
 | 
						|
    // Write the reply.
 | 
						|
    msh_reply.write(net_out);
 | 
						|
    out.buffer.writeTo(net_out);
 | 
						|
    net_out.flush();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Forward request to another target, as indicated by the passed exception.
 | 
						|
   */
 | 
						|
  private void forward_request(OutputStream net_out,
 | 
						|
    MessageHeader msh_request, RequestHeader rh_request, gnuForwardRequest info
 | 
						|
  ) throws IOException
 | 
						|
  {
 | 
						|
    MessageHeader msh_forward = new MessageHeader();
 | 
						|
    msh_forward.version = msh_request.version;
 | 
						|
 | 
						|
    ReplyHeader rh_forward = msh_forward.create_reply_header();
 | 
						|
    msh_forward.message_type = MessageHeader.REPLY;
 | 
						|
    rh_forward.reply_status = info.forwarding_code;
 | 
						|
    rh_forward.request_id = rh_request.request_id;
 | 
						|
 | 
						|
    // The forwarding code is either LOCATION_FORWARD or LOCATION_FORWARD_PERM.
 | 
						|
    BufferedCdrOutput out = new BufferedCdrOutput();
 | 
						|
    out.setOrb(this);
 | 
						|
    out.setOffset(msh_forward.getHeaderSize());
 | 
						|
 | 
						|
    rh_forward.write(out);
 | 
						|
 | 
						|
    if (msh_forward.version.since_inclusive(1, 2))
 | 
						|
      out.align(8);
 | 
						|
    out.write_Object(info.forward_reference);
 | 
						|
 | 
						|
    msh_forward.message_size = out.buffer.size();
 | 
						|
 | 
						|
    // Write the forwarding instruction.
 | 
						|
    msh_forward.write(net_out);
 | 
						|
    out.buffer.writeTo(net_out);
 | 
						|
    net_out.flush();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Contains a single servicing task.
 | 
						|
   *
 | 
						|
   * Normally, each task matches a single remote invocation. However under
 | 
						|
   * frequent tandem submissions the same task may span over several
 | 
						|
   * invocations.
 | 
						|
   *
 | 
						|
   * @param serverSocket the ORB server socket.
 | 
						|
   *
 | 
						|
   * @throws MARSHAL
 | 
						|
   * @throws IOException
 | 
						|
   */
 | 
						|
  void serve(final portServer p, ServerSocket serverSocket)
 | 
						|
    throws MARSHAL, IOException
 | 
						|
  {
 | 
						|
    final Socket service;
 | 
						|
    service = serverSocket.accept();
 | 
						|
 | 
						|
    // Tell the server there are no more resources.
 | 
						|
    if (p.running_threads >= MAX_RUNNING_THREADS)
 | 
						|
      {
 | 
						|
        serveStep(service, true);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
    new Thread()
 | 
						|
      {
 | 
						|
        public void run()
 | 
						|
        {
 | 
						|
          try
 | 
						|
            {
 | 
						|
              synchronized (p)
 | 
						|
                {
 | 
						|
                  p.running_threads++;
 | 
						|
                }
 | 
						|
              serveStep(service, false);
 | 
						|
            }
 | 
						|
          finally
 | 
						|
            {
 | 
						|
              synchronized (p)
 | 
						|
                {
 | 
						|
                  p.running_threads--;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
      }.start();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * A single servicing step, when the client socket is alrady open.
 | 
						|
   *
 | 
						|
   * Normally, each task matches a single remote invocation. However under
 | 
						|
   * frequent tandem submissions the same task may span over several
 | 
						|
   * invocations.
 | 
						|
   *
 | 
						|
   * @param service the opened client socket.
 | 
						|
   * @param no_resources if true, the "NO RESOURCES" exception is thrown to the
 | 
						|
   * client.
 | 
						|
   */
 | 
						|
  void serveStep(Socket service, boolean no_resources)
 | 
						|
  {
 | 
						|
    try
 | 
						|
      {
 | 
						|
        Serving: while (true)
 | 
						|
          {
 | 
						|
            InputStream in = service.getInputStream();
 | 
						|
            service.setSoTimeout(TOUT_START_READING_MESSAGE);
 | 
						|
 | 
						|
            MessageHeader msh_request = new MessageHeader();
 | 
						|
 | 
						|
            try
 | 
						|
              {
 | 
						|
                msh_request.read(in);
 | 
						|
              }
 | 
						|
            catch (MARSHAL ex)
 | 
						|
              {
 | 
						|
                // This exception may be thrown due closing the connection.
 | 
						|
                return;
 | 
						|
              }
 | 
						|
 | 
						|
            if (max_version != null)
 | 
						|
              {
 | 
						|
                if (!msh_request.version.until_inclusive(max_version.major,
 | 
						|
                  max_version.minor))
 | 
						|
                  {
 | 
						|
                    OutputStream out = service.getOutputStream();
 | 
						|
                    new ErrorMessage(max_version).write(out);
 | 
						|
                    return;
 | 
						|
                  }
 | 
						|
              }
 | 
						|
 | 
						|
            byte[] r = msh_request.readMessage(in, service, TOUT_WHILE_READING,
 | 
						|
              TOUT_AFTER_RECEIVING);
 | 
						|
 | 
						|
            if (msh_request.message_type == MessageHeader.REQUEST)
 | 
						|
              {
 | 
						|
                RequestHeader rh_request;
 | 
						|
 | 
						|
                BufferredCdrInput cin = new BufferredCdrInput(r);
 | 
						|
                cin.setOrb(this);
 | 
						|
                cin.setVersion(msh_request.version);
 | 
						|
                cin.setOffset(msh_request.getHeaderSize());
 | 
						|
                cin.setBigEndian(msh_request.isBigEndian());
 | 
						|
 | 
						|
                rh_request = msh_request.create_request_header();
 | 
						|
 | 
						|
                // Read header and auto set the charset.
 | 
						|
                rh_request.read(cin);
 | 
						|
 | 
						|
                // in 1.2 and higher, align the current position at
 | 
						|
                // 8 octet boundary.
 | 
						|
                if (msh_request.version.since_inclusive(1, 2))
 | 
						|
                  {
 | 
						|
                    cin.align(8);
 | 
						|
 | 
						|
                    // find the target object.
 | 
						|
                  }
 | 
						|
 | 
						|
                InvokeHandler target = (InvokeHandler) find_connected_object(
 | 
						|
                  rh_request.object_key, -1);
 | 
						|
 | 
						|
                // Prepare the reply header. This must be done in advance,
 | 
						|
                // as the size must be known for handler to set alignments
 | 
						|
                // correctly.
 | 
						|
                ReplyHeader rh_reply = msh_request.create_reply_header();
 | 
						|
 | 
						|
                // TODO log errors about not existing objects and methods.
 | 
						|
                ResponseHandlerImpl handler = new ResponseHandlerImpl(
 | 
						|
                  this, msh_request, rh_reply, rh_request);
 | 
						|
 | 
						|
                SystemException sysEx = null;
 | 
						|
 | 
						|
                try
 | 
						|
                  {
 | 
						|
                    if (no_resources)
 | 
						|
                      {
 | 
						|
                        NO_RESOURCES no = new NO_RESOURCES("Too many parallel calls");
 | 
						|
                        no.minor = Minor.Threads;
 | 
						|
                        throw no;
 | 
						|
                      }
 | 
						|
                    if (target == null)
 | 
						|
                      throw new OBJECT_NOT_EXIST();
 | 
						|
                    target._invoke(rh_request.operation, cin, handler);
 | 
						|
                  }
 | 
						|
                catch (gnuForwardRequest forwarded)
 | 
						|
                  {
 | 
						|
                    OutputStream sou = service.getOutputStream();
 | 
						|
                    forward_request(sou, msh_request, rh_request, forwarded);
 | 
						|
                    if (service != null && !service.isClosed())
 | 
						|
                      {
 | 
						|
                        // Wait for the subsequent invocations on the
 | 
						|
                        // same socket for the TANDEM_REQUEST duration.
 | 
						|
                        service.setSoTimeout(TANDEM_REQUESTS);
 | 
						|
                        continue Serving;
 | 
						|
                      }
 | 
						|
                  }
 | 
						|
                catch (UnknownException uex)
 | 
						|
                  {
 | 
						|
                    sysEx = new UNKNOWN("Unknown", 2,
 | 
						|
                      CompletionStatus.COMPLETED_MAYBE);
 | 
						|
                    sysEx.initCause(uex.originalEx);
 | 
						|
 | 
						|
                    org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();
 | 
						|
 | 
						|
                    rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(
 | 
						|
                      rh_reply.service_context, uex.originalEx, ech);
 | 
						|
 | 
						|
                    ObjectCreator.writeSystemException(ech, sysEx);
 | 
						|
                  }
 | 
						|
                catch (SystemException ex)
 | 
						|
                  {
 | 
						|
                    sysEx = ex;
 | 
						|
 | 
						|
                    org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();
 | 
						|
 | 
						|
                    rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(
 | 
						|
                      rh_reply.service_context, ex, ech);
 | 
						|
 | 
						|
                    ObjectCreator.writeSystemException(ech, ex);
 | 
						|
                  }
 | 
						|
                catch (Exception except)
 | 
						|
                  {
 | 
						|
                    // This should never happen under normal operation and
 | 
						|
                    // can only indicate errors in user object implementation.
 | 
						|
                    // We inform the user.
 | 
						|
                    except.printStackTrace();
 | 
						|
 | 
						|
                    sysEx = new UNKNOWN("Unknown", 2,
 | 
						|
                      CompletionStatus.COMPLETED_MAYBE);
 | 
						|
                    sysEx.initCause(except);
 | 
						|
 | 
						|
                    org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();
 | 
						|
 | 
						|
                    rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(
 | 
						|
                      rh_reply.service_context, except, ech);
 | 
						|
 | 
						|
                    ObjectCreator.writeSystemException(ech, sysEx);
 | 
						|
                  }
 | 
						|
 | 
						|
                // Write the response.
 | 
						|
                if (rh_request.isResponseExpected())
 | 
						|
                  {
 | 
						|
                    OutputStream sou = service.getOutputStream();
 | 
						|
                    respond_to_client(sou, msh_request, rh_request, handler,
 | 
						|
                      sysEx);
 | 
						|
                  }
 | 
						|
              }
 | 
						|
            else if (msh_request.message_type == MessageHeader.CLOSE_CONNECTION
 | 
						|
              || msh_request.message_type == MessageHeader.MESSAGE_ERROR)
 | 
						|
              {
 | 
						|
                CloseMessage.close(service.getOutputStream());
 | 
						|
                service.close();
 | 
						|
                return;
 | 
						|
              }
 | 
						|
 | 
						|
            if (service != null && !service.isClosed())
 | 
						|
 | 
						|
              // Wait for the subsequent invocations on the
 | 
						|
              // same socket for the TANDEM_REQUEST duration.
 | 
						|
              service.setSoTimeout(TANDEM_REQUESTS);
 | 
						|
            else
 | 
						|
              return;
 | 
						|
          }
 | 
						|
      }
 | 
						|
    catch (SocketException ex)
 | 
						|
      {
 | 
						|
        // OK.
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    catch (IOException ioex)
 | 
						|
      {
 | 
						|
        // Network error, probably transient.
 | 
						|
        // TODO log it.
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    finally
 | 
						|
      {
 | 
						|
        try
 | 
						|
          {
 | 
						|
            if (service!=null && !service.isClosed())
 | 
						|
              service.close();
 | 
						|
          }
 | 
						|
        catch (IOException ioex)
 | 
						|
          {
 | 
						|
            // OK.
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the ORB parameters from the properties that were accumulated
 | 
						|
   * from several locations.
 | 
						|
   */
 | 
						|
  protected void useProperties(Properties props)
 | 
						|
  {
 | 
						|
    if (props != null)
 | 
						|
      {
 | 
						|
        if (props.containsKey(LISTEN_ON))
 | 
						|
          Port = Integer.parseInt(props.getProperty(LISTEN_ON));
 | 
						|
        if (props.containsKey(NS_HOST))
 | 
						|
          ns_host = props.getProperty(NS_HOST);
 | 
						|
        try
 | 
						|
          {
 | 
						|
            if (props.containsKey(NS_PORT))
 | 
						|
              ns_port = Integer.parseInt(props.getProperty(NS_PORT));
 | 
						|
            if (props.containsKey(START_READING_MESSAGE))
 | 
						|
              TOUT_START_READING_MESSAGE =
 | 
						|
                Integer.parseInt(props.getProperty(START_READING_MESSAGE));
 | 
						|
            if (props.containsKey(WHILE_READING))
 | 
						|
              TOUT_WHILE_READING =
 | 
						|
                Integer.parseInt(props.getProperty(WHILE_READING));
 | 
						|
            if (props.containsKey(AFTER_RECEIVING))
 | 
						|
              TOUT_AFTER_RECEIVING =
 | 
						|
                Integer.parseInt(props.getProperty(AFTER_RECEIVING));
 | 
						|
            if (props.containsKey(SERVER_ERROR_PAUSE))
 | 
						|
              TWAIT_SERVER_ERROR_PAUSE =
 | 
						|
                Integer.parseInt(props.getProperty(SERVER_ERROR_PAUSE));
 | 
						|
          }
 | 
						|
        catch (NumberFormatException ex)
 | 
						|
          {
 | 
						|
            throw new BAD_PARAM("Invalid " + NS_PORT +
 | 
						|
              "property, unable to parse '" + props.getProperty(NS_PORT) +
 | 
						|
              "'"
 | 
						|
            );
 | 
						|
          }
 | 
						|
 | 
						|
        if (props.containsKey(SocketFactory.PROPERTY))
 | 
						|
          {
 | 
						|
            String factory = null;
 | 
						|
            try
 | 
						|
              {
 | 
						|
                factory = props.getProperty(SocketFactory.PROPERTY);
 | 
						|
                if (factory!=null)
 | 
						|
                  socketFactory = (SocketFactory)
 | 
						|
                    ObjectCreator.forName(factory).newInstance();
 | 
						|
              }
 | 
						|
            catch (Exception ex)
 | 
						|
              {
 | 
						|
                BAD_PARAM p = new BAD_PARAM("Bad socket factory "+factory);
 | 
						|
                p.initCause(ex);
 | 
						|
                throw p;
 | 
						|
              }
 | 
						|
          }
 | 
						|
 | 
						|
        if (props.containsKey(ORB_ID))
 | 
						|
          orb_id = props.getProperty(ORB_ID);
 | 
						|
 | 
						|
        if (props.containsKey(SERVER_ID))
 | 
						|
          server_id = props.getProperty(SERVER_ID);
 | 
						|
 | 
						|
        Enumeration en = props.elements();
 | 
						|
        while (en.hasMoreElements())
 | 
						|
          {
 | 
						|
            String item = (String) en.nextElement();
 | 
						|
            if (item.equals(REFERENCE))
 | 
						|
              initial_references.put(item,
 | 
						|
                string_to_object(props.getProperty(item))
 | 
						|
              );
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the next instance with a response being received. If all currently sent
 | 
						|
   * responses not yet processed, this method pauses till at least one of them
 | 
						|
   * is complete. If there are no requests currently sent, the method pauses
 | 
						|
   * till some request is submitted and the response is received. This strategy
 | 
						|
   * is identical to the one accepted by Suns 1.4 ORB implementation.
 | 
						|
   *
 | 
						|
   * The returned response is removed from the list of the currently submitted
 | 
						|
   * responses and is never returned again.
 | 
						|
   *
 | 
						|
   * @return the previously sent request that now contains the received
 | 
						|
   * response.
 | 
						|
   *
 | 
						|
   * @throws WrongTransaction If the method was called from the transaction
 | 
						|
   * scope different than the one, used to send the request. The exception can
 | 
						|
   * be raised only if the request is implicitly associated with some particular
 | 
						|
   * transaction.
 | 
						|
   */
 | 
						|
  public Request get_next_response() throws org.omg.CORBA.WrongTransaction
 | 
						|
  {
 | 
						|
    return asynchron.get_next_response();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Find if any of the requests that have been previously sent with
 | 
						|
   * {@link #send_multiple_requests_deferred}, have a response yet.
 | 
						|
   *
 | 
						|
   * @return true if there is at least one response to the previously sent
 | 
						|
   * request, false otherwise.
 | 
						|
   */
 | 
						|
  public boolean poll_next_response()
 | 
						|
  {
 | 
						|
    return asynchron.poll_next_response();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Send multiple prepared requests expecting to get a reply. All requests are
 | 
						|
   * send in parallel, each in its own separate thread. When the reply arrives,
 | 
						|
   * it is stored in the agreed fields of the corresponing request data
 | 
						|
   * structure. If this method is called repeatedly, the new requests are added
 | 
						|
   * to the set of the currently sent requests, but the old set is not
 | 
						|
   * discarded.
 | 
						|
   *
 | 
						|
   * @param requests the prepared array of requests.
 | 
						|
   *
 | 
						|
   * @see #poll_next_response()
 | 
						|
   * @see #get_next_response()
 | 
						|
   * @see Request#send_deferred()
 | 
						|
   */
 | 
						|
  public void send_multiple_requests_deferred(Request[] requests)
 | 
						|
  {
 | 
						|
    asynchron.send_multiple_requests_deferred(requests);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Send multiple prepared requests one way, do not caring about the answer.
 | 
						|
   * The messages, containing requests, will be marked, indicating that the
 | 
						|
   * sender is not expecting to get a reply.
 | 
						|
   *
 | 
						|
   * @param requests the prepared array of requests.
 | 
						|
   *
 | 
						|
   * @see Request#send_oneway()
 | 
						|
   */
 | 
						|
  public void send_multiple_requests_oneway(Request[] requests)
 | 
						|
  {
 | 
						|
    asynchron.send_multiple_requests_oneway(requests);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the flag, forcing all server threads to terminate.
 | 
						|
   */
 | 
						|
  protected void finalize() throws java.lang.Throwable
 | 
						|
  {
 | 
						|
    running = false;
 | 
						|
    super.finalize();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the number of objects that are connected to this ORB.
 | 
						|
   *
 | 
						|
   * @return the number of objects, connected to this ORB.
 | 
						|
   */
 | 
						|
  public int countConnectedObjects()
 | 
						|
  {
 | 
						|
    return connected_objects.size();
 | 
						|
  }
 | 
						|
}
 |