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