001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2012-2016 ForgeRock AS.
015 */
016package org.forgerock.opendj.ldap;
017
018import org.forgerock.opendj.ldap.requests.AbandonRequest;
019import org.forgerock.opendj.ldap.requests.AddRequest;
020import org.forgerock.opendj.ldap.requests.BindRequest;
021import org.forgerock.opendj.ldap.requests.CompareRequest;
022import org.forgerock.opendj.ldap.requests.DeleteRequest;
023import org.forgerock.opendj.ldap.requests.ExtendedRequest;
024import org.forgerock.opendj.ldap.requests.ModifyDNRequest;
025import org.forgerock.opendj.ldap.requests.ModifyRequest;
026import org.forgerock.opendj.ldap.requests.SearchRequest;
027import org.forgerock.opendj.ldap.responses.BindResult;
028import org.forgerock.opendj.ldap.responses.CompareResult;
029import org.forgerock.opendj.ldap.responses.ExtendedResult;
030import org.forgerock.opendj.ldap.responses.Result;
031
032import static org.forgerock.opendj.ldap.spi.LdapPromises.*;
033
034/**
035 * An abstract connection whose asynchronous methods are implemented in terms of
036 * synchronous methods.
037 * <p>
038 * <b>NOTE:</b> this implementation does not support intermediate response
039 * handlers except for extended operations, because they are not supported by
040 * the equivalent synchronous methods.
041 */
042public abstract class AbstractSynchronousConnection extends AbstractConnection {
043    /** Creates a new abstract synchronous connection. */
044    protected AbstractSynchronousConnection() {
045        // No implementation required.
046    }
047
048    /**
049     * Abandon operations are not supported because operations are performed
050     * synchronously and the ID of the request to be abandoned cannot be
051     * determined. Thread interruption must be used in order to cancel a blocked
052     * request.
053     *
054     * @param request
055     *            {@inheritDoc}
056     * @return {@inheritDoc}
057     * @throws UnsupportedOperationException
058     *             Always thrown: abandon requests are not supported for
059     *             synchronous connections.
060     */
061    @Override
062    public LdapPromise<Void> abandonAsync(final AbandonRequest request) {
063        throw new UnsupportedOperationException("Abandon requests are not supported for synchronous connections");
064    }
065
066    @Override
067    public LdapPromise<Result> addAsync(final AddRequest request,
068            final IntermediateResponseHandler intermediateResponseHandler) {
069        try {
070            return thenOnResult(add(request));
071        } catch (final LdapException e) {
072            return onException(e);
073        }
074    }
075
076    @Override
077    public LdapPromise<BindResult> bindAsync(final BindRequest request,
078            final IntermediateResponseHandler intermediateResponseHandler) {
079        try {
080            return thenOnResult(bind(request));
081        } catch (final LdapException e) {
082            return onException(e);
083        }
084    }
085
086    @Override
087    public LdapPromise<CompareResult> compareAsync(final CompareRequest request,
088            final IntermediateResponseHandler intermediateResponseHandler) {
089        try {
090            return thenOnResult(compare(request));
091        } catch (final LdapException e) {
092            return onException(e);
093        }
094    }
095
096    @Override
097    public LdapPromise<Result> deleteAsync(final DeleteRequest request,
098            final IntermediateResponseHandler intermediateResponseHandler) {
099        try {
100            return thenOnResult(delete(request));
101        } catch (final LdapException e) {
102            return onException(e);
103        }
104    }
105
106    @Override
107    public <R extends ExtendedResult> LdapPromise<R> extendedRequestAsync(final ExtendedRequest<R> request,
108            final IntermediateResponseHandler intermediateResponseHandler) {
109        try {
110            return thenOnResult(extendedRequest(request, intermediateResponseHandler));
111        } catch (final LdapException e) {
112            return onException(e);
113        }
114    }
115
116    @Override
117    public LdapPromise<Result> modifyAsync(final ModifyRequest request,
118            final IntermediateResponseHandler intermediateResponseHandler) {
119        try {
120            return thenOnResult(modify(request));
121        } catch (final LdapException e) {
122            return onException(e);
123        }
124    }
125
126    @Override
127    public LdapPromise<Result> modifyDNAsync(final ModifyDNRequest request,
128            final IntermediateResponseHandler intermediateResponseHandler) {
129        try {
130            return thenOnResult(modifyDN(request));
131        } catch (final LdapException e) {
132            return onException(e);
133        }
134    }
135
136    @Override
137    public LdapPromise<Result> searchAsync(final SearchRequest request,
138            final IntermediateResponseHandler intermediateResponseHandler, final SearchResultHandler entryHandler) {
139        try {
140            return thenOnResult(search(request, entryHandler));
141        } catch (final LdapException e) {
142            return onException(e);
143        }
144    }
145
146    private <R extends Result> LdapPromise<R> onException(final LdapException e) {
147        return newFailedLdapPromise(e);
148    }
149
150    private <R extends Result> LdapPromise<R> thenOnResult(final R result) {
151        return newSuccessfulLdapPromise(result);
152    }
153}