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 2012-2014 ForgeRock AS
025 */
026
027package org.forgerock.opendj.ldap;
028
029import org.forgerock.opendj.ldap.requests.AbandonRequest;
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.spi.LdapPromises.*;
044
045/**
046 * An abstract connection whose asynchronous methods are implemented in terms of
047 * synchronous methods.
048 * <p>
049 * <b>NOTE:</b> this implementation does not support intermediate response
050 * handlers except for extended operations, because they are not supported by
051 * the equivalent synchronous methods.
052 */
053public abstract class AbstractSynchronousConnection extends AbstractConnection {
054
055    /**
056     * Creates a new abstract synchronous connection.
057     */
058    protected AbstractSynchronousConnection() {
059        // No implementation required.
060    }
061
062    /**
063     * Abandon operations are not supported because operations are performed
064     * synchronously and the ID of the request to be abandoned cannot be
065     * determined. Thread interruption must be used in order to cancel a blocked
066     * request.
067     *
068     * @param request
069     *            {@inheritDoc}
070     * @return {@inheritDoc}
071     * @throws UnsupportedOperationException
072     *             Always thrown: abandon requests are not supported for
073     *             synchronous connections.
074     */
075    @Override
076    public LdapPromise<Void> abandonAsync(final AbandonRequest request) {
077        throw new UnsupportedOperationException("Abandon requests are not supported for synchronous connections");
078    }
079
080    @Override
081    public LdapPromise<Result> addAsync(final AddRequest request,
082            final IntermediateResponseHandler intermediateResponseHandler) {
083        try {
084            return thenOnResult(add(request));
085        } catch (final LdapException e) {
086            return onException(e);
087        }
088    }
089
090    @Override
091    public LdapPromise<BindResult> bindAsync(final BindRequest request,
092            final IntermediateResponseHandler intermediateResponseHandler) {
093        try {
094            return thenOnResult(bind(request));
095        } catch (final LdapException e) {
096            return onException(e);
097        }
098    }
099
100    @Override
101    public LdapPromise<CompareResult> compareAsync(final CompareRequest request,
102            final IntermediateResponseHandler intermediateResponseHandler) {
103        try {
104            return thenOnResult(compare(request));
105        } catch (final LdapException e) {
106            return onException(e);
107        }
108    }
109
110    @Override
111    public LdapPromise<Result> deleteAsync(final DeleteRequest request,
112            final IntermediateResponseHandler intermediateResponseHandler) {
113        try {
114            return thenOnResult(delete(request));
115        } catch (final LdapException e) {
116            return onException(e);
117        }
118    }
119
120    @Override
121    public <R extends ExtendedResult> LdapPromise<R> extendedRequestAsync(final ExtendedRequest<R> request,
122            final IntermediateResponseHandler intermediateResponseHandler) {
123        try {
124            return thenOnResult(extendedRequest(request, intermediateResponseHandler));
125        } catch (final LdapException e) {
126            return onException(e);
127        }
128    }
129
130    @Override
131    public LdapPromise<Result> modifyAsync(final ModifyRequest request,
132            final IntermediateResponseHandler intermediateResponseHandler) {
133        try {
134            return thenOnResult(modify(request));
135        } catch (final LdapException e) {
136            return onException(e);
137        }
138    }
139
140    @Override
141    public LdapPromise<Result> modifyDNAsync(final ModifyDNRequest request,
142            final IntermediateResponseHandler intermediateResponseHandler) {
143        try {
144            return thenOnResult(modifyDN(request));
145        } catch (final LdapException e) {
146            return onException(e);
147        }
148    }
149
150    @Override
151    public LdapPromise<Result> searchAsync(final SearchRequest request,
152            final IntermediateResponseHandler intermediateResponseHandler, final SearchResultHandler entryHandler) {
153        try {
154            return thenOnResult(search(request, entryHandler));
155        } catch (final LdapException e) {
156            return onException(e);
157        }
158    }
159
160    private <R extends Result> LdapPromise<R> onException(final LdapException e) {
161        return newFailedLdapPromise(e);
162    }
163
164    private <R extends Result> LdapPromise<R> thenOnResult(final R result) {
165        return newSuccessfulLdapPromise(result);
166    }
167
168}