From e399742925d1a8a1ae3dae4a86bf25d3d02e8f9c Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 09 May 2012 15:28:30 +0000
Subject: [PATCH] Fix OPENDJ-355: Add fluent API for decoding attributes
---
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Functions.java | 435 +++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 298 insertions(+), 137 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Functions.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Functions.java
index 64c21f8..87302c0 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Functions.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Functions.java
@@ -27,13 +27,16 @@
package com.forgerock.opendj.util;
-import java.util.Calendar;
+import static org.forgerock.opendj.ldap.CoreMessages.FUNCTIONS_TO_INTEGER_FAIL;
+import static org.forgerock.opendj.ldap.CoreMessages.FUNCTIONS_TO_LONG_FAIL;
+import static org.forgerock.opendj.ldap.CoreMessages.WARN_ATTR_SYNTAX_ILLEGAL_BOOLEAN;
+import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
import org.forgerock.opendj.ldap.AttributeDescription;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
-import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.GeneralizedTime;
import org.forgerock.opendj.ldap.schema.Schema;
/**
@@ -60,28 +63,45 @@
}
- private static final Function<ByteString, AttributeDescription, Schema> BYTESTRING_TO_ATTRIBUTE_DESCRIPTION =
- new Function<ByteString, AttributeDescription, Schema>() {
-
- public AttributeDescription apply(final ByteString value, final Schema p) {
- // FIXME: what should we do if parsing fails?
- return AttributeDescription.valueOf(value.toString(), p);
- }
- };
-
- private static final Function<ByteString, String, Void> BYTESTRING_TO_BASE64 =
+ private static final Function<ByteString, String, Void> BYTESTRING_TO_STRING =
new Function<ByteString, String, Void>() {
-
public String apply(final ByteString value, final Void p) {
- return Base64.encode(value);
+ return value.toString();
}
};
- private static final Function<ByteString, Boolean, Void> BYTESTRING_TO_BOOLEAN =
- new Function<ByteString, Boolean, Void>() {
+ private static final Function<Object, Object, Void> IDENTITY =
+ new Function<Object, Object, Void>() {
+ public Object apply(final Object value, final Void p) {
+ return value;
+ }
+ };
- public Boolean apply(final ByteString value, final Void p) {
- final String valueString = StaticUtils.toLowerCase(value.toString());
+ private static final Function<String, String, Void> NORMALIZE_STRING =
+ new Function<String, String, Void>() {
+ public String apply(final String value, final Void p) {
+ return StaticUtils.toLowerCase(value).trim();
+ }
+ };
+
+ private static final Function<Object, ByteString, Void> OBJECT_TO_BYTESTRING =
+ new Function<Object, ByteString, Void>() {
+ public ByteString apply(final Object value, final Void p) {
+ return ByteString.valueOf(value);
+ }
+ };
+
+ private static final Function<String, AttributeDescription, Schema> STRING_TO_ATTRIBUTE_DESCRIPTION =
+ new Function<String, AttributeDescription, Schema>() {
+ public AttributeDescription apply(final String value, final Schema p) {
+ return AttributeDescription.valueOf(value, p);
+ }
+ };
+
+ private static final Function<String, Boolean, Void> STRING_TO_BOOLEAN =
+ new Function<String, Boolean, Void>() {
+ public Boolean apply(final String value, final Void p) {
+ final String valueString = StaticUtils.toLowerCase(value);
if (valueString.equals("true") || valueString.equals("yes")
|| valueString.equals("on") || valueString.equals("1")) {
@@ -90,86 +110,159 @@
|| valueString.equals("off") || valueString.equals("0")) {
return Boolean.FALSE;
} else {
- throw new NumberFormatException("Invalid boolean value \"" + valueString
- + "\"");
+ final LocalizableMessage message =
+ WARN_ATTR_SYNTAX_ILLEGAL_BOOLEAN.get(valueString);
+ throw new LocalizedIllegalArgumentException(message);
}
}
};
- private static final Function<ByteString, Calendar, Void> BYTESTRING_TO_CALENDAR =
- new Function<ByteString, Calendar, Void>() {
+ private static final Function<String, DN, Schema> STRING_TO_DN =
+ new Function<String, DN, Schema>() {
+ public DN apply(final String value, final Schema p) {
+ return DN.valueOf(value, p);
+ }
+ };
- public Calendar apply(final ByteString value, final Void p) {
+ private static final Function<String, GeneralizedTime, Void> STRING_TO_GENERALIZED_TIME =
+ new Function<String, GeneralizedTime, Void>() {
+ public GeneralizedTime apply(final String value, final Void p) {
+ return GeneralizedTime.valueOf(value);
+ }
+ };
+
+ private static final Function<String, Integer, Void> STRING_TO_INTEGER =
+ new Function<String, Integer, Void>() {
+ public Integer apply(final String value, final Void p) {
try {
- return GeneralizedTime.decode(value);
- } catch (DecodeException e) {
- throw new LocalizedIllegalArgumentException(e.getMessageObject(), e);
+ return Integer.valueOf(value);
+ } catch (final NumberFormatException e) {
+ final LocalizableMessage message = FUNCTIONS_TO_INTEGER_FAIL.get(value);
+ throw new LocalizedIllegalArgumentException(message);
}
}
};
- private static final Function<ByteString, DN, Schema> BYTESTRING_TO_DN =
- new Function<ByteString, DN, Schema>() {
-
- public DN apply(final ByteString value, final Schema p) {
- // FIXME: what should we do if parsing fails?
-
- // FIXME: we should have a ByteString valueOf
- // implementation.
- return DN.valueOf(value.toString(), p);
+ private static final Function<String, Long, Void> STRING_TO_LONG =
+ new Function<String, Long, Void>() {
+ public Long apply(final String value, final Void p) {
+ try {
+ return Long.valueOf(value);
+ } catch (final NumberFormatException e) {
+ final LocalizableMessage message = FUNCTIONS_TO_LONG_FAIL.get(value);
+ throw new LocalizedIllegalArgumentException(message);
+ }
}
};
- private static final Function<ByteString, Integer, Void> BYTESTRING_TO_INTEGER =
- new Function<ByteString, Integer, Void>() {
+ private static final Function<ByteString, AttributeDescription, Schema> BYTESTRING_TO_ATTRIBUTE_DESCRIPTION =
+ composeSecondP(valueToString(), STRING_TO_ATTRIBUTE_DESCRIPTION);
- public Integer apply(final ByteString value, final Void p) {
- // We do not use ByteString.toInt() as we are string based.
- return Integer.valueOf(value.toString());
- }
+ private static final Function<ByteString, Boolean, Void> BYTESTRING_TO_BOOLEAN = compose(
+ valueToString(), STRING_TO_BOOLEAN);
+
+ private static final Function<ByteString, DN, Schema> BYTESTRING_TO_DN = composeSecondP(
+ valueToString(), STRING_TO_DN);
+
+ private static final Function<ByteString, GeneralizedTime, Void> BYTESTRING_TO_GENERALIZED_TIME =
+ compose(valueToString(), STRING_TO_GENERALIZED_TIME);
+
+ private static final Function<ByteString, Integer, Void> BYTESTRING_TO_INTEGER = compose(
+ valueToString(), STRING_TO_INTEGER);
+
+ private static final Function<ByteString, Long, Void> BYTESTRING_TO_LONG = compose(
+ valueToString(), STRING_TO_LONG);
+
+ /**
+ * Returns the composition of two functions. The result of the first
+ * function will be passed to the second.
+ *
+ * @param <M>
+ * The type of input values transformed by this function.
+ * @param <N>
+ * The type of output values returned by this function.
+ * @param <X>
+ * The type of intermediate values passed between the two
+ * functions.
+ * @param first
+ * The first function which will consume the input.
+ * @param second
+ * The second function which will produce the result.
+ * @return The composition.
+ */
+ public static <M, X, N> Function<M, N, Void> compose(final Function<M, X, Void> first,
+ final Function<X, N, Void> second) {
+ return new Function<M, N, Void>() {
+ public N apply(final M value, final Void p) {
+ final X tmp = first.apply(value, p);
+ return second.apply(tmp, p);
};
+ };
+ }
- private static final Function<ByteString, Long, Void> BYTESTRING_TO_LONG =
- new Function<ByteString, Long, Void>() {
-
- public Long apply(final ByteString value, final Void p) {
- // We do not use ByteString.toLong() as we are string based.
- return Long.valueOf(value.toString());
- }
+ /**
+ * Returns the composition of two functions. The result of the first
+ * function will be passed to the second. The first function will be passed
+ * an additional parameter.
+ *
+ * @param <M>
+ * The type of input values transformed by this function.
+ * @param <N>
+ * The type of output values returned by this function.
+ * @param <X>
+ * The type of intermediate values passed between the two
+ * functions.
+ * @param <P>
+ * The type of the additional parameter to the first function's
+ * {@code apply} method. Use {@link java.lang.Void} for functions
+ * that do not need an additional parameter.
+ * @param first
+ * The first function which will consume the input.
+ * @param second
+ * The second function which will produce the result.
+ * @return The composition.
+ */
+ public static <M, X, N, P> Function<M, N, P> composeFirstP(final Function<M, X, P> first,
+ final Function<X, N, Void> second) {
+ return new Function<M, N, P>() {
+ public N apply(final M value, final P p) {
+ final X tmp = first.apply(value, p);
+ return second.apply(tmp, null);
};
+ };
+ }
- private static final Function<ByteString, String, Void> BYTESTRING_TO_STRING =
- new Function<ByteString, String, Void>() {
-
- public String apply(final ByteString value, final Void p) {
- return value.toString();
- }
+ /**
+ * Returns the composition of two functions. The result of the first
+ * function will be passed to the second. The second function will be passed
+ * an additional parameter.
+ *
+ * @param <M>
+ * The type of input values transformed by this function.
+ * @param <N>
+ * The type of output values returned by this function.
+ * @param <X>
+ * The type of intermediate values passed between the two
+ * functions.
+ * @param <P>
+ * The type of the additional parameter to the second function's
+ * {@code apply} method. Use {@link java.lang.Void} for functions
+ * that do not need an additional parameter.
+ * @param first
+ * The first function which will consume the input.
+ * @param second
+ * The second function which will produce the result.
+ * @return The composition.
+ */
+ public static <M, X, N, P> Function<M, N, P> composeSecondP(final Function<M, X, Void> first,
+ final Function<X, N, P> second) {
+ return new Function<M, N, P>() {
+ public N apply(final M value, final P p) {
+ final X tmp = first.apply(value, null);
+ return second.apply(tmp, p);
};
-
- private static final Function<Object, ByteString, Void> OBJECT_TO_BYTESTRING =
- new Function<Object, ByteString, Void>() {
-
- public ByteString apply(final Object value, final Void p) {
- return ByteString.valueOf(value);
- }
- };
-
- private static final Function<String, String, Void> NORMALIZE_STRING =
- new Function<String, String, Void>() {
-
- public String apply(final String value, final Void p) {
- return StaticUtils.toLowerCase(value).trim();
- }
- };
-
- private static final Function<Object, Object, Void> IDENTITY =
- new Function<Object, Object, Void>() {
-
- public Object apply(Object value, Void p) {
- return value;
- }
-
- };
+ };
+ }
/**
* Returns a function which which always invokes {@code function} with
@@ -232,28 +325,115 @@
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as an {@code AttributeDescription} using the default
- * schema. Invalid values will result in a
+ * Returns a function which parses {@code AttributeDescription}s using the
+ * default schema. Invalid values will result in a
* {@code LocalizedIllegalArgumentException}.
*
- * @return A function which parses the string representation of a
- * {@code ByteString} as an {@code AttributeDescription}.
+ * @return A function which parses {@code AttributeDescription}s.
+ */
+ public static Function<String, AttributeDescription, Void> stringToAttributeDescription() {
+ return fixedFunction(STRING_TO_ATTRIBUTE_DESCRIPTION, Schema.getDefaultSchema());
+ }
+
+ /**
+ * Returns a function which parses {@code AttributeDescription}s using the
+ * provided schema. Invalid values will result in a
+ * {@code LocalizedIllegalArgumentException}.
+ *
+ * @param schema
+ * The schema to use for decoding attribute descriptions.
+ * @return A function which parses {@code AttributeDescription}s.
+ */
+ public static Function<String, AttributeDescription, Void> stringToAttributeDescription(
+ final Schema schema) {
+ return fixedFunction(STRING_TO_ATTRIBUTE_DESCRIPTION, schema);
+ }
+
+ /**
+ * Returns a function which parses {@code Boolean} values. The function will
+ * accept the values {@code 0}, {@code false}, {@code no}, {@code off},
+ * {@code 1}, {@code true}, {@code yes}, {@code on}. All other values will
+ * result in a {@code NumberFormatException}.
+ *
+ * @return A function which parses {@code Boolean} values.
+ */
+ public static Function<String, Boolean, Void> stringToBoolean() {
+ return STRING_TO_BOOLEAN;
+ }
+
+ /**
+ * Returns a function which parses {@code DN}s using the default schema.
+ * Invalid values will result in a {@code LocalizedIllegalArgumentException}
+ * .
+ *
+ * @return A function which parses {@code DN}s.
+ */
+ public static Function<String, DN, Void> stringToDN() {
+ return fixedFunction(STRING_TO_DN, Schema.getDefaultSchema());
+ }
+
+ /**
+ * Returns a function which parses {@code DN}s using the provided schema.
+ * Invalid values will result in a {@code LocalizedIllegalArgumentException}
+ * .
+ *
+ * @param schema
+ * The schema to use for decoding DNs.
+ * @return A function which parses {@code DN}s.
+ */
+ public static Function<String, DN, Void> stringToDN(final Schema schema) {
+ return fixedFunction(STRING_TO_DN, schema);
+ }
+
+ /**
+ * Returns a function which parses generalized time strings. Invalid values
+ * will result in a {@code LocalizedIllegalArgumentException}.
+ *
+ * @return A function which parses generalized time strings.
+ */
+ public static Function<String, GeneralizedTime, Void> stringToGeneralizedTime() {
+ return STRING_TO_GENERALIZED_TIME;
+ }
+
+ /**
+ * Returns a function which parses {@code Integer} string values. Invalid
+ * values will result in a {@code LocalizedIllegalArgumentException}.
+ *
+ * @return A function which parses {@code Integer} string values.
+ */
+ public static Function<String, Integer, Void> stringToInteger() {
+ return STRING_TO_INTEGER;
+ }
+
+ /**
+ * Returns a function which parses {@code Long} string values. Invalid
+ * values will result in a {@code LocalizedIllegalArgumentException}.
+ *
+ * @return A function which parses {@code Long} string values.
+ */
+ public static Function<String, Long, Void> stringToLong() {
+ return STRING_TO_LONG;
+ }
+
+ /**
+ * Returns a function which parses {@code AttributeDescription}s using the
+ * default schema. Invalid values will result in a
+ * {@code LocalizedIllegalArgumentException}.
+ *
+ * @return A function which parses {@code AttributeDescription}s.
*/
public static Function<ByteString, AttributeDescription, Void> valueToAttributeDescription() {
return fixedFunction(BYTESTRING_TO_ATTRIBUTE_DESCRIPTION, Schema.getDefaultSchema());
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as an {@code AttributeDescription} using the provided
- * schema. Invalid values will result in a
+ * Returns a function which parses {@code AttributeDescription}s using the
+ * provided schema. Invalid values will result in a
* {@code LocalizedIllegalArgumentException}.
*
* @param schema
* The schema to use for decoding attribute descriptions.
- * @return A function which parses the string representation of a
- * {@code ByteString} as an {@code AttributeDescription}.
+ * @return A function which parses {@code AttributeDescription}s.
*/
public static Function<ByteString, AttributeDescription, Void> valueToAttributeDescription(
final Schema schema) {
@@ -261,85 +441,66 @@
}
/**
- * Returns a function which encodes a {@code ByteString} as {@code Base64}.
+ * Returns a function which parses {@code Boolean} values. The function will
+ * accept the values {@code 0}, {@code false}, {@code no}, {@code off},
+ * {@code 1}, {@code true}, {@code yes}, {@code on}. All other values will
+ * result in a {@code NumberFormatException}.
*
- * @return A function which encodes a {@code ByteString} as {@code Base64}.
- */
- public static Function<ByteString, String, Void> valueToBase64() {
- return BYTESTRING_TO_BASE64;
- }
-
- /**
- * Returns a function which parses the string representation of a
- * {@code ByteString} to a {@code Boolean}. The function will accept the
- * values {@code 0}, {@code false}, {@code no}, {@code off}, {@code 1},
- * {@code true}, {@code yes}, {@code on}. All other values will result in a
- * {@code NumberFormatException}.
- *
- * @return A function which transforms a {@code ByteString} to a
- * {@code Boolean}.
+ * @return A function which parses {@code Boolean} values.
*/
public static Function<ByteString, Boolean, Void> valueToBoolean() {
return BYTESTRING_TO_BOOLEAN;
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as a generalized time syntax. Invalid values will
- * result in a {@code LocalizedIllegalArgumentException}.
+ * Returns a function which parses {@code DN}s using the default schema.
+ * Invalid values will result in a {@code LocalizedIllegalArgumentException}
+ * .
*
- * @return A function which parses the string representation of a
- * {@code ByteString} as generalized time syntax.
- */
- public static Function<ByteString, Calendar, Void> valueToCalendar() {
- return BYTESTRING_TO_CALENDAR;
- }
-
- /**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as a {@code DN} using the default schema. Invalid
- * values will result in a {@code LocalizedIllegalArgumentException}.
- *
- * @return A function which parses the string representation of a
- * {@code ByteString} as an {@code DN}.
+ * @return A function which parses {@code DN}s.
*/
public static Function<ByteString, DN, Void> valueToDN() {
return fixedFunction(BYTESTRING_TO_DN, Schema.getDefaultSchema());
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as a {@code DN} using the provided schema. Invalid
- * values will result in a {@code LocalizedIllegalArgumentException}.
+ * Returns a function which parses {@code DN}s using the provided schema.
+ * Invalid values will result in a {@code LocalizedIllegalArgumentException}
+ * .
*
* @param schema
* The schema to use for decoding DNs.
- * @return A function which parses the string representation of a
- * {@code ByteString} as an {@code DN}.
+ * @return A function which parses {@code DN}s.
*/
public static Function<ByteString, DN, Void> valueToDN(final Schema schema) {
return fixedFunction(BYTESTRING_TO_DN, schema);
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as an {@code Integer}. Invalid values will result in a
- * {@code NumberFormatException}.
+ * Returns a function which parses generalized time strings. Invalid values
+ * will result in a {@code LocalizedIllegalArgumentException}.
*
- * @return A function which parses the string representation of a
- * {@code ByteString} as an {@code Integer}.
+ * @return A function which parses generalized time strings.
+ */
+ public static Function<ByteString, GeneralizedTime, Void> valueToGeneralizedTime() {
+ return BYTESTRING_TO_GENERALIZED_TIME;
+ }
+
+ /**
+ * Returns a function which parses {@code Integer} string values. Invalid
+ * values will result in a {@code LocalizedIllegalArgumentException}.
+ *
+ * @return A function which parses {@code Integer} string values.
*/
public static Function<ByteString, Integer, Void> valueToInteger() {
return BYTESTRING_TO_INTEGER;
}
/**
- * Returns a function which parses the string representation of a
- * {@code ByteString} as a {@code Long}. Invalid values will result in a
- * {@code NumberFormatException}.
+ * Returns a function which parses {@code Long} string values. Invalid
+ * values will result in a {@code LocalizedIllegalArgumentException}.
*
- * @return A function which parses the string representation of a
- * {@code ByteString} as a {@code Long}.
+ * @return A function which parses {@code Long} string values.
*/
public static Function<ByteString, Long, Void> valueToLong() {
return BYTESTRING_TO_LONG;
--
Gitblit v1.10.0