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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    
028    package org.opends.server.admin;
029    import org.opends.messages.Message;
030    
031    
032    
033    import static org.opends.server.util.Validator.ensureNotNull;
034    
035    import java.util.EnumSet;
036    import java.util.HashMap;
037    import java.util.Locale;
038    import java.util.Map;
039    import 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     */
050    public 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        /**
093         * {@inheritDoc}
094         */
095        @Override
096        protected EnumPropertyDefinition<E> buildInstance(
097            AbstractManagedObjectDefinition<?, ?> d, String propertyName,
098            EnumSet<PropertyOption> options,
099            AdministratorAction adminAction,
100            DefaultBehaviorProvider<E> defaultBehavior) {
101          // Make sure that the enumeration class has been defined.
102          if (enumClass == null) {
103            throw new IllegalStateException("Enumeration class undefined");
104          }
105    
106          return new EnumPropertyDefinition<E>(d, propertyName, options,
107              adminAction, defaultBehavior, enumClass);
108        }
109      }
110    
111    
112    
113      /**
114       * Create an enumeration property definition builder.
115       *
116       * @param <E>
117       *          The enumeration that should be used for values of this
118       *          property definition.
119       * @param d
120       *          The managed object definition associated with this
121       *          property definition.
122       * @param propertyName
123       *          The property name.
124       * @return Returns the new enumeration property definition builder.
125       */
126      public static <E extends Enum<E>> Builder<E> createBuilder(
127          AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
128        return new Builder<E>(d, propertyName);
129      }
130    
131      // The enumeration class.
132      private final Class<E> enumClass;
133    
134      // Map used for decoding values.
135      private final Map<String, E> decodeMap;
136    
137    
138    
139      // Private constructor.
140      private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
141          String propertyName, EnumSet<PropertyOption> options,
142          AdministratorAction adminAction,
143          DefaultBehaviorProvider<E> defaultBehavior, Class<E> enumClass) {
144        super(d, enumClass, propertyName, options, adminAction, defaultBehavior);
145        this.enumClass = enumClass;
146    
147        // Initialize the decoding map.
148        this.decodeMap = new HashMap<String, E>();
149        for (E value : EnumSet.<E> allOf(enumClass)) {
150          String s = value.toString().trim().toLowerCase();
151          this.decodeMap.put(s, value);
152        }
153      }
154    
155    
156    
157      /**
158       * {@inheritDoc}
159       */
160      @Override
161      public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
162        return v.visitEnum(this, p);
163      }
164    
165    
166    
167      /**
168       * {@inheritDoc}
169       */
170      @Override
171      public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) {
172        return v.visitEnum(this, value, p);
173      }
174    
175    
176    
177      /**
178       * {@inheritDoc}
179       */
180      @Override
181      public E decodeValue(String value)
182          throws IllegalPropertyValueStringException {
183        ensureNotNull(value);
184    
185        String nvalue = value.trim().toLowerCase();
186        E eValue = decodeMap.get(nvalue);
187        if (eValue == null) {
188          throw new IllegalPropertyValueStringException(this, value);
189        } else {
190          return eValue;
191        }
192      }
193    
194    
195    
196      /**
197       * Get the enumeration class used for values of this property.
198       *
199       * @return Returns the enumeration class used for values of this
200       *         property.
201       */
202      public Class<E> getEnumClass() {
203        return enumClass;
204      }
205    
206    
207    
208      /**
209       * Gets the synopsis of the specified enumeration value of this
210       * enumeration property definition in the default locale.
211       *
212       * @param value
213       *          The enumeration value.
214       * @return Returns the synopsis of the specified enumeration value
215       *         of this enumeration property definition in the default
216       *         locale.
217       */
218      public final Message getValueSynopsis(E value) {
219        return getValueSynopsis(Locale.getDefault(), value);
220      }
221    
222    
223    
224      /**
225       * Gets the synopsis of the specified enumeration value of this
226       * enumeration property definition in the specified locale.
227       *
228       * @param value
229       *          The enumeration value.
230       * @param locale
231       *          The locale.
232       * @return Returns the synopsis of the specified enumeration value
233       *         of this enumeration property definition in the specified
234       *         locale.
235       */
236      public final Message getValueSynopsis(Locale locale, E value) {
237        ManagedObjectDefinitionI18NResource resource =
238          ManagedObjectDefinitionI18NResource.getInstance();
239        String property = "property." + getName()
240            + ".syntax.enumeration.value." + value.toString()
241            + ".synopsis";
242        try {
243          return resource.getMessage(getManagedObjectDefinition(),
244              property, locale);
245        } catch (MissingResourceException e) {
246          return null;
247        }
248      }
249    
250    
251    
252      /**
253       * {@inheritDoc}
254       */
255      @Override
256      public String normalizeValue(E value)
257          throws IllegalPropertyValueException {
258        ensureNotNull(value);
259    
260        return value.toString().trim().toLowerCase();
261      }
262    
263    
264    
265      /**
266       * {@inheritDoc}
267       */
268      @Override
269      public void validateValue(E value)
270          throws IllegalPropertyValueException {
271        ensureNotNull(value);
272    
273        // No additional validation required.
274      }
275    }