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-2016 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 @Override 070 protected EnumPropertyDefinition<E> buildInstance(AbstractManagedObjectDefinition<?, ?> d, 071 String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, 072 DefaultBehaviorProvider<E> defaultBehavior) { 073 // Make sure that the enumeration class has been defined. 074 if (enumClass == null) { 075 throw new IllegalStateException("Enumeration class undefined"); 076 } 077 078 return new EnumPropertyDefinition<>(d, propertyName, options, adminAction, defaultBehavior, enumClass); 079 } 080 } 081 082 /** 083 * Create an enumeration property definition builder. 084 * 085 * @param <E> 086 * The enumeration that should be used for values of this 087 * property definition. 088 * @param d 089 * The managed object definition associated with this property 090 * definition. 091 * @param propertyName 092 * The property name. 093 * @return Returns the new enumeration property definition builder. 094 */ 095 public static <E extends Enum<E>> Builder<E> createBuilder(AbstractManagedObjectDefinition<?, ?> d, 096 String propertyName) { 097 return new Builder<>(d, propertyName); 098 } 099 100 /** The enumeration class. */ 101 private final Class<E> enumClass; 102 103 /** Map used for decoding values. */ 104 private final Map<String, E> decodeMap; 105 106 /** Private constructor. */ 107 private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, 108 EnumSet<PropertyOption> options, AdministratorAction adminAction, DefaultBehaviorProvider<E> defaultBehavior, 109 Class<E> enumClass) { 110 super(d, enumClass, propertyName, options, adminAction, defaultBehavior); 111 this.enumClass = enumClass; 112 113 // Initialize the decoding map. 114 this.decodeMap = new HashMap<>(); 115 for (E value : EnumSet.<E> allOf(enumClass)) { 116 String s = value.toString().trim().toLowerCase(); 117 this.decodeMap.put(s, value); 118 } 119 } 120 121 @Override 122 public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { 123 return v.visitEnum(this, p); 124 } 125 126 @Override 127 public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) { 128 return v.visitEnum(this, value, p); 129 } 130 131 @Override 132 public E decodeValue(String value) { 133 Reject.ifNull(value); 134 135 String nvalue = value.trim().toLowerCase(); 136 E eValue = decodeMap.get(nvalue); 137 if (eValue != null) { 138 return eValue; 139 } 140 throw PropertyException.illegalPropertyValueException(this, value); 141 } 142 143 /** 144 * Get the enumeration class used for values of this property. 145 * 146 * @return Returns the enumeration class used for values of this property. 147 */ 148 public Class<E> getEnumClass() { 149 return enumClass; 150 } 151 152 /** 153 * Gets the synopsis of the specified enumeration value of this enumeration 154 * property definition in the default locale. 155 * 156 * @param value 157 * The enumeration value. 158 * @return Returns the synopsis of the specified enumeration value of this 159 * enumeration property definition in the default locale. 160 */ 161 public final LocalizableMessage getValueSynopsis(E value) { 162 return getValueSynopsis(Locale.getDefault(), value); 163 } 164 165 /** 166 * Gets the synopsis of the specified enumeration value of this enumeration 167 * property definition in the specified locale. 168 * 169 * @param value 170 * The enumeration value. 171 * @param locale 172 * The locale. 173 * @return Returns the synopsis of the specified enumeration value of this 174 * enumeration property definition in the specified locale. 175 */ 176 public final LocalizableMessage getValueSynopsis(Locale locale, E value) { 177 ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); 178 String property = "property." + getName() + ".syntax.enumeration.value." + value + ".synopsis"; 179 try { 180 return resource.getMessage(getManagedObjectDefinition(), property, locale); 181 } catch (MissingResourceException e) { 182 return null; 183 } 184 } 185 186 @Override 187 public String normalizeValue(E value) { 188 Reject.ifNull(value); 189 190 return value.toString().trim().toLowerCase(); 191 } 192 193 @Override 194 public void validateValue(E value) { 195 Reject.ifNull(value); 196 197 // No additional validation required. 198 } 199}