From 5d8774080700c97c4f290818e4b5aa42a209740b Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 23 May 2012 16:39:10 +0000
Subject: [PATCH] Add support for complex and simple JSON attribute mappings.
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java | 115 ++++++++++++++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java | 111 +++++++++++++++
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java | 111 +++++++--------
opendj3/opendj-rest2ldap/pom.xml | 2
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java | 22 +-
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java | 13 +
6 files changed, 301 insertions(+), 73 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/pom.xml b/opendj3/opendj-rest2ldap/pom.xml
index fa1dd8a..67ae69a 100644
--- a/opendj3/opendj-rest2ldap/pom.xml
+++ b/opendj3/opendj-rest2ldap/pom.xml
@@ -61,7 +61,7 @@
<dependency>
<groupId>org.forgerock.commons</groupId>
<artifactId>json-fluent</artifactId>
- <version>1.1.0</version>
+ <version>1.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java
new file mode 100644
index 0000000..fcd9f1b
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java
@@ -0,0 +1,115 @@
+/*
+ * 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.toLowerCase;
+
+import java.util.Collections;
+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.resource.exception.ResourceException;
+import org.forgerock.resource.provider.Context;
+
+/**
+ *
+ */
+public class ComplexAttributeMapper implements AttributeMapper {
+
+ private final String normalizedJsonAttributeName;
+ private final String jsonAttributeName;
+ private final AttributeMapper mapper;
+
+ /**
+ * Creates a new complex attribute mapper which will wrap the results of the
+ * provided mapper as a complex JSON object.
+ *
+ * @param jsonAttributeName
+ * The name of the complex attribute.
+ * @param mapper
+ * The mapper which should be used to provide the contents of the
+ * complex attribute.
+ */
+ public ComplexAttributeMapper(String jsonAttributeName, AttributeMapper mapper) {
+ this.jsonAttributeName = jsonAttributeName;
+ this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
+ this.mapper = mapper;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void getLDAPAttributes(Set<String> ldapAttributes) {
+ mapper.getLDAPAttributes(ldapAttributes);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
+ if (resourceAttribute.size() > 0) {
+ String rootName = resourceAttribute.get(0);
+ if (toLowerCase(rootName).equals(normalizedJsonAttributeName)) {
+ JsonPointer relativePointer = resourceAttribute.relativePointer();
+ if (relativePointer == null) {
+ // User requested the entire contents of this complex
+ // attribute.
+ mapper.getLDAPAttributes(ldapAttributes);
+ } else {
+ // User requested partial contents of this complex
+ // attribute.
+ mapper.getLDAPAttributes(ldapAttributes, relativePointer);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void toJson(Context c, Entry e,
+ final AttributeMapperCompletionHandler<Map<String, Object>> h) {
+ AttributeMapperCompletionHandler<Map<String, Object>> wrapper =
+ new AttributeMapperCompletionHandler<Map<String, Object>>() {
+
+ public void onSuccess(Map<String, Object> result) {
+ Map<String, Object> complexResult =
+ Collections.singletonMap(jsonAttributeName, (Object) result);
+ h.onSuccess(complexResult);
+ }
+
+ public void onFailure(ResourceException e) {
+ h.onFailure(e);
+ }
+ };
+ mapper.toJson(c, e, wrapper);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
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 3bb818d..f62c6f1 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
@@ -20,6 +20,7 @@
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -36,22 +37,21 @@
*
*/
public final class CompositeAttributeMapper implements AttributeMapper {
- private final Set<String> allLDAPAttributes;
- private final List<AttributeMapper> attributeMappers;
+ private final Set<String> allLDAPAttributes = new LinkedHashSet<String>();
+ private final List<AttributeMapper> attributeMappers = new LinkedList<AttributeMapper>();
/**
* 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) {
- mapper.getLDAPAttributes(tmp);
- }
- allLDAPAttributes = Collections.unmodifiableSet(tmp);
+ public CompositeAttributeMapper() {
+ // No implementation required.
+ }
+
+ public CompositeAttributeMapper addMapper(AttributeMapper mapper) {
+ attributeMappers.add(mapper);
+ mapper.getLDAPAttributes(allLDAPAttributes);
+ return this;
}
/**
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java
new file mode 100644
index 0000000..6b363b7
--- /dev/null
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java
@@ -0,0 +1,111 @@
+/*
+ * 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.attributeToJson;
+import static org.forgerock.opendj.rest2ldap.Utils.getAttributeName;
+import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
+
+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.resource.provider.Context;
+
+/**
+ *
+ */
+public final class DefaultAttributeMapper 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 DefaultAttributeMapper() {
+ // No implementation required.
+ }
+
+ public DefaultAttributeMapper includeAttribute(String... attributes) {
+ for (String attribute : attributes) {
+ includedAttributes.put(toLowerCase(attribute), attribute);
+ }
+ return this;
+ }
+
+ public DefaultAttributeMapper excludeAttribute(String... attributes) {
+ for (String attribute : attributes) {
+ excludedAttributes.put(toLowerCase(attribute), attribute);
+ }
+ return this;
+ }
+
+ public void getLDAPAttributes(Set<String> ldapAttributes) {
+ if (!includedAttributes.isEmpty()) {
+ ldapAttributes.addAll(includedAttributes.values());
+ } else {
+ // All user attributes.
+ ldapAttributes.add("*");
+ }
+ }
+
+ public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
+ 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, AttributeMapperCompletionHandler<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, attributeToJson(a));
+ }
+ }
+ h.onSuccess(result);
+ }
+
+ 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, AttributeMapperCompletionHandler<List<Attribute>> h) {
+ // TODO:
+ }
+}
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
index 2994682..651c38d 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
@@ -61,8 +61,15 @@
// Create user resource.
AttributeMapper userMapper =
- new SimpleAttributeMapper().includeAttribute("uid", "cn", "sn", "mail",
- "isMemberOf", "modifyTimestamp");
+ new CompositeAttributeMapper().addMapper(
+ new DefaultAttributeMapper().includeAttribute("uid", "isMemberOf",
+ "modifyTimestamp")).addMapper(
+ new ComplexAttributeMapper("name", new DefaultAttributeMapper()
+ .includeAttribute("cn", "sn", "givenName"))).addMapper(
+ new ComplexAttributeMapper("contactInformation",
+ new CompositeAttributeMapper().addMapper(
+ new SimpleAttributeMapper("telephoneNumber")).addMapper(
+ new SimpleAttributeMapper("emailAddress", "mail"))));
LDAPResource userResource = new LDAPResource(userContainer, userMapper);
ResourceInvoker userResourceInvoker = new ResourceInvoker();
userResourceInvoker.resource = userResource; // FIXME: Yuk!
@@ -70,7 +77,7 @@
// Create group resource.
AttributeMapper groupMapper =
- new SimpleAttributeMapper().includeAttribute("cn", "ou", "description",
+ new DefaultAttributeMapper().includeAttribute("cn", "ou", "description",
"uniquemember");
LDAPResource groupResource = new LDAPResource(groupContainer, groupMapper);
ResourceInvoker groupResourceInvoker = new ResourceInvoker();
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 43bdf36..3d3b5bf 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
@@ -16,10 +16,10 @@
package org.forgerock.opendj.rest2ldap;
-import static org.forgerock.opendj.rest2ldap.Utils.getAttributeName;
+import static org.forgerock.opendj.rest2ldap.Utils.attributeToJson;
import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
-import java.util.LinkedHashMap;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -33,78 +33,73 @@
/**
*
*/
-public final class SimpleAttributeMapper implements AttributeMapper {
+public class SimpleAttributeMapper 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>();
+ private final String ldapAttributeName;
+ private final String jsonAttributeName;
+ private final String normalizedJsonAttributeName;
- public SimpleAttributeMapper() {
- // No implementation required.
+ /**
+ * Creates a new simple attribute mapper which maps a single LDAP attribute
+ * to an entry.
+ *
+ * @param attributeName
+ * The name of the simple JSON and LDAP attribute.
+ */
+ public SimpleAttributeMapper(String attributeName) {
+ this(attributeName, attributeName);
}
- public SimpleAttributeMapper includeAttribute(String... attributes) {
- for (String attribute : attributes) {
- includedAttributes.put(toLowerCase(attribute), attribute);
- }
- return this;
+ /**
+ * Creates a new simple attribute mapper which maps a single LDAP attribute
+ * to an entry.
+ *
+ * @param jsonAttributeName
+ * The name of the simple JSON attribute.
+ * @param ldapAttributeName
+ * The name of the LDAP attribute.
+ */
+ public SimpleAttributeMapper(String jsonAttributeName, String ldapAttributeName) {
+ this.jsonAttributeName = jsonAttributeName;
+ this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
+ this.ldapAttributeName = ldapAttributeName;
}
- public SimpleAttributeMapper excludeAttribute(String... attributes) {
- for (String attribute : attributes) {
- excludedAttributes.put(toLowerCase(attribute), attribute);
- }
- return this;
- }
-
+ /**
+ * {@inheritDoc}
+ */
public void getLDAPAttributes(Set<String> ldapAttributes) {
- if (!includedAttributes.isEmpty()) {
- ldapAttributes.addAll(includedAttributes.values());
- } else {
- // All user attributes.
- ldapAttributes.add("*");
- }
+ ldapAttributes.add(ldapAttributeName);
}
+ /**
+ * {@inheritDoc}
+ */
public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
- String name = resourceAttribute.leaf();
- if (name != null) {
- if (isIncludedAttribute(name)) {
- ldapAttributes.add(name);
- } else {
- // FIXME: log something or return a ResourceException?
- }
+ if (toLowerCase(resourceAttribute.leaf()).equals(normalizedJsonAttributeName)) {
+ ldapAttributes.add(ldapAttributeName);
}
}
- public void toJson(Context c, Entry e, AttributeMapperCompletionHandler<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));
- }
+ /**
+ * {@inheritDoc}
+ */
+ public void toJson(Context c, Entry e,
+ final AttributeMapperCompletionHandler<Map<String, Object>> h) {
+ Attribute a = e.getAttribute(ldapAttributeName);
+ if (a != null) {
+ Map<String, Object> result =
+ Collections.singletonMap(jsonAttributeName, attributeToJson(a));
+ h.onSuccess(result);
}
- h.onSuccess(result);
}
- 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;
- }
-
+ /**
+ * {@inheritDoc}
+ */
public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
- // TODO:
+ // TODO Auto-generated method stub
+
}
+
}
--
Gitblit v1.10.0