View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.tools;
19  
20  import java.io.PrintStream;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.List;
24  
25  import org.apache.logging.log4j.util.Strings;
26  
27  /**
28   * Generates source code for custom or extended logger wrappers.
29   * <p>
30   * Usage:
31   * <p>
32   * To generate source code for an extended logger that adds custom log levels to the existing ones: <br>
33   * {@code java org.apache.logging.log4j.core.tools.Generate$ExtendedLogger <logger.class.name> <CUSTOMLEVEL>=<WEIGHT>
34   * [CUSTOMLEVEL2=WEIGHT2 [CUSTOMLEVEL3=WEIGHT3] ...]}
35   * <p>
36   * Example of creating an extended logger:<br>
37   * {@code java org.apache.logging.log4j.core.tools.Generate$ExtendedLogger com.mycomp.ExtLogger DIAG=350 NOTICE=450
38   * VERBOSE=550}
39   * <p>
40   * To generate source code for a custom logger that replaces the existing log levels with custom ones: <br>
41   * {@code java org.apache.logging.log4j.core.tools.Generate$CustomLogger <logger.class.name> <CUSTOMLEVEL>=<WEIGHT>
42   * [CUSTOMLEVEL2=WEIGHT2 [CUSTOMLEVEL3=WEIGHT3] ...]}
43   * <p>
44   * Example of creating a custom logger:<br>
45   * {@code java org.apache.logging.log4j.core.tools.Generate$CustomLogger com.mycomp.MyLogger DEFCON1=350 DEFCON2=450
46   * DEFCON3=550}
47   */
48  public final class Generate {
49      // Implementation note:
50      // The generated code is in the user's namespace which has its own versioning scheme, so
51      // any @since tags in the generated code deliberately mention "Log4j-2.x" rather than just the log4j version number.
52  
53      static final String PACKAGE_DECLARATION = "package %s;%n%n";
54  
55      static enum Type {
56          CUSTOM {
57              @Override
58              String imports() {
59                  return "" //
60                          + "import java.io.Serializable;%n" //
61                          + "import org.apache.logging.log4j.Level;%n" //
62                          + "import org.apache.logging.log4j.LogManager;%n" //
63                          + "import org.apache.logging.log4j.Logger;%n" //
64                          + "import org.apache.logging.log4j.Marker;%n" //
65                          + "import org.apache.logging.log4j.message.Message;%n" //
66                          + "import org.apache.logging.log4j.message.MessageFactory;%n" //
67                          + "import org.apache.logging.log4j.spi.AbstractLogger;%n" //
68                          + "import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;%n" //
69                          + "import org.apache.logging.log4j.util.MessageSupplier;%n" //
70                          + "import org.apache.logging.log4j.util.Supplier;%n"
71                          + "%n";
72              }
73  
74              @Override
75              String declaration() {
76                  return "" //
77                          + "/**%n" //
78                          + " * Custom Logger interface with convenience methods for%n" //
79                          + " * %s%n" //
80                          + " * <p>Compatible with Log4j 2.6 or higher.</p>%n" //
81                          + " */%n" //
82                          + "public final class %s implements Serializable {%n" //
83                          + "    private static final long serialVersionUID = " + System.nanoTime() + "L;%n" //
84                          + "    private final ExtendedLoggerWrapper logger;%n" //
85                          + "%n";
86              }
87  
88              @Override
89              String constructor() {
90                  return "" //
91                          + "%n" //
92                          + "    private %s(final Logger logger) {%n" //
93                          + "        this.logger = new ExtendedLoggerWrapper((AbstractLogger) logger, logger.getName(), "
94                          + "logger.getMessageFactory());%n" //
95                          + "    }%n";
96              }
97  
98              @Override
99              Class<?> generator() {
100                 return CustomLogger.class;
101             }
102         },
103         EXTEND {
104             @Override
105             String imports() {
106                 return "" //
107                         + "import org.apache.logging.log4j.Level;%n" //
108                         + "import org.apache.logging.log4j.LogManager;%n" //
109                         + "import org.apache.logging.log4j.Logger;%n" //
110                         + "import org.apache.logging.log4j.Marker;%n" //
111                         + "import org.apache.logging.log4j.message.Message;%n" //
112                         + "import org.apache.logging.log4j.message.MessageFactory;%n" //
113                         + "import org.apache.logging.log4j.spi.AbstractLogger;%n" //
114                         + "import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;%n" //
115                         + "import org.apache.logging.log4j.util.MessageSupplier;%n" //
116                         + "import org.apache.logging.log4j.util.Supplier;%n"
117                         + "%n";
118             }
119 
120             @Override
121             String declaration() {
122                 return "" //
123                         + "/**%n" //
124                         + " * Extended Logger interface with convenience methods for%n" //
125                         + " * %s%n" //
126                         + " * <p>Compatible with Log4j 2.6 or higher.</p>%n" //
127                         + " */%n" //
128                         + "public final class %s extends ExtendedLoggerWrapper {%n" //
129                         + "    private static final long serialVersionUID = " + System.nanoTime() + "L;%n" //
130                         + "    private final ExtendedLoggerWrapper logger;%n" //
131                         + "%n";
132             }
133 
134             @Override
135             String constructor() {
136                 return "" //
137                         + "%n" //
138                         + "    private %s(final Logger logger) {%n" //
139                         + "        super((AbstractLogger) logger, logger.getName(), logger.getMessageFactory());%n" //
140                         + "        this.logger = this;%n" //
141                         + "    }%n";
142             }
143 
144             @Override
145             Class<?> generator() {
146                 return ExtendedLogger.class;
147             }
148         };
149         abstract String imports();
150 
151         abstract String declaration();
152 
153         abstract String constructor();
154 
155         abstract Class<?> generator();
156     }
157 
158     static final String FQCN_FIELD = "" //
159             + "    private static final String FQCN = %s.class.getName();%n";
160 
161     static final String LEVEL_FIELD = "" //
162             + "    private static final Level %s = Level.forName(\"%s\", %d);%n";
163 
164     static final String FACTORY_METHODS = "" //
165             + "%n" //
166             + "    /**%n" //
167             + "     * Returns a custom Logger with the name of the calling class.%n" //
168             + "     * %n" //
169             + "     * @return The custom Logger for the calling class.%n" //
170             + "     */%n" //
171             + "    public static CLASSNAME create() {%n" //
172             + "        final Logger wrapped = LogManager.getLogger();%n" //
173             + "        return new CLASSNAME(wrapped);%n" //
174             + "    }%n" //
175             + "%n" //
176             + "    /**%n" //
177             + "     * Returns a custom Logger using the fully qualified name of the Class as%n" //
178             + "     * the Logger name.%n" //
179             + "     * %n" //
180             + "     * @param loggerName The Class whose name should be used as the Logger name.%n" //
181             + "     *            If null it will default to the calling class.%n" //
182             + "     * @return The custom Logger.%n" //
183             + "     */%n" //
184             + "    public static CLASSNAME create(final Class<?> loggerName) {%n" //
185             + "        final Logger wrapped = LogManager.getLogger(loggerName);%n" //
186             + "        return new CLASSNAME(wrapped);%n" //
187             + "    }%n" //
188             + "%n" //
189             + "    /**%n" //
190             + "     * Returns a custom Logger using the fully qualified name of the Class as%n" //
191             + "     * the Logger name.%n" //
192             + "     * %n" //
193             + "     * @param loggerName The Class whose name should be used as the Logger name.%n" //
194             + "     *            If null it will default to the calling class.%n" //
195             + "     * @param messageFactory The message factory is used only when creating a%n" //
196             + "     *            logger, subsequent use does not change the logger but will log%n" //
197             + "     *            a warning if mismatched.%n" //
198             + "     * @return The custom Logger.%n" //
199             + "     */%n" //
200             + "    public static CLASSNAME create(final Class<?> loggerName, final MessageFactory" //
201             + " messageFactory) {%n" //
202             + "        final Logger wrapped = LogManager.getLogger(loggerName, messageFactory);%n" //
203             + "        return new CLASSNAME(wrapped);%n" //
204             + "    }%n" //
205             + "%n" //
206             + "    /**%n" //
207             + "     * Returns a custom Logger using the fully qualified class name of the value%n" //
208             + "     * as the Logger name.%n" //
209             + "     * %n" //
210             + "     * @param value The value whose class name should be used as the Logger%n" //
211             + "     *            name. If null the name of the calling class will be used as%n" //
212             + "     *            the logger name.%n" //
213             + "     * @return The custom Logger.%n" //
214             + "     */%n" //
215             + "    public static CLASSNAME create(final Object value) {%n" //
216             + "        final Logger wrapped = LogManager.getLogger(value);%n" //
217             + "        return new CLASSNAME(wrapped);%n" //
218             + "    }%n" //
219             + "%n" //
220             + "    /**%n" //
221             + "     * Returns a custom Logger using the fully qualified class name of the value%n" //
222             + "     * as the Logger name.%n" //
223             + "     * %n" //
224             + "     * @param value The value whose class name should be used as the Logger%n" //
225             + "     *            name. If null the name of the calling class will be used as%n" //
226             + "     *            the logger name.%n" //
227             + "     * @param messageFactory The message factory is used only when creating a%n" //
228             + "     *            logger, subsequent use does not change the logger but will log%n" //
229             + "     *            a warning if mismatched.%n" //
230             + "     * @return The custom Logger.%n" //
231             + "     */%n" //
232             + "    public static CLASSNAME create(final Object value, final MessageFactory messageFactory) {%n" //
233             + "        final Logger wrapped = LogManager.getLogger(value, messageFactory);%n" //
234             + "        return new CLASSNAME(wrapped);%n" //
235             + "    }%n" //
236             + "%n" //
237             + "    /**%n" //
238             + "     * Returns a custom Logger with the specified name.%n" //
239             + "     * %n" //
240             + "     * @param name The logger name. If null the name of the calling class will%n" //
241             + "     *            be used.%n" //
242             + "     * @return The custom Logger.%n" //
243             + "     */%n" //
244             + "    public static CLASSNAME create(final String name) {%n" //
245             + "        final Logger wrapped = LogManager.getLogger(name);%n" //
246             + "        return new CLASSNAME(wrapped);%n" //
247             + "    }%n" //
248             + "%n" //
249             + "    /**%n" //
250             + "     * Returns a custom Logger with the specified name.%n" //
251             + "     * %n" //
252             + "     * @param name The logger name. If null the name of the calling class will%n" //
253             + "     *            be used.%n" //
254             + "     * @param messageFactory The message factory is used only when creating a%n" //
255             + "     *            logger, subsequent use does not change the logger but will log%n" //
256             + "     *            a warning if mismatched.%n" //
257             + "     * @return The custom Logger.%n" //
258             + "     */%n" //
259             + "    public static CLASSNAME create(final String name, final MessageFactory messageFactory) {%n" //
260             + "        final Logger wrapped = LogManager.getLogger(name, messageFactory);%n" //
261             + "        return new CLASSNAME(wrapped);%n" //
262             + "    }%n";
263 
264     static final String METHODS = "" //
265             + "%n" //
266             + "    /**%n" //
267             + "     * Logs a message with the specific Marker at the {@code CUSTOM_LEVEL} level.%n" //
268             + "     * %n" //
269             + "     * @param marker the marker data specific to this log statement%n" //
270             + "     * @param msg the message string to be logged%n" //
271             + "     */%n" //
272             + "    public void methodName(final Marker marker, final Message msg) {%n" //
273             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msg, (Throwable) null);%n" //
274             + "    }%n" //
275             + "%n" //
276             + "    /**%n" //
277             + "     * Logs a message with the specific Marker at the {@code CUSTOM_LEVEL} level.%n" //
278             + "     * %n" //
279             + "     * @param marker the marker data specific to this log statement%n" //
280             + "     * @param msg the message string to be logged%n" //
281             + "     * @param t A Throwable or null.%n" //
282             + "     */%n" //
283             + "    public void methodName(final Marker marker, final Message msg, final Throwable t) {%n" //
284             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msg, t);%n" //
285             + "    }%n" //
286             + "%n" //
287             + "    /**%n" //
288             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n" //
289             + "     * %n" //
290             + "     * @param marker the marker data specific to this log statement%n" //
291             + "     * @param message the message object to log.%n" //
292             + "     */%n" //
293             + "    public void methodName(final Marker marker, final Object message) {%n" //
294             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n" //
295             + "    }%n" //
296             + "%n" //
297             + "    /**%n" //
298             + "     * Logs a message CharSequence with the {@code CUSTOM_LEVEL} level.%n" //
299             + "     * %n" //
300             + "     * @param marker the marker data specific to this log statement%n" //
301             + "     * @param message the message CharSequence to log.%n" //
302             + "     * @since Log4j-2.6%n" //
303             + "     */%n" //
304             + "    public void methodName(final Marker marker, final CharSequence message) {%n" //
305             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n" //
306             + "    }%n" //
307             + "%n" //
308             + "    /**%n" //
309             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
310             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
311             + "     * %n" //
312             + "     * @param marker the marker data specific to this log statement%n" //
313             + "     * @param message the message to log.%n" //
314             + "     * @param t the exception to log, including its stack trace.%n" //
315             + "     */%n" //
316             + "    public void methodName(final Marker marker, final Object message, final Throwable t) {%n" //
317             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n" //
318             + "    }%n" //
319             + "%n" //
320             + "    /**%n" //
321             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
322             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
323             + "     * %n" //
324             + "     * @param marker the marker data specific to this log statement%n" //
325             + "     * @param message the CharSequence to log.%n" //
326             + "     * @param t the exception to log, including its stack trace.%n" //
327             + "     * @since Log4j-2.6%n" //
328             + "     */%n" //
329             + "    public void methodName(final Marker marker, final CharSequence message, final Throwable t) {%n" //
330             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n" //
331             + "    }%n" //
332             + "%n" //
333             + "    /**%n" //
334             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n" //
335             + "     * %n" //
336             + "     * @param marker the marker data specific to this log statement%n" //
337             + "     * @param message the message object to log.%n" //
338             + "     */%n" //
339             + "    public void methodName(final Marker marker, final String message) {%n" //
340             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n" //
341             + "    }%n" //
342             + "%n" //
343             + "    /**%n" //
344             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
345             + "     * %n" //
346             + "     * @param marker the marker data specific to this log statement%n" //
347             + "     * @param message the message to log; the format depends on the message factory.%n" //
348             + "     * @param params parameters to the message.%n" //
349             + "     * @see #getMessageFactory()%n" //
350             + "     */%n" //
351             + "    public void methodName(final Marker marker, final String message, final Object... params) {%n" //
352             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, params);%n" //
353             + "    }%n" //
354             + "%n" //
355             + "    /**%n" //
356             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
357             + "     * %n" //
358             + "     * @param marker the marker data specific to this log statement%n" //
359             + "     * @param message the message to log; the format depends on the message factory.%n" //
360             + "     * @param p0 parameter to the message.%n" //
361             + "     * @see #getMessageFactory()%n" //
362             + "     * @since Log4j-2.6%n" //
363             + "     */%n" //
364             + "    public void methodName(final Marker marker, final String message, final Object p0) {%n" //
365             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0);%n" //
366             + "    }%n" //
367             + "%n" //
368             + "    /**%n" //
369             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
370             + "     * %n" //
371             + "     * @param marker the marker data specific to this log statement%n" //
372             + "     * @param message the message to log; the format depends on the message factory.%n" //
373             + "     * @param p0 parameter to the message.%n" //
374             + "     * @param p1 parameter to the message.%n" //
375             + "     * @see #getMessageFactory()%n" //
376             + "     * @since Log4j-2.6%n" //
377             + "     */%n" //
378             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
379             + "final Object p1) {%n" //
380             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1);%n" //
381             + "    }%n" //
382             + "%n" //
383             + "    /**%n" //
384             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
385             + "     * %n" //
386             + "     * @param marker the marker data specific to this log statement%n" //
387             + "     * @param message the message to log; the format depends on the message factory.%n" //
388             + "     * @param p0 parameter to the message.%n" //
389             + "     * @param p1 parameter to the message.%n" //
390             + "     * @param p2 parameter to the message.%n" //
391             + "     * @see #getMessageFactory()%n" //
392             + "     * @since Log4j-2.6%n" //
393             + "     */%n" //
394             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
395             + "final Object p1, final Object p2) {%n" //
396             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2);%n" //
397             + "    }%n" //
398             + "%n" //
399             + "    /**%n" //
400             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
401             + "     * %n" //
402             + "     * @param marker the marker data specific to this log statement%n" //
403             + "     * @param message the message to log; the format depends on the message factory.%n" //
404             + "     * @param p0 parameter to the message.%n" //
405             + "     * @param p1 parameter to the message.%n" //
406             + "     * @param p2 parameter to the message.%n" //
407             + "     * @param p3 parameter to the message.%n" //
408             + "     * @see #getMessageFactory()%n" //
409             + "     * @since Log4j-2.6%n" //
410             + "     */%n" //
411             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
412             + "final Object p1, final Object p2,%n" //
413             + "            final Object p3) {%n" //
414             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3);%n" //
415             + "    }%n" //
416             + "%n" //
417             + "    /**%n" //
418             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
419             + "     * %n" //
420             + "     * @param marker the marker data specific to this log statement%n" //
421             + "     * @param message the message to log; the format depends on the message factory.%n" //
422             + "     * @param p0 parameter to the message.%n" //
423             + "     * @param p1 parameter to the message.%n" //
424             + "     * @param p2 parameter to the message.%n" //
425             + "     * @param p3 parameter to the message.%n" //
426             + "     * @param p4 parameter to the message.%n" //
427             + "     * @see #getMessageFactory()%n" //
428             + "     * @since Log4j-2.6%n" //
429             + "     */%n" //
430             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
431             + "final Object p1, final Object p2,%n" //
432             + "            final Object p3, final Object p4) {%n" //
433             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4);%n" //
434             + "    }%n" //
435             + "%n" //
436             + "    /**%n" //
437             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
438             + "     * %n" //
439             + "     * @param marker the marker data specific to this log statement%n" //
440             + "     * @param message the message to log; the format depends on the message factory.%n" //
441             + "     * @param p0 parameter to the message.%n" //
442             + "     * @param p1 parameter to the message.%n" //
443             + "     * @param p2 parameter to the message.%n" //
444             + "     * @param p3 parameter to the message.%n" //
445             + "     * @param p4 parameter to the message.%n" //
446             + "     * @param p5 parameter to the message.%n" //
447             + "     * @see #getMessageFactory()%n" //
448             + "     * @since Log4j-2.6%n" //
449             + "     */%n" //
450             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
451             + "final Object p1, final Object p2,%n" //
452             + "            final Object p3, final Object p4, final Object p5) {%n" //
453             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5);%n" //
454             + "    }%n" //
455             + "%n" //
456             + "    /**%n" //
457             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
458             + "     * %n" //
459             + "     * @param marker the marker data specific to this log statement%n" //
460             + "     * @param message the message to log; the format depends on the message factory.%n" //
461             + "     * @param p0 parameter to the message.%n" //
462             + "     * @param p1 parameter to the message.%n" //
463             + "     * @param p2 parameter to the message.%n" //
464             + "     * @param p3 parameter to the message.%n" //
465             + "     * @param p4 parameter to the message.%n" //
466             + "     * @param p5 parameter to the message.%n" //
467             + "     * @param p6 parameter to the message.%n" //
468             + "     * @see #getMessageFactory()%n" //
469             + "     * @since Log4j-2.6%n" //
470             + "     */%n" //
471             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
472             + "final Object p1, final Object p2,%n" //
473             + "            final Object p3, final Object p4, final Object p5, final Object p6) {%n" //
474             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6);%n" //
475             + "    }%n" //
476             + "%n" //
477             + "    /**%n" //
478             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
479             + "     * %n" //
480             + "     * @param marker the marker data specific to this log statement%n" //
481             + "     * @param message the message to log; the format depends on the message factory.%n" //
482             + "     * @param p0 parameter to the message.%n" //
483             + "     * @param p1 parameter to the message.%n" //
484             + "     * @param p2 parameter to the message.%n" //
485             + "     * @param p3 parameter to the message.%n" //
486             + "     * @param p4 parameter to the message.%n" //
487             + "     * @param p5 parameter to the message.%n" //
488             + "     * @param p6 parameter to the message.%n" //
489             + "     * @param p7 parameter to the message.%n" //
490             + "     * @see #getMessageFactory()%n" //
491             + "     * @since Log4j-2.6%n" //
492             + "     */%n" //
493             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
494             + "final Object p1, final Object p2,%n" //
495             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
496             + "            final Object p7) {%n" //
497             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7);%n" //
498             + "    }%n" //
499             + "%n" //
500             + "    /**%n" //
501             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
502             + "     * %n" //
503             + "     * @param marker the marker data specific to this log statement%n" //
504             + "     * @param message the message to log; the format depends on the message factory.%n" //
505             + "     * @param p0 parameter to the message.%n" //
506             + "     * @param p1 parameter to the message.%n" //
507             + "     * @param p2 parameter to the message.%n" //
508             + "     * @param p3 parameter to the message.%n" //
509             + "     * @param p4 parameter to the message.%n" //
510             + "     * @param p5 parameter to the message.%n" //
511             + "     * @param p6 parameter to the message.%n" //
512             + "     * @param p7 parameter to the message.%n" //
513             + "     * @param p8 parameter to the message.%n" //
514             + "     * @see #getMessageFactory()%n" //
515             + "     * @since Log4j-2.6%n" //
516             + "     */%n" //
517             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
518             + "final Object p1, final Object p2,%n" //
519             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
520             + "            final Object p7, final Object p8) {%n" //
521             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, " //
522             + "p8);%n" //
523             + "    }%n" //
524             + "%n" //
525             + "    /**%n" //
526             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
527             + "     * %n" //
528             + "     * @param marker the marker data specific to this log statement%n" //
529             + "     * @param message the message to log; the format depends on the message factory.%n" //
530             + "     * @param p0 parameter to the message.%n" //
531             + "     * @param p1 parameter to the message.%n" //
532             + "     * @param p2 parameter to the message.%n" //
533             + "     * @param p3 parameter to the message.%n" //
534             + "     * @param p4 parameter to the message.%n" //
535             + "     * @param p5 parameter to the message.%n" //
536             + "     * @param p6 parameter to the message.%n" //
537             + "     * @param p7 parameter to the message.%n" //
538             + "     * @param p8 parameter to the message.%n" //
539             + "     * @param p9 parameter to the message.%n" //
540             + "     * @see #getMessageFactory()%n" //
541             + "     * @since Log4j-2.6%n" //
542             + "     */%n" //
543             + "    public void methodName(final Marker marker, final String message, final Object p0, " //
544             + "final Object p1, final Object p2,%n" //
545             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
546             + "            final Object p7, final Object p8, final Object p9) {%n" //
547             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, " //
548             + "p8, p9);%n" //
549             + "    }%n" //
550             + "%n" //
551             + "    /**%n" //
552             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
553             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
554             + "     * %n" //
555             + "     * @param marker the marker data specific to this log statement%n" //
556             + "     * @param message the message to log.%n" //
557             + "     * @param t the exception to log, including its stack trace.%n" //
558             + "     */%n" //
559             + "    public void methodName(final Marker marker, final String message, final Throwable t) {%n" //
560             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n" //
561             + "    }%n" //
562             + "%n" //
563             + "    /**%n" //
564             + "     * Logs the specified Message at the {@code CUSTOM_LEVEL} level.%n" //
565             + "     * %n" //
566             + "     * @param msg the message string to be logged%n" //
567             + "     */%n" //
568             + "    public void methodName(final Message msg) {%n" //
569             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msg, (Throwable) null);%n" //
570             + "    }%n" //
571             + "%n" //
572             + "    /**%n" //
573             + "     * Logs the specified Message at the {@code CUSTOM_LEVEL} level.%n" //
574             + "     * %n" //
575             + "     * @param msg the message string to be logged%n" //
576             + "     * @param t A Throwable or null.%n" //
577             + "     */%n" //
578             + "    public void methodName(final Message msg, final Throwable t) {%n" //
579             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msg, t);%n" //
580             + "    }%n" //
581             + "%n" //
582             + "    /**%n" //
583             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n" //
584             + "     * %n" //
585             + "     * @param message the message object to log.%n" //
586             + "     */%n" //
587             + "    public void methodName(final Object message) {%n" //
588             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n" //
589             + "    }%n" //
590             + "%n" //
591             + "    /**%n" //
592             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
593             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
594             + "     * %n" //
595             + "     * @param message the message to log.%n" //
596             + "     * @param t the exception to log, including its stack trace.%n" //
597             + "     */%n" //
598             + "    public void methodName(final Object message, final Throwable t) {%n" //
599             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n" //
600             + "    }%n" //
601             + "%n" //
602             + "    /**%n" //
603             + "     * Logs a message CharSequence with the {@code CUSTOM_LEVEL} level.%n" //
604             + "     * %n" //
605             + "     * @param message the message CharSequence to log.%n" //
606             + "     * @since Log4j-2.6%n" //
607             + "     */%n" //
608             + "    public void methodName(final CharSequence message) {%n" //
609             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n" //
610             + "    }%n" //
611             + "%n" //
612             + "    /**%n" //
613             + "     * Logs a CharSequence at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
614             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
615             + "     * %n" //
616             + "     * @param message the CharSequence to log.%n" //
617             + "     * @param t the exception to log, including its stack trace.%n" //
618             + "     * @since Log4j-2.6%n" //
619             + "     */%n" //
620             + "    public void methodName(final CharSequence message, final Throwable t) {%n" //
621             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n" //
622             + "    }%n" //
623             + "%n" //
624             + "    /**%n" //
625             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n" //
626             + "     * %n" //
627             + "     * @param message the message object to log.%n" //
628             + "     */%n" //
629             + "    public void methodName(final String message) {%n" //
630             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n" //
631             + "    }%n" //
632             + "%n" //
633             + "    /**%n" //
634             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
635             + "     * %n" //
636             + "     * @param message the message to log; the format depends on the message factory.%n" //
637             + "     * @param params parameters to the message.%n" //
638             + "     * @see #getMessageFactory()%n" //
639             + "     */%n" //
640             + "    public void methodName(final String message, final Object... params) {%n" //
641             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, params);%n" //
642             + "    }%n" //
643             + "%n" //
644             + "    /**%n" //
645             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
646             + "     * %n" //
647             + "     * @param message the message to log; the format depends on the message factory.%n" //
648             + "     * @param p0 parameter to the message.%n" //
649             + "     * @see #getMessageFactory()%n" //
650             + "     * @since Log4j-2.6%n" //
651             + "     */%n" //
652             + "    public void methodName(final String message, final Object p0) {%n" //
653             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0);%n" //
654             + "    }%n" //
655             + "%n" //
656             + "    /**%n" //
657             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
658             + "     * %n" //
659             + "     * @param message the message to log; the format depends on the message factory.%n" //
660             + "     * @param p0 parameter to the message.%n" //
661             + "     * @param p1 parameter to the message.%n" //
662             + "     * @see #getMessageFactory()%n" //
663             + "     * @since Log4j-2.6%n" //
664             + "     */%n" //
665             + "    public void methodName(final String message, final Object p0, " //
666             + "final Object p1) {%n" //
667             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1);%n" //
668             + "    }%n" //
669             + "%n" //
670             + "    /**%n" //
671             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
672             + "     * %n" //
673             + "     * @param message the message to log; the format depends on the message factory.%n" //
674             + "     * @param p0 parameter to the message.%n" //
675             + "     * @param p1 parameter to the message.%n" //
676             + "     * @param p2 parameter to the message.%n" //
677             + "     * @see #getMessageFactory()%n" //
678             + "     * @since Log4j-2.6%n" //
679             + "     */%n" //
680             + "    public void methodName(final String message, final Object p0, " //
681             + "final Object p1, final Object p2) {%n" //
682             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2);%n" //
683             + "    }%n" //
684             + "%n" //
685             + "    /**%n" //
686             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
687             + "     * %n" //
688             + "     * @param message the message to log; the format depends on the message factory.%n" //
689             + "     * @param p0 parameter to the message.%n" //
690             + "     * @param p1 parameter to the message.%n" //
691             + "     * @param p2 parameter to the message.%n" //
692             + "     * @param p3 parameter to the message.%n" //
693             + "     * @see #getMessageFactory()%n" //
694             + "     * @since Log4j-2.6%n" //
695             + "     */%n" //
696             + "    public void methodName(final String message, final Object p0, " //
697             + "final Object p1, final Object p2,%n" //
698             + "            final Object p3) {%n" //
699             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3);%n" //
700             + "    }%n" //
701             + "%n" //
702             + "    /**%n" //
703             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
704             + "     * %n" //
705             + "     * @param message the message to log; the format depends on the message factory.%n" //
706             + "     * @param p0 parameter to the message.%n" //
707             + "     * @param p1 parameter to the message.%n" //
708             + "     * @param p2 parameter to the message.%n" //
709             + "     * @param p3 parameter to the message.%n" //
710             + "     * @param p4 parameter to the message.%n" //
711             + "     * @see #getMessageFactory()%n" //
712             + "     * @since Log4j-2.6%n" //
713             + "     */%n" //
714             + "    public void methodName(final String message, final Object p0, " //
715             + "final Object p1, final Object p2,%n" //
716             + "            final Object p3, final Object p4) {%n" //
717             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4);%n" //
718             + "    }%n" //
719             + "%n" //
720             + "    /**%n" //
721             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
722             + "     * %n" //
723             + "     * @param message the message to log; the format depends on the message factory.%n" //
724             + "     * @param p0 parameter to the message.%n" //
725             + "     * @param p1 parameter to the message.%n" //
726             + "     * @param p2 parameter to the message.%n" //
727             + "     * @param p3 parameter to the message.%n" //
728             + "     * @param p4 parameter to the message.%n" //
729             + "     * @param p5 parameter to the message.%n" //
730             + "     * @see #getMessageFactory()%n" //
731             + "     * @since Log4j-2.6%n" //
732             + "     */%n" //
733             + "    public void methodName(final String message, final Object p0, " //
734             + "final Object p1, final Object p2,%n" //
735             + "            final Object p3, final Object p4, final Object p5) {%n" //
736             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5);%n" //
737             + "    }%n" //
738             + "%n" //
739             + "    /**%n" //
740             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
741             + "     * %n" //
742             + "     * @param message the message to log; the format depends on the message factory.%n" //
743             + "     * @param p0 parameter to the message.%n" //
744             + "     * @param p1 parameter to the message.%n" //
745             + "     * @param p2 parameter to the message.%n" //
746             + "     * @param p3 parameter to the message.%n" //
747             + "     * @param p4 parameter to the message.%n" //
748             + "     * @param p5 parameter to the message.%n" //
749             + "     * @param p6 parameter to the message.%n" //
750             + "     * @see #getMessageFactory()%n" //
751             + "     * @since Log4j-2.6%n" //
752             + "     */%n" //
753             + "    public void methodName(final String message, final Object p0, " //
754             + "final Object p1, final Object p2,%n" //
755             + "            final Object p3, final Object p4, final Object p5, final Object p6) {%n" //
756             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6);%n" //
757             + "    }%n" //
758             + "%n" //
759             + "    /**%n" //
760             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
761             + "     * %n" //
762             + "     * @param message the message to log; the format depends on the message factory.%n" //
763             + "     * @param p0 parameter to the message.%n" //
764             + "     * @param p1 parameter to the message.%n" //
765             + "     * @param p2 parameter to the message.%n" //
766             + "     * @param p3 parameter to the message.%n" //
767             + "     * @param p4 parameter to the message.%n" //
768             + "     * @param p5 parameter to the message.%n" //
769             + "     * @param p6 parameter to the message.%n" //
770             + "     * @param p7 parameter to the message.%n" //
771             + "     * @see #getMessageFactory()%n" //
772             + "     * @since Log4j-2.6%n" //
773             + "     */%n" //
774             + "    public void methodName(final String message, final Object p0, " //
775             + "final Object p1, final Object p2,%n" //
776             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
777             + "            final Object p7) {%n" //
778             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7);%n" //
779             + "    }%n" //
780             + "%n" //
781             + "    /**%n" //
782             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
783             + "     * %n" //
784             + "     * @param message the message to log; the format depends on the message factory.%n" //
785             + "     * @param p0 parameter to the message.%n" //
786             + "     * @param p1 parameter to the message.%n" //
787             + "     * @param p2 parameter to the message.%n" //
788             + "     * @param p3 parameter to the message.%n" //
789             + "     * @param p4 parameter to the message.%n" //
790             + "     * @param p5 parameter to the message.%n" //
791             + "     * @param p6 parameter to the message.%n" //
792             + "     * @param p7 parameter to the message.%n" //
793             + "     * @param p8 parameter to the message.%n" //
794             + "     * @see #getMessageFactory()%n" //
795             + "     * @since Log4j-2.6%n" //
796             + "     */%n" //
797             + "    public void methodName(final String message, final Object p0, " //
798             + "final Object p1, final Object p2,%n" //
799             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
800             + "            final Object p7, final Object p8) {%n" //
801             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7, " //
802             + "p8);%n" //
803             + "    }%n" //
804             + "%n" //
805             + "    /**%n" //
806             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n" //
807             + "     * %n" //
808             + "     * @param message the message to log; the format depends on the message factory.%n" //
809             + "     * @param p0 parameter to the message.%n" //
810             + "     * @param p1 parameter to the message.%n" //
811             + "     * @param p2 parameter to the message.%n" //
812             + "     * @param p3 parameter to the message.%n" //
813             + "     * @param p4 parameter to the message.%n" //
814             + "     * @param p5 parameter to the message.%n" //
815             + "     * @param p6 parameter to the message.%n" //
816             + "     * @param p7 parameter to the message.%n" //
817             + "     * @param p8 parameter to the message.%n" //
818             + "     * @param p9 parameter to the message.%n" //
819             + "     * @see #getMessageFactory()%n" //
820             + "     * @since Log4j-2.6%n" //
821             + "     */%n" //
822             + "    public void methodName(final String message, final Object p0, " //
823             + "final Object p1, final Object p2,%n" //
824             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n" //
825             + "            final Object p7, final Object p8, final Object p9) {%n" //
826             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7, " //
827             + "p8, p9);%n" //
828             + "    }%n" //
829             + "%n" //
830             + "    /**%n" //
831             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n" //
832             + "     * the {@link Throwable} {@code t} passed as parameter.%n" //
833             + "     * %n" //
834             + "     * @param message the message to log.%n" //
835             + "     * @param t the exception to log, including its stack trace.%n" //
836             + "     */%n" //
837             + "    public void methodName(final String message, final Throwable t) {%n" //
838             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n" //
839             + "    }%n"
840             + "%n" //
841             + "    /**%n" //
842             + "     * Logs a message which is only to be constructed if the logging level is the {@code CUSTOM_LEVEL}"//
843             + "level.%n" //
844             + "     *%n" //
845             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n" //
846             + "     *            the format depends on the message factory.%n" //
847             + "     * @since Log4j-2.4%n" //
848             + "     */%n" //
849             + "    public void methodName(final Supplier<?> msgSupplier) {%n" //
850             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, (Throwable) null);%n" //
851             + "    }%n" //
852             + "%n" //
853             + "    /**%n" //
854             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n" //
855             + "     * level) including the stack trace of the {@link Throwable} <code>t</code> passed as parameter.%n"//
856             + "     *%n" //
857             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n" //
858             + "     *            the format depends on the message factory.%n" //
859             + "     * @param t the exception to log, including its stack trace.%n" //
860             + "     * @since Log4j-2.4%n" //
861             + "     */%n" //
862             + "    public void methodName(final Supplier<?> msgSupplier, final Throwable t) {%n" //
863             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, t);%n" //
864             + "    }%n" //
865             + "%n" //
866             + "    /**%n" //
867             + "     * Logs a message which is only to be constructed if the logging level is the%n" //
868             + "     * {@code CUSTOM_LEVEL} level with the specified Marker.%n" //
869             + "     *%n" //
870             + "     * @param marker the marker data specific to this log statement%n" //
871             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n" //
872             + "     *            the format depends on the message factory.%n" //
873             + "     * @since Log4j-2.4%n" //
874             + "     */%n" //
875             + "    public void methodName(final Marker marker, final Supplier<?> msgSupplier) {%n" //
876             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, (Throwable) null);%n" //
877             + "    }%n" //
878             + "%n" //
879             + "    /**%n" //
880             + "     * Logs a message with parameters which are only to be constructed if the logging level is the%n" //
881             + "     * {@code CUSTOM_LEVEL} level.%n" //
882             + "     *%n" //
883             + "     * @param marker the marker data specific to this log statement%n" //
884             + "     * @param message the message to log; the format depends on the message factory.%n" //
885             + "     * @param paramSuppliers An array of functions, which when called, produce the desired log" //
886             + " message parameters.%n" //
887             + "     * @since Log4j-2.4%n" //
888             + "     */%n" //
889             + "    public void methodName(final Marker marker, final String message, final Supplier<?>..." //
890             + " paramSuppliers) {%n" //
891             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, paramSuppliers);%n" //
892             + "    }%n" //
893             + "%n" //
894             + "    /**%n" //
895             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n" //
896             + "     * level) with the specified Marker and including the stack trace of the {@link Throwable}%n" //
897             + "     * <code>t</code> passed as parameter.%n"
898             + "     *%n" //
899             + "     * @param marker the marker data specific to this log statement%n" //
900             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n" //
901             + "     *            the format depends on the message factory.%n" //
902             + "     * @param t A Throwable or null.%n" //
903             + "     * @since Log4j-2.4%n" //
904             + "     */%n" //
905             + "    public void methodName(final Marker marker, final Supplier<?> msgSupplier, final Throwable t) {%n" //
906             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, t);%n" //
907             + "    }%n" //
908             + "%n" //
909             + "    /**%n" //
910             + "     * Logs a message with parameters which are only to be constructed if the logging level is%n" //
911             + "     * the {@code CUSTOM_LEVEL} level.%n" //
912             + "     *%n" //
913             + "     * @param message the message to log; the format depends on the message factory.%n" //
914             + "     * @param paramSuppliers An array of functions, which when called, produce the desired log" //
915             + " message parameters.%n" //
916             + "     * @since Log4j-2.4%n" //
917             + "     */%n" //
918             + "    public void methodName(final String message, final Supplier<?>... paramSuppliers) {%n" //
919             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, paramSuppliers);%n" //
920             + "    }%n" //
921             + "%n" //
922             + "    /**%n" //
923             + "     * Logs a message which is only to be constructed if the logging level is the%n" //
924             + "     * {@code CUSTOM_LEVEL} level with the specified Marker. The {@code MessageSupplier} may or may%n" //
925             + "     * not use the {@link MessageFactory} to construct the {@code Message}.%n" //
926             + "     *%n" //
927             + "     * @param marker the marker data specific to this log statement%n" //
928             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n" //
929             + "     * @since Log4j-2.4%n" //
930             + "     */%n" //
931             + "    public void methodName(final Marker marker, final MessageSupplier msgSupplier) {%n" //
932             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, (Throwable) null);%n" //
933             + "    }%n" //
934             + "%n" //
935             + "    /**%n" //
936             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n" //
937             + "     * level) with the specified Marker and including the stack trace of the {@link Throwable}%n" //
938             + "     * <code>t</code> passed as parameter. The {@code MessageSupplier} may or may not use the%n" //
939             + "     * {@link MessageFactory} to construct the {@code Message}.%n"
940             + "     *%n" //
941             + "     * @param marker the marker data specific to this log statement%n" //
942             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n" //
943             + "     * @param t A Throwable or null.%n" //
944             + "     * @since Log4j-2.4%n" //
945             + "     */%n" //
946             + "    public void methodName(final Marker marker, final MessageSupplier msgSupplier, final " //
947             + "Throwable t) {%n" //
948             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, t);%n" //
949             + "    }%n" //
950             + "%n" //
951             + "    /**%n" //
952             + "     * Logs a message which is only to be constructed if the logging level is the%n" //
953             + "     * {@code CUSTOM_LEVEL} level. The {@code MessageSupplier} may or may not use the%n" //
954             + "     * {@link MessageFactory} to construct the {@code Message}.%n"
955             + "     *%n" //
956             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n" //
957             + "     * @since Log4j-2.4%n" //
958             + "     */%n" //
959             + "    public void methodName(final MessageSupplier msgSupplier) {%n" //
960             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, (Throwable) null);%n" //
961             + "    }%n" //
962             + "%n" //
963             + "    /**%n" //
964             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n" //
965             + "     * level) including the stack trace of the {@link Throwable} <code>t</code> passed as parameter.%n"//
966             + "     * The {@code MessageSupplier} may or may not use the {@link MessageFactory} to construct the%n" //
967             + "     * {@code Message}.%n"
968             + "     *%n" //
969             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n" //
970             + "     * @param t the exception to log, including its stack trace.%n" //
971             + "     * @since Log4j-2.4%n" //
972             + "     */%n" //
973             + "    public void methodName(final MessageSupplier msgSupplier, final Throwable t) {%n" //
974             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, t);%n" //
975             + "    }%n";
976 
977     private Generate() {
978     }
979 
980     /**
981      * Generates source code for custom logger wrappers that only provide convenience methods for the specified custom
982      * levels, not for the standard built-in levels.
983      */
984     public static final class CustomLogger {
985         /**
986          * Generates source code for custom logger wrappers that only provide convenience methods for the specified
987          * custom levels, not for the standard built-in levels.
988          *
989          * @param args className of the custom logger to generate, followed by a NAME=intLevel pair for each custom log
990          *            level to generate convenience methods for
991          */
992         public static void main(final String[] args) {
993             generate(args, Type.CUSTOM);
994         }
995 
996         private CustomLogger() {
997         }
998     }
999 
1000     /**
1001      * Generates source code for extended logger wrappers that provide convenience methods for the specified custom
1002      * levels, and by extending {@code org.apache.logging.log4j.spi.ExtendedLoggerWrapper}, inherit the convenience
1003      * methods for the built-in levels provided by the {@code Logger} interface.
1004      */
1005     public static final class ExtendedLogger {
1006         /**
1007          * Generates source code for extended logger wrappers that provide convenience methods for the specified custom
1008          * levels.
1009          *
1010          * @param args className of the custom logger to generate, followed by a NAME=intLevel pair for each custom log
1011          *            level to generate convenience methods for
1012          */
1013         public static void main(final String[] args) {
1014             generate(args, Type.EXTEND);
1015         }
1016 
1017         private ExtendedLogger() {
1018         }
1019     }
1020 
1021     static class LevelInfo {
1022         final String name;
1023         final int intLevel;
1024 
1025         LevelInfo(final String description) {
1026             final String[] parts = description.split("=");
1027             name = parts[0];
1028             intLevel = Integer.parseInt(parts[1]);
1029         }
1030 
1031         public static List<LevelInfo> parse(final List<String> values, final Class<?> generator) {
1032             final List<LevelInfo> result = new ArrayList<>(values.size());
1033             for (int i = 0; i < values.size(); i++) {
1034                 try {
1035                     result.add(new LevelInfo(values.get(i)));
1036                 } catch (final Exception ex) {
1037                     System.err.println("Cannot parse custom level '" + values.get(i) + "': " + ex.toString());
1038                     usage(System.err, generator);
1039                     System.exit(-1);
1040                 }
1041             }
1042             return result;
1043         }
1044     }
1045 
1046     private static void generate(final String[] args, final Type type) {
1047         generate(args, type, System.out);
1048     }
1049 
1050     static void generate(final String[] args, final Type type, final PrintStream printStream) {
1051         if (!validate(args)) {
1052             usage(printStream, type.generator());
1053             System.exit(-1);
1054         }
1055         final List<String> values = new ArrayList<>(Arrays.asList(args));
1056         final String classFQN = values.remove(0);
1057         final List<LevelInfo> levels = LevelInfo.parse(values, type.generator());
1058         printStream.println(generateSource(classFQN, levels, type));
1059     }
1060 
1061     static boolean validate(final String[] args) {
1062         if (args.length < 2) {
1063             return false;
1064         }
1065         return true;
1066     }
1067 
1068     private static void usage(final PrintStream out, final Class<?> generator) {
1069         out.println("Usage: java " + generator.getName() + " className LEVEL1=intLevel1 [LEVEL2=intLevel2...]");
1070         out.println("       Where className is the fully qualified class name of the custom/extended logger");
1071         out.println("       to generate, followed by a space-separated list of custom log levels.");
1072         out.println("       For each custom log level, specify NAME=intLevel (without spaces).");
1073     }
1074 
1075     static String generateSource(final String classNameFQN, final List<LevelInfo> levels, final Type type) {
1076         final StringBuilder sb = new StringBuilder(10000 * levels.size());
1077         final int lastDot = classNameFQN.lastIndexOf('.');
1078         final String pkg = classNameFQN.substring(0, lastDot >= 0 ? lastDot : 0);
1079         if (!pkg.isEmpty()) {
1080             sb.append(String.format(PACKAGE_DECLARATION, pkg));
1081         }
1082         sb.append(String.format(type.imports(), ""));
1083         final String className = classNameFQN.substring(classNameFQN.lastIndexOf('.') + 1);
1084         final String javadocDescr = javadocDescription(levels);
1085         sb.append(String.format(type.declaration(), javadocDescr, className));
1086         sb.append(String.format(FQCN_FIELD, className));
1087         for (final LevelInfo level : levels) {
1088             sb.append(String.format(LEVEL_FIELD, level.name, level.name, level.intLevel));
1089         }
1090         sb.append(String.format(type.constructor(), className));
1091         sb.append(String.format(FACTORY_METHODS.replaceAll("CLASSNAME", className), ""));
1092         for (final LevelInfo level : levels) {
1093             final String methodName = camelCase(level.name);
1094             final String phase1 = METHODS.replaceAll("CUSTOM_LEVEL", level.name);
1095             final String phase2 = phase1.replaceAll("methodName", methodName);
1096             sb.append(String.format(phase2, ""));
1097         }
1098 
1099         sb.append('}');
1100         sb.append(Strings.LINE_SEPARATOR);
1101         return sb.toString();
1102     }
1103 
1104     static String javadocDescription(final List<LevelInfo> levels) {
1105         if (levels.size() == 1) {
1106             return "the " + levels.get(0).name + " custom log level.";
1107         }
1108         final StringBuilder sb = new StringBuilder(512);
1109         sb.append("the ");
1110         String sep = "";
1111         for (int i = 0; i < levels.size(); i++) {
1112             sb.append(sep);
1113             sb.append(levels.get(i).name);
1114             sep = (i == levels.size() - 2) ? " and " : ", ";
1115         }
1116         sb.append(" custom log levels.");
1117         return sb.toString();
1118     }
1119 
1120     static String camelCase(final String customLevel) {
1121         final StringBuilder sb = new StringBuilder(customLevel.length());
1122         boolean lower = true;
1123         for (final char ch : customLevel.toCharArray()) {
1124             if (ch == '_') {
1125                 lower = false;
1126                 continue;
1127             }
1128             sb.append(lower ? Character.toLowerCase(ch) : Character.toUpperCase(ch));
1129             lower = true;
1130         }
1131         return sb.toString();
1132     }
1133 }