tokenrequesthandler.java

来自「java版ace,java程序员值得一看」· Java 代码 · 共 181 行

JAVA
181
字号
package JACE.netsvcs.Token;

import java.io.*;
import java.net.SocketException;
import java.util.*;
import JACE.Connection.*;
import JACE.OS.*;
import JACE.netsvcs.Handler;

/**
 * Created by TokenAcceptor to handle token requests.  Delegates to
 * the appropriate LockHandler.  This is fairly robust, and can handle
 * multiple clients and locks (meaning requests can come in to this
 * handle with varying client IDs and token names and still be processed
 * and released appropriately.)  Compatible with the C++ ACE token service.
 *
 *@author Everett Anderson
 */
class TokenRequestHandler extends Handler
{
  /** 
   * Default constructor.
   */
  public TokenRequestHandler() {
    this.clients_ = new Vector (10);
  }
  
  /** 
   * Creates a new TokenRequest instance.
   */
  public Object newRequest ()
  {
    return new TokenRequest ();
  }

  /** 
   * Sends an error message to a client with the TokenReply.EIO
   * errno before abandoning the connection.  This is used when an IO 
   * error occured while receiving the request.
   *
   *@param lastRequest request object to get the arg from
   */
  protected void sendAbortMessage (TokenRequest lastRequest)
  {
    TokenReply reply = new TokenReply (TokenReply.EIO,
				       lastRequest.arg ());
    try {
      reply.streamOutTo (this.peer ().dataOutputStream ());
    } catch (Exception e) {
      // Doesn't matter if there is an error here, we've abandoned
      // the connection.
    }
  }

  /** 
   * Safely shuts down this handler, making sure to release any locks
   * that were touched by clients from this TokenRequestHandler.
   * 
   *@return -1 on failure, 0 on success
   */
  public synchronized int close ()
  {
    // For every client X that has used this handler
    //    for every LockHandler that X has used
    //        release the lock until it fails because X isn't the owner
    //    remove the client entries
    // Call Handler.close ()
    if (!done ()) {
      
      TokenAcceptor parent = (TokenAcceptor) parent ();
      Enumeration clientEnum = clients_.elements ();

      while (clientEnum.hasMoreElements ()) {
	String clientID = (String)clientEnum.nextElement ();
	
	Enumeration handlers = parent.getClientLockHandlers (clientID);
	if (handlers == null)
	  continue;
	
	int num = 0;
	
	while (handlers.hasMoreElements ()) {
	  LockHandler handler = (LockHandler)handlers.nextElement ();
	  
	  handler.abandonLock (clientID);

	  num++;
	}
	
	parent.removeClient (clientID);
      }

      return super.close ();
    }

    return 0;
  }

  /**
   * Read in the given TokenRequest and delegates to the appropriate
   * LockHandler.
   *
   *@see JACE.netsvcs.Handler
   *@param requestObject TokenRequest object to use
   */
  public void processRequest (Object requestObject)
    throws SocketException, EOFException, IOException
  {
    TokenRequest request = (TokenRequest)requestObject;
    TokenAcceptor parent = (TokenAcceptor) parent ();

    try {
      request.streamInFrom (this.peer ().dataInputStream ());
      
      if (!request.tokenName ().equals (lastTokenName_)) {
	// Switched tokens:
	//
	// Either find a handler that's already been made (which would
	// mean this token has been accessed before), or create a new
	// one with a new token
	handler_ = parent.getLockHandler(request.tokenName(),
					 request.tokenType());
	
	if (handler_ == null) {
	  // The client asked for an operation on a type of token
	  // that we don't know about.
	  ACE.ERROR ("Unknown lock type: " + request.tokenType ());
	  TokenReply error = new TokenReply (TokenReply.EINVAL,
					     request.arg ());
	  error.streamOutTo(this.peer ().dataOutputStream ());
	  return;
	}
	
	// Add this LockHandler to the list of those accessed by
	// this clientID
	parent.addClientLockHandler (request.clientID (),
				     handler_);
      }
      
      if (!request.clientID ().equals (lastClientID_)) {
	// Switched clients
	
	if (!clients_.contains (request.clientID ())) 
	  clients_.addElement (request.clientID ());
	
	parent.addClientLockHandler (request.clientID (),
				     handler_);
      }
      
      lastClientID_ = request.clientID ();
      lastTokenName_ = request.tokenName ();
      
      TokenReply reply = handler_.handleRequest(this, request);

      reply.streamOutTo(this.peer ().dataOutputStream ());
      
    } catch (NullPointerException e) {
      sendAbortMessage (request);
      throw e;
    } catch (IOException e) {
      sendAbortMessage (request);
      throw e;
    }
  }

  // List of clientIDs that have been processed by this instance
  // of TokenRequestHandler.  This is useful when abandoning the
  // locks of any clients that have been using this socket.
  private Vector clients_;

  // Name of the last token accessed
  private String lastTokenName_ = null;

  // Last client ID which accessed a token from this handler
  private String lastClientID_ = null;

  // Current LockHandler
  private LockHandler handler_ = null;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?