KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > transport > SocketOrChannelAcceptorImpl


1 /*
2  * @(#)SocketOrChannelAcceptorImpl.java 1.54 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.transport;
9
10 import java.io.IOException JavaDoc;
11 import java.net.InetSocketAddress JavaDoc;
12 import java.net.ServerSocket JavaDoc;
13 import java.net.Socket JavaDoc;
14 import java.nio.channels.SelectableChannel JavaDoc;
15 import java.nio.channels.SelectionKey JavaDoc;
16 import java.nio.channels.ServerSocketChannel JavaDoc;
17 import java.nio.channels.SocketChannel JavaDoc;
18 import java.security.AccessController JavaDoc;
19 import java.security.PrivilegedAction JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.LinkedList JavaDoc;
23
24 import org.omg.CORBA.CompletionStatus JavaDoc;
25 import org.omg.CORBA.INTERNAL JavaDoc;
26
27 import com.sun.corba.se.pept.broker.Broker;
28 import com.sun.corba.se.pept.encoding.InputObject;
29 import com.sun.corba.se.pept.encoding.OutputObject;
30 import com.sun.corba.se.pept.protocol.MessageMediator;
31 import com.sun.corba.se.pept.transport.Acceptor;
32 import com.sun.corba.se.pept.transport.Connection;
33 import com.sun.corba.se.pept.transport.ContactInfo;
34 import com.sun.corba.se.pept.transport.EventHandler;
35 import com.sun.corba.se.pept.transport.InboundConnectionCache;
36 import com.sun.corba.se.pept.transport.Selector;
37
38 import com.sun.corba.se.spi.extension.RequestPartitioningPolicy;
39 import com.sun.corba.se.spi.ior.IORTemplate;
40 import com.sun.corba.se.spi.ior.TaggedProfileTemplate;
41 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
42 import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
43 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
44 import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
45 import com.sun.corba.se.spi.ior.iiop.AlternateIIOPAddressComponent;
46 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
47 import com.sun.corba.se.spi.logging.CORBALogDomains;
48 import com.sun.corba.se.spi.monitoring.LongMonitoredAttributeBase;
49 import com.sun.corba.se.spi.monitoring.MonitoringConstants;
50 import com.sun.corba.se.spi.monitoring.MonitoringFactories;
51 import com.sun.corba.se.spi.monitoring.MonitoredObject;
52 import com.sun.corba.se.spi.orb.ORB;
53 import com.sun.corba.se.spi.orbutil.threadpool.Work;
54 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
55 import com.sun.corba.se.spi.transport.CorbaAcceptor;
56 import com.sun.corba.se.spi.transport.CorbaConnection;
57 import com.sun.corba.se.spi.transport.CorbaContactInfo;
58 import com.sun.corba.se.spi.transport.SocketInfo;
59 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
60
61 import com.sun.corba.se.impl.encoding.CDRInputObject;
62 import com.sun.corba.se.impl.encoding.CDROutputObject;
63 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
64 import com.sun.corba.se.impl.oa.poa.Policies; // REVISIT impl/poa specific
65
import com.sun.corba.se.impl.orbutil.ORBConstants;
66 import com.sun.corba.se.impl.orbutil.ORBUtility;
67 import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
68
69 // BEGIN Legacy support.
70
import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
71 // END Legacy support.
72

73 /**
74  * @author Harold Carr
75  */

