From 16781afd94b0ad1014b8394f524ffcc5bd89255b Mon Sep 17 00:00:00 2001
From: jarnou <jarnou@localhost>
Date: Tue, 17 Jul 2007 13:35:12 +0000
Subject: [PATCH] This fix is the refactoring of the extended operation (issue 1189).

---
 opends/src/server/org/opends/server/core/ExtendedOperation.java |  697 ++--------------------------------------------------------
 1 files changed, 25 insertions(+), 672 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/ExtendedOperation.java b/opends/src/server/org/opends/server/core/ExtendedOperation.java
index a683fc1..c588942 100644
--- a/opends/src/server/org/opends/server/core/ExtendedOperation.java
+++ b/opends/src/server/org/opends/server/core/ExtendedOperation.java
@@ -26,137 +26,26 @@
  */
 package org.opends.server.core;
 
-
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.opends.server.api.ClientConnection;
-import org.opends.server.api.ExtendedOperationHandler;
-import org.opends.server.api.plugin.PostOperationPluginResult;
-import org.opends.server.api.plugin.PreOperationPluginResult;
-import org.opends.server.api.plugin.PreParsePluginResult;
 import org.opends.server.protocols.asn1.ASN1OctetString;
-import org.opends.server.types.AbstractOperation;
-import org.opends.server.types.CancelRequest;
-import org.opends.server.types.CancelResult;
-import org.opends.server.types.Control;
-import org.opends.server.types.DisconnectReason;
-import org.opends.server.types.DN;
-import org.opends.server.types.OperationType;
-import org.opends.server.types.ResultCode;
-import org.opends.server.types.operation.PostOperationExtendedOperation;
-import org.opends.server.types.operation.PostResponseExtendedOperation;
-import org.opends.server.types.operation.PreOperationExtendedOperation;
-import org.opends.server.types.operation.PreParseExtendedOperation;
-
-import static org.opends.server.core.CoreConstants.*;
-import static org.opends.server.loggers.AccessLogger.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-
-import org.opends.server.loggers.debug.DebugLogger;
-import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.DebugLogLevel;
-import static org.opends.server.messages.CoreMessages.*;
-import static org.opends.server.messages.MessageHandler.*;
-import static org.opends.server.util.ServerConstants.*;
+import org.opends.server.types.Operation;
 
 
 
 /**
- * This class defines an extended operation, which can perform virtually any
+ * This interface defines an extended operation, which can perform virtually any
  * kind of task.
  */
