From c6f391dd4d48922b9cf1c5fac08aecc67008f869 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 04 Jun 2007 17:26:28 +0000
Subject: [PATCH] Various improvements to the PropertyDefinition classes:
---
opends/src/server/org/opends/server/admin/PropertyDefinition.java | 464 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 392 insertions(+), 72 deletions(-)
diff --git a/opends/src/server/org/opends/server/admin/PropertyDefinition.java b/opends/src/server/org/opends/server/admin/PropertyDefinition.java
index 59b434c..7a027e7 100644
--- a/opends/src/server/org/opends/server/admin/PropertyDefinition.java
+++ b/opends/src/server/org/opends/server/admin/PropertyDefinition.java
@@ -29,31 +29,186 @@
-import java.io.Serializable;
+import static org.opends.server.util.Validator.*;
+
import java.util.Comparator;
+import java.util.EnumSet;
import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Set;
/**
* An interface for querying generic property definition features.
* <p>
- * Property definitions are analogous to ConfigAttributes in the current model
- * and will play a similar role. Eventually these will replace them.
+ * Property definitions are analogous to ConfigAttributes in the
+ * current model and will play a similar role. Eventually these will
+ * replace them.
* <p>
- * Implementations <b>must</b> take care to implement the various comparison
- * methods.
+ * Implementations <b>must</b> take care to implement the various
+ * comparison methods.
* <p>
- * Implementations of this interface must be serializable. This is required so
- * that management applications can query property meta-information remotely.
- * <p>
- * TODO: define other call-backs (e.g. initial values).
+ * Implementations of this interface must be serializable. This is
+ * required so that management applications can query property
+ * meta-information remotely.
*
* @param <T>
* The data-type of values of the property.
*/
-public interface PropertyDefinition<T> extends Comparator<T>,
- Comparable<PropertyDefinition<?>>, Serializable {
+public abstract class PropertyDefinition<T> implements Comparator<T>,
+ Comparable<PropertyDefinition<?>> {
+
+ /**
+ * An interface for incrementally constructing property definitions.
+ *
+ * @param <T>
+ * The data-type of values of the property.
+ * @param <D>
+ * The type of property definition constructed by this
+ * builder.
+ */
+ protected abstract static class AbstractBuilder
+ <T, D extends PropertyDefinition<T>> {
+
+ // The default behavior provider.
+ private DefaultBehaviorProvider<T> defaultBehavior;
+
+ // The abstract managed object
+ private final AbstractManagedObjectDefinition<?, ?> definition;
+
+ // The options applicable to this definition.
+ private final EnumSet<PropertyOption> options;
+
+ // The name of this property definition.
+ private final String propertyName;
+
+
+
+ /**
+ * Create a property definition builder.
+ *
+ * @param d
+ * The managed object definition associated with this
+ * property definition.
+ * @param propertyName
+ * The property name.
+ */
+ protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> d,
+ String propertyName) {
+ this.definition = d;
+ this.propertyName = propertyName;
+ this.options = EnumSet.noneOf(PropertyOption.class);
+ this.defaultBehavior = new UndefinedDefaultBehaviorProvider<T>();
+ }
+
+
+
+ /**
+ * Construct a property definition based on the properties of this
+ * builder.
+ *
+ * @return The new property definition.
+ */
+ public final D getInstance() {
+ return buildInstance(definition, propertyName, options, defaultBehavior);
+ }
+
+
+
+ /**
+ * Set the default behavior provider.
+ *
+ * @param defaultBehavior
+ * The default behavior provider.
+ */
+ public final void setDefaultBehaviorProvider(
+ DefaultBehaviorProvider<T> defaultBehavior) {
+ ensureNotNull(defaultBehavior);
+ this.defaultBehavior = defaultBehavior;
+ }
+
+
+
+ /**
+ * Add a property definition option.
+ *
+ * @param option
+ * The property option.
+ */
+ public final void setOption(PropertyOption option) {
+ ensureNotNull(option);
+ options.add(option);
+ }
+
+
+
+ /**
+ * Build a property definition based on the properties of this
+ * builder.
+ *
+ * @param d
+ * The managed object definition associated with this
+ * property definition.
+ * @param propertyName
+ * The property name.
+ * @param options
+ * Options applicable to this definition.
+ * @param defaultBehavior
+ * The default behavior provider.
+ * @return The new property definition.
+ */
+ protected abstract D buildInstance(AbstractManagedObjectDefinition<?, ?> d,
+ String propertyName, EnumSet<PropertyOption> options,
+ DefaultBehaviorProvider<T> defaultBehavior);
+ }
+
+ // The default behavior provider.
+ private final DefaultBehaviorProvider<T> defaultBehavior;
+
+ // The abstract managed object
+ private final AbstractManagedObjectDefinition<?, ?> definition;
+
+ // Options applicable to this definition.
+ private final Set<PropertyOption> options;
+
+ // The property name.
+ private final String propertyName;
+
+ // The property value class.
+ private final Class<T> theClass;
+
+
+
+ /**
+ * Create a property definition.
+ *
+ * @param d
+ * The managed object definition associated with this
+ * property definition.
+ * @param theClass
+ * The property value class.
+ * @param propertyName
+ * The property name.
+ * @param options
+ * Options applicable to this definition.
+ * @param defaultBehavior
+ * The default behavior provider.
+ */
+ protected PropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
+ Class<T> theClass, String propertyName, EnumSet<PropertyOption> options,
+ DefaultBehaviorProvider<T> defaultBehavior) {
+ ensureNotNull(d, theClass, propertyName);
+ ensureNotNull(options, defaultBehavior);
+
+ this.definition = d;
+ this.theClass = theClass;
+ this.propertyName = propertyName;
+ this.options = EnumSet.copyOf(options);
+ this.defaultBehavior = defaultBehavior;
+ }
+
+
/**
* Apply a visitor to this property definition.
@@ -61,14 +216,36 @@
* @param <R>
* The return type of the visitor's methods.
* @param <P>
- * The type of the additional parameters to the visitor's methods.
+ * The type of the additional parameters to the visitor's
+ * methods.
* @param v
* The property definition visitor.
* @param p
* Optional additional visitor parameter.
* @return Returns a result as specified by the visitor.
*/
- <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p);
+ public abstract <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p);
+
+
+
+ /**
+ * Apply a visitor to a property value associated with this property
+ * definition.
+ *
+ * @param <R>
+ * The return type of the visitor's methods.
+ * @param <P>
+ * The type of the additional parameters to the visitor's
+ * methods.
+ * @param v
+ * The property value visitor.
+ * @param value
+ * The property value.
+ * @param p
+ * Optional additional visitor parameter.
+ * @return Returns a result as specified by the visitor.
+ */
+ public abstract <R, P> R accept(PropertyValueVisitor<R, P> v, T value, P p);
@@ -76,9 +253,10 @@
* Cast the provided value to the type associated with this property
* definition.
* <p>
- * This method only casts the object to the required type; it does not
- * validate the value once it has been cast. Subsequent validation should be
- * performed using the method {@link #validateValue(Object)}.
+ * This method only casts the object to the required type; it does
+ * not validate the value once it has been cast. Subsequent
+ * validation should be performed using the method
+ * {@link #validateValue(Object)}.
* <p>
* This method guarantees the following expression is always
* <code>true</code>:
@@ -92,28 +270,65 @@
* The property value to be cast (can be <code>null</code>).
* @return Returns the property value cast to the correct type.
* @throws ClassCastException
- * If the provided property value did not have the correct type.
+ * If the provided property value did not have the correct
+ * type.
*/
- T castValue(Object object) throws ClassCastException;
+ public final T castValue(Object object) throws ClassCastException {
+ return theClass.cast(object);
+ }
/**
- * Compares this property definition with the specified property definition
- * for order. Returns a negative integer, zero, or a positive integer if this
- * property definition is less than, equal to, or greater than the specified
- * property definition.
+ * Compares two property values for order. Returns a negative
+ * integer, zero, or a positive integer as the first argument is
+ * less than, equal to, or greater than the second.
* <p>
- * The ordering must be determined first from the property name and then base
- * on the underlying value type.
+ * This default implementation normalizes both values using
+ * {@link #normalizeValue(Object)} and then performs a
+ * case-sensitive string comparison.
+ *
+ * @param o1
+ * the first object to be compared.
+ * @param o2
+ * the second object to be compared.
+ * @return a negative integer, zero, or a positive integer as the
+ * first argument is less than, equal to, or greater than
+ * the second.
+ */
+ public int compare(T o1, T o2) {
+ ensureNotNull(o1, o2);
+
+ String s1 = normalizeValue(o1);
+ String s2 = normalizeValue(o2);
+
+ return s1.compareTo(s2);
+ }
+
+
+
+ /**
+ * Compares this property definition with the specified property
+ * definition for order. Returns a negative integer, zero, or a
+ * positive integer if this property definition is less than, equal
+ * to, or greater than the specified property definition.
+ * <p>
+ * The ordering must be determined first from the property name and
+ * then base on the underlying value type.
*
* @param o
* The reference property definition with which to compare.
- * @return Returns a negative integer, zero, or a positive integer if this
- * property definition is less than, equal to, or greater than the
- * specified property definition.
+ * @return Returns a negative integer, zero, or a positive integer
+ * if this property definition is less than, equal to, or
+ * greater than the specified property definition.
*/
- int compareTo(PropertyDefinition<?> o);
+ public final int compareTo(PropertyDefinition<?> o) {
+ int rc = propertyName.compareTo(o.propertyName);
+ if (rc == 0) {
+ rc = theClass.getName().compareTo(o.theClass.getName());
+ }
+ return rc;
+ }
@@ -126,14 +341,17 @@
* @throws IllegalPropertyValueStringException
* If the property value string is invalid.
*/
- T decodeValue(String value) throws IllegalPropertyValueStringException;
+ public abstract T decodeValue(String value)
+ throws IllegalPropertyValueStringException;
/**
- * Encode the provided property value into its string representation.
+ * Encode the provided property value into its string
+ * representation.
* <p>
- * TODO: change name to avoid confusion with toString()?
+ * This default implementation simply returns invokes the
+ * {@link Object#toString()} method on the provided value.
*
* @param value
* The property value (must not be <code>null</code>).
@@ -141,29 +359,50 @@
* @throws IllegalPropertyValueException
* If the property value is invalid.
*/
- String encodeValue(T value) throws IllegalPropertyValueException;
+ public String encodeValue(T value) throws IllegalPropertyValueException {
+ ensureNotNull(value);
+
+ return value.toString();
+ }
/**
- * Indicates whether some other object is "equal to" this property
- * definition. This method must obey the general contract of
- * <tt>Object.equals(Object)</tt>. Additionally, this method can return
- * <tt>true</tt> <i>only</i> if the specified Object is also a property
- * definition and it has the same name, as returned by {@link #getName()},
- * and also is deemed to be "compatible" with this property
- * definition. Compatibility means that the two property definitions share the
- * same underlying value type and provide similar comparator implementations.
+ * Indicates whether some other object is "equal to" this
+ * property definition. This method must obey the general contract
+ * of <tt>Object.equals(Object)</tt>. Additionally, this method
+ * can return <tt>true</tt> <i>only</i> if the specified Object
+ * is also a property definition and it has the same name, as
+ * returned by {@link #getName()}, and also is deemed to be
+ * "compatible" with this property definition.
+ * Compatibility means that the two property definitions share the
+ * same underlying value type and provide similar comparator
+ * implementations.
*
* @param o
* The reference object with which to compare.
- * @return Returns <code>true</code> only if the specified object is also a
- * property definition and it has the same name and is compatible with
- * this property definition.
+ * @return Returns <code>true</code> only if the specified object
+ * is also a property definition and it has the same name
+ * and is compatible with this property definition.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.Object#hashCode()
*/
- boolean equals(Object o);
+ @Override
+ public final boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o instanceof PropertyDefinition) {
+ PropertyDefinition other = (PropertyDefinition) o;
+ if (propertyName.equals(other.propertyName)) {
+ if (theClass.equals(other.theClass)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return false;
+ }
+ }
@@ -171,10 +410,12 @@
* Get the default behavior provider associated with this property
* definition.
*
- * @return Returns the default behavior provider associated with this
- * property definition.
+ * @return Returns the default behavior provider associated with
+ * this property definition.
*/
- DefaultBehaviorProvider<T> getDefaultBehaviorProvider();
+ public final DefaultBehaviorProvider<T> getDefaultBehaviorProvider() {
+ return defaultBehavior;
+ }
@@ -186,7 +427,9 @@
* the default locale, or <code>null</code> if there is no
* description.
*/
- String getDescription();
+ public final String getDescription() {
+ return getDescription(Locale.getDefault());
+ }
@@ -200,7 +443,30 @@
* the specified locale, or <code>null</code> if there is
* no description.
*/
- String getDescription(Locale locale);
+ public final String getDescription(Locale locale) {
+ ManagedObjectDefinitionI18NResource resource =
+ ManagedObjectDefinitionI18NResource.getInstance();
+ String property = "property." + propertyName + ".description";
+ try {
+ return resource.getMessage(definition, property, locale);
+ } catch (MissingResourceException e) {
+ return null;
+ }
+ }
+
+
+
+ /**
+ * Gets the managed object definition associated with this property
+ * definition.
+ *
+ * @return Returns the managed object definition associated with
+ * this property definition.
+ */
+ public final AbstractManagedObjectDefinition<?, ?>
+ getManagedObjectDefinition() {
+ return definition;
+ }
@@ -209,7 +475,9 @@
*
* @return Returns the name of the property.
*/
- String getName();
+ public final String getName() {
+ return propertyName;
+ }
@@ -220,7 +488,9 @@
* @return Returns the synopsis of this property definition in the
* default locale.
*/
- String getSynopsis();
+ public final String getSynopsis() {
+ return getSynopsis(Locale.getDefault());
+ }
@@ -233,40 +503,63 @@
* @return Returns the synopsis of this property definition in the
* specified locale.
*/
- String getSynopsis(Locale locale);
+ public final String getSynopsis(Locale locale) {
+ ManagedObjectDefinitionI18NResource resource =
+ ManagedObjectDefinitionI18NResource.getInstance();
+ String property = "property." + propertyName + ".synopsis";
+ try {
+ return resource.getMessage(definition, property, locale);
+ } catch (MissingResourceException e) {
+ return null;
+ }
+ }
/**
- * Returns a hash code value for this property definition. The hash code
- * should be derived from the property name.
+ * Returns a hash code value for this property definition. The hash
+ * code should be derived from the property name and the type of
+ * values handled by this property definition.
*
* @return Returns the hash code value for this property definition.
*/
- int hashCode();
+ @Override
+ public final int hashCode() {
+ int rc = 17 + propertyName.hashCode();
+ return 37 * rc + theClass.hashCode();
+ }
/**
- * Check if the specified option is set for this property definition.
+ * Check if the specified option is set for this property
+ * definition.
*
* @param option
* The option to test.
* @return Returns <code>true</code> if the option is set, or
* <code>false</code> otherwise.
*/
- boolean hasOption(PropertyOption option);
+ public final boolean hasOption(PropertyOption option) {
+ return options.contains(option);
+ }
/**
- * Get a normalized string representation of a property value. This can then
- * be used for comparisons and for generating hash-codes.
+ * Get a normalized string representation of a property value. This
+ * can then be used for comparisons and for generating hash-codes.
* <p>
- * This method may throw an exception if the provided value is invalid.
- * However, applications should not assume that implementations of this method
- * will always validate a value. This task is the responsibility of
- * {@link #validateValue(Object)}.
+ * This method may throw an exception if the provided value is
+ * invalid. However, applications should not assume that
+ * implementations of this method will always validate a value. This
+ * task is the responsibility of {@link #validateValue(Object)}.
+ * <p>
+ * This default implementation simply returns the string
+ * representation of the provided value. Sub-classes might want to
+ * override this method if this behavior is insufficient (for
+ * example, a string property definition might strip white-space and
+ * convert characters to lower-case).
*
* @param value
* The property value to be normalized.
@@ -274,30 +567,57 @@
* @throws IllegalPropertyValueException
* If the property value is invalid.
*/
- String normalizeValue(T value) throws IllegalPropertyValueException;
+ public String normalizeValue(T value) throws IllegalPropertyValueException {
+ ensureNotNull(value);
+
+ return encodeValue(value);
+ }
/**
- * Append a string representation of the property definition to the provided
- * string builder.
+ * Returns a string representation of this property definition.
+ *
+ * @return Returns a string representation of this property
+ * definition.
+ * @see Object#toString()
+ */
+ @Override
+ public final String toString() {
+ StringBuilder builder = new StringBuilder();
+ toString(builder);
+ return builder.toString();
+ }
+
+
+
+ /**
+ * Append a string representation of the property definition to the
+ * provided string builder.
+ * <p>
+ * This simple implementation just outputs the propertyName of the
+ * property definition. Sub-classes should override this method to
+ * provide more complete string representations.
*
* @param builder
- * The string builder where the string representation should be
- * appended.
+ * The string builder where the string representation
+ * should be appended.
*/
- void toString(StringBuilder builder);
+ public void toString(StringBuilder builder) {
+ builder.append(propertyName);
+ }
/**
- * Determine if the provided property value is valid according to this
- * property definition.
+ * Determine if the provided property value is valid according to
+ * this property definition.
*
* @param value
* The property value (must not be <code>null</code>).
* @throws IllegalPropertyValueException
* If the property value is invalid.
*/
- void validateValue(T value) throws IllegalPropertyValueException;
+ public abstract void validateValue(T value)
+ throws IllegalPropertyValueException;
}
--
Gitblit v1.10.0