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