View Javadoc
1   package com.jsql.view.swing.console;
2   
3   import com.jsql.util.LogLevelUtil;
4   import org.apache.logging.log4j.Level;
5   import org.apache.logging.log4j.core.*;
6   import org.apache.logging.log4j.core.appender.AbstractAppender;
7   import org.apache.logging.log4j.core.config.Property;
8   import org.apache.logging.log4j.core.config.plugins.Plugin;
9   import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
10  import org.apache.logging.log4j.core.config.plugins.PluginElement;
11  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
12  import org.apache.logging.log4j.core.layout.PatternLayout;
13  
14  import javax.swing.*;
15  import javax.swing.text.SimpleAttributeSet;
16  import java.nio.charset.StandardCharsets;
17  import java.util.Optional;
18  
19  @Plugin(
20      name = "JTextPaneAppender",
21      category = Core.CATEGORY_NAME,
22      elementType = Appender.ELEMENT_TYPE,
23      printObject = true
24  )
25  public class JTextPaneAppender extends AbstractAppender {
26      
27      private static SimpleConsoleAdapter consoleTextPane;  // Main console
28      private static SimpleConsoleAdapter javaTextPane;  // Java console
29  
30      public static final SimpleAttributeSet ATTRIBUTE_WARN = new SimpleAttributeSet();
31      public static final SimpleAttributeSet ATTRIBUTE_INFORM = new SimpleAttributeSet();
32      public static final SimpleAttributeSet ATTRIBUTE_SUCCESS = new SimpleAttributeSet();
33      public static final SimpleAttributeSet ATTRIBUTE_ALL = new SimpleAttributeSet();
34      
35      private JTextPaneAppender(String name, Layout<?> layout, Filter filter, boolean ignoreExceptions) {
36          super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
37      }
38  
39      @SuppressWarnings({ "unused", "rawtypes" })
40      @PluginFactory
41      public static JTextPaneAppender createAppender(
42          @PluginAttribute("name") String name,
43          @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
44          @PluginElement("Layout") Layout layout,
45          @PluginElement("Filters") Filter filter
46      ) {
47          if (name == null) {
48              LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "No name provided for JTextPaneAppender");
49              return null;
50          }
51          var layoutTextPane = Optional.ofNullable(layout).orElse(PatternLayout.createDefaultLayout());
52          return new JTextPaneAppender(name, layoutTextPane, filter, ignoreExceptions);
53      }
54  
55      @Override
56      public void append(LogEvent event) {
57          // Avoid errors which might occur in headless mode
58          // or logging that occurs before consoles are available
59          if (JTextPaneAppender.consoleTextPane == null || JTextPaneAppender.javaTextPane == null) {
60              return;
61          }
62          var messageLogEvent = new String[] {
63              new String(this.getLayout().toByteArray(event), StandardCharsets.UTF_8)
64          };
65          if (messageLogEvent.length == 0) {  // fixes #95664
66              return;
67          }
68          
69          var level = event.getLevel().intLevel();
70          SwingUtilities.invokeLater(() -> {
71              String message = messageLogEvent[0];
72              if (level == LogLevelUtil.CONSOLE_JAVA.intLevel()) {
73                  JTextPaneAppender.javaTextPane.append(message, JTextPaneAppender.ATTRIBUTE_WARN);
74              } else if (level == LogLevelUtil.CONSOLE_ERROR.intLevel()) {
75                  JTextPaneAppender.consoleTextPane.append(message, JTextPaneAppender.ATTRIBUTE_WARN);
76              } else if (level == LogLevelUtil.CONSOLE_INFORM.intLevel()) {
77                  JTextPaneAppender.consoleTextPane.append(message, JTextPaneAppender.ATTRIBUTE_INFORM);
78              } else if (level == LogLevelUtil.CONSOLE_SUCCESS.intLevel()) {
79                  JTextPaneAppender.consoleTextPane.append(message, JTextPaneAppender.ATTRIBUTE_SUCCESS);
80              } else if (level != LogLevelUtil.IGNORE.intLevel() && level != Level.ERROR.intLevel()) {  // ignore & stdout when unhandled exception
81                  JTextPaneAppender.consoleTextPane.append(message, JTextPaneAppender.ATTRIBUTE_ALL);
82              }
83          });
84      }
85      
86      /**
87       * Register the java console.
88       */
89      public static void registerJavaConsole(SimpleConsoleAdapter javaConsole) {
90          JTextPaneAppender.javaTextPane = javaConsole;
91      }
92  
93      /**
94       * Register the default console.
95       */
96      public static void register(SimpleConsoleAdapter consoleColored) {
97          JTextPaneAppender.consoleTextPane = consoleColored;
98      }
99  }