~ubuntu-branches/ubuntu/raring/libjboss-remoting-java/raring

« back to all changes in this revision

Viewing changes to src/main/org/jboss/remoting/InvokerRegistry.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* JBoss, Home of Professional Open Source
 
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
 
4
* by the @authors tag. See the copyright.txt in the distribution for a
 
5
* full listing of individual contributors.
 
6
*
 
7
* This is free software; you can redistribute it and/or modify it
 
8
* under the terms of the GNU Lesser General Public License as
 
9
* published by the Free Software Foundation; either version 2.1 of
 
10
* the License, or (at your option) any later version.
 
11
*
 
12
* This software is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
* Lesser General Public License for more details.
 
16
*
 
17
* You should have received a copy of the GNU Lesser General Public
 
18
* License along with this software; if not, write to the Free
 
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 
21
*/
 
22
 
 
23
package org.jboss.remoting;
 
24
 
 
25
import org.jboss.logging.Logger;
 
26
import org.jboss.remoting.serialization.ClassLoaderUtility;
 
27
import org.jboss.remoting.transport.ClientFactory;
 
28
import org.jboss.remoting.transport.ClientInvoker;
 
29
import org.jboss.remoting.transport.ServerFactory;
 
30
import org.jboss.remoting.transport.local.LocalClientInvoker;
 
31
import org.jboss.remoting.util.SecurityUtility;
 
32
 
 
33
import java.lang.reflect.InvocationTargetException;
 
34
import java.lang.reflect.Method;
 
35
import java.security.AccessController;
 
36
import java.security.PrivilegedActionException;
 
37
import java.security.PrivilegedExceptionAction;
 
38
import java.util.ArrayList;
 
39
import java.util.Collection;
 
40
import java.util.HashMap;
 
41
import java.util.HashSet;
 
42
import java.util.Iterator;
 
43
import java.util.List;
 
44
import java.util.Map;
 
45
import java.util.Set;
 
46
 
 
47
/**
 
48
 * InvokerRegistry is a simple registery for creating client and server side Invoker implementations,
 
49
 * getting information about the invokers and register as a invoker creator for one or more specific
 
50
 * transports.
 
51
 *
 
52
 * @author <a href="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
 
53
 * @author <a href="mailto:telrod@e2technologies.net">Tom Elrod</a>
 
54
 * @version $Revision: 5886 $
 
55
 */
 
56
public class InvokerRegistry
 
