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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.types; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.Random; 033 import java.util.SortedSet; 034 035 import org.opends.server.config.ConfigException; 036 037 import static org.opends.messages.UtilityMessages.*; 038 import static org.opends.server.util.StaticUtils.*; 039 040 041 042 /** 043 * This class provides a data structure that makes it possible to 044 * associate a name with a given set of characters. The name must 045 * consist only of ASCII alphabetic characters. 046 */ 047 @org.opends.server.types.PublicAPI( 048 stability=org.opends.server.types.StabilityLevel.VOLATILE, 049 mayInstantiate=true, 050 mayExtend=false, 051 mayInvoke=true) 052 public final class NamedCharacterSet 053 { 054 // The characters contained in this character set. 055 private char[] characters; 056 057 // The random number generator to use with this character set. 058 private Random random; 059 060 // The name assigned to this character set. 061 private String name; 062 063 064 065 /** 066 * Creates a new named character set with the provided information. 067 * 068 * @param name The name for this character set. 069 * @param characters The characters to include in this character 070 * set. 071 * 072 * @throws ConfigException If the provided name contains one or 073 * more illegal characters. 074 */ 075 public NamedCharacterSet(String name, char[] characters) 076 throws ConfigException 077 { 078 this.name = name; 079 this.characters = characters; 080 081 random = new Random(); 082 083 if ((name == null) || (name.length() == 0)) 084 { 085 Message message = ERR_CHARSET_CONSTRUCTOR_NO_NAME.get(); 086 throw new ConfigException(message); 087 } 088 089 for (int i=0; i < name.length(); i++) 090 { 091 if (! isAlpha(name.charAt(i))) 092 { 093 Message message = ERR_CHARSET_CONSTRUCTOR_INVALID_NAME_CHAR. 094 get(String.valueOf(name.charAt(i)), i); 095 throw new ConfigException(message); 096 } 097 } 098 } 099 100 101 102 /** 103 * Creates a new named character set with the provided information. 104 * 105 * @param name The name for this character set. 106 * @param characters The characters to include in this character 107 * set. 108 * @param random The random number generator to use with this 109 * character set. 110 * 111 * @throws ConfigException If the provided name contains one or 112 * more illegal characters. 113 */ 114 public NamedCharacterSet(String name, char[] characters, 115 Random random) 116 throws ConfigException 117 { 118 this.name = name; 119 this.characters = characters; 120 this.random = random; 121 122 if ((name == null) || (name.length() == 0)) 123 { 124 Message message = ERR_CHARSET_CONSTRUCTOR_NO_NAME.get(); 125 throw new ConfigException(message); 126 } 127 128 for (int i=0; i < name.length(); i++) 129 { 130 if (! isAlpha(name.charAt(i))) 131 { 132 Message message = ERR_CHARSET_CONSTRUCTOR_INVALID_NAME_CHAR. 133 get(String.valueOf(name.charAt(i)), i); 134 throw new ConfigException(message); 135 } 136 } 137 } 138 139 140 141 /** 142 * Retrieves the name for this character set. 143 * 144 * @return The name for this character set. 145 */ 146 public String getName() 147 { 148 return name; 149 } 150 151 152 153 /** 154 * Retrieves the characters included in this character set. 155 * 156 * @return The characters included in this character set. 157 */ 158 public char[] getCharacters() 159 { 160 return characters; 161 } 162 163 164 165 /** 166 * Retrieves a character at random from this named character set. 167 * 168 * @return The randomly-selected character from this named 169 * character set; 170 */ 171 public char getRandomCharacter() 172 { 173 if ((characters == null) || (characters.length == 0)) 174 { 175 return 0; 176 } 177 178 return characters[random.nextInt(characters.length)]; 179 } 180 181 182 183 /** 184 * Appends the specified number of characters chosen at random from 185 * this character set to the provided buffer. 186 * 187 * @param buffer The buffer to which the characters should be 188 * appended. 189 * @param count The number of characters to append to the 190 * provided buffer. 191 */ 192 public void getRandomCharacters(StringBuilder buffer, int count) 193 { 194 if ((characters == null) || (characters.length == 0)) 195 { 196 return; 197 } 198 199 for (int i=0; i < count; i++) 200 { 201 buffer.append(characters[random.nextInt(characters.length)]); 202 } 203 } 204 205 206 207 /** 208 * Encodes this character set to a form suitable for use in the 209 * value of a configuration attribute. 210 * 211 * @return The encoded character set in a form suitable for use in 212 * the value of a configuration attribute. 213 */ 214 public String encode() 215 { 216 return name + ":" + new String(characters); 217 } 218 219 220 221 /** 222 * Decodes the values of the provided configuration attribute as a 223 * set of character set definitions. 224 * 225 * @param values The set of encoded character set values to 226 * decode. 227 * 228 * @return The decoded character set definitions. 229 * 230 * @throws ConfigException If a problem occurs while attempting to 231 * decode the character set definitions. 232 */ 233 public static NamedCharacterSet[] 234 decodeCharacterSets(SortedSet<String> values) 235 throws ConfigException 236 { 237 NamedCharacterSet[] sets = new NamedCharacterSet[values.size()]; 238 int i = 0 ; 239 for (String value : values) 240 { 241 int colonPos = value.indexOf(':'); 242 if (colonPos < 0) 243 { 244 Message message = 245 ERR_CHARSET_NO_COLON.get(String.valueOf(value)); 246 throw new ConfigException(message); 247 } 248 else if (colonPos == 0) 249 { 250 Message message = 251 ERR_CHARSET_NO_NAME.get(String.valueOf(value)); 252 throw new ConfigException(message); 253 } 254 else if (colonPos == (value.length() - 1)) 255 { 256 Message message = 257 ERR_CHARSET_NO_CHARS.get(String.valueOf(value)); 258 throw new ConfigException(message); 259 } 260 else 261 { 262 String name = value.substring(0, colonPos); 263 char[] characters = value.substring(colonPos+1).toCharArray(); 264 sets[i] = new NamedCharacterSet(name, characters); 265 } 266 i++; 267 } 268 269 return sets; 270 } 271 } 272