Logo Search packages:      
Sourcecode: nailgun version File versions  Download package

void com::martiansoftware::nailgun::NGSession::run (  )  [inline]

The main NGSession loop. This gets the next socket to process, runs the nail for the socket, and loops until shut down.

Definition at line 174 of file NGSession.java.

References com::martiansoftware::nailgun::NGServer::allowsNailsByClassName(), com::martiansoftware::nailgun::NGContext::err, com::martiansoftware::nailgun::AliasManager::getAlias(), com::martiansoftware::nailgun::Alias::getAliasedClass(), com::martiansoftware::nailgun::NGServer::getAliasManager(), com::martiansoftware::nailgun::NGServer::getDefaultNailClass(), org::apache::tools::ant::ExitException::getStatus(), com::martiansoftware::nailgun::NGSessionPool::give(), com::martiansoftware::nailgun::NGContext::in, mainSignature, com::martiansoftware::nailgun::NGServer::nailFinished(), nailMainSignature, com::martiansoftware::nailgun::NGServer::nailStarted(), nextSocket(), com::martiansoftware::nailgun::NGServer::out, com::martiansoftware::nailgun::NGContext::out, server, sessionPool, com::martiansoftware::nailgun::NGContext::setArgs(), com::martiansoftware::nailgun::NGContext::setCommand(), com::martiansoftware::nailgun::NGContext::setEnv(), com::martiansoftware::nailgun::NGContext::setExitStream(), com::martiansoftware::nailgun::NGContext::setInetAddress(), com::martiansoftware::nailgun::NGContext::setNGServer(), com::martiansoftware::nailgun::NGContext::setPort(), com::martiansoftware::nailgun::NGContext::setWorkingDirectory(), and updateThreadName().

                        {
      
            updateThreadName(null);
            
            Socket socket = nextSocket();
            while (socket != null) {
                  try {
                        // buffer for reading headers
                        byte[] lbuf = new byte[5];
                        java.io.DataInputStream sockin = new java.io.DataInputStream(socket.getInputStream());
                        java.io.OutputStream sockout = socket.getOutputStream();
      
                        // client info - command line arguments and environment
                        List remoteArgs = new java.util.ArrayList();
                        Properties remoteEnv = new Properties();
                        
                        String cwd = null;                  // working directory
                        String command = null;        // alias or class name
                        
                        // read everything from the client up to and including the command
                        while (command == null) {
                              sockin.readFully(lbuf);
                              long bytesToRead = LongUtils.fromArray(lbuf, 0);
                              char chunkType = (char) lbuf[4];
                              
                              byte[] b = new byte[(int) bytesToRead];
                              sockin.readFully(b);
                              String line = new String(b, "US-ASCII");
      
                              switch(chunkType) {
                                                      
                                    case NGConstants.CHUNKTYPE_ARGUMENT:
                                                      //    command line argument
                                                      remoteArgs.add(line);
                                                      break;

                                    case NGConstants.CHUNKTYPE_ENVIRONMENT:
                                                      //    parse environment into property
                                                      int equalsIndex = line.indexOf('=');
                                                      if (equalsIndex > 0) {
                                                            remoteEnv.setProperty(
                                                                        line.substring(0, equalsIndex),
                                                                        line.substring(equalsIndex + 1));
                                                      }
                                                      String key = line.substring(0, equalsIndex);
                                                      break;
                                                      
                                    case NGConstants.CHUNKTYPE_COMMAND:
                                                      //    command (alias or classname)
                                                      command = line;
                                                      break;
                                                      
                                    case NGConstants.CHUNKTYPE_WORKINGDIRECTORY:
                                                      //    client working directory
                                                      cwd = line;
                                                      break;
                                                      
                                    default:    // freakout?
                              }
                        }
      
                        updateThreadName(socket.getInetAddress().getHostAddress() + ": " + command);
                        
                        // can't create NGInputStream until we've received a command, because at
                        // that point the stream from the client will only include stdin and stdin-eof
                        // chunks
                        InputStream in = new NGInputStream(sockin);
                        PrintStream out = new PrintStream(new NGOutputStream(sockout, NGConstants.CHUNKTYPE_STDOUT));
                        PrintStream err = new PrintStream(new NGOutputStream(sockout, NGConstants.CHUNKTYPE_STDERR));
                        PrintStream exit = new PrintStream(new NGOutputStream(sockout, NGConstants.CHUNKTYPE_EXIT));
      
                        // ThreadLocal streams for System.in/out/err redirection
                        ((ThreadLocalInputStream) System.in).init(in);
                        ((ThreadLocalPrintStream) System.out).init(out);
                        ((ThreadLocalPrintStream) System.err).init(err);
                        
                        try {
                              Alias alias = server.getAliasManager().getAlias(command);
                              Class cmdclass = null;
                              if (alias != null) {
                                    cmdclass = alias.getAliasedClass();
                              } else if (server.allowsNailsByClassName()) {
                                    cmdclass = Class.forName(command);
                              } else {
                                    cmdclass = server.getDefaultNailClass();
                              }

                              Object[] methodArgs = new Object[1];
                              Method mainMethod = null; // will be either main(String[]) or nailMain(NGContext)
                              String[] cmdlineArgs = (String[]) remoteArgs.toArray(new String[remoteArgs.size()]);
                              
                              try {
                                    mainMethod = cmdclass.getMethod("nailMain", nailMainSignature);
                                    NGContext context = new NGContext();
                                    context.setArgs(cmdlineArgs);
                                    context.in = in;
                                    context.out = out;
                                    context.err = err;
                                    context.setCommand(command);
                                    context.setExitStream(exit);
                                    context.setNGServer(server);
                                    context.setEnv(remoteEnv);
                                    context.setInetAddress(socket.getInetAddress());
                                    context.setPort(socket.getPort());
                                    context.setWorkingDirectory(cwd);
                                    methodArgs[0] = context;
                              } catch (NoSuchMethodException toDiscard) {
                                    // that's ok - we'll just try main(String[]) next.
                              }
                              
                              if (mainMethod == null) {
                                    mainMethod = cmdclass.getMethod("main", mainSignature);
                                    methodArgs[0] = cmdlineArgs;
                              }
                              
                              if (mainMethod != null) {
                                    server.nailStarted(cmdclass);
                        NGSecurityManager.setExit(exit);

                                    try {
                                          mainMethod.invoke(null, methodArgs);
                                    } catch (InvocationTargetException ite) {
                                          throw(ite.getCause());
                                    } catch (Throwable t) {
                                          throw(t);
                                    } finally {
                                          server.nailFinished(cmdclass);
                                    }
                                    exit.println(0);
                              }

                        } catch (ExitException exitEx) {
                    exit.println(exitEx.getStatus());
                    server.out.println(Thread.currentThread().getName() + " exited with status " + exitEx.getStatus());
                        } catch (Throwable t) {
                              t.printStackTrace();
                              exit.println(NGConstants.EXIT_EXCEPTION); // remote exception constant
                        }
                        
                        socket.close();
      
                  } catch (Throwable t) {
                        t.printStackTrace();
                  }

                  ((ThreadLocalInputStream) System.in).init(null);
                  ((ThreadLocalPrintStream) System.out).init(null);
                  ((ThreadLocalPrintStream) System.err).init(null);
                  
                  updateThreadName(null);
                  sessionPool.give(this);
                  socket = nextSocket();
            }

//          server.out.println("Shutdown NGSession " + instanceNumber);
      }


Generated by  Doxygen 1.6.0   Back to index