57
{
 
58
   private static final Logger log = Logger.getLogger(InvokerRegistry.class);
 
59
 
 
60
   private static boolean trace = log.isTraceEnabled();
 
61
 
 
62
   private static final Map clientLocators = new HashMap();
 
63
   private static final Map serverLocators = new HashMap();
 
64
 
 
65
   private static final Set registeredLocators = new HashSet();
 
66
   private static final Object serverLock = new Object();
 
67
   private static final Object clientLock = new Object();
 
68
 
 
69
   private static final Map transportClientFactoryClasses = new HashMap();
 
70
   private static final Map transportServerFactoryClasses = new HashMap();
 
71
   
 
72
   private static final RuntimePermission INVOKER_REGISTRY_UPDATE_PERMISSION = new RuntimePermission("invokerRegistryUpdate");
 
73
 
 
74
   /**
 
75
    * return an array of InvokerLocators that are local to this VM (server invokers)
 
76
    */
 
77
   public static final InvokerLocator[] getRegisteredServerLocators()
 
78
   {
 
79
      synchronized (serverLock)
 
80
      {
 
81
         return (InvokerLocator[]) registeredLocators.toArray(new InvokerLocator[registeredLocators.size()]);
 
82
      }
 
83
   }
 
84
 
 
85
   /**
 
86
    * return a suitable local server invoker that can service the remote invoker locator based on
 
87
    * a compatible transport
 
88
    *
 
89
    * @param remote
 
90
    */
 
91
   public static InvokerLocator getSuitableServerLocatorForRemote(InvokerLocator remote)
 
92
   {
 
93
      synchronized (serverLock)
 
94
      {
 
95
         Iterator iter = registeredLocators.iterator();
 
96
         while(iter.hasNext())
 
97
         {
 
98
            InvokerLocator l = (InvokerLocator) iter.next();
 
99
            if(l.getProtocol().equals(remote.getProtocol()))
 
100
            {
 
101
               // we found a valid transport match
 
102
               return l;
 
103
            }
 
104
         }
 
105
         return null;
 
106
      }
 
107
   }
 
108
 
 
109
   /**
 
110
    * return an array of String of the registered transports
 
111
    */
 
112
   public static final String[] getRegisteredInvokerTransports()
 
113
   {
 
114
      synchronized(clientLock)
 
115
      {
 
116
         Set set = transportClientFactoryClasses.keySet();
 
117
         String transports[] = new String[set.size()];
 
118
         return (String[]) set.toArray(transports);
 
119
      }
 
120
   }
 
121
 
 
122
   /**
 
123
    * return an array of ClientInvokers that are connected
 
124
    */
 
125
   public static final ClientInvoker[] getClientInvokers()
 
126
   {
 
127
      synchronized(clientLock)
 
128
      {
 
129
         if(clientLocators.isEmpty())
 
130
         {
 
131
            return new ClientInvoker[0];
 
132
         }
 
133
         List clientInvokerList = new ArrayList();
 
134
         Collection collection = clientLocators.values();
 
135
         Iterator itr = collection.iterator();
 
136
         while(itr.hasNext())
 
137
         {
 
138
            List holderList = (List)itr.next();
 
139
            if(holderList != null)
 
140
            {
 
141
               for(int x = 0; x < holderList.size(); x++)
 
142
               {
 
143
                  ClientInvokerHolder holder = (ClientInvokerHolder)holderList.get(x);
 
144
                  clientInvokerList.add(holder.getClientInvoker());
 
145
               }
 
146
            }
 
147
         }
 
148
 
 
149
         return (ClientInvoker[]) clientInvokerList.toArray(new ClientInvoker[clientInvokerList.size()]);
 
150
      }
 
151
   }
 
152
 
 
153
   /**
 
154
    * return an array of ServerInvokers that are connected
 
155
    */
 
156
   public static final ServerInvoker[] getServerInvokers()
 
157
   {
 
158
      synchronized(serverLock)
 
159
      {
 
160
         if(serverLocators.isEmpty())
 
161
         {
 
162
            return new ServerInvoker[0];
 
163
         }
 
164
         Collection collection = serverLocators.values();
 
165
         return (ServerInvoker[]) collection.toArray(new ServerInvoker[collection.size()]);
 
166
      }
 
167
   }
 
168
 
 
169
   /**
 
170
    * register a client/server invoker factory Class pair for a given transport
 
171
    *
 
172
    * @param transport
 
173
    * @param clientFactory implementation of org.jboss.remoting.transport.ClientFactory
 
174
    * @param serverFactory implementation of org.jboss.remoting.transport.ServerFactory
 
175
    */
 
176
   public static void registerInvokerFactories(String transport, Class clientFactory, Class serverFactory)
 
177
   {
 
178
      doSecurityCheck();
 
179
      synchronized (clientLock)
 
180
      {
 
181
         transportClientFactoryClasses.put(transport, clientFactory);
 
182
      }
 
183
      synchronized (serverLock)
 
184
      {
 
185
         transportServerFactoryClasses.put(transport, serverFactory);
 
186
      }
 
187
   }
 
188
 
 
189
   /**
 
190
    * unregister a client/server invoker factory pair for the given transport
 
191
    *
 
192
    * @param transport
 
193
    */
 
194
   public static void unregisterInvokerFactories(String transport)
 
195
   {
 
196
      doSecurityCheck();
 
197
      synchronized (clientLock)
 
198
      {
 
199
         transportClientFactoryClasses.remove(transport);
 
200
      }
 
201
      synchronized (serverLock)
 
202
      {
 
203
         transportServerFactoryClasses.remove(transport);
 
204
      }
 
205
   }
 
206
 
 
207
   public static void unregisterLocator(InvokerLocator locator)
 
208
   {
 
209
      doSecurityCheck();
 
210
      synchronized (serverLock)
 
211
      {
 
212
         serverLocators.remove(locator);
 
213
         registeredLocators.remove(locator);
 
214
      }
 
215
   }
 
216
 
 
217
   /**
 
218
    * returns true if the client invoker is registered in the local JVM for a given locator
 
219
    *
 
220
    * @param locator
 
221
    */
 
222
   public static boolean isClientInvokerRegistered(InvokerLocator locator)
 
223
   {
 
224
      synchronized(clientLock)
 
225
      {
 
226
         return clientLocators.containsKey(locator);
 
227
      }
 
228
   }
 
229
 
 
230
   /**
 
231
    * Called to destroy any cached RemoteClientInvoker copies inside the registry. This method
 
232
    * must be called when it is determined that a remote server (via the locator) is no
 
233
    * longer available.
 
234
    */
 
235
   public static void destroyClientInvoker(InvokerLocator locator, Map configuration)
 
236
   {
 
237
      doSecurityCheck();
 
238
      synchronized(clientLock)
 
239
      {
 
240
         if (trace)
 
241
         {
 
242
            log.trace("destroying client invoker " + locator + ", config " + configuration);
 
243
         }
 
244
 
 
245
         ClientInvoker invoker = decrementClientInvokerCounter(locator, configuration);
 
246
 
 
247
         if(invoker != null)
 
248
         {
 
249
            if (trace)
 
250
            {
 
251
               log.trace("disconnecting " + invoker);
 
252
            }
 
253
            invoker.disconnect();
 
254
            invoker = null;
 
255
         }
 
256
      }
 
257
   }
 
258
 
 
259
   /**
 
260
     * create a ClientInvoker instance, using the specific InvokerLocator, which is just a client-side
 
261
    * invoker to a remote server.  Will use the default configuration values for the transport.
 
262
    *
 
263
    * @param locator
 
264
    * @return
 
265
    * @throws Exception
 
266
    */
 
267
   public static ClientInvoker createClientInvoker(InvokerLocator locator)
 
268
         throws Exception
 
269
   {
 
270
      return createClientInvoker(locator, null);
 
271
   }
 
272
 
 
273
   /**
 
274
    * create a ClientInvoker instance, using the specific InvokerLocator, which is just a client-side
 
275
    * invoker to a remote server
 
276
    *
 
277
    * @param locator
 
278
    * @return
 
279
    * @throws Exception
 
280
    */
 
281
   public static ClientInvoker createClientInvoker(InvokerLocator locator, Map configuration)
 
282
         throws Exception
 
283
   {
 
284
      doSecurityCheck();
 
285
      
 
286
      if(locator == null)
 
287
      {
 
288
         throw new NullPointerException("locator cannot be null");
 
289
      }
 
290
      synchronized(clientLock)
 
291
      {
 
292
         ClientInvoker invoker = getRegisteredClientInvoker(locator, configuration);
 
293
         if(invoker != null)
 
294
         {
 
295
            if(trace) { log.trace("Found and returning cached client invoker (" + invoker + ")"); }
 
296
            return invoker;
 
297
         }
 
298
 
 
299
         boolean isForceRemote = false;
 
300
         boolean isPassByValue = false;
 
301
         Map parameters = locator.getParameters();
 
302
         if(parameters != null)
 
303
         {
 
304
            String value = (String) parameters.get(InvokerLocator.BYVALUE);
 
305
            if(value != null && Boolean.valueOf(value).booleanValue())
 
306
            {
 
307
               isPassByValue = true;
 
308
            }
 
309
            value = (String) parameters.get(InvokerLocator.FORCE_REMOTE);
 
310
            if(value != null && Boolean.valueOf(value).booleanValue())
 
311
            {
 
312
               isForceRemote = true;
 
313
            }
 
314
         }
 
315
         // configuration map will override locator params
 
316
         if(configuration != null)
 
317
         {
 
318
            String value = (String) configuration.get(InvokerLocator.BYVALUE);
 
319
            if(value != null && Boolean.valueOf(value).booleanValue())
 
320
            {
 
321
               isPassByValue = true;
 
322
            }
 
323
            value = (String) configuration.get(InvokerLocator.FORCE_REMOTE);
 
324
            if(value != null && Boolean.valueOf(value).booleanValue())
 
325
            {
 
326
               isForceRemote = true;
 
327
            }
 
328
         }
 
329
 
 
330
         // Check to see if server invoker is local
 
331
         // If in server locators map, then created locally by this class
 
332
         ServerInvoker svrInvoker = null;
 
333
         if (!isForceRemote)
 
334
         {
 
335
            synchronized (serverLock)
 
336
            {
 
337
               svrInvoker = (ServerInvoker) serverLocators.get(locator);
 
338
            }
 
339
            if(svrInvoker != null)
 
340
            {
 
341
               LocalClientInvoker localInvoker = new LocalClientInvoker(locator, configuration, isPassByValue);
 
342
               // have to set reference to local server invoker so client in invoke directly
 
343
               localInvoker.setServerInvoker(svrInvoker);
 
344
               invoker = localInvoker;
 
345
               InvokerLocator l = invoker.getLocator();
 
346
 
 
347
               addRegisteredClientInvoker(invoker, l, configuration);
 
348
            }
 
349
         }
 
350
         
 
351
         if (svrInvoker == null) //not local
 
352
         {
 
353
            String protocol = locator.getProtocol();
 
354
            if(protocol == null)
 
355
            {
 
356
               throw new NullPointerException("protocol cannot be null for the locator");
 
357
            }
 
358
 
 
359
            invoker = loadClientInvoker(protocol, locator, configuration);
 
360
 
 
361
            InvokerLocator l = invoker.getLocator();
 
362
 
 
363
            addRegisteredClientInvoker(invoker, l, configuration);
 
364
         }
 
365
         return invoker;
 
366
      }
 
367
   }
 
368
 
 
369
   private static void addRegisteredClientInvoker(ClientInvoker invoker, InvokerLocator locator, Map configuration)
 
370
   {
 
371
      ClientInvokerHolder holder = new ClientInvokerHolder(invoker, configuration);
 
372
      List holderList = (List) clientLocators.get(locator);
 
373
      if (holderList != null)
 
374
      {
 
375
         if(holderList.contains(holder))
 
376
         {
 
377
            throw new RuntimeException("Registering new ClientInvoker (" + invoker + "), but it already exists.");
 
378
         }
 
379
         else
 
380
         {
 
381
            holderList.add(holder);
 
382
         }
 
383
      }
 
384
      else
 
385
      {
 
386
         holderList = new ArrayList();
 
387
         holderList.add(holder);
 
388
         clientLocators.put(locator, holderList);
 
389
      }
 
390
 
 
391
      incrementClientInvokerCounter(holder);
 
392
 
 
393
   }
 
394
 
 
395
   /**
 
396
    * This will check the internal client invoker registry to see if there is a client invoker for
 
397
    * the specified locator that also has the same config map entries.  Will return it if found, null otherwise.
 
398
    * Note, this will also increment the internal reference count for the invoker
 
399
    * @param locator
 
400
    * @param configuration
 
401
    */
 
402
   private static ClientInvoker getRegisteredClientInvoker(InvokerLocator locator, Map configuration)
 
403
   {
 
404
      ClientInvoker invoker = null;
 
405
 
 
406
      List holderList = (List) clientLocators.get(locator);
 
407
      if (holderList != null)
 
408
      {
 
409
         for (int x = 0; x < holderList.size(); x++)
 
410
         {
 
411
            ClientInvokerHolder holder = (ClientInvokerHolder) holderList.get(x);
 
412
            if (sameInvoker(holder, configuration))
 
413
            {
 
414
               incrementClientInvokerCounter(holder);
 
415
               invoker = holder.getClientInvoker();
 
416
            }
 
417
         }
 
418
      }
 
419
 
 
420
      return invoker;
 
421
 
 
422
   }
 
423
 
 
424
   private static boolean sameInvoker(ClientInvokerHolder holder, Map configuration)
 
425
   {
 
426
      boolean isSame = false;
 
427
 
 
428
      if(holder != null && holder.getClientInvoker() != null)
 
429
      {
 
430
         Map config = holder.getConfig();
 
431
         if(config == null && configuration == null)
 
432
         {
 
433
            isSame = true;
 
434
         }
 
435
         else if(config != null && configuration != null)
 
436
         {
 
437
            isSame = config.equals(configuration);
 
438
         }
 
439
      }
 
440
 
 
441
      return isSame;
 
442
   }
 
443
 
 
444
   private static void incrementClientInvokerCounter(ClientInvokerHolder holder)
 
445
   {
 
446
      holder.incrementCount();
 
447
   }
 
448
 
 
449
   private static ClientInvoker loadClientInvoker(String protocol, InvokerLocator locator, Map configuration) throws Exception
 
450
   {
 
451
      ClientInvoker clientInvoker = null;
 
452
 
 
453
      Class transportFactoryClass = getTransportClientFactory(protocol);
 
454
      if(transportFactoryClass != null)
 
455
      {
 
456
         ClientFactory transportFactory = (ClientFactory)transportFactoryClass.newInstance();
 
457
         Method getClientInvokerMethod = getMethod(transportFactoryClass,
 
458
                                                   "createClientInvoker",
 
459
                                                   new Class[] {InvokerLocator.class, Map.class});
 
460
         clientInvoker = (ClientInvoker)getClientInvokerMethod.invoke(transportFactory, new Object[] {locator, configuration});
 
461
      }
 
462
      else
 
463
      {
 
464
         throw new ClassNotFoundException("Could not find class " + transportFactoryClass);
 
465
      }
 
466
 
 
467
      return clientInvoker;
 
468
   }
 
469
 
 
470
   private static ServerInvoker loadServerInvoker(String protocol, InvokerLocator locator, Map configuration) throws Exception
 
471
   {
 
472
      ServerInvoker serverInvoker = null;
 
473
 
 
474
      Class transportFactoryClass = getTransportServerFactory(protocol);
 
475
      if(transportFactoryClass != null)
 
476
      {
 
477
         ServerFactory transportFactory = (ServerFactory)transportFactoryClass.newInstance();
 
478
         Method getServerInvokerMethod = getMethod(transportFactoryClass,
 
479
                                                   "createServerInvoker",
 
480
                                                   new Class[] {InvokerLocator.class, Map.class});         
 
481
         serverInvoker = (ServerInvoker)getServerInvokerMethod.invoke(transportFactory, new Object[] {locator, configuration});
 
482
      }
 
483
      else
 
484
      {
 
485
         throw new ClassNotFoundException("Could not find class " + transportFactoryClass);
 
486
      }
 
487
 
 
488
      return serverInvoker;
 
489
   }
 
490
 
 
491
   private static Class getTransportClientFactory(String protocol)
 
492
         throws ClassNotFoundException
 
493
   {
 
494
      Class transportFactoryClass = (Class)transportClientFactoryClasses.get(protocol);
 
495
      if(transportFactoryClass == null)
 
496
      {
 
497
         String transportFactoryClassName = "org.jboss.remoting.transport." + protocol + ".TransportClientFactory";
 
498
         transportFactoryClass = ClassLoaderUtility.loadClass(InvokerRegistry.class, transportFactoryClassName);
 
499
         transportClientFactoryClasses.put(protocol, transportFactoryClass);
 
500
      }
 
501
      return transportFactoryClass;
 
502
   }
 
503
 
 
504
   private static Class getTransportServerFactory(String protocol)
 
505
         throws ClassNotFoundException
 
506
   {
 
507
      Class transportFactoryClass = (Class)transportServerFactoryClasses.get(protocol);
 
508
      if(transportFactoryClass == null)
 
509
      {
 
510
         String transportFactoryClassName = "org.jboss.remoting.transport." + protocol + ".TransportServerFactory";
 
511
         transportFactoryClass = ClassLoaderUtility.loadClass(transportFactoryClassName, InvokerRegistry.class);
 
512
         transportServerFactoryClasses.put(protocol, transportFactoryClass);
 
513
      }
 
514
      return transportFactoryClass;
 
515
   }
 
516
 
 
517
   /**
 
518
    * returns true if the server invoker is registered in the local JVM for a given locator/handler pair
 
519
    *
 
520
    * @param locator
 
521
    */
 
522
   public static boolean isServerInvokerRegistered(InvokerLocator locator)
 
523
   {
 
524
      synchronized(serverLock)
 
525
      {
 
526
         return serverLocators.containsKey(locator);
 
527
      }
 
528
   }
 
529
 
 
530
   /**
 
531
    * create a ServerInvoker instance, using the specific Invoker locator data and an implementation of the
 
532
    * ServerInvocationHandler interface.  Will use the default configuration values for the transport.
 
533
    *
 
534
    * @param locator
 
535
    * @return
 
536
    * @throws Exception
 
537
    */
 
538
   public static ServerInvoker createServerInvoker(InvokerLocator locator)
 
539
         throws Exception
 
540
   {
 
541
      return createServerInvoker(locator, null);
 
542
   }
 
543
 
 
544
   /**
 
545
    * create a ServerInvoker instance, using the specific Invoker locator data and an implementation of the
 
546
    * ServerInvocationHandler interface along with
 
547
    *
 
548
    * @param locator
 
549
    * @return
 
550
    * @throws Exception
 
551
    */
 
552
   public static ServerInvoker createServerInvoker(InvokerLocator locator, Map configuration)
 
553
         throws Exception
 
554
   {
 
555
      doSecurityCheck();
 
556
      ServerInvoker invoker = null;
 
557
      synchronized(serverLock)
 
558
      {
 
559
         invoker = (ServerInvoker) serverLocators.get(locator);
 
560
         if(invoker != null)
 
561
         {
 
562
            throw new InvalidConfigurationException("The invoker for locator (" + locator + ") is already " +
 
563
                                                    "in use by another Connector.  Either change the locator or " +
 
564
                                                    "add new handlers to existing Connector.");
 
565
         }
 
566
         String protocol = locator.getProtocol();
 
567
 
 
568
         invoker = loadServerInvoker(protocol, locator, configuration);
 
569
 
 
570
         serverLocators.put(locator, invoker);
 
571
         registeredLocators.add(invoker.getLocator());
 
572
      }
 
573
      return invoker;
 
574
   }
 
575
 
 
576
   public static void destroyServerInvoker(ServerInvoker invoker)
 
577
   {
 
578
      doSecurityCheck();
 
579
      if(invoker != null)
 
580
      {
 
581
         InvokerLocator locator = invoker.getLocator();
 
582
         unregisterLocator(locator);
 
583
      }
 
584
   }
 
585
 
 
586
   private static ClientInvoker decrementClientInvokerCounter(InvokerLocator locator, Map configuration)
 
587
   {
 
588
      List holderList = (List)clientLocators.get(locator);
 
589
 
 
590
      if (holderList == null)
 
591
      {
 
592
         log.debug("Could not decrement client invoker counter for locator " + locator +
 
593
            " as does not exist in invoker registry.");
 
594
         return null;
 
595
      }
 
596
 
 
597
      ClientInvokerHolder holder = null;
 
598
 
 
599
      // now look for specific invoker by configuration map
 
600
      for(int x = 0; x < holderList.size(); x++)
 
601
      {
 
602
         holder = (ClientInvokerHolder)holderList.get(x);
 
603
         if(holder != null)
 
604
         {
 
605
            Map config = holder.getConfig();
 
606
            if(config == null && configuration == null)
 
607
            {
 
608
               break;
 
609
            }
 
610
            else if(config != null && configuration != null)
 
611
            {
 
612
               if(config.equals(configuration))
 
613
               {
 
614
                  break;
 
615
               }
 
616
            }
 
617
         }
 
618
      }
 
619
 
 
620
      if (holder == null)
 
621
      {
 
622
         log.debug("Could not decrement client invoker counter for locator " + locator +
 
623
                   "as does not exist in invoker registry with matching configuraion map.");
 
624
         return null;
 
625
      }
 
626
 
 
627
      ClientInvoker clientInvoker =  null;
 
628
      holder.decrementCount();
 
629
 
 
630
      if(holder.getCount() == 0)
 
631
      {
 
632
         clientInvoker = holder.getClientInvoker();
 
633
         holderList.remove(holder);
 
634
         if(holderList.isEmpty())
 
635
         {
 
636
            clientLocators.remove(locator);
 
637
         }
 
638
 
 
639
         log.debug("removed " + clientInvoker + " from registry");
 
640
      }
 
641
      else
 
642
      {
 
643
         log.debug("decremented " + holder.getClientInvoker() +
 
644
            "'s count, current count " + holder.getCount());
 
645
      }
 
646
 
 
647
      return clientInvoker;
 
648
   }
 
649
 
 
650
   /**
 
651
    * This is needed by the ServerInvoker since it may change the port being used (if port specified was <= 0) to
 
652
    * next available port.
 
653
    *
 
654
    * @param locator
 
655
    * @param newLocator
 
656
    */
 
657
   public static void updateServerInvokerLocator(InvokerLocator locator, InvokerLocator newLocator)
 
658
   {
 
659
      doSecurityCheck();
 
660
      synchronized (serverLock)
 
661
      {
 
662
         Object si = serverLocators.get(locator);
 
663
         serverLocators.remove(locator);
 
664
         registeredLocators.remove(locator);
 
665
         serverLocators.put(newLocator, si);
 
666
         registeredLocators.add(newLocator);
 
667
      }
 
668
   }
 
669
 
 
670
   /**
 
671
    * Indicates if a specific transport protocol type (e.g. socket, sslsocket, rmi, https)
 
672
    * supports ssl.  Note: almost all transports are able to support ssl if socket/serversocket
 
673
    * factory is set with an ssl version, so this is really just a hint from the invoker implementation.
 
674
    *
 
675
    * @param transport
 
676
    * @return
 
677
    * @throws Exception
 
678
    */
 
679
   public static boolean isSSLSupported(String transport) throws Exception
 
680
   {
 
681
      doSecurityCheck();
 
682
      boolean isSSLSupported = false;
 
683
      Class transportFactoryClass = null;
 
684
      try
 
685
      {
 
686
         synchronized (clientLock)
 
687
         {
 
688
            transportFactoryClass = getTransportClientFactory(transport);
 
689
         }
 
690
         ClientFactory clientFactory = (ClientFactory)transportFactoryClass.newInstance();
 
691
         Method meth = getMethod(transportFactoryClass, "supportsSSL", new Class[]{});         
 
692
         Boolean boolVal = (Boolean)meth.invoke(clientFactory, null);
 
693
         isSSLSupported = boolVal.booleanValue();
 
694
      }
 
695
      catch (ClassNotFoundException e)
 
696
      {
 
697
         Exception ex = new Exception("Can not verify transport (" + transport + ") supports SSL because can not find invoker implementation matching transport.");
 
698
         ex.initCause(e);
 
699
         throw ex;
 
700
      }
 
701
      catch (NoSuchMethodException e)
 
702
      {
 
703
         Exception ex = new Exception("Can not call supportsSSL method on client factory class (" + transportFactoryClass + ") as there is no such method.");
 
704
         ex.initCause(e);
 
705
         throw ex;
 
706
      }
 
707
      catch (IllegalAccessException e)
 
708
      {
 
709
         Exception ex = new Exception("Can not call create instance of client factory class (" + transportFactoryClass + ").");
 
710
         ex.initCause(e);
 
711
         throw ex;
 
712
      }
 
713
      catch (InvocationTargetException e)
 
714
      {
 
715
         Exception ex = new Exception("Can not call supportsSSL method on client factory class (" + transportFactoryClass + ").");
 
716
         ex.initCause(e);
 
717
         throw ex;
 
718
      }
 
719
      catch (InstantiationException e)
 
720
      {
 
721
         Exception ex = new Exception("Can not call supportsSSL method on client factory class (" + transportFactoryClass + ").");
 
722
         ex.initCause(e);
 
723
         throw ex;
 
724
      }
 
725
 
 
726
      return isSSLSupported;
 
727
   }
 
728
 
 
729
   public String toString()
 
730
   {
 
731
      return "InvokerRegistry[" + Integer.toHexString(hashCode()) + "]";
 
732
   }
 
733
 
 
734
   private static class ClientInvokerHolder
 
735
   {
 
736
      private ClientInvoker invoker = null;
 
737
      private Map config = null;
 
738
      private int counter = 0;
 
739
 
 
740
      public ClientInvokerHolder(ClientInvoker invoker, Map config)
 
741
      {
 
742
         this.invoker = invoker;
 
743
         this.config = config;
 
744
      }
 
745
 
 
746
      public void incrementCount()
 
747
      {
 
748
         counter++;
 
749
      }
 
750
 
 
751
      public void decrementCount()
 
752
      {
 
753
         counter--;
 
754
         if(counter < 0)
 
755
         {
 
756
            throw new RuntimeException("ClientInvokerHolder decremented to negative number for client invoker " + invoker);
 
757
         }
 
758
      }
 
759
 
 
760
      public int getCount()
 
761
      {
 
762
         return counter;
 
763
      }
 
764
 
 
765
      public ClientInvoker getClientInvoker()
 
766
      {
 
767
         return invoker;
 
768
      }
 
769
 
 
770
      public Map getConfig()
 
771
      {
 
772
         return config;
 
773
      }
 
774
 
 
775
      public boolean equals(Object o)
 
776
      {
 
777
         boolean isEqual = false;
 
778
 
 
779
         if(o instanceof ClientInvokerHolder)
 
780
         {
 
781
            ClientInvokerHolder h = (ClientInvokerHolder)o;
 
782
            if(invoker.equals(h.getClientInvoker()))
 
783
            {
 
784
               Map configuration = h.getConfig();
 
785
               if(config == null && configuration == null)
 
786
               {
 
787
                  isEqual = true;
 
788
               }
 
789
               else if(config != null && configuration != null)
 
790
               {
 
791
                  isEqual = config.equals(configuration);
 
792
               }
 
793
            }
 
794
         }
 
795
         return isEqual;
 
796
      }
 
797
 
 
798
   }
 
799
   
 
800
   static private Method getMethod(final Class c, final String name, final Class[] parameterTypes)
 
801
   throws NoSuchMethodException
 
802
   {
 
803
      if (SecurityUtility.skipAccessControl())
 
804
      {
 
805
         return c.getMethod(name, parameterTypes);
 
806
      }
 
807
 
 
808
      try
 
809
      {
 
810
         return (Method) AccessController.doPrivileged( new PrivilegedExceptionAction()
 
811
         {
 
812
            public Object run() throws NoSuchMethodException
 
813
            {
 
814
               return c.getMethod(name, parameterTypes);
 
815
            }
 
816
         });
 
817
      }
 
818
      catch (PrivilegedActionException e)
 
819
      {
 
820
         throw (NoSuchMethodException) e.getCause();
 
821
      }
 
822
   }
 
823
   
 
824
   static private void doSecurityCheck()
 
825
   {
 
826
      // If there is no Security Manager, the issue is moot.
 
827
      final SecurityManager sm = System.getSecurityManager();
 
828
      if (sm == null)
 
829
      {
 
830
         return;
 
831
      }
 
832
 
 
833
      // If the calling code is not verifiably in Remoting, then require it to have InvokerRegistryUpdatePermission.
 
834
      sm.checkPermission(INVOKER_REGISTRY_UPDATE_PERMISSION);
 
835
   }
 
836
}