From b0a81eda9a0b2717e90dee49af53adc71f7cc3dc Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 31 Jan 2013 18:01:23 +0000
Subject: [PATCH] Fix OPENDJ-690: Rest2LDAP - Implement basic search support
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java | 150 ++++++++++++++++++++++++++------------------------
1 files changed, 78 insertions(+), 72 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
index b69fcf8..9d7f367 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
@@ -11,26 +11,29 @@
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
- * Copyright 2012 ForgeRock AS.
+ * Copyright 2012-2013 ForgeRock AS.
*/
package org.forgerock.opendj.rest2ldap;
+import static org.forgerock.opendj.rest2ldap.Utils.accumulate;
+import static org.forgerock.opendj.rest2ldap.Utils.transform;
+
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
import org.forgerock.json.fluent.JsonPointer;
import org.forgerock.json.fluent.JsonValue;
-import org.forgerock.json.resource.ResourceException;
import org.forgerock.json.resource.ResultHandler;
-import org.forgerock.json.resource.ServerContext;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.Filter;
+import org.forgerock.opendj.ldap.Function;
/**
* An attribute mapper which combines the results of a set of subordinate
@@ -62,9 +65,10 @@
* {@inheritDoc}
*/
@Override
- public void getLDAPAttributes(final JsonPointer jsonAttribute, final Set<String> ldapAttributes) {
+ public void getLDAPAttributes(final Context c, final JsonPointer jsonAttribute,
+ final Set<String> ldapAttributes) {
for (final AttributeMapper attribute : attributeMappers) {
- attribute.getLDAPAttributes(jsonAttribute, ldapAttributes);
+ attribute.getLDAPAttributes(c, jsonAttribute, ldapAttributes);
}
}
@@ -72,49 +76,68 @@
* {@inheritDoc}
*/
@Override
- public void toJSON(final ServerContext c, final Entry e,
- final ResultHandler<Map<String, Object>> h) {
- final ResultHandler<Map<String, Object>> resultAccumulater = new ResultHandler<Map<String, Object>>() {
- private final AtomicInteger latch = new AtomicInteger(attributeMappers.size());
- private final List<Map<String, Object>> results = new ArrayList<Map<String, Object>>(
- latch.get());
+ public void getLDAPFilter(final Context c, final FilterType type,
+ final JsonPointer jsonAttribute, final String operator, final Object valueAssertion,
+ final ResultHandler<Filter> h) {
+ final ResultHandler<Filter> handler =
+ accumulate(attributeMappers.size(), transform(
+ new Function<List<Filter>, Filter, Void>() {
+ @Override
+ public Filter apply(final List<Filter> value, final Void p) {
+ // Remove unmapped filters and combine using logical-OR.
+ final Iterator<Filter> i = value.iterator();
+ while (i.hasNext()) {
+ final Filter f = i.next();
+ if (f == null) {
+ // No mapping so remove.
+ i.remove();
+ } else if (f == c.getConfig().getFalseFilter()) {
+ return c.getConfig().getFalseFilter();
+ } else if (f == c.getConfig().getTrueFilter()) {
+ return c.getConfig().getTrueFilter();
+ }
+ }
+ switch (value.size()) {
+ case 0:
+ // No mappings found.
+ return null;
+ case 1:
+ return value.get(0);
+ default:
+ return Filter.or(value);
+ }
+ }
+ }, h));
+ for (final AttributeMapper subMapper : attributeMappers) {
+ subMapper.getLDAPFilter(c, type, jsonAttribute, operator, valueAssertion, handler);
+ }
+ }
- @Override
- public void handleError(final ResourceException e) {
- // Ensure that handler is only invoked once.
- if (latch.getAndSet(0) > 0) {
- h.handleError(e);
- }
- }
-
- @Override
- public void handleResult(final Map<String, Object> result) {
- if (result != null && !result.isEmpty()) {
- synchronized (this) {
- results.add(result);
- }
- }
- if (latch.decrementAndGet() == 0) {
- final Map<String, Object> mergeResult;
- switch (results.size()) {
- case 0:
- mergeResult = Collections.<String, Object> emptyMap();
- break;
- case 1:
- mergeResult = results.get(0);
- break;
- default:
- mergeResult = new LinkedHashMap<String, Object>();
- mergeJsonValues(results, mergeResult);
- break;
- }
- h.handleResult(mergeResult);
- }
- }
- };
-
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void toJSON(final Context c, final Entry e, final ResultHandler<Map<String, Object>> h) {
+ final ResultHandler<Map<String, Object>> handler =
+ accumulate(attributeMappers.size(), transform(
+ new Function<List<Map<String, Object>>, Map<String, Object>, Void>() {
+ @Override
+ public Map<String, Object> apply(final List<Map<String, Object>> value,
+ final Void p) {
+ switch (value.size()) {
+ case 0:
+ return Collections.<String, Object> emptyMap();
+ case 1:
+ return value.get(0) != null ? value.get(0) : Collections
+ .<String, Object> emptyMap();
+ default:
+ return mergeJsonValues(value,
+ new LinkedHashMap<String, Object>());
+ }
+ }
+ }, h));
for (final AttributeMapper mapper : attributeMappers) {
- mapper.toJSON(c, e, resultAccumulater);
+ mapper.toJSON(c, e, handler);
}
}
@@ -122,21 +145,10 @@
* {@inheritDoc}
*/
@Override
- public void toLDAP(final ServerContext c, final JsonValue v,
- final ResultHandler<List<Attribute>> h) {
+ public void toLDAP(final Context c, final JsonValue v, final ResultHandler<List<Attribute>> h) {
// TODO Auto-generated method stub
-
}
- /**
- * Merge one JSON value into another.
- *
- * @param srcValue
- * The source value.
- * @param dstValue
- * The destination value, into which which the value should be
- * merged.
- */
@SuppressWarnings("unchecked")
private void mergeJsonValue(final Map<String, Object> srcValue,
final Map<String, Object> dstValue) {
@@ -150,8 +162,8 @@
} else if ((existingValue instanceof Map) && (newValue instanceof Map)) {
// Merge two maps - create a new Map, in case the existing one
// is unmodifiable.
- existingValue = new LinkedHashMap<String, Object>(
- (Map<String, Object>) existingValue);
+ existingValue =
+ new LinkedHashMap<String, Object>((Map<String, Object>) existingValue);
mergeJsonValue((Map<String, Object>) newValue, (Map<String, Object>) existingValue);
} else if ((existingValue instanceof List) && (newValue instanceof List)) {
// Merge two lists- create a new List, in case the existing one
@@ -166,19 +178,13 @@
}
}
- /**
- * Merge the provided list of JSON values into a single value.
- *
- * @param srcValues
- * The source values.
- * @param dstValue
- * The destination value, into which which the values should be
- * merged.
- */
- private void mergeJsonValues(final List<Map<String, Object>> srcValues,
+ private Map<String, Object> mergeJsonValues(final List<Map<String, Object>> srcValues,
final Map<String, Object> dstValue) {
for (final Map<String, Object> value : srcValues) {
- mergeJsonValue(value, dstValue);
+ if (value != null) {
+ mergeJsonValue(value, dstValue);
+ }
}
+ return dstValue;
}
}
--
Gitblit v1.10.0