76 public class SocketOrChannelAcceptorImpl
77     extends
78     EventHandlerBase
79     implements
80     CorbaAcceptor,
81     SocketOrChannelAcceptor,
82     Work,
83     // BEGIN Legacy
84
SocketInfo,
85     LegacyServerSocketEndPointInfo
86     // END Legacy
87
{
88     protected ServerSocketChannel JavaDoc serverSocketChannel;
89     protected ServerSocket JavaDoc serverSocket;
90     protected int port;
91     protected long enqueueTime;
92     protected boolean initialized;
93     protected ORBUtilSystemException wrapper ;
94     protected InboundConnectionCache connectionCache;
95
96     // BEGIN Legacy
97
protected String JavaDoc type = "";
98     protected String JavaDoc name = "";
99     protected String JavaDoc hostname;
100     protected int locatorPort;
101     // END Legacy
102

103     public SocketOrChannelAcceptorImpl(ORB orb)
104     {
105     this.orb = orb;
106     wrapper = ORBUtilSystemException.get( orb,
107         CORBALogDomains.RPC_TRANSPORT ) ;
108
109     setWork(this);
110     initialized = false;
111
112     // BEGIN Legacy support.
113
this.hostname = orb.getORBData().getORBServerHost();
114     this.name = LegacyServerSocketEndPointInfo.NO_NAME;
115     this.locatorPort = -1;
116     // END Legacy support.
117
}
118
119     public SocketOrChannelAcceptorImpl(ORB orb, int port)
120     {
121     this(orb);
122     this.port = port;
123     }
124
125     // BEGIN Legacy support.
126
public SocketOrChannelAcceptorImpl(ORB orb, int port,
127                        String JavaDoc name, String JavaDoc type)
128     {
129     this(orb, port);
130     this.name = name;
131     this.type = type;
132     }
133     // END Legacy support.
134

135     ////////////////////////////////////////////////////
136
//
137
// pept.transport.Acceptor
138
//
139

140     public boolean initialize()
141     {
142     if (initialized) {
143         return false;
144     }
145     if (orb.transportDebugFlag) {
146         dprint(".initialize: " + this);
147     }
148     InetSocketAddress JavaDoc inetSocketAddress = null;
149     try {
150         if (orb.getORBData().getListenOnAllInterfaces().equals(ORBConstants.LISTEN_ON_ALL_INTERFACES)) {
151         inetSocketAddress = new InetSocketAddress JavaDoc(port);
152         } else {
153         String JavaDoc host = orb.getORBData().getORBServerHost();
154         inetSocketAddress = new InetSocketAddress JavaDoc(host, port);
155         }
156         serverSocket = orb.getORBData().getSocketFactory()
157         .createServerSocket(type, inetSocketAddress);
158         internalInitialize();
159     } catch (Throwable JavaDoc t) {
160         throw wrapper.createListenerFailed( t, Integer.toString(port) ) ;
161     }
162     initialized = true;
163     return true;
164     }
165
166     protected void internalInitialize()
167     throws Exception JavaDoc
168     {
169     // Determine the listening port (for the IOR).
170
// This is important when using emphemeral ports (i.e.,
171
// when the port value to the constructor is 0).
172

173     port = serverSocket.getLocalPort();
174
175     // Register with transport (also sets up monitoring).
176

177     orb.getCorbaTransportManager().getInboundConnectionCache(this);
178
179     // Finish configuation.
180

181     serverSocketChannel = serverSocket.getChannel();
182
183     if (serverSocketChannel != null) {
184         setUseSelectThreadToWait(
185             orb.getORBData().acceptorSocketUseSelectThreadToWait());
186         serverSocketChannel.configureBlocking(
187             ! orb.getORBData().acceptorSocketUseSelectThreadToWait());
188     } else {
189         // Configure to use listener and reader threads.
190
setUseSelectThreadToWait(false);
191     }
192     setUseWorkerThreadForEvent(
193             orb.getORBData().acceptorSocketUseWorkerThreadForEvent());
194
195     }
196
197     public boolean initialized()
198     {
199     return initialized;
200     }
201
202     public String JavaDoc getConnectionCacheType()
203     {
204     return this.getClass().toString();
205     }
206
207     public void setConnectionCache(InboundConnectionCache connectionCache)
208     {
209     this.connectionCache = connectionCache;
210     }
211
212     public InboundConnectionCache getConnectionCache()
213     {
214     return connectionCache;
215     }
216
217     public boolean shouldRegisterAcceptEvent()
218     {
219     return true;
220     }
221
222     public void accept()
223     {
224     try {
225         SocketChannel JavaDoc socketChannel = null;
226         Socket JavaDoc socket = null;
227         if (serverSocketChannel == null) {
228         socket = serverSocket.accept();
229         } else {
230         socketChannel = serverSocketChannel.accept();
231         socket = socketChannel.socket();
232         }
233         orb.getORBData().getSocketFactory()
234         .setAcceptedSocketOptions(this, serverSocket, socket);
235         if (orb.transportDebugFlag) {
236         dprint(".accept: " +
237                (serverSocketChannel == null
238             ? serverSocket.toString()
239             : serverSocketChannel.toString()));
240         }
241
242         CorbaConnection connection =
243         new SocketOrChannelConnectionImpl(orb, this, socket);
244         if (orb.transportDebugFlag) {
245         dprint(".accept: new: " + connection);
246         }
247
248         // NOTE: The connection MUST be put in the cache BEFORE being
249
// registered with the selector. Otherwise if the bytes
250
// are read on the connection it will attempt a time stamp
251
// but the cache will be null, resulting in NPE.
252
getConnectionCache().put(this, connection);
253
254         if (connection.shouldRegisterServerReadEvent()) {
255         Selector selector = orb.getTransportManager().getSelector(0);
256         selector.registerForEvent(connection.getEventHandler());
257         }
258
259         getConnectionCache().reclaim();
260
261     } catch (IOException JavaDoc e) {
262         if (orb.transportDebugFlag) {
263         dprint(".accept:", e);
264         }
265         orb.getTransportManager().getSelector(0).unregisterForEvent(this);
266         // REVISIT - need to close - recreate - then register new one.
267
orb.getTransportManager().getSelector(0).registerForEvent(this);
268         // NOTE: if register cycling we do not want to shut down ORB
269
// since local beans will still work. Instead one will see
270
// a growing log file to alert admin of problem.
271
}
272     }
273
274     public void close ()
275     {
276     try {
277         if (orb.transportDebugFlag) {
278         dprint(".close->:");
279         }
280         Selector selector = orb.getTransportManager().getSelector(0);
281         selector.unregisterForEvent(this);
282         if (serverSocketChannel != null) {
283         serverSocketChannel.close();
284         }
285         if (serverSocket != null) {
286         serverSocket.close();
287         }
288     } catch (IOException JavaDoc e) {
289         if (orb.transportDebugFlag) {
290         dprint(".close:", e);
291         }
292     } finally {
293         if (orb.transportDebugFlag) {
294         dprint(".close<-:");
295         }
296     }
297     }
298
299     public EventHandler getEventHandler()
300     {
301     return this;
302     }
303
304     ////////////////////////////////////////////////////
305
//
306
// CorbaAcceptor
307
//
308

309     public String JavaDoc getObjectAdapterId()
310     {
311     return null;
312     }
313
314     public String JavaDoc getObjectAdapterManagerId()
315     {
316     return null;
317     }
318
319     public void addToIORTemplate(IORTemplate iorTemplate,
320                  Policies policies,
321                  String JavaDoc codebase)
322     {
323     Iterator JavaDoc iterator = iorTemplate.iteratorById(
324             org.omg.IOP.TAG_INTERNET_IOP.value);
325
326     String JavaDoc hostname = orb.getORBData().getORBServerHost();
327
328     if (iterator.hasNext()) {
329         // REVISIT - how does this play with legacy ORBD port exchange?
330
IIOPAddress iiopAddress =
331         IIOPFactories.makeIIOPAddress(orb, hostname, port);
332         AlternateIIOPAddressComponent iiopAddressComponent =
333         IIOPFactories.makeAlternateIIOPAddressComponent(iiopAddress);
334
335         while (iterator.hasNext()) {
336         TaggedProfileTemplate taggedProfileTemplate =
337             (TaggedProfileTemplate) iterator.next();
338         taggedProfileTemplate.add(iiopAddressComponent);
339         }
340     } else {
341         GIOPVersion version = orb.getORBData().getGIOPVersion();
342         int templatePort;
343         if (policies.forceZeroPort()) {
344         templatePort = 0;
345         } else if (policies.isTransient()) {
346         templatePort = port;
347         } else {
348         templatePort = orb.getLegacyServerSocketManager()
349                    .legacyGetPersistentServerPort(SocketInfo.IIOP_CLEAR_TEXT);
350         }
351         IIOPAddress addr =
352         IIOPFactories.makeIIOPAddress(orb, hostname, templatePort);
353         IIOPProfileTemplate iiopProfile =
354         IIOPFactories.makeIIOPProfileTemplate(orb, version, addr);
355         if (version.supportsIORIIOPProfileComponents()) {
356         iiopProfile.add(IIOPFactories.makeCodeSetsComponent(orb));
357         iiopProfile.add(IIOPFactories.makeMaxStreamFormatVersionComponent());
358             RequestPartitioningPolicy rpPolicy = (RequestPartitioningPolicy)
359             policies.get_effective_policy(
360                           ORBConstants.REQUEST_PARTITIONING_POLICY);
361         if (rpPolicy != null) {
362             iiopProfile.add(
363                  IIOPFactories.makeRequestPartitioningComponent(
364                  rpPolicy.getValue()));
365         }
366         if (codebase != null && codebase != "") {
367             iiopProfile.add(IIOPFactories. makeJavaCodebaseComponent(codebase));
368         }
369         if (orb.getORBData().isJavaSerializationEnabled()) {
370             iiopProfile.add(
371                IIOPFactories.makeJavaSerializationComponent());
372         }
373         }
374         iorTemplate.add(iiopProfile);
375     }
376     }
377
378     public String JavaDoc getMonitoringName()
379     {
380     return "AcceptedConnections";
381     }
382
383     ////////////////////////////////////////////////////
384
//
385
// EventHandler methods
386
//
387

388     public SelectableChannel JavaDoc getChannel()
389     {
390     return serverSocketChannel;
391     }
392
393     public int getInterestOps()
394     {
395     return SelectionKey.OP_ACCEPT;
396     }
397
398     public Acceptor getAcceptor()
399     {
400     return this;
401     }
402
403     public Connection getConnection()
404     {
405     throw new RuntimeException JavaDoc("Should not happen.");
406     }
407
408     ////////////////////////////////////////////////////
409
//
410
// Work methods.
411
//
412

413     /* CONFLICT: with legacy below.
414     public String getName()
415     {
416     return this.toString();
417     }
418     */

419
420     public void doWork()
421     {
422     try {
423         if (orb.transportDebugFlag) {
424         dprint(".doWork->: " + this);
425         }
426         if (selectionKey.isAcceptable()) {
427                 AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
428             public java.lang.Object JavaDoc run() {
429             accept();
430             return null;
431             }
432         });
433         } else {
434         if (orb.transportDebugFlag) {
435             dprint(".doWork: ! selectionKey.isAcceptable: " + this);
436         }
437         }
438     } catch (SecurityException JavaDoc se) {
439         if (orb.transportDebugFlag) {
440         dprint(".doWork: ignoring SecurityException: "
441                + se
442                + " " + this);
443         }
444         String JavaDoc permissionStr = ORBUtility.getClassSecurityInfo(getClass());
445             wrapper.securityExceptionInAccept(se, permissionStr);
446     } catch (Exception JavaDoc ex) {
447         if (orb.transportDebugFlag) {
448         dprint(".doWork: ignoring Exception: "
449                + ex
450                + " " + this);
451         }
452             wrapper.exceptionInAccept(ex);
453     } catch (Throwable JavaDoc t) {
454         if (orb.transportDebugFlag) {
455         dprint(".doWork: ignoring Throwable: "
456                + t
457                + " " + this);
458         }
459     } finally {
460
461             // IMPORTANT: To avoid bug (4953599), we force the
462
// Thread that does the NIO select to also do the
463
// enable/disable of Ops using SelectionKey.interestOps().
464
// Otherwise, the SelectionKey.interestOps() may block
465
// indefinitely.
466
// NOTE: If "acceptorSocketUseWorkerThreadForEvent" is
467
// set to to false in ParserTable.java, then this method,
468
// doWork(), will get executed by the same thread
469
// (SelectorThread) that does the NIO select.
470
// If "acceptorSocketUseWorkerThreadForEvent" is set
471
// to true, a WorkerThread will execute this method,
472
// doWork(). Hence, the registering of the enabling of
473
// the SelectionKey's interestOps is done here instead
474
// of calling SelectionKey.interestOps(<interest op>).
475

476             Selector selector = orb.getTransportManager().getSelector(0);
477             selector.registerInterestOps(this);
478
479         if (orb.transportDebugFlag) {
480         dprint(".doWork<-:" + this);
481         }
482     }
483     }
484
485     public void setEnqueueTime(long timeInMillis)
486     {
487     enqueueTime = timeInMillis;
488     }
489
490     public long getEnqueueTime()
491     {
492     return enqueueTime;
493     }
494
495
496     //
497
// Factory methods.
498
//
499

