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 2015 ForgeRock AS. 016 */ 017package org.forgerock.opendj.config; 018 019import org.forgerock.util.Reject; 020 021import java.util.EnumSet; 022import java.util.HashMap; 023import java.util.Locale; 024import java.util.Map; 025import java.util.MissingResourceException; 026 027import org.forgerock.i18n.LocalizableMessage; 028 029/** 030 * Enumeration property definition. 031 * 032 * @param <E> 033 * The enumeration that should be used for values of this property 034 * definition. 035 */ 036public final class EnumPropertyDefinition<E extends Enum<E>> extends PropertyDefinition<E> { 037 038 /** 039 * An interface for incrementally constructing enumeration property 040 * definitions. 041 * 042 * @param <E> 043 * The enumeration that should be used for values of this 044 * property definition. 045 */ 046 public static final class Builder<E extends Enum<E>> extends AbstractBuilder<E, EnumPropertyDefinition<E>> { 047 048 /** The enumeration class. */ 049 private Class<E> enumClass; 050 051 /** Private constructor. */ 052 private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { 053 super(d, propertyName); 054 this.enumClass = null; 055 } 056 057 /** 058 * Set the enumeration class which should be used for values of this 059 * property definition. 060 * 061 * @param enumClass 062 * The enumeration class which should be used for values of 063 * this property definition. 064 */ 065 public final void setEnumClass(Class<E> enumClass) { 066 this.enumClass = enumClass; 067 } 068 069 /** {@inheritDoc} */ 070 @Override 071 protected EnumPropertyDefinition<E> buildInstance(AbstractManagedObjectDefinition<?, ?> d, 072 String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, 073 DefaultBehaviorProvider<E> defaultBehavior) { 074 // Make sure that the enumeration class has been defined. 075 if (enumClass == null) { 076 throw new IllegalStateException("Enumeration class undefined"); 077 } 078 079 return new EnumPropertyDefinition<>(d, propertyName, options, adminAction, defaultBehavior, enumClass); 080 } 081 } 082 083 /** 084 * Create an enumeration property definition builder. 085 * 086 * @param <E> 087 * The enumeration that should be used for values of this 088 * property definition. 089 * @param d 090 * The managed object definition associated with this property 091 * definition. 092 * @param propertyName 093 * The property name. 094 * @return Returns the new enumeration property definition builder. 095 */ 096 public static <E extends Enum<E>> Builder<E> createBuilder(AbstractManagedObjectDefinition<?, ?> d, 097 String propertyName) { 098 return new Builder<>(d, propertyName); 099 } 100 101 /** The enumeration class. */ 102 private final Class<E> enumClass; 103 104 /** Map used for decoding values. */ 105 private final Map<String, E> decodeMap; 106 107 /** Private constructor. */ 108 private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, 109 EnumSet<PropertyOption> options, AdministratorAction adminAction, DefaultBehaviorProvider<E> defaultBehavior, 110 Class<E> enumClass) { 111 super(d, enumClass, propertyName, options, adminAction, defaultBehavior); 112 this.enumClass = enumClass; 113 114 // Initialize the decoding map. 115 this.decodeMap = new HashMap<>(); 116 for (E value : EnumSet.<E> allOf(enumClass)) { 117 String s = value.toString().trim().toLowerCase(); 118 this.decodeMap.put(s, value); 119 } 120 } 121 122 /** {@inheritDoc} */ 123 @Override 124 public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { 125 return v.visitEnum(this, p); 126 } 127 128 /** {@inheritDoc} */ 129 @Override 130 public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) { 131 return v.visitEnum(this, value, p); 132 } 133 134 /** {@inheritDoc} */ 135 @Override 136 public E decodeValue(String value) { 137 Reject.ifNull(value); 138 139 String nvalue = value.trim().toLowerCase(); 140 E eValue = decodeMap.get(nvalue); 141 if (eValue != null) { 142 return eValue; 143 } 144 throw PropertyException.illegalPropertyValueException(this, value); 145 } 146 147 /** 148 * Get the enumeration class used for values of this property. 149 * 150 * @return Returns the enumeration class used for values of this property. 151 */ 152 public Class<E> getEnumClass() { 153 return enumClass; 154 } 155 156 /** 157 * Gets the synopsis of the specified enumeration value of this enumeration 158 * property definition in the default locale. 159 * 160 * @param value 161 * The enumeration value. 162 * @return Returns the synopsis of the specified enumeration value of this 163 * enumeration property definition in the default locale. 164 */ 165 public final LocalizableMessage getValueSynopsis(E value) { 166 return getValueSynopsis(Locale.getDefault(), value); 167 } 168 169 /** 170 * Gets the synopsis of the specified enumeration value of this enumeration 171 * property definition in the specified locale. 172 * 173 * @param value 174 * The enumeration value. 175 * @param locale 176 * The locale. 177 * @return Returns the synopsis of the specified enumeration value of this 178 * enumeration property definition in the specified locale. 179 */ 180 public final LocalizableMessage getValueSynopsis(Locale locale, E value) { 181 ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); 182 String property = "property." + getName() + ".syntax.enumeration.value." + value + ".synopsis"; 183 try { 184 return resource.getMessage(getManagedObjectDefinition(), property, locale); 185 } catch (MissingResourceException e) { 186 return null; 187 } 188 } 189 190 /** {@inheritDoc} */ 191 @Override 192 public String normalizeValue(E value) { 193 Reject.ifNull(value); 194 195 return value.toString().trim().toLowerCase(); 196 } 197 198 /** {@inheritDoc} */ 199 @Override 200 public void validateValue(E value) { 201 Reject.ifNull(value); 202 203 // No additional validation required. 204 } 205}