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.jdbc;
18
19 import java.io.PrintWriter;
20 import java.lang.reflect.Method;
21 import java.sql.Connection;
22 import java.sql.SQLException;
23 import javax.sql.DataSource;
24
25 import org.apache.logging.log4j.Logger;
26 import org.apache.logging.log4j.core.config.plugins.Plugin;
27 import org.apache.logging.log4j.core.config.plugins.PluginAttr;
28 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
29 import org.apache.logging.log4j.status.StatusLogger;
30
31
32
33
34
35 @Plugin(name = "ConnectionFactory", category = "Core", elementType = "connectionSource", printObject = true)
36 public final class FactoryMethodConnectionSource implements ConnectionSource {
37 private static final Logger LOGGER = StatusLogger.getLogger();
38
39 private final DataSource dataSource;
40 private final String description;
41
42 private FactoryMethodConnectionSource(final DataSource dataSource, final String className, final String methodName,
43 final String returnType) {
44 this.dataSource = dataSource;
45 this.description = "factory{ public static " + returnType + " " + className + "." + methodName + "() }";
46 }
47
48 @Override
49 public Connection getConnection() throws SQLException {
50 return this.dataSource.getConnection();
51 }
52
53 @Override
54 public String toString() {
55 return this.description;
56 }
57
58
59
60
61
62
63
64
65
66
67
68 @PluginFactory
69 public static FactoryMethodConnectionSource createConnectionSource(@PluginAttr("class") final String className,
70 @PluginAttr("method") final String methodName) {
71 if (className == null || className.length() == 0 || methodName == null || methodName.length() == 0) {
72 LOGGER.error("No class name or method name specified for the connection factory method.");
73 return null;
74 }
75
76 final Method method;
77 try {
78 final Class<?> factoryClass = Class.forName(className);
79 method = factoryClass.getMethod(methodName);
80 } catch (final Exception e) {
81 LOGGER.error(e.toString(), e);
82 return null;
83 }
84
85 final Class<?> returnType = method.getReturnType();
86 String returnTypeString = returnType.getName();
87 DataSource dataSource;
88 if (returnType == DataSource.class) {
89 try {
90 dataSource = (DataSource) method.invoke(null);
91 returnTypeString += "[" + dataSource + "]";
92 } catch (final Exception e) {
93 LOGGER.error(e.toString(), e);
94 return null;
95 }
96 } else if (returnType == Connection.class) {
97 dataSource = new DataSource() {
98 @Override
99 public Connection getConnection() throws SQLException {
100 try {
101 return (Connection) method.invoke(null);
102 } catch (final Exception e) {
103 throw new SQLException("Failed to obtain connection from factory method.", e);
104 }
105 }
106
107 @Override
108 public Connection getConnection(final String username, final String password) throws SQLException {
109 throw new UnsupportedOperationException();
110 }
111
112 @Override
113 public int getLoginTimeout() throws SQLException {
114 throw new UnsupportedOperationException();
115 }
116
117 @Override
118 public PrintWriter getLogWriter() throws SQLException {
119 throw new UnsupportedOperationException();
120 }
121
122
123 @SuppressWarnings("unused")
124 public java.util.logging.Logger getParentLogger() {
125 throw new UnsupportedOperationException();
126 }
127
128 @Override
129 public boolean isWrapperFor(final Class<?> iface) throws SQLException {
130 return false;
131 }
132
133 @Override
134 public void setLoginTimeout(final int seconds) throws SQLException {
135 throw new UnsupportedOperationException();
136 }
137
138 @Override
139 public void setLogWriter(final PrintWriter out) throws SQLException {
140 throw new UnsupportedOperationException();
141 }
142
143 @Override
144 public <T> T unwrap(final Class<T> iface) throws SQLException {
145 return null;
146 }
147 };
148 } else {
149 LOGGER.error("Method [{}.{}()] returns unsupported type [{}].", className, methodName,
150 returnType.getName());
151 return null;
152 }
153
154 return new FactoryMethodConnectionSource(dataSource, className, methodName, returnTypeString);
155 }
156 }