/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyrighted [year] [name of copyright owner]". * * Copyright 2012 ForgeRock AS. All rights reserved. */ package org.forgerock.opendj.rest2ldap; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.forgerock.json.fluent.JsonPointer; import org.forgerock.json.fluent.JsonValue; import org.forgerock.opendj.ldap.Entry; import org.forgerock.opendj.ldap.ErrorResultException; import org.forgerock.opendj.ldap.ResultHandler; import org.forgerock.opendj.ldap.SearchResultHandler; 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.exception.NotSupportedException; import org.forgerock.resource.exception.ResourceException; import org.forgerock.resource.provider.ActionRequest; import org.forgerock.resource.provider.ActionResultHandler; import org.forgerock.resource.provider.Context; import org.forgerock.resource.provider.CreateRequest; import org.forgerock.resource.provider.CreateResultHandler; import org.forgerock.resource.provider.DeleteRequest; import org.forgerock.resource.provider.DeleteResultHandler; import org.forgerock.resource.provider.PatchRequest; import org.forgerock.resource.provider.PatchResultHandler; import org.forgerock.resource.provider.QueryRequest; import org.forgerock.resource.provider.QueryResultHandler; import org.forgerock.resource.provider.ReadRequest; import org.forgerock.resource.provider.ReadResultHandler; import org.forgerock.resource.provider.Resource; import org.forgerock.resource.provider.UpdateRequest; import org.forgerock.resource.provider.UpdateResultHandler; /** * */ public class LDAPResource implements Resource { private Set allLDAPAttributes; private final EntryContainer container; private final List mappers; /** * Creates a new LDAP resource. * * @param container * The entry container which will be used to interact with the * LDAP server. * @param mappers * The list of attribute mappers. */ public LDAPResource(final EntryContainer container, final List mappers) { this.container = container; this.mappers = mappers; cacheAllLDAPAttributes(); } /** * {@inheritDoc} */ public void action(final ActionRequest request, final Context context, final ActionResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } /** * {@inheritDoc} */ public void create(final CreateRequest request, final Context context, final CreateResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } /** * {@inheritDoc} */ public void delete(final DeleteRequest request, final Context context, final DeleteResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } /** * {@inheritDoc} */ public void patch(final PatchRequest request, final Context context, final PatchResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } /** * {@inheritDoc} */ public void query(final QueryRequest request, final Context context, final QueryResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } /** * {@inheritDoc} */ public void read(final ReadRequest request, final Context context, final ReadResultHandler out) { final String id = request.getId(); if (id == null) { // List the entries. final SearchResultHandler handler = new SearchResultHandler() { private final List resourceIDs = new ArrayList(); public boolean handleEntry(final SearchResultEntry entry) { // TODO: should the resource or the container define the ID // mapping? resourceIDs.add(container.getIDFromEntry(entry)); return true; } public void handleErrorResult(final ErrorResultException error) { out.setFailure(adaptErrorResult(error)); } public boolean handleReference(final SearchResultReference reference) { // TODO: should this be classed as an error since rest2ldap // assumes entries are all colocated. return true; } public void handleResult(final Result result) { out.setResult(id, null, new JsonValue(resourceIDs)); } }; container.listEntries(context, handler); } else { // Read a single entry. // TODO: Determine the set of LDAP attributes that need to be read. final Set requestedAttributes = new LinkedHashSet(); final Set requestedLDAPAttributes = getRequestedLDAPAttributes(requestedAttributes); final ResultHandler handler = new ResultHandler() { public void handleErrorResult(final ErrorResultException error) { out.setFailure(adaptErrorResult(error)); } public void handleResult(final SearchResultEntry entry) { final String revision = getRevisionFromEntry(entry); final ResultHandler mapHandler = new ResultHandler() { public void handleErrorResult( final ErrorResultException error) { out.setFailure(adaptErrorResult(error)); } public void handleResult(final JsonValue result) { out.setResult(id, revision, result); } }; mapEntryToJson(context, requestedAttributes, entry, mapHandler); } }; container.readEntry(context, id, requestedLDAPAttributes, handler); } } /** * {@inheritDoc} */ public void update(final UpdateRequest request, final Context context, final UpdateResultHandler out) { out.setFailure(new NotSupportedException("Not yet implemented")); } private ResourceException adaptErrorResult(final ErrorResultException error) { // TODO Auto-generated method stub return null; } /** * Caches the set of LDAP attributes associated with all of this resource's * mappers. */ private void cacheAllLDAPAttributes() { allLDAPAttributes = new LinkedHashSet(mappers.size()); for (final AttributeMapper mapper : mappers) { allLDAPAttributes.addAll(mapper.getAllLDAPAttributes()); } } /** * Determines the set of LDAP attributes to request in an LDAP read (search, * post-read), based on the provided set of JSON pointers. * * @param requestedAttributes * The set of resource attributes to be read. * @return The set of LDAP attributes associated with the resource * attributes. */ private Set getRequestedLDAPAttributes(final Set requestedAttributes) { if (requestedAttributes.isEmpty()) { // Full read. return allLDAPAttributes; } else { // Partial read. final Set requestedLDAPAttributes = new LinkedHashSet(requestedAttributes.size()); for (final JsonPointer requestedAttribute : requestedAttributes) { for (final AttributeMapper mapper : mappers) { requestedLDAPAttributes.addAll(mapper.getLDAPAttributesFor(requestedAttribute)); } } return requestedLDAPAttributes; } } private String getRevisionFromEntry(final SearchResultEntry entry) { // TODO Auto-generated method stub return null; } private void mapEntryToJson(final Context c, final Set requestedAttributes, final Entry result, final ResultHandler h) { // TODO Auto-generated method stub } }