001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2015 ForgeRock AS.
016 */
017
018package org.opends.server.admin;
019import org.forgerock.i18n.LocalizableMessage;
020
021
022
023import static org.forgerock.util.Reject.ifNull;
024
025import java.util.EnumSet;
026import java.util.HashMap;
027import java.util.Locale;
028import java.util.Map;
029import java.util.MissingResourceException;
030
031
032
033/**
034 * Enumeration property definition.
035 *
036 * @param <E>
037 *          The enumeration that should be used for values of this
038 *          property definition.
039 */
040public final class EnumPropertyDefinition<E extends Enum<E>> extends
041    PropertyDefinition<E> {
042
043  /**
044   * An interface for incrementally constructing enumeration property
045   * definitions.
046   *
047   * @param <E>
048   *          The enumeration that should be used for values of this
049   *          property definition.
050   */
051  public static class Builder<E extends Enum<E>> extends
052      AbstractBuilder<E, EnumPropertyDefinition<E>> {
053
054    /** The enumeration class. */
055    private Class<E> enumClass;
056
057
058
059    /** Private constructor. */
060    private Builder(
061        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
062      super(d, propertyName);
063      this.enumClass = null;
064    }
065
066
067
068    /**
069     * Set the enumeration class which should be used for values of
070     * this property definition.
071     *
072     * @param enumClass
073     *          The enumeration class which should be used for values
074     *          of this property definition.
075     */
076    public final void setEnumClass(Class<E> enumClass) {
077      this.enumClass = enumClass;
078    }
079
080
081
082    /** {@inheritDoc} */
083    @Override
084    protected EnumPropertyDefinition<E> buildInstance(
085        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
086        EnumSet<PropertyOption> options,
087        AdministratorAction adminAction,
088        DefaultBehaviorProvider<E> defaultBehavior) {
089      // Make sure that the enumeration class has been defined.
090      if (enumClass == null) {
091        throw new IllegalStateException("Enumeration class undefined");
092      }
093
094      return new EnumPropertyDefinition<>(d, propertyName, options,
095          adminAction, defaultBehavior, enumClass);
096    }
097  }
098
099
100
101  /**
102   * Create an enumeration property definition builder.
103   *
104   * @param <E>
105   *          The enumeration that should be used for values of this
106   *          property definition.
107   * @param d
108   *          The managed object definition associated with this
109   *          property definition.
110   * @param propertyName
111   *          The property name.
112   * @return Returns the new enumeration property definition builder.
113   */
114  public static <E extends Enum<E>> Builder<E> createBuilder(
115      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
116    return new Builder<>(d, propertyName);
117  }
118
119  /** The enumeration class. */
120  private final Class<E> enumClass;
121
122  /** Map used for decoding values. */
123  private final Map<String, E> decodeMap;
124
125
126
127  /** Private constructor. */
128  private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
129      String propertyName, EnumSet<PropertyOption> options,
130      AdministratorAction adminAction,
131      DefaultBehaviorProvider<E> defaultBehavior, Class<E> enumClass) {
132    super(d, enumClass, propertyName, options, adminAction, defaultBehavior);
133    this.enumClass = enumClass;
134
135    // Initialize the decoding map.
136    this.decodeMap = new HashMap<>();
137    for (E value : EnumSet.<E> allOf(enumClass)) {
138      String s = value.toString().trim().toLowerCase();
139      this.decodeMap.put(s, value);
140    }
141  }
142
143
144
145  /** {@inheritDoc} */
146  @Override
147  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
148    return v.visitEnum(this, p);
149  }
150
151
152
153  /** {@inheritDoc} */
154  @Override
155  public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) {
156    return v.visitEnum(this, value, p);
157  }
158
159
160
161  /** {@inheritDoc} */
162  @Override
163  public E decodeValue(String value)
164      throws PropertyException {
165    ifNull(value);
166
167    String nvalue = value.trim().toLowerCase();
168    E eValue = decodeMap.get(nvalue);
169    if (eValue == null) {
170      throw PropertyException.illegalPropertyValueException(this, value);
171    } else {
172      return eValue;
173    }
174  }
175
176
177
178  /**
179   * Get the enumeration class used for values of this property.
180   *
181   * @return Returns the enumeration class used for values of this
182   *         property.
183   */
184  public Class<E> getEnumClass() {
185    return enumClass;
186  }
187
188
189
190  /**
191   * Gets the synopsis of the specified enumeration value of this
192   * enumeration property definition in the default locale.
193   *
194   * @param value
195   *          The enumeration value.
196   * @return Returns the synopsis of the specified enumeration value
197   *         of this enumeration property definition in the default
198   *         locale.
199   */
200  public final LocalizableMessage getValueSynopsis(E value) {
201    return getValueSynopsis(Locale.getDefault(), value);
202  }
203
204
205
206  /**
207   * Gets the synopsis of the specified enumeration value of this
208   * enumeration property definition in the specified locale.
209   *
210   * @param value
211   *          The enumeration value.
212   * @param locale
213   *          The locale.
214   * @return Returns the synopsis of the specified enumeration value
215   *         of this enumeration property definition in the specified
216   *         locale.
217   */
218  public final LocalizableMessage getValueSynopsis(Locale locale, E value) {
219    ManagedObjectDefinitionI18NResource resource =
220      ManagedObjectDefinitionI18NResource.getInstance();
221    String property = "property." + getName()
222        + ".syntax.enumeration.value." + value
223        + ".synopsis";
224    try {
225      return resource.getMessage(getManagedObjectDefinition(),
226          property, locale);
227    } catch (MissingResourceException e) {
228      return null;
229    }
230  }
231
232
233
234  /** {@inheritDoc} */
235  @Override
236  public String normalizeValue(E value)
237      throws PropertyException {
238    ifNull(value);
239
240    return value.toString().trim().toLowerCase();
241  }
242
243
244
245  /** {@inheritDoc} */
246  @Override
247  public void validateValue(E value)
248      throws PropertyException {
249    ifNull(value);
250
251    // No additional validation required.
252  }
253}