500     // REVISIT: refactor into common base or delegate.
501
public MessageMediator createMessageMediator(Broker broker,
502                          Connection connection)
503     {
504     // REVISIT - no factoring so cheat to avoid code dup right now.
505
// REVISIT **** COUPLING !!!!
506
ContactInfo contactInfo = new SocketOrChannelContactInfoImpl();
507     return contactInfo.createMessageMediator(broker, connection);
508     }
509
510     // REVISIT: refactor into common base or delegate.
511
public MessageMediator finishCreatingMessageMediator(Broker broker,
512                                  Connection connection,
513                                  MessageMediator messageMediator)
514     {
515     // REVISIT - no factoring so cheat to avoid code dup right now.
516
// REVISIT **** COUPLING !!!!
517
ContactInfo contactInfo = new SocketOrChannelContactInfoImpl();
518     return contactInfo.finishCreatingMessageMediator(broker,
519                                   connection, messageMediator);
520     }
521
522     public InputObject createInputObject(Broker broker,
523                      MessageMediator messageMediator)
524     {
525     CorbaMessageMediator corbaMessageMediator = (CorbaMessageMediator)
526         messageMediator;
527     return new CDRInputObject((ORB)broker,
528                   (CorbaConnection)messageMediator.getConnection(),
529                   corbaMessageMediator.getDispatchBuffer(),
530                   corbaMessageMediator.getDispatchHeader());
531     }
532
533     public OutputObject createOutputObject(Broker broker,
534                        MessageMediator messageMediator)
535     {
536     CorbaMessageMediator corbaMessageMediator = (CorbaMessageMediator)
537         messageMediator;
538     return new CDROutputObject((ORB) broker, corbaMessageMediator,
539                    corbaMessageMediator.getReplyHeader(),
540                    corbaMessageMediator.getStreamFormatVersion());
541     }
542
543     ////////////////////////////////////////////////////
544
//
545
// SocketOrChannelAcceptor
546
//
547

