📄 orbfunctional.java
字号:
*/ 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 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 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(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -