1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.appender.db.jpa;
18
19 import java.lang.reflect.Constructor;
20
21 import org.apache.logging.log4j.core.Filter;
22 import org.apache.logging.log4j.core.LogEvent;
23 import org.apache.logging.log4j.core.appender.AbstractAppender;
24 import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
25 import org.apache.logging.log4j.core.config.plugins.Plugin;
26 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
27 import org.apache.logging.log4j.core.config.plugins.PluginElement;
28 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
29 import org.apache.logging.log4j.core.util.Booleans;
30 import org.apache.logging.log4j.core.util.Loader;
31 import org.apache.logging.log4j.util.Strings;
32
33
34
35
36
37
38
39
40 @Plugin(name = "JPA", category = "Core", elementType = "appender", printObject = true)
41 public final class JpaAppender extends AbstractDatabaseAppender<JpaDatabaseManager> {
42 private static final long serialVersionUID = 1L;
43
44 private final String description;
45
46 private JpaAppender(final String name, final Filter filter, final boolean ignoreExceptions,
47 final JpaDatabaseManager manager) {
48 super(name, filter, ignoreExceptions, manager);
49 this.description = this.getName() + "{ manager=" + this.getManager() + " }";
50 }
51
52 @Override
53 public String toString() {
54 return this.description;
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 @PluginFactory
72 public static JpaAppender createAppender(
73 @PluginAttribute("name") final String name,
74 @PluginAttribute("ignoreExceptions") final String ignore,
75 @PluginElement("Filter") final Filter filter,
76 @PluginAttribute("bufferSize") final String bufferSize,
77 @PluginAttribute("entityClassName") final String entityClassName,
78 @PluginAttribute("persistenceUnitName") final String persistenceUnitName) {
79 if (Strings.isEmpty(entityClassName) || Strings.isEmpty(persistenceUnitName)) {
80 LOGGER.error("Attributes entityClassName and persistenceUnitName are required for JPA Appender.");
81 return null;
82 }
83
84 final int bufferSizeInt = AbstractAppender.parseInt(bufferSize, 0);
85 final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
86
87 try {
88 @SuppressWarnings("unchecked")
89 final Class<? extends AbstractLogEventWrapperEntity> entityClass =
90 (Class<? extends AbstractLogEventWrapperEntity>) Loader.loadClass(entityClassName);
91
92 if (!AbstractLogEventWrapperEntity.class.isAssignableFrom(entityClass)) {
93 LOGGER.error("Entity class [{}] does not extend AbstractLogEventWrapperEntity.", entityClassName);
94 return null;
95 }
96
97 try {
98 entityClass.getConstructor();
99 } catch (final NoSuchMethodException e) {
100 LOGGER.error("Entity class [{}] does not have a no-arg constructor. The JPA provider will reject it.",
101 entityClassName);
102 return null;
103 }
104
105 final Constructor<? extends AbstractLogEventWrapperEntity> entityConstructor =
106 entityClass.getConstructor(LogEvent.class);
107
108 final String managerName = "jpaManager{ description=" + name + ", bufferSize=" + bufferSizeInt
109 + ", persistenceUnitName=" + persistenceUnitName + ", entityClass=" + entityClass.getName() + '}';
110
111 final JpaDatabaseManager manager = JpaDatabaseManager.getJPADatabaseManager(
112 managerName, bufferSizeInt, entityClass, entityConstructor, persistenceUnitName
113 );
114 if (manager == null) {
115 return null;
116 }
117
118 return new JpaAppender(name, filter, ignoreExceptions, manager);
119 } catch (final ClassNotFoundException e) {
120 LOGGER.error("Could not load entity class [{}].", entityClassName, e);
121 return null;
122 } catch (final NoSuchMethodException e) {
123 LOGGER.error("Entity class [{}] does not have a constructor with a single argument of type LogEvent.",
124 entityClassName);
125 return null;
126 }
127 }
128 }