001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2009-2010 Sun Microsystems, Inc.
025 *      Portions copyright 2011-2014 ForgeRock AS.
026 */
027
028package org.forgerock.opendj.ldap.spi;
029
030import org.forgerock.opendj.ldap.Connection;
031import org.forgerock.opendj.ldap.DecodeException;
032import org.forgerock.opendj.ldap.DecodeOptions;
033import org.forgerock.opendj.ldap.IntermediateResponseHandler;
034import org.forgerock.opendj.ldap.LdapException;
035import org.forgerock.opendj.ldap.ResultCode;
036import org.forgerock.opendj.ldap.requests.ExtendedRequest;
037import org.forgerock.opendj.ldap.requests.Requests;
038import org.forgerock.opendj.ldap.requests.StartTLSExtendedRequest;
039import org.forgerock.opendj.ldap.responses.ExtendedResult;
040import org.forgerock.util.promise.PromiseImpl;
041
042import static org.forgerock.opendj.ldap.LdapException.*;
043
044/**
045 * Extended result promise implementation.
046 *
047 * @param <S>
048 *            The type of result returned by this promise.
049 */
050public final class ExtendedResultLdapPromiseImpl<S extends ExtendedResult> extends
051        ResultLdapPromiseImpl<ExtendedRequest<S>, S> {
052    ExtendedResultLdapPromiseImpl(final int requestID, final ExtendedRequest<S> request,
053            final IntermediateResponseHandler intermediateResponseHandler,
054            final Connection connection) {
055        super(new PromiseImpl<S, LdapException>() {
056            @Override
057            protected LdapException tryCancel(boolean mayInterruptIfRunning) {
058                if (!StartTLSExtendedRequest.OID.equals(request.getOID())) {
059                    connection.abandonAsync(Requests.newAbandonRequest(requestID));
060                    return newLdapException(ResultCode.CLIENT_SIDE_USER_CANCELLED);
061                }
062
063                /*
064                 * No other operations can be performed while a startTLS is active.
065                 * Therefore it is not possible to cancel startTLS requests,
066                 * since doing so will leave the connection in a state which
067                 * prevents other operations from being performed.
068                 */
069                return null;
070            }
071        }, requestID, request, intermediateResponseHandler, connection);
072    }
073
074    @Override
075    public boolean isBindOrStartTLS() {
076        return StartTLSExtendedRequest.OID.equals(getRequest().getOID());
077    }
078
079    /**
080     * Decode an extended result.
081     *
082     * @param result
083     *            Extended result to decode.
084     * @param options
085     *            Decoding options.
086     * @return The decoded extended result.
087     * @throws DecodeException
088     *             If a problem occurs during decoding.
089     */
090    public S decodeResult(final ExtendedResult result, final DecodeOptions options) throws DecodeException {
091        return getRequest().getResultDecoder().decodeExtendedResult(result, options);
092    }
093
094    @Override
095    S newErrorResult(final ResultCode resultCode, final String diagnosticMessage,
096            final Throwable cause) {
097        return getRequest().getResultDecoder().newExtendedErrorResult(resultCode, "", diagnosticMessage);
098    }
099}