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