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

Matthew Swift
31.01.2013 b0a81eda9a0b2717e90dee49af53adc71f7cc3dc
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Utils.java
@@ -11,7 +11,7 @@
 * 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;
@@ -21,13 +21,18 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.bind.DatatypeConverter;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.json.resource.ResultHandler;
import org.forgerock.opendj.ldap.Attribute;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.Function;
import org.forgerock.opendj.ldap.Functions;
import org.forgerock.opendj.ldap.schema.Syntax;
@@ -36,37 +41,85 @@
 * Internal utility methods.
 */
final class Utils {
    /**
     * Implementation class for {@link #accumulate}.
     *
     * @param <V>
     *            The type of result.
     */
    private static final class AccumulatingResultHandler<V> implements ResultHandler<V> {
        private final ResultHandler<List<V>> handler;
        private final AtomicInteger latch;
        private final List<V> results;
        private AccumulatingResultHandler(final int size, final ResultHandler<List<V>> handler) {
            this.latch = new AtomicInteger(size);
            this.results = new ArrayList<V>(size);
            this.handler = handler;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void handleError(final ResourceException e) {
            // Ensure that handler is only invoked once.
            if (latch.getAndSet(0) > 0) {
                handler.handleError(e);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void handleResult(final V result) {
            synchronized (results) {
                results.add(result);
            }
            if (latch.decrementAndGet() == 0) {
                handler.handleResult(results);
            }
        }
    }
    // @Checkstyle:off
    private static final Function<ByteString, Object, Attribute> BYTESTRING_TO_JSON =
            new Function<ByteString, Object, Attribute>() {
        @Override
        public Object apply(final ByteString value, final Attribute a) {
            final Syntax syntax = a.getAttributeDescription().getAttributeType().getSyntax();
            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());
            }
        }
    };
    // @Checkstyle:on
                @Override
                public Object apply(final ByteString value, final Attribute a) {
                    final Syntax syntax =
                            a.getAttributeDescription().getAttributeType().getSyntax();
                    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());
                    }
                }
            };
    static <V> ResultHandler<V> accumulate(final int size, final ResultHandler<List<V>> handler) {
        return new AccumulatingResultHandler<V>(size, handler);
    }
    static Object attributeToJson(final Attribute a) {
        final Function<ByteString, Object, Void> f = Functions.fixedFunction(BYTESTRING_TO_JSON, a);
        final boolean isSingleValued = a.getAttributeDescription().getAttributeType()
                .isSingleValue();
        final boolean isSingleValued =
                a.getAttributeDescription().getAttributeType().isSingleValue();
        return isSingleValued ? a.parse().as(f) : asList(a.parse().asSetOf(f));
    }
    // @Checkstyle:on
    static Function<ByteString, Object, Attribute> byteStringToJson() {
        return BYTESTRING_TO_JSON;
    }
@@ -89,10 +142,62 @@
        return a.getAttributeDescription().withoutOption("binary").toString();
    }
    static Filter toFilter(final Context c, final FilterType type, final String ldapAttribute,
            final Object valueAssertion) {
        final String v = String.valueOf(valueAssertion);
        final Filter filter;
        switch (type) {
        case CONTAINS:
            filter = Filter.substrings(ldapAttribute, null, Collections.singleton(v), null);
            break;
        case STARTS_WITH:
            filter = Filter.substrings(ldapAttribute, v, null, null);
            break;
        case EQUAL_TO:
            filter = Filter.equality(ldapAttribute, v);
            break;
        case GREATER_THAN:
            filter = Filter.greaterThan(ldapAttribute, v);
            break;
        case GREATER_THAN_OR_EQUAL_TO:
            filter = Filter.greaterOrEqual(ldapAttribute, v);
            break;
        case LESS_THAN:
            filter = Filter.lessThan(ldapAttribute, v);
            break;
        case LESS_THAN_OR_EQUAL_TO:
            filter = Filter.lessOrEqual(ldapAttribute, v);
            break;
        case PRESENT:
            filter = Filter.present(ldapAttribute);
            break;
        case EXTENDED:
        default:
            filter = c.getConfig().getFalseFilter(); // Not supported.
            break;
        }
        return filter;
    }
    static String toLowerCase(final String s) {
        return s != null ? s.toLowerCase(Locale.ENGLISH) : null;
    }
    static <M, N> ResultHandler<M> transform(final Function<M, N, Void> f,
            final ResultHandler<N> handler) {
        return new ResultHandler<M>() {
            @Override
            public void handleError(final ResourceException error) {
                handler.handleError(error);
            }
            @Override
            public void handleResult(final M result) {
                handler.handleResult(f.apply(result, null));
            }
        };
    }
    private static <T> List<T> asList(final Collection<T> c) {
        if (c instanceof List) {
            return (List<T>) c;