From eda03abb06f41962772d6439f14a3395ca99bd5e Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 15 May 2012 16:16:52 +0000
Subject: [PATCH] Checkpoint dev.
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java | 112 +++++++++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EtagStrategy.java | 26 ++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java | 89 ++++++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java | 117 ++++++-----
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java | 39 +--
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java | 178 +++++++++++++++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java | 6
7 files changed, 492 insertions(+), 75 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
index 32e593e..9387131 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.forgerock.json.fluent.JsonPointer;
@@ -33,30 +34,30 @@
public interface AttributeMapper {
/**
- * Returns an unmodifiable set containing the names of the LDAP attributes
- * required by this attribute mapper. The returned set should only contain
- * the names of attributes found in the LDAP entry directly associated with
- * the resource.
+ * Returns an unmodifiable collection containing the names of the LDAP
+ * attributes required by this attribute mapper. The returned collection
+ * should only contain the names of attributes found in the LDAP entry
+ * directly associated with the resource.
*
- * @return An unmodifiable set containing the names of the LDAP attributes
- * required by this attribute mapper.
+ * @return An unmodifiable collection containing the names of the LDAP
+ * attributes required by this attribute mapper.
*/
- Set<String> getAllLDAPAttributes();
+ Collection<String> getAllLDAPAttributes();
/**
- * Returns an unmodifiable collection containing the names of the LDAP
- * attributes required by this attribute mapper and which are associated
- * with the provided resource attribute. The returned set should only
- * contain the names of attributes found in the LDAP entry directly
- * associated with the resource.
+ * Adds the names of the LDAP attributes required by this attribute mapper
+ * which are associated with the provided resource attribute.
+ * <p>
+ * Implementations should only add the names of attributes found in the LDAP
+ * entry directly associated with the resource.
*
* @param resourceAttribute
* The name of the resource attribute requested by the client.
- * @return An unmodifiable collection containing the names of the LDAP
- * attributes required by this attribute mapper and which are
- * associated with the provided resource attribute.
+ * @param ldapAttributes
+ * The set into which the required LDAP attribute names should be
+ * put.
*/
- Collection<String> getLDAPAttributesFor(JsonPointer resourceAttribute);
+ void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes);
/**
* Transforms attributes contained in the provided LDAP entry to JSON
@@ -69,10 +70,9 @@
*
* @param c
* @param e
- * @param v
* @param h
*/
- void toJson(Context c, Entry e, JsonValue v, ResultHandler<JsonValue> h);
+ void toJson(Context c, Entry e, ResultHandler<Map<String, Object>> h);
/**
* Transforms JSON content in the provided JSON value to LDAP attributes,
@@ -84,10 +84,9 @@
*
* @param c
* @param v
- * @param a
* @param h
*/
- void toLDAP(Context c, JsonValue v, List<Attribute> a, ResultHandler<Entry> h);
+ void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h);
// TODO: methods for obtaining schema information (e.g. name, description,
// type information).
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
new file mode 100644
index 0000000..1bcfee1
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
@@ -0,0 +1,178 @@
+/*
+ * 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.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+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.opendj.ldap.Attribute;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.ResultHandler;
+import org.forgerock.resource.provider.Context;
+
+/**
+ *
+ */
+public final class CompositeAttributeMapper implements AttributeMapper {
+ private final Set<String> allLDAPAttributes;
+ private final List<AttributeMapper> attributeMappers;
+
+ /**
+ * Creates a new composite attribute mapper.
+ *
+ * @param attributeMappers
+ * The list of attribute mappers.
+ */
+ public CompositeAttributeMapper(final List<AttributeMapper> attributeMappers) {
+ this.attributeMappers = new ArrayList<AttributeMapper>(attributeMappers);
+ Set<String> tmp = new LinkedHashSet<String>(attributeMappers.size());
+ for (final AttributeMapper mapper : attributeMappers) {
+ tmp.addAll(mapper.getAllLDAPAttributes());
+ }
+ allLDAPAttributes = Collections.unmodifiableSet(tmp);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getAllLDAPAttributes() {
+ return allLDAPAttributes;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes) {
+ for (AttributeMapper attribute : attributeMappers) {
+ attribute.getLDAPAttributesFor(resourceAttribute, ldapAttributes);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void toJson(Context c, Entry e, final ResultHandler<Map<String, Object>> h) {
+ 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 handleErrorResult(ErrorResultException error) {
+ // Ensure that handler is only invoked once.
+ if (latch.getAndSet(0) > 0) {
+ h.handleErrorResult(error);
+ }
+ }
+
+ public void handleResult(Map<String, Object> result) {
+ 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);
+ }
+ }
+ };
+
+ for (AttributeMapper mapper : attributeMappers) {
+ mapper.toJson(c, e, resultAccumulater);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /**
+ * 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(List<Map<String, Object>> srcValues, Map<String, Object> dstValue) {
+ for (Map<String, Object> value : srcValues) {
+ mergeJsonValue(value, dstValue);
+ }
+ }
+
+ /**
+ * 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(Map<String, Object> srcValue, Map<String, Object> dstValue) {
+ for (Map.Entry<String, Object> record : srcValue.entrySet()) {
+ String key = record.getKey();
+ Object newValue = record.getValue();
+ Object existingValue = dstValue.get(key);
+ if (existingValue == null) {
+ // Value is new, so just add it.
+ dstValue.put(key, newValue);
+ } 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);
+ 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
+ // is unmodifiable.
+ List<Object> tmp = new ArrayList<Object>((List<Object>) existingValue);
+ tmp.addAll((List<Object>) newValue);
+ existingValue = tmp;
+ }
+
+ // Replace the existing value.
+ dstValue.put(key, newValue);
+ }
+ }
+}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
index cb98f56..5b4e80d 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EntryContainer.java
@@ -16,7 +16,7 @@
package org.forgerock.opendj.rest2ldap;
-import java.util.Set;
+import java.util.Collection;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.SearchResultHandler;
@@ -48,7 +48,7 @@
/**
* Reads the entry having the specified resource ID.
- *
+ *
* @param c
* The request context.
* @param id
@@ -58,7 +58,7 @@
* @param h
* The result handler.
*/
- public void readEntry(final Context c, final String id, final Set<String> attributes,
+ public void readEntry(final Context c, final String id, final Collection<String> attributes,
final ResultHandler<SearchResultEntry> h) {
// TODO Auto-generated method stub
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EtagStrategy.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EtagStrategy.java
new file mode 100644
index 0000000..5071e2c
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/EtagStrategy.java
@@ -0,0 +1,26 @@
+/*
+ * 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 org.forgerock.opendj.ldap.Entry;
+
+/**
+ *
+ */
+public interface EtagStrategy {
+ String getEtagFromEntry(final Entry entry);
+}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java
new file mode 100644
index 0000000..0ea36f9
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/IdentityAttributeMapper.java
@@ -0,0 +1,112 @@
+/*
+ * 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 static org.forgerock.opendj.rest2ldap.Utils.getAttributeName;
+import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.forgerock.json.fluent.JsonPointer;
+import org.forgerock.json.fluent.JsonValue;
+import org.forgerock.opendj.ldap.Attribute;
+import org.forgerock.opendj.ldap.Entry;
+import org.forgerock.opendj.ldap.ResultHandler;
+import org.forgerock.resource.provider.Context;
+
+/**
+ *
+ */
+public final class IdentityAttributeMapper implements AttributeMapper {
+
+ // All user attributes by default.
+ private final Map<String, String> includedAttributes = new LinkedHashMap<String, String>();
+ private final Map<String, String> excludedAttributes = new LinkedHashMap<String, String>();
+
+ public IdentityAttributeMapper() {
+ // No implementation required.
+ }
+
+ public IdentityAttributeMapper includeAttribute(String... attributes) {
+ for (String attribute : attributes) {
+ includedAttributes.put(toLowerCase(attribute), attribute);
+ }
+ return this;
+ }
+
+ public IdentityAttributeMapper excludeAttribute(String... attributes) {
+ for (String attribute : attributes) {
+ excludedAttributes.put(toLowerCase(attribute), attribute);
+ }
+ return this;
+ }
+
+ public Collection<String> getAllLDAPAttributes() {
+ if (!includedAttributes.isEmpty()) {
+ return includedAttributes.values();
+ } else {
+ // All user attributes.
+ return Collections.emptySet();
+ }
+ }
+
+ public void getLDAPAttributesFor(JsonPointer resourceAttribute, Set<String> ldapAttributes) {
+ String name = resourceAttribute.leaf();
+ if (name != null) {
+ if (isIncludedAttribute(name)) {
+ ldapAttributes.add(name);
+ } else {
+ // FIXME: log something or return a ResourceException?
+ }
+ }
+ }
+
+ public void toJson(Context c, Entry e, ResultHandler<Map<String, Object>> h) {
+ Map<String, Object> result = new LinkedHashMap<String, Object>(e.getAttributeCount());
+ for (Attribute a : e.getAllAttributes()) {
+ String name = getAttributeName(a);
+ if (isIncludedAttribute(name)) {
+ result.put(name, Utils.attributeToJson(a));
+ }
+ }
+ }
+
+ private boolean isIncludedAttribute(String name) {
+ String lowerName = toLowerCase(name);
+
+ // Ignore the requested attribute if it has been excluded.
+ if (excludedAttributes.containsKey(lowerName)) {
+ return false;
+ }
+
+ // Include all attributes by default.
+ if (includedAttributes.isEmpty() || includedAttributes.containsKey(lowerName)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public void toLDAP(Context c, JsonValue v, ResultHandler<List<Attribute>> h) {
+ // TODO:
+ }
+}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
index 579148f..d67d9d4 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
@@ -17,16 +17,24 @@
package org.forgerock.opendj.rest2ldap;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
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.AssertionFailureException;
+import org.forgerock.opendj.ldap.AuthenticationException;
+import org.forgerock.opendj.ldap.AuthorizationException;
+import org.forgerock.opendj.ldap.ConnectionException;
+import org.forgerock.opendj.ldap.EntryNotFoundException;
import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.MultipleEntriesFoundException;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.SearchResultHandler;
+import org.forgerock.opendj.ldap.TimeoutResultException;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.ldap.responses.SearchResultReference;
@@ -53,23 +61,27 @@
*
*/
public class LDAPResource implements Resource {
- private Set<String> allLDAPAttributes;
- private final EntryContainer container;
- private final List<AttributeMapper> mappers;
+ private final EntryContainer entryContainer;
+ private final AttributeMapper attributeMapper;
+ private final EtagStrategy etagStrategy;
/**
* Creates a new LDAP resource.
- *
- * @param container
+ *
+ * @param entryContainer
* The entry container which will be used to interact with the
* LDAP server.
- * @param mappers
- * The list of attribute mappers.
+ * @param etagStrategy
+ * The algorithm which should be used to obtain a resource's etag
+ * from an entry.
+ * @param attributeMapper
+ * The attribute mapper.
*/
- public LDAPResource(final EntryContainer container, final List<AttributeMapper> mappers) {
- this.container = container;
- this.mappers = mappers;
- cacheAllLDAPAttributes();
+ public LDAPResource(final EntryContainer entryContainer, final EtagStrategy etagStrategy,
+ final AttributeMapper attributeMapper) {
+ this.entryContainer = entryContainer;
+ this.etagStrategy = etagStrategy;
+ this.attributeMapper = attributeMapper;
}
/**
@@ -125,7 +137,7 @@
public boolean handleEntry(final SearchResultEntry entry) {
// TODO: should the resource or the container define the ID
// mapping?
- resourceIDs.add(container.getIDFromEntry(entry));
+ resourceIDs.add(entryContainer.getIDFromEntry(entry));
return true;
}
@@ -135,7 +147,7 @@
public boolean handleReference(final SearchResultReference reference) {
// TODO: should this be classed as an error since rest2ldap
- // assumes entries are all colocated.
+ // assumes entries are all colocated?
return true;
}
@@ -143,13 +155,13 @@
out.setResult(id, null, new JsonValue(resourceIDs));
}
};
- container.listEntries(context, handler);
+ entryContainer.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 =
+ final Collection<String> requestedLDAPAttributes =
getRequestedLDAPAttributes(requestedAttributes);
final ResultHandler<SearchResultEntry> handler =
@@ -159,23 +171,22 @@
}
public void handleResult(final SearchResultEntry entry) {
- final String revision = getRevisionFromEntry(entry);
-
- final ResultHandler<JsonValue> mapHandler =
- new ResultHandler<JsonValue>() {
+ final String revision = etagStrategy.getEtagFromEntry(entry);
+ final ResultHandler<Map<String, Object>> mapHandler =
+ new ResultHandler<Map<String, Object>>() {
public void handleErrorResult(
final ErrorResultException error) {
out.setFailure(adaptErrorResult(error));
}
- public void handleResult(final JsonValue result) {
- out.setResult(id, revision, result);
+ public void handleResult(final Map<String, Object> result) {
+ out.setResult(id, revision, new JsonValue(result));
}
};
- mapEntryToJson(context, requestedAttributes, entry, mapHandler);
+ attributeMapper.toJson(context, entry, mapHandler);
}
};
- container.readEntry(context, id, requestedLDAPAttributes, handler);
+ entryContainer.readEntry(context, id, requestedLDAPAttributes, handler);
}
}
@@ -187,56 +198,58 @@
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.
+ * Adapts an LDAP result code to a resource exception.
+ *
+ * @param error
+ * The LDAP error that should be adapted.
+ * @return The equivalent resource exception.
*/
- private void cacheAllLDAPAttributes() {
- allLDAPAttributes = new LinkedHashSet<String>(mappers.size());
- for (final AttributeMapper mapper : mappers) {
- allLDAPAttributes.addAll(mapper.getAllLDAPAttributes());
+ private ResourceException adaptErrorResult(final ErrorResultException error) {
+ int resourceResultCode;
+ try {
+ throw error;
+ } catch (AssertionFailureException e) {
+ resourceResultCode = ResourceException.VERSION_MISMATCH;
+ } catch (AuthenticationException e) {
+ resourceResultCode = 401;
+ } catch (AuthorizationException e) {
+ resourceResultCode = ResourceException.FORBIDDEN;
+ } catch (ConnectionException e) {
+ resourceResultCode = ResourceException.UNAVAILABLE;
+ } catch (EntryNotFoundException e) {
+ resourceResultCode = ResourceException.NOT_FOUND;
+ } catch (MultipleEntriesFoundException e) {
+ resourceResultCode = ResourceException.INTERNAL_ERROR;
+ } catch (TimeoutResultException e) {
+ resourceResultCode = 408;
+ } catch (ErrorResultException e) {
+ resourceResultCode = ResourceException.INTERNAL_ERROR;
}
+ return ResourceException.getException(resourceResultCode, null, error.getMessage(), error);
}
/**
* 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<String> getRequestedLDAPAttributes(final Set<JsonPointer> requestedAttributes) {
+ private Collection<String> getRequestedLDAPAttributes(final Set<JsonPointer> requestedAttributes) {
if (requestedAttributes.isEmpty()) {
// Full read.
- return allLDAPAttributes;
+ return attributeMapper.getAllLDAPAttributes();
} else {
// Partial read.
final Set<String> requestedLDAPAttributes =
new LinkedHashSet<String>(requestedAttributes.size());
for (final JsonPointer requestedAttribute : requestedAttributes) {
- for (final AttributeMapper mapper : mappers) {
- requestedLDAPAttributes.addAll(mapper.getLDAPAttributesFor(requestedAttribute));
- }
+ attributeMapper.getLDAPAttributesFor(requestedAttribute, requestedLDAPAttributes);
}
return requestedLDAPAttributes;
}
}
-
- private String getRevisionFromEntry(final SearchResultEntry entry) {
- // TODO Auto-generated method stub
- return null;
- }
-
- private void mapEntryToJson(final Context c, final Set<JsonPointer> requestedAttributes,
- final Entry result, final ResultHandler<JsonValue> h) {
- // TODO Auto-generated method stub
-
- }
}
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
new file mode 100644
index 0000000..676562d
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -0,0 +1,89 @@
+/*
+ * 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 static org.forgerock.opendj.ldap.schema.CoreSchema.getBooleanSyntax;
+import static org.forgerock.opendj.ldap.schema.CoreSchema.getGeneralizedTimeSyntax;
+import static org.forgerock.opendj.ldap.schema.CoreSchema.getIntegerSyntax;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.forgerock.opendj.ldap.Attribute;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.Function;
+import org.forgerock.opendj.ldap.Functions;
+import org.forgerock.opendj.ldap.schema.Syntax;
+
+/**
+ *
+ */
+public final class Utils {
+
+ private static final Function<ByteString, Object, Syntax> BYTESTRING_TO_JSON =
+ new Function<ByteString, Object, Syntax>() {
+ public Object apply(final ByteString value, final Syntax syntax) {
+ if (syntax.equals(getBooleanSyntax())) {
+ return Functions.byteStringToBoolean().apply(value, null);
+ } else if (syntax.equals(getIntegerSyntax())) {
+ return Functions.byteStringToLong().apply(value, null);
+ } else if (syntax.equals(getGeneralizedTimeSyntax())) {
+ return DatatypeConverter.printDateTime(Functions
+ .byteStringToGeneralizedTime().apply(value, null).toCalendar());
+ } else if (syntax.isHumanReadable()) {
+ return Functions.byteStringToString().apply(value, null);
+ } else {
+ // Base 64 encoded binary.
+ return DatatypeConverter.printBase64Binary(value.toByteArray());
+ }
+ }
+ };
+
+ // Prevent instantiation.
+ private Utils() {
+ // No implementation required.
+ }
+
+ private static <T> List<T> asList(Collection<T> c) {
+ if (c instanceof List) {
+ return (List<T>) c;
+ } else {
+ List<T> result = new ArrayList<T>(c.size());
+ result.addAll(c);
+ return result;
+ }
+ }
+
+ public static Object attributeToJson(Attribute a) {
+ Syntax syntax = a.getAttributeDescription().getAttributeType().getSyntax();
+ Function<ByteString, Object, Void> f = Functions.fixedFunction(BYTESTRING_TO_JSON, syntax);
+ boolean isSingleValued = a.getAttributeDescription().getAttributeType().isSingleValue();
+ return isSingleValued ? a.parse().as(f) : asList(a.parse().asSetOf(f));
+ }
+
+ public static String getAttributeName(Attribute a) {
+ return a.getAttributeDescription().withoutOption("binary").toString();
+ }
+
+ public static String toLowerCase(String s) {
+ return s != null ? s.toLowerCase(Locale.ENGLISH) : null;
+ }
+}
--
Gitblit v1.10.0