/** {@inheritDoc} */ @Override public <R extends ExtendedResult> void handleExtendedRequest( final Integer messageID, final ExtendedRequest<R> request, final IntermediateResponseHandler intermediateResponseHandler, final LdapResultHandler<R> resultHandler) { if (request.getOID().equals(CancelExtendedRequest.OID)) { // Decode the request as a cancel request. CancelExtendedRequest cancelRequest; try { cancelRequest = CancelExtendedRequest.DECODER.decodeExtendedRequest(request, new DecodeOptions()); } catch (final DecodeException e) { // Couldn't decode a cancel request. resultHandler.handleException( newLdapException(ResultCode.PROTOCOL_ERROR, e.getLocalizedMessage())); return; } /* * Register the request in the pending requests table. Even * though this request cannot be cancelled, it is important to * do this in order to monitor the number of pending operations. */ final RequestContextImpl<R, LdapResultHandler<R>> requestContext = new RequestContextImpl<>(this, resultHandler, messageID, false); if (addPendingRequest(requestContext)) { // Find and cancel the request. final RequestContextImpl<?, ?> cancelledRequest = getPendingRequest(cancelRequest.getRequestID()); if (cancelledRequest != null) { final LocalizableMessage cancelReason = INFO_CANCELED_BY_CANCEL_REQUEST.get(messageID); cancelledRequest.cancel(cancelReason, request, requestContext, true); } else { /* * Couldn't find the request. Invoke on context in order * to remove pending request. */ requestContext.handleException(newLdapException(ResultCode.NO_SUCH_OPERATION)); } } } else { // StartTLS requests cannot be cancelled. boolean isCancelSupported = !request.getOID().equals(StartTLSExtendedRequest.OID); final RequestContextImpl<R, LdapResultHandler<R>> requestContext = new RequestContextImpl<>(this, resultHandler, messageID, isCancelSupported); if (addPendingRequest(requestContext)) { requestHandler.handleExtendedRequest( requestContext, request, intermediateResponseHandler, requestContext); } } }
private void handleTooLate() { final R cancelResult = request.getResultDecoder().newExtendedErrorResult(ResultCode.TOO_LATE, "", ""); resultHandler.handleException(newLdapException(cancelResult)); }
private <R extends ExtendedResult> void cancel( final LocalizableMessage reason, final ExtendedRequest<R> cancelRequest, final LdapResultHandler<R> cancelResultHandler, final boolean sendResult) { Reject.ifNull(reason); if (!isCancelSupported) { if (cancelResultHandler != null) { final Result result = Responses.newGenericExtendedResult(ResultCode.CANNOT_CANCEL); cancelResultHandler.handleException(newLdapException(result)); } return; } List<CancelRequestListener> tmpListeners = null; boolean invokeResultHandler = false; boolean resultHandlerIsSuccess = false; synchronized (stateLock) { switch (state) { case PENDING: /* Switch to CANCEL_REQUESTED state. */ cancelRequestReason = reason; if (cancelResultHandler != null) { cancelResultHandlers = new LinkedList<>(); cancelResultHandlers.add( new ExtendedResultHandlerHolder<R>(cancelRequest, cancelResultHandler)); } tmpListeners = cancelRequestListeners; cancelRequestListeners = null; state = RequestState.CANCEL_REQUESTED; this.sendResult &= sendResult; break; case CANCEL_REQUESTED: /* * Cancel already request so listeners already invoked. */ if (cancelResultHandler != null) { if (cancelResultHandlers == null) { cancelResultHandlers = new LinkedList<>(); } cancelResultHandlers.add( new ExtendedResultHandlerHolder<R>(cancelRequest, cancelResultHandler)); } break; case TOO_LATE: case RESULT_SENT: /* * Cannot cancel, so invoke result handler immediately * outside of lock. */ if (cancelResultHandler != null) { invokeResultHandler = true; resultHandlerIsSuccess = false; } break; case CANCELLED: /* * Multiple cancellation attempts. Clients should not do * this, but the cancel will effectively succeed * immediately, so invoke result handler immediately outside * of lock. */ if (cancelResultHandler != null) { invokeResultHandler = true; resultHandlerIsSuccess = true; } break; } } /* Invoke listeners outside of lock. */ if (tmpListeners != null) { for (final CancelRequestListener listener : tmpListeners) { listener.handleCancelRequest(reason); } } if (invokeResultHandler) { if (resultHandlerIsSuccess) { final R result = cancelRequest.getResultDecoder().newExtendedErrorResult(ResultCode.SUCCESS, "", ""); cancelResultHandler.handleResult(result); } else { final Result result = Responses.newGenericExtendedResult(ResultCode.TOO_LATE); cancelResultHandler.handleException(newLdapException(result)); } } }