mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
26.12.2012 58ffacee660a4eb792f49dd311a4e2ddda05afad
Checkpoint local changes: add more attribute mapping support.
2 files added
8 files modified
309 ■■■■ changed files
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java 20 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java 33 ●●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java 14 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ConstantAttributeMapper.java 79 ●●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java 19 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java 8 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java 4 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java 60 ●●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java 57 ●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java 15 ●●●●● patch | view | raw | blame | history
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/AttributeMapper.java
@@ -32,33 +32,19 @@
public interface AttributeMapper {
    /**
     * Adds the names of the all the LDAP attributes required by this attribute
     * mapper to the provided set.
     * <p>
     * Implementations should only add the names of attributes found in the LDAP
     * entry directly associated with the resource.
     *
     * @param ldapAttributes
     *            The set into which the required LDAP attribute names should be
     *            put.
     */
    void getLDAPAttributes(Set<String> ldapAttributes);
    /**
     * Adds the names of the LDAP attributes required by this attribute mapper
     * which are associated with the provided resource attribute to the provided
     * set.
     * <p>
     * Implementations should only add the names of attributes found in the LDAP
     * entry directly associated with the resource.
     *
     * @param jsonAttribute
     *            The name of the resource attribute requested by the client.
     * @param ldapAttributes
     *            The set into which the required LDAP attribute names should be
     *            put.
     * @param resourceAttribute
     *            The name of the resource attribute requested by the client.
     */
    void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute);
    void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes);
    /**
     * Transforms attributes contained in the provided LDAP entry to JSON
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ComplexAttributeMapper.java
@@ -51,35 +51,17 @@
     */
    public ComplexAttributeMapper(String jsonAttributeName, AttributeMapper mapper) {
        this.jsonAttributeName = jsonAttributeName;
        this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
        this.mapper = mapper;
        this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
    }
    /**
     * {@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);
                }
            }
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        if (attributeMatchesPointer(jsonAttribute)) {
            JsonPointer relativePointer = jsonAttribute.relativePointer();
            mapper.getLDAPAttributes(relativePointer, ldapAttributes);
        }
    }
@@ -112,4 +94,9 @@
    }
    private boolean attributeMatchesPointer(JsonPointer resourceAttribute) {
        return resourceAttribute.isEmpty()
                || toLowerCase(resourceAttribute.get(0)).equals(normalizedJsonAttributeName);
    }
}
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/CompositeAttributeMapper.java
@@ -19,7 +19,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -37,7 +36,6 @@
 *
 */
