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