-public class ExtendedOperation
-       extends AbstractOperation
-       implements PreParseExtendedOperation, PreOperationExtendedOperation,
-                  PostOperationExtendedOperation, PostResponseExtendedOperation
+public interface ExtendedOperation
+       extends Operation
 {
   /**
-   * The tracer object for the debug logger.
-   */
-  private static final DebugTracer TRACER = DebugLogger.getTracer();
-
-  // The value for the request associated with this extended operation.
-  private ASN1OctetString requestValue;
-
-  // The value for the response associated with this extended operation.
-  private ASN1OctetString responseValue;
-
-  // Indicates whether a response has yet been sent for this operation.
-  private boolean responseSent;
-
-  // The cancel request that has been issued for this extended operation.
-  private CancelRequest cancelRequest;
-
-  // The set of response controls for this extended operation.
-  private List<Control> responseControls;
-
-  // The OID for the request associated with this extended operation.
-  private String requestOID;
-
-  // The OID for the response associated with this extended operation.
-  private String responseOID;
-
-
-
-  /**
-   * Creates a new extended operation with the provided information.
+   * Retrieves the OID for the request associated with this extended
+   * operation.
    *
-   * @param  clientConnection  The client connection with which this operation
-   *                           is associated.
-   * @param  operationID       The operation ID for this operation.
-   * @param  messageID         The message ID of the request with which this
-   *                           operation is associated.
-   * @param  requestControls   The set of controls included in the request.
-   * @param  requestOID        The OID for the request associated with this
-   *                           extended operation.
-   * @param  requestValue      The value for the request associated with this
-   *                           extended operation.
+   * @return  The OID for the request associated with this extended
+   *          operation.
    */
-  public ExtendedOperation(ClientConnection clientConnection, long operationID,
-                           int messageID, List<Control> requestControls,
-                           String requestOID, ASN1OctetString requestValue)
-  {
-    super(clientConnection, operationID, messageID, requestControls);
-
-
-    this.requestOID   = requestOID;
-    this.requestValue = requestValue;
-
-    responseOID      = null;
-    responseValue    = null;
-    responseControls = new ArrayList<Control>();
-    cancelRequest    = null;
-    responseSent     = false;
-  }
-
-
-
-  /**
-   * Retrieves the OID for the request associated with this extended operation.
-   *
-   * @return  The OID for the request associated with this extended operation.
-   */
-  public final String getRequestOID()
-  {
-    return requestOID;
-  }
-
-
-
-  /**
-   * Specifies the OID for the request associated with this extended operation.
-   * This should only be called by pre-parse plugins.
-   *
-   * @param  requestOID  The OID for the request associated with this extended
-   *                     operation.
-   */
-  public final void setRequestOID(String requestOID)
-  {
-    this.requestOID = requestOID;
-  }
+  public String getRequestOID();
 
 
 
@@ -164,498 +53,48 @@
    * Retrieves the value for the request associated with this extended
    * operation.
    *
-   * @return  The value for the request associated with this extended operation.
+   * @return  The value for the request associated with this extended
+   *          operation.
    */
-  public final ASN1OctetString getRequestValue()
-  {
-    return requestValue;
-  }
+  public ASN1OctetString getRequestValue();
 
 
 
   /**
-   * Specifies the value for the request associated with this extended
-   * operation.  This should only be called by pre-parse plugins.
-   *
-   * @param  requestValue  The value for the request associated with this
-   *                       extended operation.
-   */
-  public final void setRequestValue(ASN1OctetString requestValue)
-  {
-    this.requestValue = requestValue;
-  }
-
-
-
-  /**
-   * Retrieves the OID to include in the response to the client.  This should
-   * not be called by pre-parse or pre-operation plugins.
+   * Retrieves the OID to include in the response to the client.
    *
    * @return  The OID to include in the response to the client.
    */
-  public final String getResponseOID()
-  {
-    return responseOID;
-  }
+  public String getResponseOID();
 
 
 
   /**
-   * Specifies the OID to include in the response to the client.  This should
-   * not be called by post-response plugins.
+   * Specifies the OID to include in the response to the client.
    *
-   * @param  responseOID  The OID to include in the response to the client.
+   * @param  responseOID  The OID to include in the response to the
+   *                      client.
    */
-  public final void setResponseOID(String responseOID)
-  {
-    this.responseOID = responseOID;
-  }
+  public void setResponseOID(String responseOID);
 
 
 
   /**
-   * Retrieves the value to include in the response to the client.  This should
-   * not be called by pre-parse or pre-operation plugins.
+   * Retrieves the value to include in the response to the client.
    *
    * @return  The value to include in the response to the client.
    */
-  public final ASN1OctetString getResponseValue()
-  {
-    return responseValue;
-  }
+  public ASN1OctetString getResponseValue();
 
 
 
   /**
-   * Specifies the value to include in the response to the client.  This should
-   * not be called by post-response plugins.
+   * Specifies the value to include in the response to the client.
    *
-   * @param  responseValue  The value to include in the response to the client.
+   * @param  responseValue  The value to include in the response to
+   *                        the client.
    */
-  public final void setResponseValue(ASN1OctetString responseValue)
-  {
-    this.responseValue = responseValue;
-  }
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final OperationType getOperationType()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    return OperationType.EXTENDED;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void disconnectClient(DisconnectReason disconnectReason,
-                                     boolean sendNotification, String message,
-                                     int messageID)
-  {
-    // Before calling clientConnection.disconnect, we need to mark this
-    // operation as cancelled so that the attempt to cancel it later won't cause
-    // an unnecessary delay.
-    setCancelResult(CancelResult.CANCELED);
-
-    clientConnection.disconnect(disconnectReason, sendNotification, message,
-                                messageID);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final String[][] getRequestLogElements()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    return new String[][]
-    {
-      new String[] { LOG_ELEMENT_EXTENDED_REQUEST_OID, requestOID }
-    };
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final String[][] getResponseLogElements()
-  {
-    // Note that no debugging will be done in this method because it is a likely
-    // candidate for being called by the logging subsystem.
-
-    String resultCode = String.valueOf(getResultCode().getIntValue());
-
-    String errorMessage;
-    StringBuilder errorMessageBuffer = getErrorMessage();
-    if (errorMessageBuffer == null)
-    {
-      errorMessage = null;
-    }
-    else
-    {
-      errorMessage = errorMessageBuffer.toString();
-    }
-
-    String matchedDNStr;
-    DN matchedDN = getMatchedDN();
-    if (matchedDN == null)
-    {
-      matchedDNStr = null;
-    }
-    else
-    {
-      matchedDNStr = matchedDN.toString();
-    }
-
-    String referrals;
-    List<String> referralURLs = getReferralURLs();
-    if ((referralURLs == null) || referralURLs.isEmpty())
-    {
-      referrals = null;
-    }
-    else
-    {
-      StringBuilder buffer = new StringBuilder();
-      Iterator<String> iterator = referralURLs.iterator();
-      buffer.append(iterator.next());
-
-      while (iterator.hasNext())
-      {
-        buffer.append(", ");
-        buffer.append(iterator.next());
-      }
-
-      referrals = buffer.toString();
-    }
-
-    String processingTime =
-         String.valueOf(getProcessingTime());
-
-    return new String[][]
-    {
-      new String[] { LOG_ELEMENT_RESULT_CODE, resultCode },
-      new String[] { LOG_ELEMENT_ERROR_MESSAGE, errorMessage },
-      new String[] { LOG_ELEMENT_MATCHED_DN, matchedDNStr },
-      new String[] { LOG_ELEMENT_REFERRAL_URLS, referrals },
-      new String[] { LOG_ELEMENT_EXTENDED_RESPONSE_OID, responseOID },
-      new String[] { LOG_ELEMENT_PROCESSING_TIME, processingTime }
-    };
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final List<Control> getResponseControls()
-  {
-    return responseControls;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void addResponseControl(Control control)
-  {
-    responseControls.add(control);
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void removeResponseControl(Control control)
-  {
-    responseControls.remove(control);
-  }
-
-
-
-  /**
-   * Performs the work of actually processing this operation.  This
-   * should include all processing for the operation, including
-   * invoking plugins, logging messages, performing access control,
-   * managing synchronization, and any other work that might need to
-   * be done in the course of processing.
-   */
-  public final void run()
-  {
-    setResultCode(ResultCode.UNDEFINED);
-
-
-    // Get the plugin config manager that will be used for invoking plugins.
-    PluginConfigManager pluginConfigManager =
-         DirectoryServer.getPluginConfigManager();
-    boolean skipPostOperation = false;
-
-
-    // Start the processing timer.
-    setProcessingStartTime();
-
-
-    // Check for and handle a request to cancel this operation.
-    if (cancelRequest != null)
-    {
-      if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-             requestOID.equals(OID_START_TLS_REQUEST)))
-      {
-        indicateCancelled(cancelRequest);
-        setProcessingStopTime();
-        return;
-      }
-    }
-
-
-    // Create a labeled block of code that we can break out of if a problem is
-    // detected.
-extendedProcessing:
-    {
-      // Invoke the pre-parse extended plugins.
-      PreParsePluginResult preParseResult =
-           pluginConfigManager.invokePreParseExtendedPlugins(this);
-      if (preParseResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the request and
-        // result and return.
-        setResultCode(ResultCode.CANCELED);
-
-        int msgID = MSGID_CANCELED_BY_PREPARSE_DISCONNECT;
-        appendErrorMessage(getMessage(msgID));
-
-        setProcessingStopTime();
-
-        logExtendedRequest(this);
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
-        return;
-      }
-      else if (preParseResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        logExtendedRequest(this);
-        break extendedProcessing;
-      }
-      else if (preParseResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break extendedProcessing;
-      }
-
-
-      // Log the extended request message.
-      logExtendedRequest(this);
-
-
-      // Check for and handle a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-               requestOID.equals(OID_START_TLS_REQUEST)))
-        {
-          indicateCancelled(cancelRequest);
-          setProcessingStopTime();
-          pluginConfigManager.invokePostResponseExtendedPlugins(this);
-          return;
-        }
-      }
-
-
-      // Get the extended operation handler for the request OID.  If there is
-      // none, then fail.
-      ExtendedOperationHandler handler =
-           DirectoryServer.getExtendedOperationHandler(requestOID);
-      if (handler == null)
-      {
-        setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
-        appendErrorMessage(getMessage(MSGID_EXTENDED_NO_HANDLER,
-                                      String.valueOf(requestOID)));
-        break extendedProcessing;
-      }
-
-
-      // Look at the controls included in the request and ensure that all
-      // critical controls are supported by the handler.
-      List<Control> requestControls = getRequestControls();
-      if ((requestControls != null) && (! requestControls.isEmpty()))
-      {
-        for (Control c : requestControls)
-        {
-          if (! c.isCritical())
-          {
-            // The control isn't critical, so we don't care if it's supported
-            // or not.
-          }
-          else if (! handler.supportsControl(c.getOID()))
-          {
-            setResultCode(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
-
-            int msgID = MSGID_EXTENDED_UNSUPPORTED_CRITICAL_CONTROL;
-            appendErrorMessage(getMessage(msgID, String.valueOf(requestOID),
-                                          c.getOID()));
-
-            break extendedProcessing;
-          }
-        }
-      }
-
-
-      // Check to see if the client has permission to perform the
-      // extended operation.
-
-      // FIXME: for now assume that this will check all permission
-      // pertinent to the operation. This includes proxy authorization
-      // and any other controls specified.
-      if (AccessControlConfigManager.getInstance()
-          .getAccessControlHandler().isAllowed(this) == false) {
-        setResultCode(ResultCode.INSUFFICIENT_ACCESS_RIGHTS);
-
-        int msgID = MSGID_EXTENDED_AUTHZ_INSUFFICIENT_ACCESS_RIGHTS;
-        appendErrorMessage(getMessage(msgID, String.valueOf(requestOID)));
-
-        skipPostOperation = true;
-        break extendedProcessing;
-      }
-
-      // Invoke the pre-operation extended plugins.
-      PreOperationPluginResult preOpResult =
-           pluginConfigManager.invokePreOperationExtendedPlugins(this);
-      if (preOpResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the result
-        // and return.
-        setResultCode(ResultCode.CANCELED);
-
-        int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-        appendErrorMessage(getMessage(msgID));
-
-        setProcessingStopTime();
-
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
-        return;
-      }
-      else if (preOpResult.sendResponseImmediately())
-      {
-        skipPostOperation = true;
-        break extendedProcessing;
-      }
-      else if (preOpResult.skipCoreProcessing())
-      {
-        skipPostOperation = false;
-        break extendedProcessing;
-      }
-
-
-      // Check for and handle a request to cancel this operation.
-      if (cancelRequest != null)
-      {
-        if (! (requestOID.equals(OID_CANCEL_REQUEST) ||
-               requestOID.equals(OID_START_TLS_REQUEST)))
-        {
-          indicateCancelled(cancelRequest);
-          setProcessingStopTime();
-          pluginConfigManager.invokePostResponseExtendedPlugins(this);
-          return;
-        }
-      }
-
-
-      // Actually perform the processing for this operation.
-      handler.processExtendedOperation(this);
-    }
-
-
-    // Indicate that it is now too late to attempt to cancel the operation.
-    setCancelResult(CancelResult.TOO_LATE);
-
-
-    // Invoke the post-operation extended plugins.
-    if (! skipPostOperation)
-    {
-      PostOperationPluginResult postOpResult =
-           pluginConfigManager.invokePostOperationExtendedPlugins(this);
-      if (postOpResult.connectionTerminated())
-      {
-        // There's no point in continuing with anything.  Log the result and
-        // return.
-        setResultCode(ResultCode.CANCELED);
-
-        int msgID = MSGID_CANCELED_BY_PREOP_DISCONNECT;
-        appendErrorMessage(getMessage(msgID));
-
-        setProcessingStopTime();
-
-        logExtendedResponse(this);
-        pluginConfigManager.invokePostResponseExtendedPlugins(this);
-        return;
-      }
-    }
-
-
-    // Stop the processing timer.
-    setProcessingStopTime();
-
-
-    // Send the response to the client, if it has not already been sent.
-    if (! responseSent)
-    {
-      responseSent = true;
-      clientConnection.sendResponse(this);
-    }
-
-
-    // Log the extended response.
-    logExtendedResponse(this);
-
-
-
-    // Invoke the post-response extended plugins.
-    pluginConfigManager.invokePostResponseExtendedPlugins(this);
-  }
-
-
-
-  /**
-   * Sends an extended response to the client if none has already been sent.
-   * Note that extended operation handlers are strongly discouraged from using
-   * this method when it is not necessary because its use will prevent the
-   * response from being sent after post-operation plugin processing, which may
-   * impact the result that should be included.  Nevertheless, it may be needed
-   * in some special cases in which the response must be sent before the
-   * extended operation handler completes its processing (e.g., the StartTLS
-   * operation in which the response must be sent in the clear before actually
-   * enabling TLS protection).
-   */
-  public final void sendExtendedResponse()
-  {
-    if (! responseSent)
-    {
-      responseSent = true;
-      clientConnection.sendResponse(this);
-    }
-  }
-
-
+  public void setResponseValue(ASN1OctetString responseValue);
 
   /**
    * Indicates that the response for this extended operation has been sent from
@@ -663,92 +102,6 @@
    * extended operation for the case in which it needs to send a response in the
    * clear after TLS negotiation has already started on the connection.
    */
-  public final void setResponseSent()
-  {
-    this.responseSent = true;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelResult cancel(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-
-    CancelResult cancelResult = getCancelResult();
-    long stopWaitingTime = System.currentTimeMillis() + 5000;
-    while ((cancelResult == null) &&
-           (System.currentTimeMillis() < stopWaitingTime))
-    {
-      try
-      {
-        Thread.sleep(50);
-      }
-      catch (Exception e)
-      {
-        if (debugEnabled())
-        {
-          TRACER.debugCaught(DebugLogLevel.ERROR, e);
-        }
-      }
-
-      cancelResult = getCancelResult();
-    }
-
-    if (cancelResult == null)
-    {
-      // This can happen in some rare cases (e.g., if a client disconnects and
-      // there is still a lot of data to send to that client), and in this case
-      // we'll prevent the cancel thread from blocking for a long period of
-      // time.
-      cancelResult = CancelResult.CANNOT_CANCEL;
-    }
-
-    return cancelResult;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final CancelRequest getCancelRequest()
-  {
-    return cancelRequest;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public boolean setCancelRequest(CancelRequest cancelRequest)
-  {
-    this.cancelRequest = cancelRequest;
-    return true;
-  }
-
-
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override()
-  public final void toString(StringBuilder buffer)
-  {
-    buffer.append("ExtendedOperation(connID=");
-    buffer.append(clientConnection.getConnectionID());
-    buffer.append(", opID=");
-    buffer.append(operationID);
-    buffer.append(", oid=");
-    buffer.append(requestOID);
-    buffer.append(")");
-  }
-
+  public void setResponseSent();
 }
 

--
Gitblit v1.10.0