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 2008 Sun Microsystems, Inc.
026     */
027    
028    package org.opends.messages;
029    
030    import java.util.Locale;
031    import java.util.ResourceBundle;
032    import java.util.HashMap;
033    import java.util.Map;
034    
035    /**
036     * Base class for all Message descriptor classes.
037     */
038    @org.opends.server.types.PublicAPI(
039        stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
040        mayInstantiate=false,
041        mayExtend=false,
042        mayInvoke=true)
043    public abstract class MessageDescriptor {
044    
045      /**
046       * ID for messages that don't have a real ID.
047       */
048      public static final int NULL_ID = -1;
049    
050      /**
051       * The maximum number of arguments that can be handled by
052       * a specific subclass.  If you define more subclasses be
053       * sure to increment this number appropriately.
054       */
055      static public final int DESCRIPTOR_MAX_ARG_HANDLER = 11;
056    
057      /**
058       * The base name of the specific argument handling subclasses
059       * defined below.  The class names consist of the base name
060       * followed by a number indicating the number of arguments
061       * that they handle when creating messages or the letter "N"
062       * meaning any number of arguments.
063       */
064      public static final String DESCRIPTOR_CLASS_BASE_NAME = "Arg";
065    
066      /**
067       * Subclass for creating messages with no arguments.
068       */
069      @org.opends.server.types.PublicAPI(
070          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
071          mayInstantiate=true,
072          mayExtend=false,
073          mayInvoke=true)
074      static public final class Arg0 extends MessageDescriptor {
075    
076        /**
077         * Cached copy of the message created by this descriptor.  We can
078         * get away with this for the zero argument message because it is
079         * immutable.
080         */
081        private Message message;
082    
083        private boolean requiresFormat;
084    
085        /**
086         * Creates a parameterized instance.
087         * @param rbBase base of the backing resource bundle
088         * @param key for accessing the format string from the resource bundle
089         * @param category of created messages
090         * @param severity of created messages
091         * @param ordinal of created messages
092         * @param classLoader the class loader to be used to get the ResourceBundle
093         */
094        public Arg0(String rbBase, String key, Category category,
095                  Severity severity, int ordinal, ClassLoader classLoader) {
096          super(rbBase, key, category, severity, ordinal, classLoader);
097          message = new Message(this);
098          requiresFormat = containsArgumentLiterals(getFormatString());
099        }
100    
101        /**
102         * Creates a parameterized instance.
103         * @param rbBase base of the backing resource bundle
104         * @param key for accessing the format string from the resource bundle
105         * @param mask to apply to the USER_DEFINED category
106         * @param severity of created messages
107         * @param ordinal of created messages
108         * @param classLoader the class loader to be used to get the ResourceBundle
109         */
110        public Arg0(String rbBase, String key, int mask,
111                  Severity severity, int ordinal, ClassLoader classLoader) {
112          super(rbBase, key, mask, severity, ordinal, classLoader);
113          message = new Message(this);
114          requiresFormat = containsArgumentLiterals(getFormatString());
115        }
116    
117        /**
118         * Creates a message.
119         * @return Message object
120         */
121        public Message get() {
122          return message;
123        }
124    
125        /**
126         * {@inheritDoc}
127         */
128        boolean requiresFormatter() {
129          return requiresFormat;
130        }
131      }
132    
133      /**
134       * Subclass for creating messages with one argument.
135       * @param <T1> The type of the first message argument.
136       */
137      @org.opends.server.types.PublicAPI(
138          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
139          mayInstantiate=true,
140          mayExtend=false,
141          mayInvoke=true)
142      static public final class Arg1<T1> extends MessageDescriptor {
143    
144        /**
145         * Creates a parameterized instance.
146         * @param rbBase base of the backing resource bundle
147         * @param key for accessing the format string from the resource bundle
148         * @param category of created messages
149         * @param severity of created messages
150         * @param ordinal of created messages
151         * @param classLoader the class loader to be used to get the ResourceBundle
152         */
153        public Arg1(String rbBase, String key, Category category,
154                  Severity severity, int ordinal, ClassLoader classLoader) {
155          super(rbBase, key, category, severity, ordinal, classLoader);
156        }
157    
158        /**
159         * Creates a parameterized instance.
160         * @param rbBase base of the backing resource bundle
161         * @param key for accessing the format string from the resource bundle
162         * @param mask to apply to the USER_DEFINED category
163         * @param severity of created messages
164         * @param ordinal of created messages
165         * @param classLoader the class loader to be used to get the ResourceBundle
166         */
167        public Arg1(String rbBase, String key, int mask,
168                  Severity severity, int ordinal, ClassLoader classLoader) {
169          super(rbBase, key, mask, severity, ordinal, classLoader);
170        }
171    
172        /**
173         * Creates a message with arguments that will replace format
174         * specifiers in the assocated format string when the message
175         * is rendered to string representation.
176         * @return Message object
177         * @param a1 message argument
178         */
179        public Message get(T1 a1) {
180          return new Message(this, a1);
181        }
182    
183        /**
184         * {@inheritDoc}
185         */
186        boolean requiresFormatter() {
187          return true;
188        }
189    
190      }
191    
192      /**
193       * Subclass for creating messages with two arguments.
194       * @param <T1> The type of the first message argument.
195       * @param <T2> The type of the second message argument.
196       */
197      @org.opends.server.types.PublicAPI(
198          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
199          mayInstantiate=true,
200          mayExtend=false,
201          mayInvoke=true)
202      static public final class Arg2<T1, T2> extends MessageDescriptor {
203    
204        /**
205         * Creates a parameterized instance.
206         * @param rbBase base of the backing resource bundle
207         * @param key for accessing the format string from the resource bundle
208         * @param category of created messages
209         * @param severity of created messages
210         * @param ordinal of created messages
211         * @param classLoader the class loader to be used to get the ResourceBundle
212         */
213        public Arg2(String rbBase, String key, Category category,
214                  Severity severity, int ordinal, ClassLoader classLoader) {
215          super(rbBase, key, category, severity, ordinal, classLoader);
216        }
217    
218        /**
219         * Creates a parameterized instance.
220         * @param rbBase base of the backing resource bundle
221         * @param key for accessing the format string from the resource bundle
222         * @param mask to apply to the USER_DEFINED category
223         * @param severity of created messages
224         * @param ordinal of created messages
225         * @param classLoader the class loader to be used to get the ResourceBundle
226         */
227        public Arg2(String rbBase, String key, int mask,
228                  Severity severity, int ordinal, ClassLoader classLoader) {
229          super(rbBase, key, mask, severity, ordinal, classLoader);
230        }
231    
232        /**
233         * Creates a message with arguments that will replace format
234         * specifiers in the assocated format string when the message
235         * is rendered to string representation.
236         * @return Message object
237         * @param a1 message argument
238         * @param a2 message argument
239         */
240        public Message get(T1 a1, T2 a2) {
241          return new Message(this, a1, a2);
242        }
243    
244        /**
245         * {@inheritDoc}
246         */
247        boolean requiresFormatter() {
248          return true;
249        }
250    
251      }
252    
253      /**
254       * Subclass for creating messages with three arguments.
255       * @param <T1> The type of the first message argument.
256       * @param <T2> The type of the second message argument.
257       * @param <T3> The type of the third message argument.
258       */
259      @org.opends.server.types.PublicAPI(
260          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
261          mayInstantiate=true,
262          mayExtend=false,
263          mayInvoke=true)
264      static public final class Arg3<T1, T2, T3> extends MessageDescriptor {
265    
266        /**
267         * Creates a parameterized instance.
268         * @param rbBase base of the backing resource bundle
269         * @param key for accessing the format string from the resource bundle
270         * @param category of created messages
271         * @param severity of created messages
272         * @param ordinal of created messages
273         * @param classLoader the class loader to be used to get the ResourceBundle
274         */
275        public Arg3(String rbBase, String key, Category category,
276                  Severity severity, int ordinal, ClassLoader classLoader) {
277          super(rbBase, key, category, severity, ordinal, classLoader);
278        }
279    
280        /**
281         * Creates a parameterized instance.
282         * @param rbBase base of the backing resource bundle
283         * @param key for accessing the format string from the resource bundle
284         * @param mask to apply to the USER_DEFINED category
285         * @param severity of created messages
286         * @param ordinal of created messages
287         * @param classLoader the class loader to be used to get the ResourceBundle
288         */
289        public Arg3(String rbBase, String key, int mask,
290                  Severity severity, int ordinal, ClassLoader classLoader) {
291          super(rbBase, key, mask, severity, ordinal, classLoader);
292        }
293    
294        /**
295         * Creates a message with arguments that will replace format
296         * specifiers in the assocated format string when the message
297         * is rendered to string representation.
298         * @return Message object
299         * @param a1 message argument
300         * @param a2 message argument
301         * @param a3 message argument
302         */
303        public Message get(T1 a1, T2 a2, T3 a3) {
304          return new Message(this, a1, a2, a3);
305        }
306    
307        /**
308         * {@inheritDoc}
309         */
310        boolean requiresFormatter() {
311          return true;
312        }
313    
314      }
315    
316      /**
317       * Subclass for creating messages with four arguments.
318       * @param <T1> The type of the first message argument.
319       * @param <T2> The type of the second message argument.
320       * @param <T3> The type of the third message argument.
321       * @param <T4> The type of the fourth message argument.
322       */
323      @org.opends.server.types.PublicAPI(
324          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
325          mayInstantiate=true,
326          mayExtend=false,
327          mayInvoke=true)
328      static public final class Arg4<T1, T2, T3, T4> extends MessageDescriptor {
329    
330        /**
331         * Creates a parameterized instance.
332         * @param rbBase base of the backing resource bundle
333         * @param key for accessing the format string from the resource bundle
334         * @param category of created messages
335         * @param severity of created messages
336         * @param ordinal of created messages
337         * @param classLoader the class loader to be used to get the ResourceBundle
338         */
339        public Arg4(String rbBase, String key, Category category,
340                  Severity severity, int ordinal, ClassLoader classLoader) {
341          super(rbBase, key, category, severity, ordinal, classLoader);
342        }
343    
344        /**
345         * Creates a parameterized instance.
346         * @param rbBase base of the backing resource bundle
347         * @param key for accessing the format string from the resource bundle
348         * @param mask to apply to the USER_DEFINED category
349         * @param severity of created messages
350         * @param ordinal of created messages
351         * @param classLoader the class loader to be used to get the ResourceBundle
352         */
353        public Arg4(String rbBase, String key, int mask,
354                  Severity severity, int ordinal, ClassLoader classLoader) {
355          super(rbBase, key, mask, severity, ordinal, classLoader);
356        }
357    
358        /**
359         * Creates a message with arguments that will replace format
360         * specifiers in the assocated format string when the message
361         * is rendered to string representation.
362         * @return Message object
363         * @param a1 message argument
364         * @param a2 message argument
365         * @param a3 message argument
366         * @param a4 message argument
367         */
368        public Message get(T1 a1, T2 a2, T3 a3, T4 a4) {
369          return new Message(this, a1, a2, a3, a4);
370        }
371    
372        /**
373         * {@inheritDoc}
374         */
375        boolean requiresFormatter() {
376          return true;
377        }
378    
379      }
380    
381      /**
382       * Subclass for creating messages with five arguments.
383       * @param <T1> The type of the first message argument.
384       * @param <T2> The type of the second message argument.
385       * @param <T3> The type of the third message argument.
386       * @param <T4> The type of the fourth message argument.
387       * @param <T5> The type of the fifth message argument.
388       */
389      @org.opends.server.types.PublicAPI(
390          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
391          mayInstantiate=true,
392          mayExtend=false,
393          mayInvoke=true)
394      static public final class Arg5<T1, T2, T3, T4, T5> extends MessageDescriptor {
395    
396        /**
397         * Creates a parameterized instance.
398         * @param rbBase base of the backing resource bundle
399         * @param key for accessing the format string from the resource bundle
400         * @param category of created messages
401         * @param severity of created messages
402         * @param ordinal of created messages
403         * @param classLoader the class loader to be used to get the ResourceBundle
404         */
405        public Arg5(String rbBase, String key, Category category,
406                  Severity severity, int ordinal, ClassLoader classLoader) {
407          super(rbBase, key, category, severity, ordinal, classLoader);
408        }
409    
410        /**
411         * Creates a parameterized instance.
412         * @param rbBase base of the backing resource bundle
413         * @param key for accessing the format string from the resource bundle
414         * @param mask to apply to the USER_DEFINED category
415         * @param severity of created messages
416         * @param ordinal of created messages
417         * @param classLoader the class loader to be used to get the ResourceBundle
418         */
419        public Arg5(String rbBase, String key, int mask,
420                  Severity severity, int ordinal, ClassLoader classLoader) {
421          super(rbBase, key, mask, severity, ordinal, classLoader);
422        }
423    
424        /**
425         * Creates a message with arguments that will replace format
426         * specifiers in the assocated format string when the message
427         * is rendered to string representation.
428         * @return Message object
429         * @param a1 message argument
430         * @param a2 message argument
431         * @param a3 message argument
432         * @param a4 message argument
433         * @param a5 message argument
434         */
435        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) {
436          return new Message(this, a1, a2, a3, a4, a5);
437        }
438    
439        /**
440         * {@inheritDoc}
441         */
442        boolean requiresFormatter() {
443          return true;
444        }
445    
446      }
447    
448      /**
449       * Subclass for creating messages with six arguments.
450       * @param <T1> The type of the first message argument.
451       * @param <T2> The type of the second message argument.
452       * @param <T3> The type of the third message argument.
453       * @param <T4> The type of the fourth message argument.
454       * @param <T5> The type of the fifth message argument.
455       * @param <T6> The type of the sixth message argument.
456       */
457      @org.opends.server.types.PublicAPI(
458          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
459          mayInstantiate=true,
460          mayExtend=false,
461          mayInvoke=true)
462      static public final class Arg6<T1, T2, T3, T4, T5, T6> extends
463          MessageDescriptor {
464    
465        /**
466         * Creates a parameterized instance.
467         * @param rbBase base of the backing resource bundle
468         * @param key for accessing the format string from the resource bundle
469         * @param category of created messages
470         * @param severity of created messages
471         * @param ordinal of created messages
472         * @param classLoader the class loader to be used to get the ResourceBundle
473         */
474        public Arg6(String rbBase, String key, Category category,
475                  Severity severity, int ordinal, ClassLoader classLoader) {
476          super(rbBase, key, category, severity, ordinal, classLoader);
477        }
478    
479        /**
480         * Creates a parameterized instance.
481         * @param rbBase base of the backing resource bundle
482         * @param key for accessing the format string from the resource bundle
483         * @param mask to apply to the USER_DEFINED category
484         * @param severity of created messages
485         * @param ordinal of created messages
486         * @param classLoader the class loader to be used to get the ResourceBundle
487         */
488        public Arg6(String rbBase, String key, int mask,
489                  Severity severity, int ordinal, ClassLoader classLoader) {
490          super(rbBase, key, mask, severity, ordinal, classLoader);
491        }
492    
493        /**
494         * Creates a message with arguments that will replace format
495         * specifiers in the assocated format string when the message
496         * is rendered to string representation.
497         * @return Message object
498         * @param a1 message argument
499         * @param a2 message argument
500         * @param a3 message argument
501         * @param a4 message argument
502         * @param a5 message argument
503         * @param a6 message argument
504         */
505        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) {
506          return new Message(this, a1, a2, a3, a4, a5, a6);
507        }
508    
509        /**
510         * {@inheritDoc}
511         */
512        boolean requiresFormatter() {
513          return true;
514        }
515    
516      }
517    
518      /**
519       * Subclass for creating messages with seven arguments.
520       * @param <T1> The type of the first message argument.
521       * @param <T2> The type of the second message argument.
522       * @param <T3> The type of the third message argument.
523       * @param <T4> The type of the fourth message argument.
524       * @param <T5> The type of the fifth message argument.
525       * @param <T6> The type of the sixth message argument.
526       * @param <T7> The type of the seventh message argument.
527       */
528      @org.opends.server.types.PublicAPI(
529          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
530          mayInstantiate=true,
531          mayExtend=false,
532          mayInvoke=true)
533      static public final class Arg7<T1, T2, T3, T4, T5, T6, T7>
534              extends MessageDescriptor
535      {
536    
537        /**
538         * Creates a parameterized instance.
539         * @param rbBase base of the backing resource bundle
540         * @param key for accessing the format string from the resource bundle
541         * @param category of created messages
542         * @param severity of created messages
543         * @param ordinal of created messages
544         * @param classLoader the class loader to be used to get the ResourceBundle
545         */
546        public Arg7(String rbBase, String key, Category category,
547                  Severity severity, int ordinal, ClassLoader classLoader) {
548          super(rbBase, key, category, severity, ordinal, classLoader);
549        }
550    
551        /**
552         * Creates a parameterized instance.
553         * @param rbBase base of the backing resource bundle
554         * @param key for accessing the format string from the resource bundle
555         * @param mask to apply to the USER_DEFINED category
556         * @param severity of created messages
557         * @param ordinal of created messages
558         * @param classLoader the class loader to be used to get the ResourceBundle
559         */
560        public Arg7(String rbBase, String key, int mask,
561                  Severity severity, int ordinal, ClassLoader classLoader) {
562          super(rbBase, key, mask, severity, ordinal, classLoader);
563        }
564    
565        /**
566         * Creates a message with arguments that will replace format
567         * specifiers in the assocated format string when the message
568         * is rendered to string representation.
569         * @return Message object
570         * @param a1 message argument
571         * @param a2 message argument
572         * @param a3 message argument
573         * @param a4 message argument
574         * @param a5 message argument
575         * @param a6 message argument
576         * @param a7 message argument
577         */
578        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) {
579          return new Message(this, a1, a2, a3, a4, a5, a6, a7);
580        }
581    
582        /**
583         * {@inheritDoc}
584         */
585        boolean requiresFormatter() {
586          return true;
587        }
588    
589      }
590    
591      /**
592       * Subclass for creating messages with eight arguments.
593       * @param <T1> The type of the first message argument.
594       * @param <T2> The type of the second message argument.
595       * @param <T3> The type of the third message argument.
596       * @param <T4> The type of the fourth message argument.
597       * @param <T5> The type of the fifth message argument.
598       * @param <T6> The type of the sixth message argument.
599       * @param <T7> The type of the seventh message argument.
600       * @param <T8> The type of the eighth message argument.
601       */
602      @org.opends.server.types.PublicAPI(
603          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
604          mayInstantiate=true,
605          mayExtend=false,
606          mayInvoke=true)
607      static public final class Arg8<T1, T2, T3, T4, T5, T6, T7, T8>
608              extends MessageDescriptor
609      {
610    
611        /**
612         * Creates a parameterized instance.
613         * @param rbBase base of the backing resource bundle
614         * @param key for accessing the format string from the resource bundle
615         * @param category of created messages
616         * @param severity of created messages
617         * @param ordinal of created messages
618         * @param classLoader the class loader to be used to get the ResourceBundle
619         */
620        public Arg8(String rbBase, String key, Category category,
621                  Severity severity, int ordinal, ClassLoader classLoader) {
622          super(rbBase, key, category, severity, ordinal, classLoader);
623        }
624    
625        /**
626         * Creates a parameterized instance.
627         * @param rbBase base of the backing resource bundle
628         * @param key for accessing the format string from the resource bundle
629         * @param mask to apply to the USER_DEFINED category
630         * @param severity of created messages
631         * @param ordinal of created messages
632         * @param classLoader the class loader to be used to get the ResourceBundle
633         */
634        public Arg8(String rbBase, String key, int mask,
635                  Severity severity, int ordinal, ClassLoader classLoader) {
636          super(rbBase, key, mask, severity, ordinal, classLoader);
637        }
638    
639        /**
640         * Creates a message with arguments that will replace format
641         * specifiers in the assocated format string when the message
642         * is rendered to string representation.
643         * @return Message object
644         * @param a1 message argument
645         * @param a2 message argument
646         * @param a3 message argument
647         * @param a4 message argument
648         * @param a5 message argument
649         * @param a6 message argument
650         * @param a7 message argument
651         * @param a8 message argument
652         */
653        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6,
654                              T7 a7, T8 a8) {
655          return new Message(this, a1, a2, a3, a4, a5, a6, a7, a8);
656        }
657    
658        /**
659         * {@inheritDoc}
660         */
661        boolean requiresFormatter() {
662          return true;
663        }
664    
665      }
666    
667      /**
668       * Subclass for creating messages with nine arguments.
669       * @param <T1> The type of the first message argument.
670       * @param <T2> The type of the second message argument.
671       * @param <T3> The type of the third message argument.
672       * @param <T4> The type of the fourth message argument.
673       * @param <T5> The type of the fifth message argument.
674       * @param <T6> The type of the sixth message argument.
675       * @param <T7> The type of the seventh message argument.
676       * @param <T8> The type of the eighth message argument.
677       * @param <T9> The type of the ninth message argument.
678       */
679      @org.opends.server.types.PublicAPI(
680          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
681          mayInstantiate=true,
682          mayExtend=false,
683          mayInvoke=true)
684      static public final class Arg9<T1, T2, T3, T4, T5, T6, T7, T8, T9>
685              extends MessageDescriptor {
686    
687        /**
688         * Creates a parameterized instance.
689         * @param rbBase base of the backing resource bundle
690         * @param key for accessing the format string from the resource bundle
691         * @param category of created messages
692         * @param severity of created messages
693         * @param ordinal of created messages
694         * @param classLoader the class loader to be used to get the ResourceBundle
695         */
696        public Arg9(String rbBase, String key, Category category,
697                  Severity severity, int ordinal, ClassLoader classLoader) {
698          super(rbBase, key, category, severity, ordinal, classLoader);
699        }
700    
701        /**
702         * Creates a parameterized instance.
703         * @param rbBase base of the backing resource bundle
704         * @param key for accessing the format string from the resource bundle
705         * @param mask to apply to the USER_DEFINED category
706         * @param severity of created messages
707         * @param ordinal of created messages
708         * @param classLoader the class loader to be used to get the ResourceBundle
709         */
710        public Arg9(String rbBase, String key, int mask,
711                  Severity severity, int ordinal, ClassLoader classLoader) {
712          super(rbBase, key, mask, severity, ordinal, classLoader);
713        }
714    
715        /**
716         * Creates a message with arguments that will replace format
717         * specifiers in the assocated format string when the message
718         * is rendered to string representation.
719         * @return Message object
720         * @param a1 message argument
721         * @param a2 message argument
722         * @param a3 message argument
723         * @param a4 message argument
724         * @param a5 message argument
725         * @param a6 message argument
726         * @param a7 message argument
727         * @param a8 message argument
728         * @param a9 message argument
729         */
730        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6,
731                              T7 a7, T8 a8, T9 a9) {
732          return new Message(this, a1, a2, a3, a4, a5, a6, a7, a8, a9);
733        }
734    
735        /**
736         * {@inheritDoc}
737         */
738        boolean requiresFormatter() {
739          return true;
740        }
741    
742      }
743    
744      /**
745       * Subclass for creating messages with ten arguments.
746       * @param <T1> The type of the first message argument.
747       * @param <T2> The type of the second message argument.
748       * @param <T3> The type of the third message argument.
749       * @param <T4> The type of the fourth message argument.
750       * @param <T5> The type of the fifth message argument.
751       * @param <T6> The type of the sixth message argument.
752       * @param <T7> The type of the seventh message argument.
753       * @param <T8> The type of the eighth message argument.
754       * @param <T9> The type of the ninth message argument.
755       * @param <T10> The type of the tenth message argument.
756       */
757      @org.opends.server.types.PublicAPI(
758          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
759          mayInstantiate=true,
760          mayExtend=false,
761          mayInvoke=true)
762      static public final class Arg10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
763              extends MessageDescriptor {
764    
765        /**
766         * Creates a parameterized instance.
767         * @param rbBase base of the backing resource bundle
768         * @param key for accessing the format string from the resource bundle
769         * @param category of created messages
770         * @param severity of created messages
771         * @param ordinal of created messages
772         * @param classLoader the class loader to be used to get the ResourceBundle
773         */
774        public Arg10(String rbBase, String key, Category category,
775                   Severity severity, int ordinal, ClassLoader classLoader) {
776          super(rbBase, key, category, severity, ordinal, classLoader);
777        }
778    
779        /**
780         * Creates a parameterized instance.
781         * @param rbBase base of the backing resource bundle
782         * @param key for accessing the format string from the resource bundle
783         * @param mask to apply to the USER_DEFINED category
784         * @param severity of created messages
785         * @param ordinal of created messages
786         * @param classLoader the class loader to be used to get the ResourceBundle
787         */
788        public Arg10(String rbBase, String key, int mask,
789                  Severity severity, int ordinal, ClassLoader classLoader) {
790          super(rbBase, key, mask, severity, ordinal, classLoader);
791        }
792    
793        /**
794         * Creates a message with arguments that will replace format
795         * specifiers in the assocated format string when the message
796         * is rendered to string representation.
797         * @return Message object
798         * @param a1 message argument
799         * @param a2 message argument
800         * @param a3 message argument
801         * @param a4 message argument
802         * @param a5 message argument
803         * @param a6 message argument
804         * @param a7 message argument
805         * @param a8 message argument
806         * @param a9 message argument
807         * @param a10 message argument
808         */
809        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6,
810                              T7 a7, T8 a8, T9 a9, T10 a10) {
811          return new Message(this, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
812        }
813    
814        /**
815         * {@inheritDoc}
816         */
817        boolean requiresFormatter() {
818          return true;
819        }
820    
821      }
822    
823      /**
824       * Subclass for creating messages with eleven arguments.
825       * @param <T1> The type of the first message argument.
826       * @param <T2> The type of the second message argument.
827       * @param <T3> The type of the third message argument.
828       * @param <T4> The type of the fourth message argument.
829       * @param <T5> The type of the fifth message argument.
830       * @param <T6> The type of the sixth message argument.
831       * @param <T7> The type of the seventh message argument.
832       * @param <T8> The type of the eighth message argument.
833       * @param <T9> The type of the ninth message argument.
834       * @param <T10> The type of the tenth message argument.
835       * @param <T11> The type of the eleventh message argument.
836       */
837      @org.opends.server.types.PublicAPI(
838          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
839          mayInstantiate=true,
840          mayExtend=false,
841          mayInvoke=true)
842      static public final class Arg11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
843              extends MessageDescriptor
844      {
845    
846        /**
847         * Creates a parameterized instance.
848         * @param rbBase base of the backing resource bundle
849         * @param key for accessing the format string from the resource bundle
850         * @param category of created messages
851         * @param severity of created messages
852         * @param ordinal of created messages
853         * @param classLoader the class loader to be used to get the ResourceBundle
854         */
855        public Arg11(String rbBase, String key, Category category,
856                   Severity severity, int ordinal, ClassLoader classLoader) {
857          super(rbBase, key, category, severity, ordinal, classLoader);
858        }
859    
860        /**
861         * Creates a parameterized instance.
862         * @param rbBase base of the backing resource bundle
863         * @param key for accessing the format string from the resource bundle
864         * @param mask to apply to the USER_DEFINED category
865         * @param severity of created messages
866         * @param ordinal of created messages
867         * @param classLoader the class loader to be used to get the ResourceBundle
868         */
869        public Arg11(String rbBase, String key, int mask,
870                  Severity severity, int ordinal, ClassLoader classLoader) {
871          super(rbBase, key, mask, severity, ordinal, classLoader);
872        }
873    
874        /**
875         * Creates a message with arguments that will replace format
876         * specifiers in the assocated format string when the message
877         * is rendered to string representation.
878         * @return Message object
879         * @param a1 message argument
880         * @param a2 message argument
881         * @param a3 message argument
882         * @param a4 message argument
883         * @param a5 message argument
884         * @param a6 message argument
885         * @param a7 message argument
886         * @param a8 message argument
887         * @param a9 message argument
888         * @param a10 message argument
889         * @param a11 message argument
890         */
891        public Message get(T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6,
892                              T7 a7, T8 a8, T9 a9, T10 a10, T11 a11) {
893          return new Message(this, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
894        }
895    
896        /**
897         * {@inheritDoc}
898         */
899        boolean requiresFormatter() {
900          return true;
901        }
902    
903      }
904    
905      /**
906       * Subclass for creating messages with an any number of arguments.
907       * In general this class should be used when a message needs to be
908       * defined with more arguments that can be handled with the current
909       * number of subclasses
910       */
911      @org.opends.server.types.PublicAPI(
912          stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
913          mayInstantiate=true,
914          mayExtend=false,
915          mayInvoke=true)
916      static public final class ArgN extends MessageDescriptor {
917    
918        /**
919         * Creates a parameterized instance.
920         * @param rbBase base of the backing resource bundle
921         * @param key for accessing the format string from the resource bundle
922         * @param category of created messages
923         * @param severity of created messages
924         * @param ordinal of created messages
925         * @param classLoader the class loader to be used to get the ResourceBundle
926         */
927        public ArgN(String rbBase, String key, Category category,
928                   Severity severity, int ordinal, ClassLoader classLoader) {
929          super(rbBase, key, category, severity, ordinal, classLoader);
930        }
931    
932        /**
933         * Creates a parameterized instance.
934         * @param rbBase base of the backing resource bundle
935         * @param key for accessing the format string from the resource bundle
936         * @param mask to apply to the USER_DEFINED category
937         * @param severity of created messages
938         * @param ordinal of created messages
939         * @param classLoader the class loader to be used to get the ResourceBundle
940         */
941        public ArgN(String rbBase, String key, int mask,
942                  Severity severity, int ordinal, ClassLoader classLoader) {
943          super(rbBase, key, mask, severity, ordinal, classLoader);
944        }
945    
946        /**
947         * Creates a message with arguments that will replace format
948         * specifiers in the assocated format string when the message
949         * is rendered to string representation.
950         * @return Message object
951         * @param args message arguments
952         */
953        public Message get(Object... args) {
954          return new Message(this, args);
955        }
956    
957        /**
958         * {@inheritDoc}
959         */
960        boolean requiresFormatter() {
961          return true;
962        }
963    
964      }
965    
966      /**
967       * A descriptor for creating a raw message from a <code>String</code>.
968       * In general this descriptor should NOT be used internally.  OpenDS
969       * plugins may want to use the mechanism to create messages without
970       * storing their strings in resource bundles.
971       */
972      @org.opends.server.types.PublicAPI(
973          stability=org.opends.server.types.StabilityLevel.PRIVATE
974      )
975      static final class Raw extends MessageDescriptor {
976    
977        private String formatString;
978    
979        private boolean requiresFormatter;
980    
981        /**
982         * Creates a parameterized instance.
983         * @param formatString for created messages
984         */
985        Raw(CharSequence formatString) {
986          this(formatString, Category.USER_DEFINED, Severity.INFORMATION);
987        }
988    
989        /**
990         * Creates a parameterized instance.
991         * @param formatString for created messages
992         * @param category for created messages
993         * @param severity for created messages
994         */
995        Raw(CharSequence formatString, Category category,
996                                    Severity severity) {
997          super(null, null, category, severity, null, null);
998          this.formatString = formatString != null ? formatString.toString() : "";
999          this.requiresFormatter = formatString.toString().matches(".*%.*");
1000        }
1001    
1002        /**
1003         * Creates a parameterized instance.  Created messages will
1004         * have a category of <code>Category.USER_DEFINED</code>.
1005         * @param formatString for created messages
1006         * @param mask for created messages
1007         * @param severity for created messages
1008         */
1009        Raw(CharSequence formatString, int mask, Severity severity) {
1010          super(null, null, mask, severity, null, null);
1011          this.formatString = formatString != null ? formatString.toString() : "";
1012        }
1013    
1014        /**
1015         * Creates a message with arguments that will replace format
1016         * specifiers in the assocated format string when the message
1017         * is rendered to string representation.
1018         * @return Message object
1019         * @param args message arguments
1020         */
1021        public Message get(Object... args) {
1022          return new Message(this, args);
1023        }
1024    
1025        /**
1026         * Overridden in order to bypass the resource bundle
1027         * plumbing and return the format string directly.
1028         * @param locale ignored
1029         * @return format string
1030         */
1031        @Override
1032        String getFormatString(Locale locale) {
1033          return this.formatString;
1034        }
1035    
1036        /**
1037         * {@inheritDoc}
1038         */
1039        boolean requiresFormatter() {
1040          return this.requiresFormatter;
1041        }
1042    
1043      }
1044    
1045      /** String for accessing backing resource bundle. */
1046      private final String rbBase;
1047    
1048      /** Used for accessing format string from the resource bundle. */
1049      private final String key;
1050    
1051      /** Category for messages created by this descriptor. */
1052      private final Category category;
1053    
1054      /**
1055       * Custom mask associated with messages created by this
1056       * descriptor.  The value of this variable might be null
1057       * to indicate that the mask should come from
1058       * <code>category</code>.
1059       */
1060      private final Integer mask;
1061    
1062      /**
1063       * The severity associated with messages created by this
1064       * descriptor.
1065       */
1066      private final Severity severity;
1067    
1068      /**
1069       * The value that makes a message unique among other messages
1070       * having the same severity and category.  May be null for
1071       * raw messages.
1072       */
1073      private final Integer ordinal;
1074    
1075      /**
1076       * The class loader to be used to retrieve the ResourceBundle.  If null
1077       * the default class loader will be used.
1078       */
1079      private final ClassLoader classLoader;
1080    
1081    
1082      private final Map<Locale,String> formatStrMap = new HashMap<Locale,String>();
1083    
1084      /**
1085       * Obtains the category of this descriptor.  Gauranteed not to be null.
1086       * @return Category of this message
1087       */
1088      public final Category getCategory() {
1089        return this.category;
1090      }
1091    
1092      /**
1093       * Obtains the severity of this descriptor.  Gauranteed not to be null.
1094       * @return Category of this message
1095       */
1096      public final Severity getSeverity() {
1097        return this.severity;
1098      }
1099    
1100      /**
1101       * Obtains the ordinal value for this message which makes messages
1102       * unique among messages defined with the same category and severity.
1103       * @return int ordinal value
1104       */
1105      public final int getOrdinal() {
1106        if (this.ordinal == null)
1107          return 0;
1108        else
1109          return this.ordinal;
1110      }
1111    
1112      /**
1113       * Returns the ID unique to all OpenDS messages.
1114       * @return unique ID
1115       */
1116      public final int getId() {
1117        if (this.ordinal == null) { // ordinal may be null for raw messages
1118          return NULL_ID;
1119        } else {
1120          return this.ordinal | this.category.getMask() | this.severity.getMask();
1121        }
1122      }
1123    
1124      /**
1125       * Obtains the mask of this descriptor.  The mask will either be
1126       * the mask of the associated <code>Category</code> or the mask
1127       * explicitly set in the constructor.
1128       * @return Integer mask value
1129       */
1130      public final int getMask() {
1131        if (this.mask != null) {
1132          return this.mask;
1133        } else {
1134          return this.category.getMask();
1135        }
1136      }
1137    
1138      /**
1139       * Returns the key for accessing the message template in a resource bundle.
1140       * May be null for raw messages.
1141       * @return key of this message
1142       */
1143      public final String getKey() {
1144        return this.key;
1145      }
1146    
1147      /**
1148       * Obtains the resource bundle base string used to access the
1149       * resource bundle containing created message's format string.
1150       * May be null for raw messages.
1151       * @return string base
1152       */
1153      public final String getBase() {
1154        return this.rbBase;
1155      }
1156    
1157      /**
1158       * Indicates whether or not this descriptor format string should
1159       * be processed by Formatter during string rendering.
1160       * @return boolean where true means Formatter should be used; false otherwise
1161       * @see java.util.Formatter
1162       */
1163      abstract boolean requiresFormatter();
1164    
1165      /**
1166       * Obtains the format string for constructing the string
1167       * value of this message according to the default
1168       * locale.
1169       * @return format string
1170       */
1171      final String getFormatString() {
1172        return getFormatString(Locale.getDefault());
1173      }
1174    
1175      /**
1176       * Obtains the format string for constructing the string
1177       * value of this message according to the requested
1178       * locale.
1179       * @param locale for the returned format string
1180       * @return format string
1181       */
1182      String getFormatString(Locale locale) {
1183        String fmtStr = formatStrMap.get(locale);
1184        if (fmtStr == null) {
1185          ResourceBundle bundle = getBundle(locale);
1186          fmtStr = bundle.getString(this.key);
1187          formatStrMap.put(locale, fmtStr);
1188        }
1189        return fmtStr;
1190      }
1191    
1192      /**
1193       * Indicates whether or not formatting should be applied
1194       * to the given format string.  Note that a format string
1195       * might have literal specifiers (%% or %n for example) that
1196       * require formatting but are not replaced by arguments.
1197       * @param s candiate for formatting
1198       * @return boolean where true indicates that the format
1199       *         string requires formatting
1200       */
1201      protected final boolean containsArgumentLiterals(String s) {
1202        return s.matches(".*%[n|%].*"); // match Formatter literals
1203      }
1204    
1205      private ResourceBundle getBundle(Locale locale) {
1206        if (locale == null) locale = Locale.getDefault();
1207        if (classLoader == null)
1208        {
1209          return ResourceBundle.getBundle(this.rbBase, locale);
1210        }
1211        else
1212        {
1213          return ResourceBundle.getBundle(this.rbBase, locale, classLoader);
1214        }
1215      }
1216    
1217      /**
1218       * Creates a parameterized message descriptor.
1219       * @param rbBase string for accessing the underlying message bundle
1220       * @param key for accessing the format string from the message bundle
1221       * @param category of any created message
1222       * @param severity of any created message
1223       * @param ordinal of any created message
1224       * @param classLoader the class loader to be used to get the ResourceBundle
1225       */
1226      private MessageDescriptor(String rbBase, String key, Category category,
1227                         Severity severity, Integer ordinal,
1228                         ClassLoader classLoader) {
1229        if (category == null) {
1230          throw new NullPointerException("Null Category value for message " +
1231                  "descriptor with key " + key);
1232        }
1233        if (severity == null) {
1234          throw new NullPointerException("Null Severity value for message " +
1235                  "descriptor with key " + key);
1236        }
1237        this.rbBase = rbBase;
1238        this.key = key;
1239        this.category = category;
1240        this.severity = severity;
1241        this.ordinal = ordinal;
1242        this.classLoader = classLoader;
1243        this.mask = null;
1244      }
1245    
1246      /**
1247       * Creates a parameterized message descriptor.  Messages created by
1248       * this descriptor will have a category of <code>Category.USER_DEFINED</code>
1249       * and have a custom mask indicated by <code>mask</code>.
1250       * @param rbBase string for accessing the underlying message bundle
1251       * @param key for accessing the format string from the message bundle
1252       * @param mask custom mask
1253       * @param severity of any created message
1254       * @param ordinal of any created message
1255       * @param classLoader the class loader to be used to get the ResourceBundle
1256       */
1257      private MessageDescriptor(String rbBase, String key, int mask,
1258                         Severity severity, Integer ordinal,
1259                         ClassLoader classLoader) {
1260        if (severity == null) {
1261          throw new NullPointerException("Null Severity value for message " +
1262                  "descriptor with key " + key);
1263        }
1264        this.rbBase = rbBase;
1265        this.key = key;
1266        this.category = Category.USER_DEFINED;
1267        this.severity = severity;
1268        this.ordinal = ordinal;
1269        this.classLoader = classLoader;
1270        this.mask = mask;
1271      }
1272    
1273    }