mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

ludovicp
29.35.2010 7c30dbb5403772b323df3ad907d9ed15d23b5aee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2007-2009 Sun Microsystems, Inc.
 */
 
package org.opends.messages;
 
import java.util.Locale;
import java.util.List;
import java.util.LinkedList;
import java.io.Serializable;
 
/**
 * A builder used specifically for messages.  As messages are
 * appended they are translated to their string representation
 * for storage using the locale specified in the constructor.
 *
 * Note that before you use this class you should consider whether
 * it is appropriate.  In general composing messages by appending
 * message to each other may not produce a message that is
 * formatted appropriately for all locales.  It is usually better
 * to create messages by composition.  In other words you should
 * create a base message that contains one or more string argument
 * specifiers (%s) and define other message objects to use as
 * replacement variables.  In this way language translators have
 * a change to reformat the message for a particular locale if
 * necessary.
 */
@org.opends.server.types.PublicAPI(
    stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
    mayInstantiate=true,
    mayExtend=false,
    mayInvoke=true)
public final class MessageBuilder implements Appendable, CharSequence,
    Serializable
{
 
  private static final long serialVersionUID = -3292823563904285315L;
 
  /** Used internally to store appended messages. */
  private final StringBuilder sb = new StringBuilder();
 
  /** Used internally to store appended messages. */
  private final List<Message> messages = new LinkedList<Message>();
 
  /** Used to render the string representation of appended messages. */
  private final Locale locale;
 
  /**
   * Constructs an instance that will build messages
   * in the default locale.
   */
  public MessageBuilder() {
    this(Locale.getDefault());
  }
 
  /**
   * Constructs an instance that will build messages
   * in the default locale having an initial message.
   *
   * @param message initial message
   */
  public MessageBuilder(Message message) {
    this(Locale.getDefault());
    append(message);
  }
 
  /**
   * Constructs an instance that will build messages
   * in the default locale having an initial message.
   *
   * @param message initial message
   */
  public MessageBuilder(String message) {
    this(Locale.getDefault());
    append(message);
  }
 
  /**
   * Constructs an instance from another <code>MessageBuilder</code>.
   *
   * @param mb from which to construct a new message builder
   */
  public MessageBuilder(MessageBuilder mb) {
    for (Message msg : mb.messages) {
      this.messages.add(msg);
    }
    this.sb.append(sb);
    this.locale = mb.locale;
  }
 
  /**
   * Constructs an instance that will build messages
   * in a specified locale.
   *
   * @param locale used for translating appended messages
   */
  public MessageBuilder(Locale locale) {
    this.locale = locale;
  }
 
  /**
   * Append a message to this builder.  The string
   * representation of the locale specifed in the
   * constructor will be stored in this builder.
   *
   * @param message to be appended
   * @return reference to this builder
   */
  public MessageBuilder append(Message message) {
    if (message != null) {
      sb.append(message.toString(locale));
      messages.add(message);
    }
    return this;
  }
 
  /**
   * Append an integer to this builder.
   *
   * @param number to append
   * @return reference to this builder
   */
  public MessageBuilder append(int number) {
    append(String.valueOf(number));
    return this;
  }
 
  /**
   * Append an object to this builder.
   *
   * @param object to append
   * @return reference to this builder
   */
  public MessageBuilder append(Object object) {
    if (object != null) {
      append(String.valueOf(object));
    }
    return this;
  }
 
 
  /**
   * Append a string to this builder.
   *
   * @param cs to append
   * @return reference to this builder
   */
  public MessageBuilder append(CharSequence cs) {
    if (cs != null) {
      sb.append(cs);
      if (cs instanceof Message) {
        messages.add((Message)cs);
      } else {
        messages.add(Message.raw(cs));
      }
    }
    return this;
  }
 
  /**
   * Appends a subsequence of the specified character sequence to this
   * <tt>Appendable</tt>.
   *
   * <p> An invocation of this method of the form <tt>out.append(csq, start,
   * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
   * exactly the same way as the invocation
   *
   * <pre>
   *     out.append(csq.subSequence(start, end)) </pre>
   *
   * @param  csq
   *         The character sequence from which a subsequence will be
   *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
   *         will be appended as if <tt>csq</tt> contained the four
   *         characters <tt>"null"</tt>.
   *
   * @param  start
   *         The index of the first character in the subsequence
   *
   * @param  end
   *         The index of the character following the last character in the
   *         subsequence
   *
   * @return  A reference to this <tt>Appendable</tt>
   *
   * @throws  IndexOutOfBoundsException
   *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
   *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
   *          <tt>csq.length()</tt>
   */
  public MessageBuilder append(CharSequence csq, int start, int end)
    throws IndexOutOfBoundsException
  {
    return append(csq.subSequence(start, end));
  }
 
  /**
   * Appends the specified character to this <tt>Appendable</tt>.
   *
   * @param  c
   *         The character to append
   *
   * @return  A reference to this <tt>Appendable</tt>
   */
  public MessageBuilder append(char c) {
    return append(String.valueOf(c));
  }
 
  /**
   * Returns a string containing the characters in this sequence in the same
   * order as this sequence.  The length of the string will be the length of
   * this sequence.
   *
   * @return  a string consisting of exactly this sequence of characters
   */
  public String toString() {
    return sb.toString();
  }
 
  /**
   * Returns a string representation of the appended content
   * in the specific locale.  Only <code>Message</code>s
   * appended to this builder are rendered in the requested
   * locale.  Raw strings appended to this buffer are not
   * translated to different locale.
   *
   * @param locale requested
   * @return String representation
   */
  public String toString(Locale locale) {
    StringBuilder sb = new StringBuilder();
    for (Message m : messages) {
      sb.append(m.toString(locale));
    }
    return sb.toString();
  }
 
  /**
   * Returns a raw message representation of the appended content.
   * <p>
   * If the first object appended to this <code>MessageBuilder</code>
   * was a <code>Message</code> then the returned message will
   * inherit its category and severity. Otherwise the returned message
   * will have category {@link org.opends.messages.Category#USER_DEFINED}
   *  and severity {@link org.opends.messages.Severity#INFORMATION}.
   *
   * @return Message raw message representing builder content
   */
  public Message toMessage() {
    if(messages.isEmpty())
    {
      return Message.EMPTY;
    }
 
    StringBuffer fmtString = new StringBuffer();
    for (int i = 0; i < messages.size(); i++) {
      fmtString.append("%s");
    }
 
    // Inherit the category and severity of the first message.
    MessageDescriptor md = messages.get(0).getDescriptor();
    return Message.raw(md.getCategory(), md.getSeverity(), fmtString,
        messages.toArray());
  }
 
  /**
   * Returns the length of the string representation of this builder
   * using the default locale.
   *
   * @return  the number of <code>char</code>s in this message
   */
  public int length() {
    return length(Locale.getDefault());
  }
 
  /**
   * Returns the <code>char</code> value at the specified index of
   * the string representation of this builder using the default locale.
   *
   * @param   index   the index of the <code>char</code> value to be returned
   *
   * @return  the specified <code>char</code> value
   *
   * @throws  IndexOutOfBoundsException
   *          if the <tt>index</tt> argument is negative or not less than
   *          <tt>length()</tt>
   */
  public char charAt(int index) throws IndexOutOfBoundsException {
    return charAt(Locale.getDefault(), index);
  }
 
  /**
   * Returns a new <code>CharSequence</code> that is a subsequence of
   * the string representation of this builder using the default locale.
   * The subsequence starts with the <code>char</code>
   * value at the specified index and ends with the <code>char</code>
   * value at index <tt>end - 1</tt>.  The length (in <code>char</code>s)
   * of the returned sequence is <tt>end - start</tt>, so if
   * <tt>start == end</tt> then an empty sequence is returned.
   *
   * @param   start   the start index, inclusive
   * @param   end     the end index, exclusive
   *
   * @return  the specified subsequence
   *
   * @throws  IndexOutOfBoundsException
   *          if <tt>start</tt> or <tt>end</tt> are negative,
   *          if <tt>end</tt> is greater than <tt>length()</tt>,
   *          or if <tt>start</tt> is greater than <tt>end</tt>
   */
  public CharSequence subSequence(int start, int end)
          throws IndexOutOfBoundsException
  {
    return subSequence(Locale.getDefault(), start, end);
  }
 
  /**
   * Returns the length of the string representation of this builder
   * using a specific locale.
   *
   * @param   locale for which the rendering of this message will be
   *          used in determining the length
   * @return  the number of <code>char</code>s in this message
   */
  public int length(Locale locale) {
    return toString(locale).length();
  }
 
  /**
   * Returns the <code>char</code> value at the specified index of
   * the string representation of this builder using a specific locale.
   *
   * @param   locale for which the rendering of this message will be
   *          used in determining the character
   * @param   index   the index of the <code>char</code> value to be returned
   *
   * @return  the specified <code>char</code> value
   *
   * @throws  IndexOutOfBoundsException
   *          if the <tt>index</tt> argument is negative or not less than
   *          <tt>length()</tt>
   */
  public char charAt(Locale locale, int index)
          throws IndexOutOfBoundsException
  {
    return toString(locale).charAt(index);
  }
 
  /**
   * Returns a new <code>CharSequence</code> that is a subsequence of
   * the string representation of this builder using a specific locale.
   * The subsequence starts with the <code>char</code>
   * value at the specified index and ends with the <code>char</code>
   * value at index <tt>end - 1</tt>.  The length (in <code>char</code>s)
   * of the returned sequence is <tt>end - start</tt>, so if
   * <tt>start == end</tt> then an empty sequence is returned.
   *
   * @param   locale for which the rendering of this message will be
   *          used in determining the character
   * @param   start   the start index, inclusive
   * @param   end     the end index, exclusive
   *
   * @return  the specified subsequence
   *
   * @throws  IndexOutOfBoundsException
   *          if <tt>start</tt> or <tt>end</tt> are negative,
   *          if <tt>end</tt> is greater than <tt>length()</tt>,
   *          or if <tt>start</tt> is greater than <tt>end</tt>
   */
  public CharSequence subSequence(Locale locale, int start, int end)
    throws IndexOutOfBoundsException
  {
    return toString(locale).subSequence(start, end);
  }
 
 
}