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