KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > orb > Delegate


1 package org.jacorb.orb;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.*;
25
26 import org.apache.avalon.framework.logger.Logger;
27 import org.apache.avalon.framework.configuration.Configurable;
28 import org.apache.avalon.framework.configuration.DefaultConfiguration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30
31 import org.jacorb.ir.RepositoryID;
32 import org.jacorb.imr.ImRAccessImpl;
33 import org.jacorb.orb.giop.*;
34 import org.jacorb.orb.iiop.*;
35 import org.jacorb.orb.portableInterceptor.*;
36 import org.jacorb.orb.util.*;
37 import org.jacorb.poa.util.POAUtil;
38 import org.jacorb.util.Time;
39 import org.jacorb.util.ObjectUtil;
40 import org.jacorb.config.Configuration;
41
42 import org.omg.CORBA.*;
43 import org.omg.CORBA.Object JavaDoc;
44 import org.omg.CORBA.portable.*;
45 import org.omg.GIOP.LocateStatusType_1_2;
46 import org.omg.IOP.ServiceContext JavaDoc;
47 import org.omg.Messaging.*;
48 import org.omg.PortableInterceptor.SUCCESSFUL JavaDoc;
49 import org.omg.PortableServer.POAPackage.*;
50 import org.omg.TimeBase.UtcT;
51 import org.omg.PortableServer.ServantLocatorPackage.CookieHolder JavaDoc;
52 import org.omg.PortableServer.Servant JavaDoc;
53
54 /**
55  * JacORB implementation of CORBA object reference
56  *
57  * @author Gerald Brose
58  * @version $Id: Delegate.java,v 1.111 2005/04/22 13:19:48 andre.spiegel Exp $
59  *
60  */

