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