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;
029
030import org.forgerock.opendj.ldap.requests.AddRequest;
031import org.forgerock.opendj.ldap.requests.BindRequest;
032import org.forgerock.opendj.ldap.requests.CompareRequest;
033import org.forgerock.opendj.ldap.requests.DeleteRequest;
034import org.forgerock.opendj.ldap.requests.ExtendedRequest;
035import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
036import org.forgerock.opendj.ldap.requests.ModifyRequest;
037import org.forgerock.opendj.ldap.requests.SearchRequest;
038import org.forgerock.opendj.ldap.responses.BindResult;
039import org.forgerock.opendj.ldap.responses.CompareResult;
040import org.forgerock.opendj.ldap.responses.ExtendedResult;
041import org.forgerock.opendj.ldap.responses.Result;
042
043import static org.forgerock.opendj.ldap.LdapException.*;
044
045/**
046 * An abstract connection whose synchronous methods are implemented in terms of
047 * asynchronous methods.
048 */
049public abstract class AbstractAsynchronousConnection extends AbstractConnection {
050
051    /**
052     * Creates a new abstract asynchronous connection.
053     */
054    protected AbstractAsynchronousConnection() {
055        // No implementation required.
056    }
057
058    /** {@inheritDoc} */
059    @Override
060    public Result add(final AddRequest request) throws LdapException {
061        return blockingGetOrThrow(addAsync(request));
062    }
063
064    /** {@inheritDoc} */
065    @Override
066    public BindResult bind(final BindRequest request) throws LdapException {
067        return blockingGetOrThrow(bindAsync(request));
068    }
069
070    /** {@inheritDoc} */
071    @Override
072    public CompareResult compare(final CompareRequest request) throws LdapException {
073        return blockingGetOrThrow(compareAsync(request));
074    }
075
076    /** {@inheritDoc} */
077    @Override
078    public Result delete(final DeleteRequest request) throws LdapException {
079        return blockingGetOrThrow(deleteAsync(request));
080    }
081
082    /** {@inheritDoc} */
083    @Override
084    public <R extends ExtendedResult> R extendedRequest(final ExtendedRequest<R> request,
085            final IntermediateResponseHandler handler) throws LdapException {
086        return blockingGetOrThrow(extendedRequestAsync(request, handler));
087    }
088
089    /** {@inheritDoc} */
090    @Override
091    public Result modify(final ModifyRequest request) throws LdapException {
092        return blockingGetOrThrow(modifyAsync(request));
093    }
094
095    /** {@inheritDoc} */
096    @Override
097    public Result modifyDN(final ModifyDNRequest request) throws LdapException {
098        return blockingGetOrThrow(modifyDNAsync(request));
099    }
100
101    /** {@inheritDoc} */
102    @Override
103    public Result search(final SearchRequest request, final SearchResultHandler handler) throws LdapException {
104        return blockingGetOrThrow(searchAsync(request, handler));
105    }
106
107    private <T extends Result> T blockingGetOrThrow(LdapPromise<T> promise) throws LdapException {
108        try {
109            return promise.getOrThrow();
110        } catch (InterruptedException e) {
111            throw interrupted(e);
112        }
113    }
114
115    /** Handle thread interruption. */
116    private LdapException interrupted(InterruptedException e) {
117        return newLdapException(ResultCode.CLIENT_SIDE_USER_CANCELLED, e);
118    }
119}