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.Core;
28 import org.apache.logging.log4j.core.config.plugins.Plugin;
29 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
30 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
31 import org.apache.logging.log4j.status.StatusLogger;
32 import org.apache.logging.log4j.util.LoaderUtil;
33 import org.apache.logging.log4j.util.Strings;
34
35
36
37
38
39 @Plugin(name = "ConnectionFactory", category = Core.CATEGORY_NAME, elementType = "connectionSource", printObject = true)
40 public final class FactoryMethodConnectionSource implements ConnectionSource {
41 private static final Logger LOGGER = StatusLogger.getLogger();
42
43 private final DataSource dataSource;
44 private final String description;
45
46 private FactoryMethodConnectionSource(final DataSource dataSource, final String className, final String methodName,
47 final String returnType) {
48 this.dataSource = dataSource;
49 this.description = "factory{ public static " + returnType + ' ' + className + '.' + methodName + "() }";
50 }
51
52 @Override
53 public Connection getConnection() throws SQLException {
54 return this.dataSource.getConnection();
55 }
56
57 @Override
58 public String toString() {
59 return this.description;
60 }
61
62
63
64
65
66
67
68
69
70
71
72 @PluginFactory
73 public static FactoryMethodConnectionSource createConnectionSource(
74 @PluginAttribute("class") final String className,
75 @PluginAttribute("method") final String methodName) {
76 if (Strings.isEmpty(className) || Strings.isEmpty(methodName)) {
77 LOGGER.error("No class name or method name specified for the connection factory method.");
78 return null;
79 }
80
81 final Method method;
82 try {
83 final Class<?> factoryClass = LoaderUtil.loadClass(className);
84 method = factoryClass.getMethod(methodName);
85 } catch (final Exception e) {
86 LOGGER.error(e.toString(), e);
87 return null;
88 }
89
90 final Class<?> returnType = method.getReturnType();
91 String returnTypeString = returnType.getName();
92 DataSource dataSource;
93 if (returnType == DataSource.class) {
94 try {
95 dataSource = (DataSource) method.invoke(null);
96 returnTypeString += "[" + dataSource + ']';
97 } catch (final Exception e) {
98 LOGGER.error(e.toString(), e);
99 return null;
100 }
101 } else if (returnType == Connection.class) {
102 dataSource = new DataSource() {
103 @Override
104 public Connection getConnection() throws SQLException {
105 try {
106 return (Connection) method.invoke(null);
107 } catch (final Exception e) {
108 throw new SQLException("Failed to obtain connection from factory method.", e);
109 }
110 }
111
112 @Override
113 public Connection getConnection(final String username, final String password) throws SQLException {
114 throw new UnsupportedOperationException();
115 }
116
117 @Override
118 public int getLoginTimeout() throws SQLException {
119 throw new UnsupportedOperationException();
120 }
121
122 @Override
123 public PrintWriter getLogWriter() throws SQLException {
124 throw new UnsupportedOperationException();
125 }
126
127 @Override
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 }