61
62 public final class Delegate
63     extends org.omg.CORBA_2_3.portable.Delegate JavaDoc
64     implements Configurable
65 {
66     // WARNING: DO NOT USE _pior DIRECTLY, BECAUSE THAT IS NOT MT
67
// SAFE. USE getParsedIOR() INSTEAD, AND KEEP A METHOD-LOCAL COPY
68
// OF THE REFERENCE.
69
private ParsedIOR _pior = null;
70     private org.omg.IOP.IOR JavaDoc ior = null;
71     private ClientConnection connection = null;
72     private String JavaDoc objectReference = null;
73
74     /* save original ior for fallback */
75     private ParsedIOR piorOriginal = null;
76
77     /* save iors to detect and prevent locate forward loop */
78     private ParsedIOR piorLastFailed = null;
79
80     /* flag to indicate if this is the delegate for the ImR */
81     private boolean isImR = false;
82
83     private boolean bound = false;
84     private org.jacorb.poa.POA poa;
85
86     private org.jacorb.orb.ORB orb = null;
87     private Logger logger = null;
88
89     /** set after the first attempt to determine whether
90         this reference is to a local object */

91     private boolean resolved_locality = false;
92
93     private Set pending_replies = new HashSet();
94     private Barrier pending_replies_sync = new Barrier();
95
96     private java.lang.Object JavaDoc bind_sync = new java.lang.Object JavaDoc();
97
98     private boolean locate_on_bind_performed = false;
99
100     private ClientConnectionManager conn_mg = null;
101
102     private Map policy_overrides;
103
104     private boolean doNotCheckExceptions = false; //Setting for Appligator
105

106     private CookieHolder JavaDoc cookie = null;
107
108     private String JavaDoc invokedOperation = null;
109
110     /** the configuration object for this delegate */
111     private org.apache.avalon.framework.configuration.Configuration configuration = null;
112
113     /** configuration properties */
114     private boolean useIMR;
115     private boolean locateOnBind;
116
117     /**
118      * A general note on the synchronization concept
119      *
120      * The main problem that has to be addressed by synchronization
121      * means is the case when an object reference is shared by
122      * threads, and LocationForwards (e.g. thrown by the ImR) or
123      * ForwardRequest (thrown by ClientInterceptors) involved. In
124      * these cases, the rebinding to another target can occur while
125      * there are still other requests active. Therefore, the act of
126      * rebinding must be synchronized, so every thread sees a
127      * consistent state.
128      *
129      * Synchronization is done via the bind_sync object. Please also
130      * have a look at the comment for opration bind().
131      */

132
133
134     /* constructors: */
135
136     private Delegate()
137     {
138     }
139
140     public Delegate ( org.jacorb.orb.ORB orb, ParsedIOR pior )
141     {
142         this.orb = orb;
143         _pior = pior;
144
145         checkIfImR( _pior.getTypeId() );
146         conn_mg = orb.getClientConnectionManager();
147     }
148
149     public Delegate( org.jacorb.orb.ORB orb, String JavaDoc object_reference )
150     {
151         if ( object_reference.indexOf( "IOR:" ) != 0 )
152         {
153             throw new org.omg.CORBA.INV_OBJREF JavaDoc( "Not an IOR: " +
154                                                 object_reference );
155         }
156
157         this.orb = orb;
158         this.objectReference = object_reference;
159         conn_mg = orb.getClientConnectionManager();
160     }
161
162     public Delegate(org.jacorb.orb.ORB orb, org.omg.IOP.IOR JavaDoc ior)
163     {
164         this.orb = orb;
165         this.ior = ior;
166         conn_mg = orb.getClientConnectionManager();
167     }
168
169     /**
170      * special constructor for appligator
171      */

172     public Delegate( org.jacorb.orb.ORB orb,
173                      String JavaDoc object_reference,
174                      boolean _donotcheckexceptions )
175     {
176         this( orb, object_reference );
177         doNotCheckExceptions = _donotcheckexceptions;
178     }
179
180
181     public void configure(org.apache.avalon.framework.configuration.Configuration configuration)
182         throws org.apache.avalon.framework.configuration.ConfigurationException
183     {
184         this.configuration = configuration;
185         logger =
186             ((Configuration)configuration).getNamedLogger("jacorb.orb.delegate");
187         useIMR =
188             configuration.getAttribute("jacorb.use_imr","off").equals("on");
189         locateOnBind =
190             configuration.getAttribute("jacorb.locate_on_bind","off").equals("on");
191
192         if (objectReference != null)
193             _pior = new ParsedIOR( objectReference, orb, logger);
194         else if (ior!=null)
195             _pior = new ParsedIOR( ior, orb, logger);
196         else if (_pior == null )
197             throw new ConfigurationException("Neither objectReference nor IOR set!");
198         checkIfImR( _pior.getTypeId() );
199    }
200
201
202     public boolean doNotCheckExceptions()
203     {
204         return doNotCheckExceptions;
205     }
206
207     /**
208      * Method to determine if this delegate is the delegate for the ImR.
209      * This information is needed when trying to determine if the ImR has
210      * gone down and come back up at a different addresss. All delegates
211      * except the delegate of the ImR itself will try to determine if the
212      * ImR has gone down and come back up at a new address if a connection
213      * to the ImR can't be made. If the delegate of the ImR itself has
214      * failed to connect then the ImR hasn't come back up!
215      */

216     private void checkIfImR( String JavaDoc typeId )
217     {
218         if ( typeId.equals( "IDL:org/jacorb/imr/ImplementationRepository:1.0" ) )
219         {
220             isImR = true;
221         }
222     }
223
224
225     public int _get_TCKind()
226     {
227         return org.omg.CORBA.TCKind._tk_objref;
228     }
229
230
231     /**
232      * This bind is a combination of the old _init() and bind()
233      * operations. It first inits this delegate with the information
234      * supplied by the (parsed) IOR. Then it requests a new
235      * ClientConnection from the ConnectionsManager. This will *NOT*
236      * open up a TCP connection, but the connection is needed for the
237      * GIOP message ids. The actual TCP connection is automatically
238      * opened up by the ClientConnection, when the first request is
239      * sent. This has the advantage, that COMM_FAILURES can only occur
240      * inside of _invoke, where they get handled properly (falling
241      * back, etc.)
242      */

243     private void bind()
244     {
245         // ? why was that int synchronized block?
246
if (bound)
247             return ;
248
249         synchronized (bind_sync)
250         {
251             if ( bound )
252                 return ;
253
254             org.omg.ETF.Profile p = _pior.getEffectiveProfile();
255             if (p == null)
256                 throw new org.omg.CORBA.COMM_FAILURE JavaDoc ("no effective profile");
257
258             connection = conn_mg.getConnection(p);
259             bound = true;
260
261             /* The delegate could query the server for the object
262              * location using a GIOP locate request to make sure the
263              * first call will get through without redirections
264              * (provided the server's answer is definite):
265              */

266             if (( ! locate_on_bind_performed ) &&
267                     locateOnBind )
268             {
269                 //only locate once, because bind is called from the
270
//switch statement below again.
271
locate_on_bind_performed = true;
272
273                 try
274                 {
275                     LocateRequestOutputStream lros =
276                         new LocateRequestOutputStream
277                             ( _pior.get_object_key(),
278                               connection.getId(),
279                               ( int ) _pior.getEffectiveProfile().version().minor );
280
281                     LocateReplyReceiver receiver =
282                         new LocateReplyReceiver(orb);
283
284                     connection.sendRequest( lros,
285                                             receiver,
286                                             lros.getRequestId(),
287                                             true ); //response expected
288

289                     LocateReplyInputStream lris = receiver.getReply();
290
291                     switch ( lris.rep_hdr.locate_status.value() )
292                     {
293
294                     case LocateStatusType_1_2._UNKNOWN_OBJECT :
295                         {
296                             throw new org.omg.CORBA.UNKNOWN JavaDoc( "Could not bind to object, server does not know it!" );
297                         }
298
299                     case LocateStatusType_1_2._OBJECT_HERE :
300                         {
301                             break;
302                         }
303
304                     case LocateStatusType_1_2._OBJECT_FORWARD :
305                         {
306                             //fall through
307
}
308
309                     case LocateStatusType_1_2._OBJECT_FORWARD_PERM :
310                         {
311                             //_OBJECT_FORWARD_PERM is actually more or
312
//less deprecated
313
rebind( orb.object_to_string( lris.read_Object() ) );
314                             break;
315                         }
316
317                     case LocateStatusType_1_2._LOC_SYSTEM_EXCEPTION :
318                         {
319                             throw SystemExceptionHelper.read( lris );
320
321                             //break;
322
}
323
324                     case LocateStatusType_1_2._LOC_NEEDS_ADDRESSING_MODE :
325                         {
326                             throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc( "Server responded to LocateRequest with a status of LOC_NEEDS_ADDRESSING_MODE, but this isn't yet implemented by JacORB" );
327
328                             //break;
329
}
330
331                     default :
332                         {
333                             throw new RuntimeException JavaDoc( "Unknown reply status for LOCATE_REQUEST: " + lris.rep_hdr.locate_status.value() );
334                         }
335
336                     }
337
338                 }
339                 catch ( org.omg.CORBA.SystemException JavaDoc se )
340                 {
341                     //rethrow
342
throw se;
343                 }
344                 catch ( Exception JavaDoc e )
345                 {
346                     if (logger.isWarnEnabled())
347                         logger.warn( e.getMessage() );
348                 }
349
350             }
351
352             //wake up threads waiting for the pior
353
bind_sync.notifyAll();
354         }
355     }
356
357     public void rebind(String JavaDoc object_reference)
358     {
359  // synchronized (bind_sync)
360
// {
361
if (object_reference.indexOf( "IOR:" ) == 0)
362             {
363                 rebind( new ParsedIOR( object_reference, orb, logger ) );
364             }
365             else
366             {
367                 throw new org.omg.CORBA.INV_OBJREF JavaDoc( "Not an IOR: " +
368                                                     object_reference );
369             }
370             // }
371
}
372
373     public void rebind( org.omg.CORBA.Object JavaDoc o )
374     {
375         rebind(orb.object_to_string(o));
376     }
377
378     public void rebind( ParsedIOR p )
379     {
380         synchronized ( bind_sync )
381         {
382             if ( p.equals( _pior ) )
383             {
384                 //already bound to target so just return
385
return ;
386             }
387
388             if ( piorLastFailed != null && piorLastFailed.equals( p ) )
389             {
390                 //we've already failed to bind to the ior
391
throw new org.omg.CORBA.TRANSIENT JavaDoc();
392             }
393
394             if ( piorOriginal == null )
395             {
396                 //keep original pior for fallback
397
piorOriginal = _pior;
398             }
399
400             _pior = p;
401
402             if ( connection != null )
403             {
404                 conn_mg.releaseConnection( connection );
405                 connection = null;
406             }
407
408             //to tell bind() that it has to take action
409
bound = false;
410
411             bind();
412         }
413     }
414
415     public org.omg.CORBA.Request JavaDoc create_request( org.omg.CORBA.Object JavaDoc self,
416             org.omg.CORBA.Context JavaDoc ctx,
417             java.lang.String JavaDoc operation ,
418             org.omg.CORBA.NVList JavaDoc args,
419             org.omg.CORBA.NamedValue JavaDoc result )
420     {
421         bind();
422
423         return new org.jacorb.orb.dii.Request( self,
424                                                orb,
425                                                connection,
426                                                getParsedIOR().get_object_key(),
427                                                operation,
428                                                args,
429                                                ctx,
430                                                result );
431     }
432
433     public org.omg.CORBA.Request JavaDoc create_request( org.omg.CORBA.Object JavaDoc self,
434             org.omg.CORBA.Context JavaDoc ctx,
435             String JavaDoc operation,
436             org.omg.CORBA.NVList JavaDoc arg_list,
437             org.omg.CORBA.NamedValue JavaDoc result,
438             org.omg.CORBA.ExceptionList JavaDoc exceptions,
439             org.omg.CORBA.ContextList JavaDoc contexts )
440     {
441         throw new org.omg.CORBA.NO_IMPLEMENT JavaDoc();
442     }
443
444     public synchronized org.omg.CORBA.Object JavaDoc duplicate( org.omg.CORBA.Object JavaDoc self )
445     {
446         return self;
447     }
448
449     public boolean equals(java.lang.Object JavaDoc obj)
450     {
451         return ( obj instanceof org.omg.CORBA.Object JavaDoc &&
452                  toString().equals( obj.toString() ) );
453     }
454
455     public boolean equals( org.omg.CORBA.Object JavaDoc self, java.lang.Object JavaDoc obj )
456     {
457         return equals( obj );
458     }
459
460     protected void finalize() throws Throwable JavaDoc
461     {
462         try
463         {
464             if ( connection != null )
465             {
466                 // Synchronization for inc/dec of clients is handled inside
467
// releaseConnection.
468
conn_mg.releaseConnection( connection );
469             }
470
471             // Call using string rather than this to prevent data race warning.
472
orb._release( getParsedIOR().getIORString() );
473
474             if ( logger.isDebugEnabled() )
475             {
476                 logger.debug("Delegate gc'ed!");
477             }
478         }
479         finally
480         {
481             super.finalize();
482         }
483     }
484
485     public org.omg.CORBA.DomainManager JavaDoc[] get_domain_managers
486     ( org.omg.CORBA.Object JavaDoc self )
487     {
488         return null;
489     }
490
491     /**
492      * The get_policy operation returns the policy object of the
493      * specified type, which applies to this object. It returns the
494      * effective Policy for the object reference. The effective Policy
495      * is the one that would be used if a request were made. This
496      * Policy is determined first by obtaining the effective override
497      * for the PolicyType as returned by get_client_policy. The
498      * effective override is then compared with the Policy as
499      * specified in the IOR.
500      * <p>
501      * The effective Policy is determined by reconciling the effective
502      * override and the IOR-specified Policy. If the two policies
503      * cannot be reconciled, the standard system exception INV_POLICY
504      * is raised with standard minor code 1. The absence of a Policy
505      * value in the IOR implies that any legal value may be used.
506      */

507
508     public org.omg.CORBA.Policy JavaDoc get_policy( org.omg.CORBA.Object JavaDoc self,
509                                             int policy_type )
510     {
511         Policy result = get_client_policy(policy_type);
512         if (result != null)
513         {
514             // TODO: "reconcile" with server-side policy
515
return result;
516         }
517         else
518         {
519             // if not locally overridden, ask the server
520
return get_policy( self,
521                                policy_type,
522                                request( self, "_get_policy", true ) );
523         }
524     }
525
526     /**
527      * Gets the effective overriding policy with the given type from
528      * the client-side, or null if this policy type is unset.
529      *
530      * (Implementation is incomplete, we don't check PolicyCurrent, i.e.
531      * at the thread-level)
532      */

533
534     public org.omg.CORBA.Policy JavaDoc get_client_policy(int policy_type)
535     {
536         Integer JavaDoc key = new Integer JavaDoc(policy_type);
537         Policy result = null;
538
539         if (policy_overrides != null)
540         {
541             result = (Policy)policy_overrides.get(key);
542         }
543         
544         if ( result == null )
545         {
546             // no override at the object level for this type, now
547
// check at the thread level, ie PolicyCurrent.
548
// TODO: currently not implemented
549

550             // check at the ORB-level
551
org.omg.CORBA.Policy JavaDoc[] orbPolicies =
552                 orb.getPolicyManager().get_policy_overrides(new int[]{policy_type});
553             if ( orbPolicies!= null && orbPolicies.length == 1)
554                 result = orbPolicies[0];
555         }
556         
557         return result;
558     }
559     
560
561     public org.omg.CORBA.Policy JavaDoc get_policy( org.omg.CORBA.Object JavaDoc self,
562                                             int policy_type,
563                                             org.omg.CORBA.portable.OutputStream JavaDoc os )
564     {
565         // ask object implementation
566
while ( true )
567         {
568             try
569             {
570                 os.write_Object( self );
571                 os.write_long( policy_type );
572                 org.omg.CORBA.portable.InputStream JavaDoc is = invoke( self, os );
573                 return org.omg.CORBA.PolicyHelper.narrow( is.read_Object() );
574             }
575             catch ( RemarshalException r )
576             {
577             }
578             catch ( ApplicationException _ax )
579             {
580                 String JavaDoc _id = _ax.getId();
581                 throw new RuntimeException JavaDoc( "Unexpected exception " + _id );
582             }
583
584         }
585     } // get_policy
586

587     public UtcT getRequestEndTime()
588     {
589         Policy p = get_client_policy (REQUEST_END_TIME_POLICY_TYPE.value);
590         if (p != null)
591             return ((org.omg.Messaging.RequestEndTimePolicy)p).end_time();
592         else
593             return null;
594     }
595
596     public UtcT getReplyEndTime()
597     {
598         Policy p = get_client_policy (REPLY_END_TIME_POLICY_TYPE.value);
599         if (p != null)
600             return ((org.omg.Messaging.ReplyEndTimePolicy)p).end_time();
601         else
602             return null;
603     }
604
605     public UtcT getRequestStartTime()
606     {
607         Policy p = get_client_policy (REQUEST_START_TIME_POLICY_TYPE.value);
608         if (p != null)
609             return ((org.omg.Messaging.RequestStartTimePolicy)p).start_time();
610         else
611             return null;
612     }
613
614     public UtcT getReplyStartTime()
615     {
616         Policy p = get_client_policy (REPLY_START_TIME_POLICY_TYPE.value);
617         if (p != null)
618             return ((org.omg.Messaging.ReplyStartTimePolicy)p).start_time();
619         else
620             return null;
621     }
622
623     public long getRelativeRoundtripTimeout()
624     {
625         Policy p = get_client_policy (RELATIVE_RT_TIMEOUT_POLICY_TYPE.value);
626         if (p != null)
627             return ((org.omg.Messaging.RelativeRoundtripTimeoutPolicy)p)
628                                                             .relative_expiry();
629         else
630             return -1;
631     }
632
633     public long getRelativeRequestTimeout()
634     {
635         Policy p = get_client_policy (RELATIVE_REQ_TIMEOUT_POLICY_TYPE.value);
636         if (p != null)
637             return ((org.omg.Messaging.RelativeRequestTimeoutPolicy)p)
638                                                             .relative_expiry();
639         else
640             return -1;
641     }
642
643     public short getSyncScope()
644     {
645         Policy p = get_client_policy (SYNC_SCOPE_POLICY_TYPE.value);
646         if (p != null)
647             return ((org.omg.Messaging.SyncScopePolicy)p).synchronization();
648         else
649             return ((org.omg.Messaging.SYNC_WITH_TRANSPORT.value));
650     }
651
652     /**
653      * @deprecated Deprecated by CORBA 2.3
654      */

655
656     public org.omg.CORBA.InterfaceDef JavaDoc get_interface( org.omg.CORBA.Object JavaDoc self )
657     {
658         return org.omg.CORBA.InterfaceDefHelper.narrow( get_interface_def( self ) ) ;
659     }
660
661     public org.omg.CORBA.Object JavaDoc get_interface_def (org.omg.CORBA.Object JavaDoc self)
662     {
663         // If local object call _interface directly
664

665         if (is_really_local (self))
666         {
667             org.omg.PortableServer.Servant JavaDoc servant;
668             org.omg.CORBA.portable.ServantObject JavaDoc so;
669
670             so = servant_preinvoke (self, "_interface", java.lang.Object JavaDoc.class);
671
672             // If preinvoke returns null POA spec, 11.3.4 states OBJ_ADAPTER
673
// should be thrown.
674
if (so == null )
675             {
676                 throw new OBJ_ADAPTER ( "Servant from pre_invoke was null" );
677             }
678             try
679             {
680                 servant = (org.omg.PortableServer.Servant JavaDoc) so.servant;
681                 orb.set_delegate (servant);
682                 return (servant._get_interface_def());
683             }
684             finally
685             {
686                 servant_postinvoke (self, so);
687             }
688         }
689         else
690         {
691             org.omg.CORBA.portable.OutputStream JavaDoc os;
692             org.omg.CORBA.portable.InputStream JavaDoc is;
693
694             while (true)
695             {
696                 try
697                 {
698                     os = request (self, "_interface", true);
699                     is = invoke (self, os);
700                     return is.read_Object();
701                 }
702                 catch (RemarshalException re)
703                 {
704                 }
705                 catch (Exception JavaDoc ex)
706                 {
707                     return null;
708                 }
709             }
710         }
711     }
712
713     ClientConnection getConnection()
714     {
715         synchronized ( bind_sync )
716         {
717             bind();
718             return connection;
719         }
720     }
721
722     public org.omg.IOP.IOR JavaDoc getIOR()
723     {
724         synchronized ( bind_sync )
725         {
726             if ( piorOriginal != null )
727             {
728                 return piorOriginal.getIOR();
729             }
730             else
731             {
732                 return getParsedIOR().getIOR();
733             }
734         }
735     }
736
737     public byte[] getObjectId()
738     {
739         synchronized ( bind_sync )
740         {
741             bind();
742
743             return POAUtil.extractOID( getParsedIOR().get_object_key() );
744         }
745     }
746
747     public byte[] getObjectKey()
748     {
749         synchronized ( bind_sync )
750         {
751             bind();
752
753             return getParsedIOR().get_object_key();
754         }
755     }
756
757     public ParsedIOR getParsedIOR()
758     {
759         synchronized ( bind_sync )
760         {
761             while ( _pior == null )
762             {
763                 try
764                 {
765                     bind_sync.wait();
766                 }
767                 catch ( InterruptedException JavaDoc ie )
768                 {
769                 }
770             }
771
772             return _pior;
773         }
774     }
775
776     public void resolvePOA (org.omg.CORBA.Object JavaDoc self)
777     {
778         if (! resolved_locality)
779         {
780             resolved_locality = true;
781             org.jacorb.poa.POA local_poa = orb.findPOA (this, self);
782
783             if (local_poa != null)
784             {
785                 poa = local_poa;
786             }
787         }
788     }
789
790     public org.jacorb.poa.POA getPOA()
791     {
792         return ( org.jacorb.poa.POA ) poa;
793     }
794
795     /**
796      */

797
798     public org.omg.CORBA.portable.ObjectImpl JavaDoc getReference( org.jacorb.poa.POA _poa )
799     {
800         if ( logger.isDebugEnabled() )
801         {
802             logger.debug("Delegate.getReference with POA <" +
803                           ( _poa != null ? _poa._getQualifiedName() : " empty" ) + ">" );
804         }
805
806         if ( _poa != null ) // && _poa._localStubsSupported())
807
poa = _poa;
808
809         org.omg.CORBA.portable.ObjectImpl JavaDoc o =
810             new org.jacorb.orb.Reference( typeId() );
811
812         o._set_delegate( this );
813
814         return o;
815     }
816
817     public int hash( org.omg.CORBA.Object JavaDoc self, int x )
818     {
819         return hashCode();
820     }
821
822     public int hashCode()
823     {
824         return getIDString().hashCode();
825     }
826
827     public int hashCode( org.omg.CORBA.Object JavaDoc self )
828     {
829         return hashCode();
830     }
831
832     /**
833      * Invokes an asynchronous operation using this object reference by
834      * sending the request marshalled in the OutputStream. The reply
835      * will be directed to the supplied ReplyHandler.
836      */

837     public void invoke( org.omg.CORBA.Object JavaDoc self,
838                         org.omg.CORBA.portable.OutputStream JavaDoc os,
839                         org.omg.Messaging.ReplyHandler replyHandler )
840       throws ApplicationException, RemarshalException
841     {
842         // discard result, it is always null
843
invoke_internal (self, os, replyHandler, true);
844     }
845
846     /**
847      * Invokes a synchronous operation using this object reference
848      * by sending the request marshalled in the OutputStream.
849      * @return the reply, if a reply is expected for this request.
850      * If no reply is expected, returns null.
851      */

852     public org.omg.CORBA.portable.InputStream JavaDoc invoke
853                                        ( org.omg.CORBA.Object JavaDoc self,
854                                          org.omg.CORBA.portable.OutputStream JavaDoc os )
855       throws ApplicationException, RemarshalException
856     {
857         return invoke_internal (self, os, null, false);
858     }
859
860     /**
861      * Internal implementation of both invoke() methods. Note that
862      * the boolean argument <code>async</code> is necessary to differentiate
863      * between synchronous and asynchronous calls, because the ReplyHandler
864      * can be null even for an asynchronous call.
865      */

866     private org.omg.CORBA.portable.InputStream JavaDoc invoke_internal
867                                ( org.omg.CORBA.Object JavaDoc self,
868                                  org.omg.CORBA.portable.OutputStream JavaDoc os,
869                                  org.omg.Messaging.ReplyHandler replyHandler,
870                                  boolean async )
871         throws ApplicationException, RemarshalException
872     {
873         RequestOutputStream ros = (RequestOutputStream)os;
874         ReplyReceiver receiver = null;
875
876         ClientInterceptorHandler interceptors =
877             new ClientInterceptorHandler( orb, ros, self, this,
878                                           piorOriginal, connection );
879
880         interceptors.handle_send_request();
881
882         try
883         {
884             if ( !ros.response_expected() ) // oneway op
885
{
886                 invoke_oneway (ros, interceptors);
887                 return null;
888             }
889             else // response expected, synchronous or asynchronous
890
{
891                 receiver = new ReplyReceiver(this,
892                                              ros.operation(),
893                                              ros.getReplyEndTime(),
894                                              interceptors,
895                                              replyHandler );
896
897                 // Store the receiver in pending_replies, so in the
898
// case of a LocationForward a RemarshalException can
899
// be thrown to *all* waiting threads.
900

901                 synchronized ( pending_replies )
902                 {
903                     pending_replies.add ( receiver );
904                 }
905
906                 synchronized ( bind_sync )
907                 {
908                     if ( ros.getConnection() == connection )
909                     {
910                         //RequestOutputStream has been created for
911
//exactly this connection
912
connection.sendRequest( ros,
913                                                 receiver,
914                                                 ros.requestId(),
915                                                 true ); // response expected
916
}
917                     else
918                     {
919                         if (logger.isDebugEnabled())
920                             logger.debug("invoke: RemarshalException");
921
922                         // RequestOutputStream has been created for
923
// another connection, so try again
924
throw new RemarshalException();
925                     }
926                 }
927             }
928         }
929         catch ( org.omg.CORBA.SystemException JavaDoc cfe )
930         {
931             if (logger.isDebugEnabled())
932                 logger.debug("invoke: SystemException");
933
934             if( !async )
935             {
936                // Remove ReplyReceiver to break up reference cycle
937
// Otherwise gc will not detect this Delegate and
938
// will never finalize it.
939
synchronized (pending_replies)
940                {
941                    pending_replies.remove (receiver);
942                }
943             }
944
945             interceptors.handle_receive_exception ( cfe );
946
947             if ( cfe instanceof org.omg.CORBA.TRANSIENT JavaDoc )
948             {
949                 // The exception is a TRANSIENT, so try rebinding.
950
if ( try_rebind() )
951                 {
952                     throw new RemarshalException();
953                 }
954             }
955
956             throw cfe;
957         }
958
959         if ( !async && receiver != null )
960         {
961             // Synchronous invocation, response expected.
962
// This call blocks until the reply arrives.
963
org.omg.CORBA.portable.InputStream JavaDoc is = receiver.getReply();
964
965             return is;
966         }
967         else
968         {
969             return null;
970         }
971     }
972
973     private void invoke_oneway (RequestOutputStream ros,
974                                 ClientInterceptorHandler interceptors)
975         throws RemarshalException, ApplicationException
976     {
977         switch (ros.syncScope())
978         {
979             case SYNC_NONE.value:
980                 passToTransport (ros);
981                 interceptors.handle_receive_other (SUCCESSFUL.value);
982                 break;
983
984             case SYNC_WITH_TRANSPORT.value:
985                 connection.sendRequest (ros, false);
986                 interceptors.handle_receive_other (SUCCESSFUL.value);
987                 break;
988
989             case SYNC_WITH_SERVER.value:
990             case SYNC_WITH_TARGET.value:
991                 ReplyReceiver rcv = new ReplyReceiver (this,
992                                                        ros.operation(),
993                                                        ros.getReplyEndTime(),
994                                                        interceptors,
995                                                        null);
996                 connection.sendRequest (ros, rcv, ros.requestId(), true);
997                 ReplyInputStream in = rcv.getReply();
998                 interceptors.handle_receive_reply (in);
999                 break;
1000
1001            default:
1002                throw new org.omg.CORBA.MARSHAL JavaDoc
1003                    ("Illegal SYNC_SCOPE: " + ros.syncScope(),
1004                     0, CompletionStatus.COMPLETED_MAYBE);
1005        }
1006    }
1007
1008    private void passToTransport (final RequestOutputStream ros)
1009    {
1010        new Thread JavaDoc (new Runnable JavaDoc()
1011        {
1012            public void run()
1013            {
1014                connection.sendRequest (ros, false);
1015            }
1016        }).start();
1017    }
1018
1019    private boolean try_rebind()
1020    {
1021        synchronized ( bind_sync )
1022        {
1023            if( logger.isDebugEnabled())
1024            {
1025                logger.debug("Delegate.try_rebind" );
1026            }
1027
1028            if ( piorOriginal != null )
1029            {
1030                if( logger.isDebugEnabled())
1031                {
1032                    logger.debug("Delegate: falling back to original IOR");
1033                }
1034
1035                //keep last failed ior to detect forwarding loops
1036
piorLastFailed = getParsedIOR();
1037
1038                //rebind to the original ior
1039
rebind( piorOriginal );
1040
1041                //clean up and start fresh
1042
piorOriginal = null;
1043                piorLastFailed = null; // supplied byte Kevin Heifner, OCI
1044

1045                return true;
1046            }
1047            else if ( useIMR && ! isImR )
1048            {
1049                Integer JavaDoc orbTypeId = getParsedIOR().getORBTypeId();
1050
1051                // only lookup ImR if IOR is generated by JacORB
1052
if ( orbTypeId == null ||
1053                     orbTypeId.intValue() != ORBConstants.JACORB_ORB_ID )
1054                {
1055                    if( logger.isDebugEnabled())
1056                    {
1057                        logger.debug("Delegate: foreign IOR detected" );
1058                    }
1059                    return false;
1060                }
1061
1062                if( logger.isDebugEnabled())
1063                {
1064                    logger.debug("Delegate: JacORB IOR detected" );
1065                }
1066
1067                byte[] object_key = getParsedIOR().get_object_key();
1068
1069                // No backup IOR so it may be that the ImR is down
1070
// Attempt to resolve the ImR again to see if it has
1071
// come back up at a different address
1072

1073                if( logger.isDebugEnabled())
1074                {
1075                    logger.debug("Delegate: attempting to contact ImR" );
1076                }
1077
1078                ImRAccess imr = null;
1079
1080                try
1081                {
1082                    imr = ImRAccessImpl.connect(orb);
1083                }
1084                catch ( Exception JavaDoc e )
1085                {
1086                    if( logger.isDebugEnabled())
1087                    {
1088                        logger.debug("Delegate: failed to contact ImR" );
1089                    }
1090                    return false;
1091                }
1092
1093                //create a corbaloc URL to use to contact the server
1094
StringBuffer JavaDoc corbaloc = new StringBuffer JavaDoc( "corbaloc:iiop:" );
1095
1096                corbaloc.append( imr.getImRHost() );
1097                corbaloc.append( ":" );
1098                corbaloc.append( imr.getImRPort() );
1099                corbaloc.append( "/" );
1100                corbaloc.append( CorbaLoc.parseKey( object_key ) );
1101
1102                //rebind to the new IOR
1103
rebind( new ParsedIOR( corbaloc.toString(), orb, logger));
1104
1105                //clean up and start fresh
1106
piorOriginal = null;
1107                piorLastFailed = null; //***
1108

1109                return true;
1110            }
1111            else
1112            {
1113                return false;
1114            }
1115        }
1116    }
1117
1118    public void invokeInterceptors( ClientRequestInfoImpl info, short op )
1119        throws RemarshalException
1120    {
1121        ClientInterceptorIterator intercept_iter =
1122            orb.getInterceptorManager().getClientIterator();
1123
1124        try
1125        {
1126            intercept_iter.iterate( info, op );
1127        }
1128        catch ( org.omg.PortableInterceptor.ForwardRequest JavaDoc fwd )
1129        {
1130            rebind( orb.object_to_string( fwd.forward ) );
1131            throw new RemarshalException();
1132        }
1133        catch ( org.omg.CORBA.UserException JavaDoc ue )
1134        {
1135            if (logger.isErrorEnabled())
1136                logger.error( ue.getMessage() );
1137        }
1138    }
1139
1140    /**
1141     * Determines whether the object denoted by self
1142     * has type logical_type_id or a subtype of it
1143     */

1144
1145    public boolean is_a( org.omg.CORBA.Object JavaDoc self, String JavaDoc logical_type_id )
1146    {
1147        /* First, try to find out without a remote invocation. */
1148
1149        /* check most derived type as defined in the IOR first
1150         * (this type might otherwise not be found if the helper
1151         * is consulted and the reference was not narrowed to
1152         * the most derived type. In this case, the ids returned by
1153         * the helper won't contain the most derived type
1154         */

1155
1156        ParsedIOR pior = getParsedIOR();
1157
1158        if ( pior.getTypeId().equals( logical_type_id ) )
1159            return true;
1160
1161        /* The Ids in ObjectImpl will at least contain the type id
1162             found in the object reference itself.
1163        */

1164        String JavaDoc[] ids = ( ( org.omg.CORBA.portable.ObjectImpl JavaDoc ) self )._ids();
1165
1166        /* the last id will be CORBA.Object, and we know that already... */
1167        for ( int i = 0; i < ids.length - 1; i++ )
1168        {
1169            if ( ids[ i ].equals( logical_type_id ) )
1170                return true;
1171        }
1172
1173        /* ok, we could not affirm by simply looking at the locally available
1174           type ids, so ask the object itself */

1175
1176        // If local object call _is_a directly
1177
if (is_really_local (self))
1178        {
1179            org.omg.PortableServer.Servant JavaDoc servant;
1180            org.omg.CORBA.portable.ServantObject JavaDoc so;
1181
1182            so = servant_preinvoke (self, "_is_a", java.lang.Object JavaDoc.class);
1183
1184            // If preinvoke returns null POA spec, 11.3.4 states OBJ_ADAPTER
1185
// should be thrown.
1186
if (so == null )
1187            {
1188                throw new OBJ_ADAPTER( "Servant from pre_invoke was null" );
1189            }
1190            try
1191            {
1192                servant = (org.omg.PortableServer.Servant JavaDoc)so.servant;
1193                orb.set_delegate(servant);
1194                return servant._is_a(logical_type_id);
1195            }
1196            finally
1197            {
1198                servant_postinvoke(self, so);
1199            }
1200        }
1201        else
1202        {
1203            // Try to avoid remote call - is it a derived type?
1204
try
1205            {
1206                // Retrieve the local stub for the object in question. Then call the _ids method
1207
// and see if any match the logical_type_id otherwise fall back to remote.
1208

1209                String JavaDoc classname = RepositoryID.className( ids[0], "_Stub", null );
1210                
1211                int lastDot = classname.lastIndexOf( '.' );
1212                StringBuffer JavaDoc scn = new StringBuffer JavaDoc( classname.substring( 0, lastDot + 1) );
1213                scn.append( '_' );
1214                scn.append( classname.substring( lastDot + 1 ) );
1215
1216                // This will only work if there is a correspondence between the Java class
1217
// name and the Repository ID. If prefixes have been using then this mapping
1218
// may have been lost.
1219

1220                // First, search with stub name
1221
// if not found, try with the 'org.omg.stub' prefix to support package
1222
// with javax prefix
1223
Class JavaDoc stub=null;
1224                try {
1225                    stub = ObjectUtil.classForName( scn.toString());
1226                } catch (ClassNotFoundException JavaDoc e) {
1227                    stub = ObjectUtil.classForName("org.omg.stub."+scn.toString());
1228                }
1229                
1230                Method JavaDoc idm = stub.getMethod ( "_ids", (Class JavaDoc[]) null );
1231                String JavaDoc newids[] = (String JavaDoc[] )idm.invoke( stub.newInstance(), (java.lang.Object JavaDoc[]) null );
1232
1233                for ( int i = 0; i < newids.length ; i++ )
1234                {
1235                    if (newids[i].equals( logical_type_id ) )
1236                    {
1237                        return true;
1238                    }
1239                }
1240            }
1241            // If it fails fall back to a remote call.
1242
catch (Throwable JavaDoc e)
1243            {
1244                if (logger.isDebugEnabled())
1245                    logger.debug("trying is_a remotely");
1246            }
1247
1248            org.omg.CORBA.portable.OutputStream JavaDoc os;
1249            org.omg.CORBA.portable.InputStream JavaDoc is;
1250
1251            while (true)
1252            {
1253                try
1254                {
1255                    os = request(self, "_is_a", true);
1256                    os.write_string(logical_type_id);
1257                    is = invoke(self, os);
1258                    return is.read_boolean();
1259                }
1260                catch (RemarshalException re)
1261                {
1262                }
1263                catch (ApplicationException ax)
1264                {
1265                    throw new RuntimeException JavaDoc ("Unexpected exception " + ax.getId());
1266                }
1267            }
1268        }
1269    }
1270
1271    public boolean is_equivalent(org.omg.CORBA.Object JavaDoc self,
1272                                 org.omg.CORBA.Object JavaDoc obj)
1273    {
1274        boolean result = true;
1275
1276        if (self != obj)
1277        {
1278            ParsedIOR pior1 = new ParsedIOR( obj.toString(), orb, logger );
1279            ParsedIOR pior2 = new ParsedIOR( self.toString(), orb, logger );
1280            result = pior2.getIDString().equals( pior1.getIDString() );
1281        }
1282
1283        return result;
1284    }
1285
1286    public String JavaDoc getIDString()
1287    {
1288        return getParsedIOR().getIDString();
1289    }
1290
1291    /**
1292     * @return true if this object lives on a local POA and
1293     * interceptors are not installed. When interceptors are
1294     * installed this returns false so that stubs do not call
1295     * direct to implementation, avoiding installed interceptors.
1296     */

1297
1298    public boolean is_local(org.omg.CORBA.Object JavaDoc self)
1299    {
1300        if (orb.hasRequestInterceptors())
1301        {
1302            return false;
1303        }
1304        return is_really_local(self);
1305    }
1306
1307    /**
1308     * @return true if this object lives on a local POA
1309     */

1310
1311    private boolean is_really_local(org.omg.CORBA.Object JavaDoc self)
1312    {
1313        if (poa == null)
1314        {
1315            resolvePOA(self);
1316        }
1317
1318        return poa != null;
1319    }
1320
1321    public boolean is_nil()
1322    {
1323        ParsedIOR pior = getParsedIOR();
1324
1325        return ( pior.getIOR().type_id.equals( "" ) &&
1326                 pior.getIOR().profiles.length == 0 );
1327    }
1328
1329    public boolean non_existent (org.omg.CORBA.Object JavaDoc self)
1330    {
1331        // If local object call _non_existent directly
1332

1333        if (is_really_local(self))
1334        {
1335            org.omg.PortableServer.Servant JavaDoc servant;
1336            org.omg.CORBA.portable.ServantObject JavaDoc so;
1337
1338            so = servant_preinvoke(self, "_non_existent", java.lang.Object JavaDoc.class);
1339
1340            try
1341            {
1342                servant = (org.omg.PortableServer.Servant JavaDoc)so.servant;
1343                orb.set_delegate(servant);
1344                return servant._non_existent();
1345            }
1346            finally
1347            {
1348                servant_postinvoke(self, so);
1349            }
1350        }
1351        else
1352        {
1353            org.omg.CORBA.portable.OutputStream JavaDoc os;
1354            org.omg.CORBA.portable.InputStream JavaDoc is;
1355
1356            while (true)
1357            {
1358                try
1359                {
1360                    os = request(self, "_non_existent", true);
1361                    is = invoke(self, os);
1362                    return is.read_boolean();
1363                }
1364                catch (RemarshalException re)
1365                {
1366                }
1367                catch (ApplicationException e)
1368                {
1369                    throw new RuntimeException JavaDoc( "Unexpected exception " + e.getId() );
1370                }
1371            }
1372        }
1373    }
1374
1375    public org.omg.CORBA.ORB JavaDoc orb( org.omg.CORBA.Object JavaDoc self )
1376    {
1377        return orb;
1378    }
1379
1380    public synchronized void release( org.omg.CORBA.Object JavaDoc self )
1381    {
1382    }
1383
1384    /**
1385     * releases the InputStream
1386     */

1387    public void releaseReply( org.omg.CORBA.Object JavaDoc self,
1388                              org.omg.CORBA.portable.InputStream JavaDoc is )
1389    {
1390        if ( is != null )
1391        {
1392            try
1393            {
1394                is.close();
1395            }
1396            catch ( java.io.IOException JavaDoc io )
1397            {
1398            }
1399        }
1400        Time.waitFor (getReplyStartTime());
1401    }
1402
1403    public synchronized org.omg.CORBA.Request JavaDoc request( org.omg.CORBA.Object JavaDoc self,
1404                                                       String JavaDoc operation )
1405    {
1406        synchronized ( bind_sync )
1407        {
1408            bind();
1409            return new org.jacorb.orb.dii.Request( self,
1410                                                   orb,
1411                                                   connection,
1412                                                   getParsedIOR().get_object_key(),
1413                                                   operation );
1414        }
1415
1416    }
1417
1418    /**
1419     */

1420
1421    public synchronized org.omg.CORBA.portable.OutputStream JavaDoc request
1422                                                 ( org.omg.CORBA.Object JavaDoc self,
1423                                                   String JavaDoc operation,
1424                                                   boolean responseExpected )
1425    {
1426        // Compute the deadlines for this request based on any absolute or
1427
// relative timing policies that have been specified. Compute this
1428
// now, because it is the earliest possible time, and therefore any
1429
// relative timeouts will cover the entire invocation.
1430

1431        UtcT requestEndTime = getRequestEndTime();
1432        long requestTimeout = getRelativeRequestTimeout();
1433
1434        if ((requestTimeout != 0) || (requestEndTime != null)) {
1435            requestEndTime = Time.earliest(Time.corbaFuture (requestTimeout),
1436                                           requestEndTime);
1437            if (Time.hasPassed(requestEndTime))
1438                throw new TIMEOUT("Request End Time exceeded prior to invocation",
1439                                  0, CompletionStatus.COMPLETED_NO);
1440        }
1441
1442        UtcT replyEndTime = getReplyEndTime();
1443        long roundtripTimeout = getRelativeRoundtripTimeout();
1444
1445        if ((roundtripTimeout != 0) || (replyEndTime != null)) {
1446            replyEndTime = Time.earliest(Time.corbaFuture (roundtripTimeout),
1447                                         replyEndTime);
1448            if (Time.hasPassed(replyEndTime))
1449                throw new TIMEOUT("Reply End Time exceeded prior to invocation",
1450                                  0, CompletionStatus.COMPLETED_NO);
1451        }
1452
1453        synchronized ( bind_sync )
1454        {
1455            bind();
1456
1457            ParsedIOR p = getParsedIOR();
1458
1459            RequestOutputStream ros =
1460                new RequestOutputStream( connection,
1461                                         connection.getId(),
1462                                         operation,
1463                                         responseExpected,
1464                                         getSyncScope(),
1465                                         getRequestStartTime(),
1466                                         requestEndTime,
1467                                         replyEndTime,
1468                                         p.get_object_key(),
1469                                         ( int ) p.getEffectiveProfile().version().minor );
1470
1471            // CodeSets are only negotiated once per connection,
1472
// not for each individual request
1473
// (CORBA 3.0, 13.10.2.6, second paragraph).
1474
if (!connection.isTCSNegotiated())
1475            {
1476                connection.setCodeSet(p);
1477            }
1478
1479            //Setting the codesets not until here results in the
1480
//header being writtend using the default codesets. On the
1481
//other hand, the server side must have already read the
1482
//header to discover the codeset service context.
1483
ros.setCodeSet( connection.getTCS(), connection.getTCSW() );
1484
1485            return ros;
1486        }
1487
1488    }
1489
1490    /**
1491     * Overrides servant_postinvoke() in org.omg.CORBA.portable.Delegate<BR>
1492     * called from generated stubs after a local operation
1493     */

1494
1495
1496    public void servant_postinvoke( org.omg.CORBA.Object JavaDoc self, ServantObject servant )
1497    {
1498        if (poa != null)
1499        {
1500            if ( poa.isUseServantManager() )
1501            {
1502               if (! poa.isRetain() &&
1503                   cookie != null &&
1504                   invokedOperation != null )
1505               {
1506                  // ServantManager is a ServantLocator:
1507
// call postinvoke
1508
try
1509                  {
1510                     byte [] oid =
1511                         POAUtil.extractOID( getParsedIOR().get_object_key() );
1512                     org.omg.PortableServer.ServantLocator JavaDoc sl =
1513                         ( org.omg.PortableServer.ServantLocator JavaDoc ) poa.get_servant_manager();
1514
1515                     sl.postinvoke( oid, poa, invokedOperation, cookie.value, (Servant JavaDoc)servant.servant );
1516
1517                     // delete stored values
1518
cookie = null;
1519                     invokedOperation = null;
1520                  }
1521                  catch ( Throwable JavaDoc e )
1522                  {
1523                      if (logger.isWarnEnabled())
1524                          logger.warn( e.getMessage() );
1525                  }
1526               }
1527            }
1528           poa.removeLocalRequest();
1529        }
1530        orb.getPOACurrent()._removeContext( Thread.currentThread() );
1531    }
1532
1533    /**
1534     * Overrides servant_preinvoke() in org.omg.CORBA.portable.Delegate<BR>
1535     * called from generated stubs before a local operation
1536     */

1537
1538    public ServantObject servant_preinvoke( org.omg.CORBA.Object JavaDoc self,
1539                                            String JavaDoc operation,
1540                                            Class JavaDoc expectedType )
1541    {
1542        if (poa == null)
1543        {
1544            resolvePOA(self);
1545        }
1546
1547        if (poa != null)
1548        {
1549            // remember that a local request is outstanding. On
1550
// any exit through an exception, this must be cleared again,
1551
// otherwise the POA will hangon destruction (bug #400).
1552
poa.addLocalRequest();
1553
1554            ServantObject so = new ServantObject();
1555
1556            try
1557            {
1558                if ( ( poa.isRetain() && !poa.isUseServantManager() ) ||
1559                     poa.useDefaultServant() )
1560                {
1561                    // no ServantManagers, but AOM use
1562
try
1563                    {
1564                        so.servant = poa.reference_to_servant( self );
1565                    }
1566                    catch( WrongAdapter e )
1567                    {
1568                        // exit on an error condition, but need to clean up first (added to fix bug #400)
1569
poa.removeLocalRequest();
1570                        throw new OBJ_ADAPTER( "WrongAdapter caught when converting servant to reference. " + e );
1571                    }
1572                    catch( WrongPolicy e )
1573                    {
1574                        // exit on an error condition, but need to clean up first (added to fix bug #400)
1575
poa.removeLocalRequest();
1576                        throw new OBJ_ADAPTER("WrongPolicy caught" + e );
1577                    }
1578                    catch( ObjectNotActive e )
1579                    {
1580                        // exit on an error condition, but need to clean up first (added to fix bug #400)
1581
poa.removeLocalRequest();
1582                        throw new org.omg.CORBA.OBJECT_NOT_EXIST JavaDoc();
1583                    }
1584                }
1585                else if ( poa.isUseServantManager() )
1586                {
1587                    byte [] oid =
1588                    POAUtil.extractOID( getParsedIOR().get_object_key() );
1589                    org.omg.PortableServer.ServantManager JavaDoc sm =
1590                        poa.get_servant_manager();
1591
1592                    if ( poa.isRetain() )
1593                    {
1594                        // ServantManager is a ServantActivator:
1595
// see if the servant is already activated
1596
try
1597                        {
1598                            so.servant = poa.id_to_servant( oid );
1599                        }
1600                        catch( ObjectNotActive ona )
1601                        {
1602                            // okay, we need to activate it
1603
org.omg.PortableServer.ServantActivator JavaDoc sa =
1604                                ( org.omg.PortableServer.ServantActivator JavaDoc ) sm ;
1605                            org.omg.PortableServer.ServantActivatorHelper.narrow( sm );
1606                            so.servant = sa.incarnate( oid, poa );
1607                            orb.set_delegate(so.servant);
1608                        }
1609                    }
1610                    else
1611                    {
1612                        // ServantManager is a ServantLocator:
1613
// locate a servant
1614

1615                        org.omg.PortableServer.ServantLocator JavaDoc sl =
1616                            ( org.omg.PortableServer.ServantLocator JavaDoc ) sm;
1617
1618                        // store this for postinvoke
1619

1620                        cookie =
1621                           new org.omg.PortableServer.ServantLocatorPackage.CookieHolder JavaDoc();
1622
1623                        invokedOperation = operation;
1624
1625                        so.servant =
1626                            sl.preinvoke( oid, poa, operation, cookie );
1627                    }
1628                }
1629                else
1630                {
1631                    throw new INTERNAL("Internal error: we should not have gotten to this piece of code!");
1632                }
1633            }
1634            catch( WrongPolicy e )
1635            {
1636                // exit on an error condition, but need to clean up first (added to fix bug #400)
1637
poa.removeLocalRequest();
1638                throw new OBJ_ADAPTER( "WrongPolicy caught" + e );
1639            }
1640            catch( org.omg.PortableServer.ForwardRequest JavaDoc e )
1641            {
1642                if( logger.isDebugEnabled() )
1643                {
1644                    logger.debug("Caught forwardrequest to " + e.forward_reference + " from " + self );
1645                }
1646                return servant_preinvoke(e.forward_reference, operation, expectedType);
1647            }
1648
1649            if ( !expectedType.isInstance( so.servant ) )
1650            {
1651                if( logger.isWarnEnabled() )
1652                {
1653                    logger.warn("Expected " + expectedType +
1654                                " got " + so.servant.getClass() );
1655                }
1656
1657                poa.removeLocalRequest();
1658                return null;
1659            }
1660            else
1661            {
1662                orb.getPOACurrent()._addContext(
1663                    Thread.currentThread(),
1664                    new org.jacorb.poa.LocalInvocationContext(
1665                        orb,
1666                        poa,
1667                        getObjectId(),
1668                        ( org.omg.PortableServer.Servant JavaDoc ) so.servant
1669                                                             )
1670                                               );
1671            }
1672            return so;
1673        }
1674        if (logger.isWarnEnabled())
1675        {
1676            logger.warn("No POA! servant_preinvoke returns null");
1677        }
1678        return null;
1679    }
1680
1681    public String JavaDoc toString()
1682    {
1683        synchronized ( bind_sync )
1684        {
1685            if ( piorOriginal != null )
1686                return piorOriginal.getIORString();
1687            else
1688                return getParsedIOR().getIORString();
1689        }
1690
1691    }
1692
1693    public String JavaDoc toString( org.omg.CORBA.Object JavaDoc self )
1694    {
1695        return toString();
1696    }
1697
1698    public String JavaDoc typeId()
1699    {
1700        return getParsedIOR().getIOR().type_id;
1701    }
1702
1703    public org.omg.CORBA.Object JavaDoc set_policy_override( org.omg.CORBA.Object JavaDoc self,
1704                                                     org.omg.CORBA.Policy JavaDoc[] policies,
1705                                                     org.omg.CORBA.SetOverrideType JavaDoc set_add )
1706    {
1707        if (policy_overrides == null)
1708        {
1709            policy_overrides = new HashMap();
1710        }
1711        if ( set_add == org.omg.CORBA.SetOverrideType.SET_OVERRIDE )
1712        {
1713            policy_overrides.clear();
1714        }
1715
1716        for ( int i = 0; i < policies.length; i++ )
1717        {
1718            policy_overrides.put( new Integer JavaDoc( policies[ i ].policy_type() ), policies[ i ] );
1719        }
1720
1721        return self;
1722    }
1723
1724    public String JavaDoc get_codebase( org.omg.CORBA.Object JavaDoc self )
1725    {
1726        return getParsedIOR().getCodebaseComponent();
1727    }
1728
1729    public Set get_pending_replies()
1730    {
1731        return pending_replies;
1732    }
1733
1734    public void replyDone (ReplyPlaceholder placeholder)
1735    {
1736        synchronized (pending_replies)
1737        {
1738            pending_replies.remove (placeholder);
1739        }
1740    }
1741
1742    public void lockBarrier()
1743    {
1744        pending_replies_sync.lockBarrier();
1745    }
1746
1747    public void waitOnBarrier()
1748    {
1749        pending_replies_sync.waitOnBarrier();
1750    }
1751
1752    public void openBarrier()
1753    {
1754        pending_replies_sync.openBarrier();
1755    }
1756
1757    private static class Barrier
1758    {
1759        private boolean is_open = true;
1760
1761        public synchronized void waitOnBarrier()
1762        {
1763            while (! is_open)
1764            {
1765                try
1766                {
1767                    this.wait();
1768                }
1769                catch ( InterruptedException JavaDoc e )
1770                {
1771                    //ignore
1772
}
1773            }
1774        }
1775
1776        public synchronized void lockBarrier()
1777        {
1778            is_open = false;
1779        }
1780
1781        public synchronized void openBarrier()
1782        {
1783            is_open = true;
1784
1785            this.notifyAll();
1786        }
1787    }
1788}
1789
Popular Tags