Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / gnu / CORBA / Poa / gnuServantObject.java
blob020897a45b44b8283e19b3fdb7dd5844e2da0abf
1 /* gnuServantObject.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.CORBA.Poa;
41 import gnu.CORBA.GIOP.ReplyHeader;
42 import gnu.CORBA.IorDelegate;
43 import gnu.CORBA.IorObject;
44 import gnu.CORBA.Interceptor.gnuServerRequestInfo;
45 import gnu.CORBA.typecodes.RecordTypeCode;
46 import gnu.CORBA.IOR;
47 import gnu.CORBA.IorProvider;
48 import gnu.CORBA.Minor;
49 import gnu.CORBA.ObjectCreator;
50 import gnu.CORBA.Unexpected;
51 import gnu.CORBA.ResponseHandlerImpl;
52 import gnu.CORBA.StreamHolder;
54 import org.omg.CORBA.Any;
55 import org.omg.CORBA.BAD_OPERATION;
56 import org.omg.CORBA.BAD_PARAM;
57 import org.omg.CORBA.CompletionStatus;
58 import org.omg.CORBA.OBJECT_NOT_EXIST;
59 import org.omg.CORBA.OBJ_ADAPTER;
60 import org.omg.CORBA.ORB;
61 import org.omg.CORBA.SystemException;
62 import org.omg.CORBA.TCKind;
63 import org.omg.CORBA.TRANSIENT;
64 import org.omg.CORBA.UserException;
65 import org.omg.CORBA.portable.InputStream;
66 import org.omg.CORBA.portable.InvokeHandler;
67 import org.omg.CORBA.portable.ObjectImpl;
68 import org.omg.CORBA.portable.OutputStream;
69 import org.omg.CORBA.portable.ResponseHandler;
70 import org.omg.PortableInterceptor.ForwardRequest;
71 import org.omg.PortableInterceptor.ServerRequestInterceptorOperations;
72 import org.omg.PortableServer.CurrentOperations;
73 import org.omg.PortableServer.DynamicImplementation;
74 import org.omg.PortableServer.ImplicitActivationPolicyValue;
75 import org.omg.PortableServer.POA;
76 import org.omg.PortableServer.POAManager;
77 import org.omg.PortableServer.POAManagerPackage.State;
78 import org.omg.PortableServer.Servant;
79 import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
80 import org.omg.PortableServer.ServantRetentionPolicyValue;
81 import org.omg.PortableServer.portable.Delegate;
83 import java.io.IOException;
85 import java.util.Arrays;
87 /**
88 * Represents a CORBA object, being locally served by the associated servant.
89 * The calls to the object are forwarded to the calls to the servant.
91 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
93 public class gnuServantObject extends ObjectImpl
94 implements org.omg.CORBA.Object,
95 InvokeHandler,
96 CurrentOperations,
97 IorProvider
99 /**
100 * The associated servant that must also implement the {@link InvokeHandler}
101 * interface. This value can be temporary null if the object was created using
102 * POA.create_reference or POA.create_reference_with_id, private to force
103 * always to use {@link setServant}.
105 private Servant servant;
108 * The Id of this object.
110 public final byte[] Id;
113 * The poa that takes care about this object.
115 public final gnuPOA poa;
118 * The POA manager, used to control the work of this object.
120 public final POAManager manager;
123 * The orb.
125 public final ORB_1_4 orb;
128 * The object repository ids, if they were specified separately. Normally, the
129 * ids are requested from the servant.
131 public final String[] repository_ids;
134 * Create an object with no connected servant. The servant must be set later.
136 * @param a_repository_ids an array of repository ids, can be null (then ids
137 * will be requested from the servant).
138 * @param an_id the object id.
139 * @param a_poa the POA.
141 public gnuServantObject(String[] a_repository_ids, byte[] an_id,
142 gnuPOA a_poa, ORB_1_4 an_orb
145 repository_ids = a_repository_ids;
146 Id = an_id;
147 manager = a_poa.the_POAManager();
148 poa = a_poa;
149 orb = an_orb;
153 * Get the IOR as it would be for this object.
155 public IOR getIor()
157 return orb.getLocalIor(this);
161 * Create a servant object, associated with the passed servant.
163 * @param a_servant a servant, serving this object.
164 * @param an_id an Object Id for this object.
166 * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler}.
168 public gnuServantObject(Servant a_servant, byte[] an_id, ORB_1_4 an_orb,
169 gnuPOA a_poa
172 Id = an_id;
173 setServant(a_servant);
174 poa = a_poa;
175 if (poa != null)
177 manager = poa.the_POAManager();
179 else
181 manager = null;
183 repository_ids = null;
184 orb = an_orb;
188 * Set a servant, if it has not been previously set.
190 * @param a_servant a servant to set, can be null to indicate the necessity
191 * for the subsequent activation.
193 * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler} or
194 * {@link DynamicImplementation} and also not null.
196 public void setServant(Servant a_servant)
198 if (a_servant != null &&
199 !(a_servant instanceof InvokeHandler) &&
200 !(a_servant instanceof DynamicImplementation)
203 throw new BAD_PARAM("Must be either InvokeHandler or " +
204 "DynamicImplementation, but is " + a_servant
207 servant = a_servant;
211 * Returns the associated servant.
213 public Servant getServant()
215 return servant;
219 * Return the associated invocation handler.
221 public InvokeHandler getHandler(String operation, CookieHolder cookie,
222 boolean forwarding_allowed
223 ) throws gnuForwardRequest
225 if (servant != null)
227 return servantToHandler(servant);
229 else
231 // Use servant locator to locate the servant.
232 if (poa.servant_locator != null)
236 servant =
237 poa.servant_locator.preinvoke(Id, poa, operation, cookie);
238 return servantToHandler(servant);
240 catch (org.omg.PortableServer.ForwardRequest forw_ex)
242 if (forwarding_allowed)
244 throw new gnuForwardRequest(forw_ex.forward_reference);
246 else
248 servant =
249 ForwardedServant.create(forw_ex.forward_reference);
250 return servantToHandler(servant);
254 else
255 // Use servant activator to locate the servant.
256 if (poa.applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) &&
257 poa.applies(ServantRetentionPolicyValue.RETAIN)
262 poa.activate_object_with_id(Id, servant, forwarding_allowed);
263 servant = poa.id_to_servant(Id);
264 return servantToHandler(servant);
266 catch (gnuForwardRequest forwarded)
268 throw forwarded;
270 catch (Exception ex)
272 BAD_OPERATION bad =
273 new BAD_OPERATION("Unable to activate", Minor.Activation,
274 CompletionStatus.COMPLETED_NO
276 bad.initCause(ex);
277 throw bad;
280 else if (poa.default_servant != null)
282 servant = poa.default_servant;
283 return servantToHandler(servant);
286 // No servant and no servant manager - throw exception.
287 else
289 throw new BAD_OPERATION("Unable to activate", Minor.Activation,
290 CompletionStatus.COMPLETED_NO
297 * Convert the servant to invocation handler.
299 public InvokeHandler servantToHandler(Servant a_servant)
301 if (a_servant instanceof InvokeHandler)
303 return (InvokeHandler) a_servant;
305 else if (a_servant instanceof DynamicImplementation)
307 return new DynamicImpHandler((DynamicImplementation) a_servant);
309 else
311 throw new BAD_OPERATION(a_servant +
312 " must be either InvokeHandler or " + "POA DynamicImplementation"
318 * Create a servant object, associated with the passed servant. Requests the
319 * object id from the servant. Depending on the policies of the servants POA,
320 * the calls are eithe not synchronized or synchronized on POA or ORB.
322 * @param a_servant a servant, serving this object.
323 * @param an_id an Object Id for this object.
325 public gnuServantObject(Servant a_servant, gnuPOA a_poa)
327 this(a_servant, a_servant._object_id(), (ORB_1_4) a_servant._orb(), a_poa);
331 * Delegates call to servant, passing the poa and Id.
333 public String[] _ids()
335 if (repository_ids == null)
337 return getServant()._all_interfaces(poa, Id);
339 else
341 return repository_ids;
346 * Gets a string representation.
348 public String toString()
350 StringBuffer b = new StringBuffer("Servant object (");
351 for (int i = 0; i < Id.length; i++)
353 b.append(Integer.toHexString(Id [ i ] & 0xFF));
354 b.append(' ');
356 b.append(')');
357 return b.toString();
361 * Always returns true.
363 public boolean _is_local()
365 return true;
369 * Check if this object could be named by the given repository id.
371 * @param idl_id the repository id to check.
373 * @return true if it is one of the possible repository ids of this object.
375 public boolean _is_a(String idl_id)
377 String[] maybe = _ids();
378 for (int i = 0; i < maybe.length; i++)
380 if (maybe [ i ].equals(idl_id))
382 return true;
385 return false;
389 * Get an ORB, associated with the servant of this object.
391 * @return
393 public ORB _orb()
395 return getServant()._orb();
399 * Handle the invocation (delegates to servant).
401 * @throws TRANSIENT minor 0x535503e9 if the POA is in discarding mode.
402 * @throws OBJ_ADAPTER minor 0x535503ea if the POA is inactivated.
403 * @throws OBJECT_NOT_EXISTS minor 0x535503ec if this object is inactivated.
405 * @specnote see {@link POAManagerOperations} for specnotes about the minor
406 * codes.
408 public OutputStream _invoke(String method, InputStream input,
409 ResponseHandler r_handler
410 ) throws SystemException
412 boolean intercept = false;
413 ServerRequestInterceptorOperations interceptor = null;
414 gnuServerRequestInfo info = null;
415 ResponseHandlerImpl i_handler = null;
419 if (orb.iServer != null &&
420 r_handler instanceof ResponseHandlerImpl
423 interceptor = orb.iServer;
425 i_handler = (ResponseHandlerImpl) r_handler;
427 info =
428 new gnuServerRequestInfo(this, i_handler.request_header,
429 i_handler.reply_header
431 intercept = true;
433 interceptor.receive_request_service_contexts(info);
438 CookieHolder cookie = null;
439 AOM.Obj self = poa.aom.get(Id);
441 if (poa.servant_locator != null)
443 // If the servant locator is in use, it is always responsible
444 // for providing the servant.
445 self.servant = servant = null;
446 cookie = new CookieHolder();
448 else if (self != null && self.isDeactiveted())
450 if (poa.applies(
451 ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION
452 ) &&
453 poa.servant_activator != null
456 // Reset the servant, forcing the subsequent activation.
457 servant = null;
459 else
461 throw new OBJECT_NOT_EXIST("Object deactivated",
462 0x535503ec, CompletionStatus.COMPLETED_NO
467 InvokeHandler handler = getHandler(method, cookie, true);
469 Delegate d = null;
473 d = servant._get_delegate();
474 orb.currents.put(Thread.currentThread(), this);
476 catch (Exception ex)
478 // In some cases exception is thrown if the delegate is not set.
480 if (d instanceof ServantDelegateImpl)
482 // If the delegate is already set, check maybe we can
483 // reuse the existing instance.
484 if (((ServantDelegateImpl) d).object != this)
486 servant._set_delegate(new ServantDelegateImpl(servant, poa, Id));
489 else
491 servant._set_delegate(new ServantDelegateImpl(servant, poa, Id));
496 switch (manager.get_state().value())
498 case State._ACTIVE :
500 OutputStream rt;
503 if (intercept)
505 interceptor.receive_request(info);
508 rt = handler._invoke(method, input, r_handler);
510 if (intercept)
512 // Handler is casted into i_handler.
513 if (i_handler.isExceptionReply())
515 info.m_reply_header.reply_status =
516 ReplyHeader.USER_EXCEPTION;
518 // Make Any, holding the user exception.
519 Any a = orb.create_any();
520 OutputStream buf = i_handler.getBuffer();
521 InputStream in = buf.create_input_stream();
522 String uex_idl = "unknown";
525 in.mark(Integer.MAX_VALUE);
526 uex_idl = in.read_string();
527 in.reset();
529 catch (IOException e)
531 throw new Unexpected(e);
536 UserException exception =
537 ObjectCreator.readUserException(uex_idl,
541 ObjectCreator.insertWithHelper(a,
542 exception
545 catch (Exception e)
547 // Failed due any reason, insert without
548 // helper.
549 a.insert_Streamable(new StreamHolder(
550 buf.create_input_stream()
554 RecordTypeCode r =
555 new RecordTypeCode(TCKind.tk_except);
556 r.setId(uex_idl);
557 r.setName(ObjectCreator.getDefaultName(
558 uex_idl
563 info.m_usr_exception = a;
564 interceptor.send_exception(info);
566 else
568 info.m_reply_header.reply_status =
569 ReplyHeader.NO_EXCEPTION;
570 interceptor.send_reply(info);
574 catch (SystemException sys_ex)
576 if (intercept)
578 info.m_reply_header.reply_status =
579 ReplyHeader.SYSTEM_EXCEPTION;
580 info.m_sys_exception = sys_ex;
581 interceptor.send_exception(info);
583 throw sys_ex;
586 return rt;
588 case State._HOLDING :
590 // The holding mode is implemented
591 // relying on the holding capabilites of the network
592 // support (if any).
593 // TODO FIXME in more recent CORBA applications, the
594 // client
595 // ORB can free the connection and wait for a server side
596 // notification about the completed request. Implement
597 // this
598 // as soon as JDK specification would allow bidirectional
599 // policy.
600 int sleep = 5;
601 int max = 500;
603 // Wait till the state will be switched into some other
604 // mode.
605 while (manager.get_state().value() == State._HOLDING)
609 Thread.sleep(sleep);
610 if (sleep < max)
612 sleep = max;
615 catch (InterruptedException ex)
620 // Handle another mode.
621 return _invoke(method, input, r_handler);
623 case State._DISCARDING :
624 throw new TRANSIENT("Discarding mode", 0x535503e9,
625 CompletionStatus.COMPLETED_NO
628 case State._INACTIVE :
629 throw new OBJ_ADAPTER("POA deactivated", 0x535503ea,
630 CompletionStatus.COMPLETED_NO
633 default :
634 throw new InternalError(); // No more states.
637 finally
639 if (poa.servant_locator != null)
641 poa.servant_locator.postinvoke(Id, poa, method,
642 cookie.value, servant
644 servant = null;
648 finally
650 orb.currents.remove(Thread.currentThread());
653 catch (ForwardRequest fex)
655 // May be thrown by interceptor.
656 if (intercept)
658 Forwarding:
659 while (true)
661 info.m_reply_header.reply_status =
662 ReplyHeader.LOCATION_FORWARD;
663 info.m_forward_reference = fex.forward;
666 interceptor.send_other(info);
667 break Forwarding;
669 catch (ForwardRequest fex2)
671 info.m_forward_reference = fex2.forward;
672 fex.forward = info.m_forward_reference;
676 throw new gnuForwardRequest(fex.forward);
678 catch (gnuForwardRequest fex)
680 // May be thrown during activation.
681 if (intercept)
683 Forwarding:
684 while (true)
686 info.m_reply_header.reply_status =
687 ReplyHeader.LOCATION_FORWARD;
688 info.m_forward_reference = fex.forward_reference;
691 interceptor.send_other(info);
692 break Forwarding;
694 catch (ForwardRequest fex2)
696 info.m_forward_reference = fex2.forward;
697 fex.forward_reference = (ObjectImpl) fex2.forward;
701 throw fex;
706 * Compare with another object for equality, comparing the object keys.
708 public boolean equals(java.lang.Object other)
710 if (other instanceof gnuServantObject)
712 gnuServantObject o = (gnuServantObject) other;
714 return Arrays.equals(o.Id, Id);
716 else
718 return false;
723 * Get the hash code, based on the object key.
725 public int hashCode()
727 long s = 0;
728 int v = 1;
729 for (int i = 0; i < Id.length; i++)
731 s += Id [ i ] * v;
732 if (s > Integer.MAX_VALUE)
734 s = s % Integer.MAX_VALUE;
735 v = 1;
737 v = v * 8;
739 return (int) (s % Integer.MAX_VALUE);
743 * Get the object id.
745 public byte[] get_object_id()
747 return Id;
751 * Get POA.
753 public POA get_POA()
755 return poa;
759 * Returns without action.
761 public void _release()
766 * Returns without action.
768 public void _releaseReply(InputStream stream)
773 * Checks if this object is equivalent to another instance. These objects are
774 * assumed equal if they are connected to the same orb and poa under the same
775 * Id, regardless of they delegates.
777 * @param another instance to check.
778 * @return
780 public boolean _is_equivalent(org.omg.CORBA.Object other)
782 if (other instanceof gnuServantObject)
784 gnuServantObject g = (gnuServantObject) other;
785 return orb == g.orb && poa == g.poa && Arrays.equals(Id, g.Id);
787 else if (other instanceof IorObject)
789 IorObject ir = ((IorObject) other);
792 IorDelegate ird = (IorDelegate) ir._get_delegate();
793 byte[] ior_id = poa.idFormIor(ird.getIor().key);
794 if (ior_id != null && Arrays.equals(ior_id, Id))
796 return true;
798 else
800 return false;
803 catch (Exception ex)
805 // Non - typical delegate or very specific subclass of
806 // IOR_constructed_object.
807 return super._is_equivalent(other);
810 return super._is_equivalent(other);