diff options
| author | Mark Wielaard <mark@gcc.gnu.org> | 2005-11-15 23:20:01 +0000 |
|---|---|---|
| committer | Mark Wielaard <mark@gcc.gnu.org> | 2005-11-15 23:20:01 +0000 |
| commit | 8f523f3a1047919d3563daf1ef47ba87336ebe89 (patch) | |
| tree | a5eb7cf42a51869cc8aa1fad7ad6a90cca47fdd8 /libjava/classpath/gnu/CORBA/Functional_ORB.java | |
| parent | 02e549bfaaec38f68307e7f34e46ea57ea1809af (diff) | |
Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated.
* Makefile.in: Likewise.
* scripts/makemake.tcl: Use glob -nocomplain.
From-SVN: r107049
Diffstat (limited to 'libjava/classpath/gnu/CORBA/Functional_ORB.java')
| -rw-r--r-- | libjava/classpath/gnu/CORBA/Functional_ORB.java | 1627 |
1 files changed, 0 insertions, 1627 deletions
diff --git a/libjava/classpath/gnu/CORBA/Functional_ORB.java b/libjava/classpath/gnu/CORBA/Functional_ORB.java deleted file mode 100644 index 1565b2cf14a..00000000000 --- a/libjava/classpath/gnu/CORBA/Functional_ORB.java +++ /dev/null @@ -1,1627 +0,0 @@ -/* Functional_ORB.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.cdrBufInput; -import gnu.CORBA.CDR.cdrBufOutput; -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 org.omg.CORBA.BAD_OPERATION; -import org.omg.CORBA.BAD_PARAM; -import org.omg.CORBA.CompletionStatus; -import org.omg.CORBA.DATA_CONVERSION; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.NO_RESOURCES; -import org.omg.CORBA.OBJECT_NOT_EXIST; -import org.omg.CORBA.Object; -import org.omg.CORBA.ORBPackage.InvalidName; -import org.omg.CORBA.Request; -import org.omg.CORBA.SystemException; -import org.omg.CORBA.UNKNOWN; -import org.omg.CORBA.WrongTransaction; -import org.omg.CORBA.portable.Delegate; -import org.omg.CORBA.portable.InvokeHandler; -import org.omg.CORBA.portable.ObjectImpl; -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.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 Functional_ORB extends Restricted_ORB -{ - /** - * 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. - */ - 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; - } - - /** - * Enter the serving loop (get request/process it). All portServer normally - * terminate thy threads when the Functional_ORB.running is set to false. - */ - public void run() - { - try - { - service = new ServerSocket(s_port); - } - catch (IOException ex) - { - BAD_OPERATION bad = - new BAD_OPERATION("Unable to open the server socket."); - bad.initCause(ex); - throw bad; - } - - 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 5 seconds. Do not terminate the - // service due potentially transient error. - try - { - Thread.sleep(5000); - } - 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. - */ - 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; - - /** - * 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"; - - /** - * 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 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. - */ - private 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. - */ - private 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. - */ - private int TOUT_AFTER_RECEIVING = 40 * 60 * 1000; - - /** - * 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 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. - */ - private 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; - - /** - * Create the instance of the Functional ORB. - */ - public Functional_ORB() - { - 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 = new ServerSocket(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 = new ServerSocket(a_port); - s.close(); - Port = a_port + 1; - return a_port; - } - catch (IOException ex) - { - // Repeat the loop if this exception has been thrown. - } - } - - try - { - // Try any port. - s = new ServerSocket(); - a_port = s.getLocalPort(); - s.close(); - return a_port; - } - catch (IOException ex) - { - NO_RESOURCES bad = - new NO_RESOURCES("Unable to open the server socket."); - bad.initCause(ex); - 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 Simple_delegate) - { - byte[] key = ((Simple_delegate) 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; - - // Must be the same port. - if (ior.Internet.port != Port) - return null; - - return find_connected_object(ior.key); - } - - /** - * 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 the 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 Simple_delegate) - return ((Simple_delegate) 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() - { - 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(); - } - } - } - - /** - * 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 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) - { - ObjectImpl impl = stubFinder.search(this, ior); - try - { - if (impl._get_delegate() == null) - impl._set_delegate(new IOR_Delegate(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 IOR_Delegate(this, ior)); - } - - object = impl; - connected_objects.add(ior.key, impl, ior.Internet.port, null); - } - 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(); - - IOR_contructed_object iorc = new IOR_contructed_object(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. - * - * @return the connected object, null if none. - */ - protected org.omg.CORBA.Object find_connected_object(byte[] key) - { - Connected_objects.cObject ref = connected_objects.get(key); - return ref == null ? null : 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(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.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 ]; - 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(); - try - { - ior.Internet.host = InetAddress.getLocalHost().getHostAddress(); - ior.Internet.port = ref.port; - } - catch (UnknownHostException ex) - { - throw new BAD_OPERATION("Cannot resolve the local host address"); - } - 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}). - */ - private 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 Simple_delegate(this, ior)); - } - catch (BAD_OPERATION ex) - { - // Some colaborants may throw this exception. - impl._set_delegate(new Simple_delegate(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, - bufferedResponseHandler 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; - - cdrBufOutput out = - new cdrBufOutput(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. - cdrBufOutput out = new cdrBufOutput(); - 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 = new byte[ msh_request.message_size ]; - - int n = 0; - - service.setSoTimeout(TOUT_WHILE_READING); - - reading: - while (n < r.length) - { - n += in.read(r, n, r.length - n); - } - - service.setSoTimeout(TOUT_AFTER_RECEIVING); - - if (msh_request.message_type == MessageHeader.REQUEST) - { - RequestHeader rh_request; - - cdrBufInput cin = new cdrBufInput(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); - - // 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. - bufferedResponseHandler handler = - new bufferedResponseHandler(this, msh_request, rh_reply, - rh_request - ); - - SystemException sysEx = null; - - try - { - if (no_resources) - throw new NO_RESOURCES(); - 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 (SystemException ex) - { - sysEx = ex; - - org.omg.CORBA.portable.OutputStream ech = - handler.createExceptionReply(); - ObjectCreator.writeSystemException(ech, ex); - } - catch (Exception except) - { - except.printStackTrace(); - sysEx = - new UNKNOWN("Unknown", 2, - CompletionStatus.COMPLETED_MAYBE - ); - - org.omg.CORBA.portable.OutputStream ech = - handler.createExceptionReply(); - - 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; - } - ; - - // TODO log error: "Not a request message." - 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; - } - } - - private 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)); - } - catch (NumberFormatException ex) - { - throw new BAD_PARAM("Invalid " + NS_PORT + - "property, unable to parse '" + props.getProperty(NS_PORT) + - "'" - ); - } - - 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(); - } -}
\ No newline at end of file |
