| | |
| | | |
| | | 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 { |
| | | // FIXME: This will inherit from JsonResource. |
| | | private EntryContainer container; |
| | | private List<AttributeMapper> mappers; |
| | | public class LDAPResource implements Resource { |
| | | private Set<String> allLDAPAttributes; |
| | | private final EntryContainer container; |
| | | private final List<AttributeMapper> mappers; |
| | | |
| | | /** |
| | | * Creates a new LDAP resource. |
| | |
| | | * @param mappers |
| | | * The list of attribute mappers. |
| | | */ |
| | | public LDAPResource(EntryContainer container, List<AttributeMapper> mappers) { |
| | | public LDAPResource(final EntryContainer container, final List<AttributeMapper> 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<String> resourceIDs = new ArrayList<String>(); |
| | | |
| | | 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<JsonPointer> requestedAttributes = new LinkedHashSet<JsonPointer>(); |
| | | final Set<String> requestedLDAPAttributes = |
| | | getRequestedLDAPAttributes(requestedAttributes); |
| | | |
| | | final ResultHandler<SearchResultEntry> handler = |
| | | new ResultHandler<SearchResultEntry>() { |
| | | public void handleErrorResult(final ErrorResultException error) { |
| | | out.setFailure(adaptErrorResult(error)); |
| | | } |
| | | |
| | | public void handleResult(final SearchResultEntry entry) { |
| | | final String revision = getRevisionFromEntry(entry); |
| | | |
| | | final ResultHandler<JsonValue> mapHandler = |
| | | new ResultHandler<JsonValue>() { |
| | | 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<String>(mappers.size()); |
| | | for (AttributeMapper mapper : mappers) { |
| | | for (final AttributeMapper mapper : mappers) { |
| | | allLDAPAttributes.addAll(mapper.getAllLDAPAttributes()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Reads a resource from the LDAP directory. |
| | | * |
| | | * @param c |
| | | * The request context. |
| | | * @param r |
| | | * The read request. |
| | | * @param h |
| | | * The read result handler. |
| | | */ |
| | | public void read(final Context c, final ReadRequest r, |
| | | final CompletionHandler<JsonValue> h) { |
| | | // Determine the set of LDAP attributes that need to be read. |
| | | final Set<JsonPointer> requestedAttributes = r.getRequestedAttributes(); |
| | | Set<String> requestedLDAPAttributes = getRequestedLDAPAttributes(requestedAttributes); |
| | | |
| | | // Create a completion handler which will convert the entry to a |
| | | // JsonValue. |
| | | CompletionHandler<Entry> eh = new CompletionHandler<Entry>() { |
| | | public void failed(Throwable t) { |
| | | // Unable to read the entry. |
| | | handleReadFailure(c, h, t); |
| | | } |
| | | |
| | | public void completed(Entry result) { |
| | | // Convert the entry to a JsonValue. |
| | | mapEntryToJson(c, requestedAttributes, result, h); |
| | | } |
| | | |
| | | }; |
| | | |
| | | // Read the entry. |
| | | container.readEntry(c, r.getResourceID(), requestedLDAPAttributes, eh); |
| | | } |
| | | |
| | | /** |
| | | * Determines the set of LDAP attributes to request in an LDAP read (search, |
| | | * post-read), based on the provided set of JSON pointers. |
| | | * |
| | |
| | | * @return The set of LDAP attributes associated with the resource |
| | | * attributes. |
| | | */ |
| | | private Set<String> getRequestedLDAPAttributes( |
| | | Set<JsonPointer> requestedAttributes) { |
| | | private Set<String> getRequestedLDAPAttributes(final Set<JsonPointer> requestedAttributes) { |
| | | if (requestedAttributes.isEmpty()) { |
| | | // Full read. |
| | | return allLDAPAttributes; |
| | | } else { |
| | | // Partial read. |
| | | Set<String> requestedLDAPAttributes = new LinkedHashSet<String>( |
| | | requestedAttributes.size()); |
| | | for (JsonPointer requestedAttribute : requestedAttributes) { |
| | | for (AttributeMapper mapper : mappers) { |
| | | requestedLDAPAttributes.addAll(mapper |
| | | .getLDAPAttributesFor(requestedAttribute)); |
| | | final Set<String> requestedLDAPAttributes = |
| | | new LinkedHashSet<String>(requestedAttributes.size()); |
| | | for (final JsonPointer requestedAttribute : requestedAttributes) { |
| | | for (final AttributeMapper mapper : mappers) { |
| | | requestedLDAPAttributes.addAll(mapper.getLDAPAttributesFor(requestedAttribute)); |
| | | } |
| | | } |
| | | return requestedLDAPAttributes; |
| | | } |
| | | } |
| | | |
| | | private void handleReadFailure(Context c, CompletionHandler<JsonValue> h, |
| | | Throwable t) { |
| | | private String getRevisionFromEntry(final SearchResultEntry entry) { |
| | | // TODO Auto-generated method stub |
| | | |
| | | return null; |
| | | } |
| | | |
| | | private void mapEntryToJson(Context c, |
| | | Set<JsonPointer> requestedAttributes, Entry result, |
| | | CompletionHandler<JsonValue> h) { |
| | | private void mapEntryToJson(final Context c, final Set<JsonPointer> requestedAttributes, |
| | | final Entry result, final ResultHandler<JsonValue> h) { |
| | | // TODO Auto-generated method stub |
| | | |
| | | } |