From 56a6404d2b1c440d78a3c833b6d9e6f392875a68 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 11 Mar 2013 20:51:32 +0000
Subject: [PATCH] Additional fix for OPENDJ-699: Implement DN reference mapping

---
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java    |    2 +-
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java                    |    2 ++
 opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java |   44 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
index 4db950a..ae72b5f 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
@@ -39,12 +39,15 @@
 import org.forgerock.json.resource.ResultHandler;
 import org.forgerock.opendj.ldap.Attribute;
 import org.forgerock.opendj.ldap.AttributeDescription;
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.DN;
 import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.EntryNotFoundException;
 import org.forgerock.opendj.ldap.ErrorResultException;
 import org.forgerock.opendj.ldap.Filter;
 import org.forgerock.opendj.ldap.Function;
 import org.forgerock.opendj.ldap.LinkedAttribute;
+import org.forgerock.opendj.ldap.MultipleEntriesFoundException;
 import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchResultHandler;
 import org.forgerock.opendj.ldap.SearchScope;
@@ -296,8 +299,8 @@
                         v.isList() ? v : new JsonValue(singletonList(v.getObject()));
                 final Attribute reference = new LinkedAttribute(ldapAttributeName);
                 final AtomicInteger pendingSearches = new AtomicInteger(valueList.size());
-                final AtomicReference<ErrorResultException> exception =
-                        new AtomicReference<ErrorResultException>();
+                final AtomicReference<ResourceException> exception =
+                        new AtomicReference<ResourceException>();
 
                 for (final JsonValue value : valueList) {
                     mapper.toLDAP(c, value, new ResultHandler<List<Attribute>>() {
@@ -338,9 +341,9 @@
                             }
 
                             // Now search for the referenced entry in to get its DN.
+                            final ByteString primaryKeyValue = primaryKeyAttribute.firstValue();
                             final Filter filter =
-                                    Filter.equality(primaryKey.toString(), primaryKeyAttribute
-                                            .firstValue());
+                                    Filter.equality(primaryKey.toString(), primaryKeyValue);
                             final SearchRequest search = createSearchRequest(filter);
                             c.getConnection()
                                     .searchSingleEntryAsync(
@@ -350,7 +353,29 @@
                                                 @Override
                                                 public void handleErrorResult(
                                                         final ErrorResultException error) {
-                                                    exception.compareAndSet(null, error);
+                                                    ResourceException re;
+                                                    try {
+                                                        throw error;
+                                                    } catch (EntryNotFoundException e) {
+                                                        // FIXME: improve error message.
+                                                        re =
+                                                                new BadRequestException(
+                                                                        "the resource referenced by '"
+                                                                                + primaryKeyValue
+                                                                                        .toString()
+                                                                                + "' does not exist");
+                                                    } catch (MultipleEntriesFoundException e) {
+                                                        // FIXME: improve error message.
+                                                        re =
+                                                                new BadRequestException(
+                                                                        "the resource referenced by '"
+                                                                                + primaryKeyValue
+                                                                                        .toString()
+                                                                                + "' is ambiguous");
+                                                    } catch (ErrorResultException e) {
+                                                        re = adapt(e);
+                                                    }
+                                                    exception.compareAndSet(null, re);
                                                     completeIfNecessary();
                                                 }
 
@@ -370,7 +395,7 @@
                                 if (exception.get() == null) {
                                     h.handleResult(singletonList(reference));
                                 } else {
-                                    h.handleError(adapt(exception.get()));
+                                    h.handleError(exception.get());
                                 }
                             }
                         }
@@ -407,7 +432,12 @@
 
                     @Override
                     public void handleErrorResult(final ErrorResultException error) {
-                        handler.handleError(adapt(error));
+                        if (!(error instanceof EntryNotFoundException)) {
+                            handler.handleError(adapt(error));
+                        } else {
+                            // The referenced entry does not exist so ignore it since it cannot be mapped.
+                            handler.handleResult(null);
+                        }
                     }
 
                     @Override
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
index c1ddd3c..2297aae 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
@@ -183,7 +183,7 @@
             final String operator, final Object valueAssertion, final ResultHandler<Filter> h) {
         if (jsonAttribute.isEmpty()) {
             try {
-                final ByteString va = encoder().apply(valueAssertion, null);
+                final ByteString va = valueAssertion != null ? encoder().apply(valueAssertion, null) : null;
                 h.handleResult(toFilter(c, type, ldapAttributeName.toString(), va));
             } catch (Exception e) {
                 // Invalid assertion value - bad request.
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
index 5b8dbf7..f8f5c14 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -201,6 +201,8 @@
         int resourceResultCode;
         try {
             throw t;
+        } catch (final ResourceException e) {
+            return e;
         } catch (final AssertionFailureException e) {
             resourceResultCode = ResourceException.VERSION_MISMATCH;
         } catch (final AuthenticationException e) {

--
Gitblit v1.10.0