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