public final class CompositeAttributeMapper implements AttributeMapper {
    private final Set<String> allLDAPAttributes = new LinkedHashSet<String>();
    private final List<AttributeMapper> attributeMappers = new LinkedList<AttributeMapper>();
    /**
@@ -50,23 +48,15 @@
    public CompositeAttributeMapper addMapper(AttributeMapper mapper) {
        attributeMappers.add(mapper);
        mapper.getLDAPAttributes(allLDAPAttributes);
        return this;
    }
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(Set<String> ldapAttributes) {
        ldapAttributes.addAll(allLDAPAttributes);
    }
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        for (AttributeMapper attribute : attributeMappers) {
            attribute.getLDAPAttributes(ldapAttributes, resourceAttribute);
            attribute.getLDAPAttributes(jsonAttribute, ldapAttributes);
        }
    }
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ConstantAttributeMapper.java
New file
@@ -0,0 +1,79 @@
/*
 * 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.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.provider.Context;
/**
 *
 */
public class ConstantAttributeMapper implements AttributeMapper {
    private final String jsonAttributeName;
    private final Object jsonAttributeValue;
    /**
     * Creates a new constant attribute mapper which maps a single LDAP
     * attribute to a fixed value.
     *
     * @param attributeName
     *            The name of the simple JSON attribute.
     * @param attributeValue
     *            The value of the simple JSON attribute.
     */
    public ConstantAttributeMapper(String attributeName, Object attributeValue) {
        this.jsonAttributeName = attributeName;
        this.jsonAttributeValue = attributeValue;
    }
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        // Nothing to do.
    }
    /**
     * {@inheritDoc}
     */
    public void toJson(Context c, Entry e,
            final AttributeMapperCompletionHandler<Map<String, Object>> h) {
        // FIXME: how do we know if the user requested it???
        Map<String, Object> result =
                Collections.singletonMap(jsonAttributeName, jsonAttributeValue);
        h.onSuccess(result);
    }
    /**
     * {@inheritDoc}
     */
    public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
        // TODO Auto-generated method stub
    }
}
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/DefaultAttributeMapper.java
@@ -67,14 +67,23 @@
        }
    }
    public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
        String name = resourceAttribute.leaf();
        if (name != null) {
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        switch (jsonAttribute.size()) {
        case 0:
            // Requested everything.
            if (!includedAttributes.isEmpty()) {
                ldapAttributes.addAll(includedAttributes.values());
            } else {
                // All user attributes.
                ldapAttributes.add("*");
            }
            break;
        default:
            String name = jsonAttribute.get(0);
            if (isIncludedAttribute(name)) {
                ldapAttributes.add(name);
            } else {
                // FIXME: log something or return a ResourceException?
            }
            break;
        }
    }
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Example.java
@@ -20,6 +20,7 @@
import org.forgerock.opendj.ldap.ConnectionFactory;
import org.forgerock.opendj.ldap.Connections;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.Functions;
import org.forgerock.opendj.ldap.LDAPConnectionFactory;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.resource.framework.JsonResourceProvider;
@@ -68,8 +69,11 @@
                                .includeAttribute("cn", "sn", "givenName"))).addMapper(
                        new ComplexAttributeMapper("contactInformation",
                                new CompositeAttributeMapper().addMapper(
                                        new SimpleAttributeMapper("telephoneNumber")).addMapper(
                                        new SimpleAttributeMapper("emailAddress", "mail"))));
                                        new SimpleAttributeMapper("telephoneNumber").withDecoder(
                                                Functions.byteStringToString()).forceSingleValued(
                                                true)).addMapper(
                                        new SimpleAttributeMapper("emailAddress", "mail")
                                                .forceSingleValued(true))));
        LDAPResource userResource = new LDAPResource(userContainer, userMapper);
        ResourceInvoker userResourceInvoker = new ResourceInvoker();
        userResourceInvoker.resource = userResource; // FIXME: Yuk!
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/LDAPResource.java
@@ -230,12 +230,12 @@
        if (requestedAttributes.isEmpty()) {
            // Full read.
            requestedLDAPAttributes = new LinkedHashSet<String>();
            attributeMapper.getLDAPAttributes(requestedLDAPAttributes);
            attributeMapper.getLDAPAttributes(new JsonPointer(), requestedLDAPAttributes);
        } else {
            // Partial read.
            requestedLDAPAttributes = new LinkedHashSet<String>(requestedAttributes.size());
            for (final JsonPointer requestedAttribute : requestedAttributes) {
                attributeMapper.getLDAPAttributes(requestedLDAPAttributes, requestedAttribute);
                attributeMapper.getLDAPAttributes(requestedAttribute, requestedLDAPAttributes);
            }
        }
        return requestedLDAPAttributes;
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/ReferenceAttributeMapper.java
New file
@@ -0,0 +1,60 @@
/*
 * 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.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 class ReferenceAttributeMapper implements AttributeMapper {
    // private final EntryContainer referencedContainer;
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        // TODO Auto-generated method stub
    }
    /**
     * {@inheritDoc}
     */
    public void toJson(Context c, Entry e, AttributeMapperCompletionHandler<Map<String, Object>> h) {
        // TODO Auto-generated method stub
    }
    /**
     * {@inheritDoc}
     */
    public void toLDAP(Context c, JsonValue v, AttributeMapperCompletionHandler<List<Attribute>> h) {
        // TODO Auto-generated method stub
    }
}
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/SimpleAttributeMapper.java
@@ -16,7 +16,7 @@
package org.forgerock.opendj.rest2ldap;
import static org.forgerock.opendj.rest2ldap.Utils.attributeToJson;
import static org.forgerock.opendj.rest2ldap.Utils.byteStringToJson;
import static org.forgerock.opendj.rest2ldap.Utils.toLowerCase;
import java.util.Collections;
@@ -27,7 +27,10 @@
import org.forgerock.json.fluent.JsonPointer;
import org.forgerock.json.fluent.JsonValue;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.Entry;
import org.forgerock.opendj.ldap.Function;
import org.forgerock.opendj.ldap.Functions;
import org.forgerock.resource.provider.Context;
/**
@@ -39,6 +42,11 @@
    private final String jsonAttributeName;
    private final String normalizedJsonAttributeName;
    private boolean forceSingleValued = false;
    private Object defaultValue = null;
    private boolean isReadOnly = false;
    private Function<ByteString, ?, Void> decoder = null;
    /**
     * Creates a new simple attribute mapper which maps a single LDAP attribute
     * to an entry.
@@ -61,24 +69,42 @@
     */
    public SimpleAttributeMapper(String jsonAttributeName, String ldapAttributeName) {
        this.jsonAttributeName = jsonAttributeName;
        this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
        this.ldapAttributeName = ldapAttributeName;
        this.normalizedJsonAttributeName = toLowerCase(jsonAttributeName);
    }
    public SimpleAttributeMapper withDefaultValue(Object defaultValue) {
        this.defaultValue = defaultValue;
        return this;
    }
    public SimpleAttributeMapper isReadOnly(boolean readOnly) {
        this.isReadOnly = readOnly;
        return this;
    }
    public SimpleAttributeMapper forceSingleValued(boolean singleValued) {
        this.forceSingleValued = singleValued;
        return this;
    }
    public SimpleAttributeMapper withDecoder(Function<ByteString, ?, Void> f) {
        this.decoder = f;
        return this;
    }
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(Set<String> ldapAttributes) {
    public void getLDAPAttributes(JsonPointer jsonAttribute, Set<String> ldapAttributes) {
        if (attributeMatchesPointer(jsonAttribute)) {
        ldapAttributes.add(ldapAttributeName);
    }
    }
    /**
     * {@inheritDoc}
     */
    public void getLDAPAttributes(Set<String> ldapAttributes, JsonPointer resourceAttribute) {
        if (toLowerCase(resourceAttribute.leaf()).equals(normalizedJsonAttributeName)) {
            ldapAttributes.add(ldapAttributeName);
        }
    private boolean attributeMatchesPointer(JsonPointer resourceAttribute) {
        return resourceAttribute.isEmpty()
                || toLowerCase(resourceAttribute.get(0)).equals(normalizedJsonAttributeName);
    }
    /**
@@ -88,8 +114,15 @@
            final AttributeMapperCompletionHandler<Map<String, Object>> h) {
        Attribute a = e.getAttribute(ldapAttributeName);
        if (a != null) {
            Map<String, Object> result =
                    Collections.singletonMap(jsonAttributeName, attributeToJson(a));
            Function<ByteString, ?, Void> f =
                    decoder == null ? Functions.fixedFunction(byteStringToJson(), a) : decoder;
            final Object value;
            if (forceSingleValued || a.getAttributeDescription().getAttributeType().isSingleValue()) {
                value = a.parse().as(f, defaultValue);
            } else {
                value = a.parse().asSetOf(f, defaultValue);
            }
            Map<String, Object> result = Collections.singletonMap(jsonAttributeName, value);
            h.onSuccess(result);
        }
    }
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -38,9 +38,10 @@
 */
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) {
    private static final Function<ByteString, Object, Attribute> BYTESTRING_TO_JSON =
            new Function<ByteString, Object, Attribute>() {
                public Object apply(final ByteString value, final Attribute a) {
                    Syntax syntax = a.getAttributeDescription().getAttributeType().getSyntax();
                    if (syntax.equals(getBooleanSyntax())) {
                        return Functions.byteStringToBoolean().apply(value, null);
                    } else if (syntax.equals(getIntegerSyntax())) {
@@ -72,9 +73,12 @@
        }
    }
    static Function<ByteString, Object, Attribute> byteStringToJson() {
        return BYTESTRING_TO_JSON;
    }
    static Object attributeToJson(Attribute a) {
        Syntax syntax = a.getAttributeDescription().getAttributeType().getSyntax();
        Function<ByteString, Object, Void> f = Functions.fixedFunction(BYTESTRING_TO_JSON, syntax);
        Function<ByteString, Object, Void> f = Functions.fixedFunction(BYTESTRING_TO_JSON, a);
        boolean isSingleValued = a.getAttributeDescription().getAttributeType().isSingleValue();
        return isSingleValued ? a.parse().as(f) : asList(a.parse().asSetOf(f));
    }
@@ -100,4 +104,5 @@
        }
        return object;
    }
}