mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
22.28.2012 b362d9da285a8dc1b86db29b945feb3bc245b03b
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
@@ -18,50 +18,167 @@
import java.util.Collection;
import org.forgerock.opendj.ldap.Connection;
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.SearchResultHandler;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
import org.forgerock.resource.provider.Context;
/**
 *
 */
public final class EntryContainer {
    // FIXME: make this configurable, also allow use of DN.
    private static final String UUID_ATTRIBUTE = "entryUUID";
    /**
     * @param entry
     * @return
     */
    public String getIDFromEntry(final SearchResultEntry entry) {
        // TODO Auto-generated method stub
        return null;
    // FIXME: make this configurable.
    private static final String ETAG_ATTRIBUTE = "etag";
    private final ConnectionFactory factory;
    private final DN baseDN;
    private abstract class AbstractRequestCompletionHandler<R, H extends ResultHandler<? super R>>
            implements ResultHandler<R> {
        final H resultHandler;
        final Connection connection;
        AbstractRequestCompletionHandler(final Connection connection, final H resultHandler) {
            this.connection = connection;
            this.resultHandler = resultHandler;
        }
        @Override
        public final void handleErrorResult(final ErrorResultException error) {
            connection.close();
            resultHandler.handleErrorResult(error);
        }
        @Override
        public final void handleResult(final R result) {
            connection.close();
            resultHandler.handleResult(result);
        }
    }
    /**
     * @param context
     * @param handler
     */
    private abstract class ConnectionCompletionHandler<R> implements ResultHandler<Connection> {
        private final ResultHandler<? super R> resultHandler;
        ConnectionCompletionHandler(final ResultHandler<? super R> resultHandler) {
            this.resultHandler = resultHandler;
        }
        @Override
        public final void handleErrorResult(final ErrorResultException error) {
            resultHandler.handleErrorResult(error);
        }
        @Override
        public abstract void handleResult(Connection connection);
    }
    private final class RequestCompletionHandler<R> extends
            AbstractRequestCompletionHandler<R, ResultHandler<? super R>> {
        RequestCompletionHandler(final Connection connection,
                final ResultHandler<? super R> resultHandler) {
            super(connection, resultHandler);
        }
    }
    private final class SearchRequestCompletionHandler extends
            AbstractRequestCompletionHandler<Result, SearchResultHandler> implements
            SearchResultHandler {
        SearchRequestCompletionHandler(final Connection connection,
                final SearchResultHandler resultHandler) {
            super(connection, resultHandler);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public final boolean handleEntry(final SearchResultEntry entry) {
            return resultHandler.handleEntry(entry);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public final boolean handleReference(final SearchResultReference reference) {
            return resultHandler.handleReference(reference);
        }
    }
    public EntryContainer(DN baseDN, ConnectionFactory factory) {
        this.baseDN = baseDN;
        this.factory = factory;
    }
    public void listEntries(final Context context, final SearchResultHandler handler) {
        // TODO Auto-generated method stub
        final ConnectionCompletionHandler<Result> outerHandler =
                new ConnectionCompletionHandler<Result>(handler) {
                    @Override
                    public void handleResult(final Connection connection) {
                        final SearchRequestCompletionHandler innerHandler =
                                new SearchRequestCompletionHandler(connection, handler);
                        SearchRequest request =
                                Requests.newSearchRequest(baseDN, SearchScope.SINGLE_LEVEL, Filter
                                        .objectClassPresent(), UUID_ATTRIBUTE, ETAG_ATTRIBUTE);
                        connection.searchAsync(request, null, innerHandler);
                    }
                };
        factory.getConnectionAsync(outerHandler);
    }
    /**
     * Reads the entry having the specified resource ID.
     *
     * @param c
     *            The request context.
     * @param id
     *            The resource ID.
     * @param attributes
     *            The set of LDAP attributes to be read.
     * @param h
     *            The result handler.
     */
    public void readEntry(final Context c, final String id, final Collection<String> attributes,
            final ResultHandler<SearchResultEntry> h) {
        // TODO Auto-generated method stub
            final ResultHandler<SearchResultEntry> handler) {
        final ConnectionCompletionHandler<SearchResultEntry> outerHandler =
                new ConnectionCompletionHandler<SearchResultEntry>(handler) {
                    @Override
                    public void handleResult(final Connection connection) {
                        final RequestCompletionHandler<SearchResultEntry> innerHandler =
                                new RequestCompletionHandler<SearchResultEntry>(connection, handler);
                        // FIXME: who is responsible for adding the UUID and
                        // etag attributes to this search?
                        String[] tmp = attributes.toArray(new String[attributes.size() + 2]);
                        tmp[tmp.length - 2] = UUID_ATTRIBUTE;
                        tmp[tmp.length - 1] = ETAG_ATTRIBUTE;
                        SearchRequest request =
                                Requests.newSearchRequest(baseDN, SearchScope.SINGLE_LEVEL, Filter
                                        .equality(UUID_ATTRIBUTE, id), tmp);
                        connection.searchSingleEntryAsync(request, innerHandler);
                    }
                };
        factory.getConnectionAsync(outerHandler);
    }
    public String getIDFromEntry(final Entry entry) {
        return entry.parseAttribute(UUID_ATTRIBUTE).asString();
    }
    public String getEtagFromEntry(final Entry entry) {
        return entry.parseAttribute(ETAG_ATTRIBUTE).asString();
    }
}