1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795 |
- /* 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();
- }
- }
|