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}