548     public ServerSocket JavaDoc getServerSocket()
549     {
550     return serverSocket;
551     }
552
553     ////////////////////////////////////////////////////
554
//
555
// Implementation.
556
//
557

558     public String JavaDoc toString()
559     {
560     String JavaDoc sock;
561     if (serverSocketChannel == null) {
562         if (serverSocket == null) {
563         sock = "(not initialized)";
564         } else {
565         sock = serverSocket.toString();
566         }
567     } else {
568         sock = serverSocketChannel.toString();
569     }
570
571     return
572         toStringName() +
573         "["
574         + sock + " "
575         + type + " "
576         + shouldUseSelectThreadToWait() + " "
577         + shouldUseWorkerThreadForEvent()
578         + "]" ;
579     }
580
581     protected String JavaDoc toStringName()
582     {
583     return "SocketOrChannelAcceptorImpl";
584     }
585
586     protected void dprint(String JavaDoc msg)
587     {
588     ORBUtility.dprint(toStringName(), msg);
589     }
590
591     protected void dprint(String JavaDoc msg, Throwable JavaDoc t)
592     {
593     dprint(msg);
594     t.printStackTrace(System.out);
595     }
596
597     // BEGIN Legacy support
598
////////////////////////////////////////////////////
599
//
600
// LegacyServerSocketEndPointInfo and EndPointInfo
601
//
602

603     public String JavaDoc getType()
604     {
605     return type;
606     }
607
608     public String JavaDoc getHostName()
609     {
610     return hostname;
611     }
612
613     public String JavaDoc getHost()
614     {
615     return hostname;
616     }
617
618     public int getPort()
619     {
620     return port;
621     }
622
623     public int getLocatorPort()
624     {
625     return locatorPort;
626     }
627
628     public void setLocatorPort (int port)
629     {
630     locatorPort = port;
631     }
632
633     public String JavaDoc getName()
634     {
635     // Kluge alert:
636
// Work and Legacy both define getName.
637
// Try to make this behave best for most cases.
638
String JavaDoc result =
639         name.equals(LegacyServerSocketEndPointInfo.NO_NAME) ?
640         this.toString() : name;
641     return result;
642     }
643     // END Legacy support
644
}
645
646 // End of file.
647
Popular Tags