1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.domain;
23
24 import java.io.InputStream;
25 import java.sql.Connection;
26 import java.sql.DatabaseMetaData;
27 import java.sql.PreparedStatement;
28 import java.sql.ResultSet;
29 import java.sql.SQLException;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34
35 import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
36 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
37 import org.apache.avalon.framework.activity.Initializable;
38 import org.apache.avalon.framework.configuration.Configurable;
39 import org.apache.avalon.framework.configuration.Configuration;
40 import org.apache.avalon.framework.configuration.ConfigurationException;
41 import org.apache.avalon.framework.service.ServiceException;
42 import org.apache.avalon.framework.service.ServiceManager;
43 import org.apache.avalon.framework.service.Serviceable;
44 import org.apache.james.services.FileSystem;
45 import org.apache.james.util.sql.JDBCUtil;
46 import org.apache.james.util.sql.SqlResources;
47
48
49
50
51 public class JDBCDomainList extends AbstractDomainList implements Serviceable,Configurable,Initializable {
52
53 private DataSourceSelector datasources;
54 private DataSourceComponent dataSourceComponent;
55 private FileSystem fileSystem;
56
57 private String tableName = null;
58 private String dataSourceName = null;
59
60
61
62
63 protected SqlResources sqlQueries;
64
65
66
67
68 private String sqlFileName;
69
70 protected String datasourceName;
71
72
73
74
75 public void service(ServiceManager arg0) throws ServiceException {
76 super.service(arg0);
77 datasources = (DataSourceSelector)arg0.lookup(DataSourceSelector.ROLE);
78 setFileSystem((FileSystem) arg0.lookup(FileSystem.ROLE));
79 }
80
81
82
83
84 public void configure(Configuration arg0) throws ConfigurationException {
85 Configuration config = arg0.getChild("repositoryPath");
86
87 if (config == null) {
88 throw new ConfigurationException("RepositoryPath must configured");
89 }
90
91 String destination = config.getValue();
92
93 if ( ! destination.endsWith("/") ) {
94 destination += "/";
95 }
96
97
98
99 List urlParams = new ArrayList();
100 int start = 5;
101
102 int end = destination.indexOf('/', start);
103 while ( end > -1 ) {
104 urlParams.add(destination.substring(start, end));
105 start = end + 1;
106 end = destination.indexOf('/', start);
107 }
108
109
110 if (urlParams.size() != 2) {
111 StringBuffer exceptionBuffer =
112 new StringBuffer(256)
113 .append("Malformed destinationURL - Must be of the format '")
114 .append("db://<data-source>/<table>'. Was passed ")
115 .append(arg0.getAttribute("repositoryPath"));
116 throw new ConfigurationException(exceptionBuffer.toString());
117 }
118 dataSourceName = (String)urlParams.get(0);
119 tableName = (String)urlParams.get(1);
120
121
122 if (getLogger().isDebugEnabled()) {
123 StringBuffer logBuffer =
124 new StringBuffer(128)
125 .append("Parsed URL: table = '")
126 .append(tableName)
127 .append("'");
128 getLogger().debug(logBuffer.toString());
129 }
130
131 sqlFileName = arg0.getChild("sqlFile").getValue();
132
133 Configuration autoConf = arg0.getChild("autodetect");
134 if (autoConf != null) {
135 setAutoDetect(autoConf.getValueAsBoolean(true));
136 }
137
138 Configuration autoIPConf = arg0.getChild("autodetectIP");
139 if (autoConf != null) {
140 setAutoDetectIP(autoIPConf.getValueAsBoolean(true));
141 }
142 }
143
144
145
146
147 public void initialize() throws Exception {
148
149 setDataSourceComponent((DataSourceComponent) datasources.select(dataSourceName));
150
151 StringBuffer logBuffer = null;
152 if (getLogger().isDebugEnabled()) {
153 getLogger().debug(this.getClass().getName() + ".initialize()");
154 }
155
156
157 Connection conn = dataSourceComponent.getConnection();
158 PreparedStatement createStatement = null;
159
160 try {
161
162
163 InputStream sqlFile = null;
164 try {
165 sqlFile = fileSystem.getResource(sqlFileName);
166 sqlFileName = null;
167 } catch (Exception e) {
168 getLogger().fatalError(e.getMessage(), e);
169 throw e;
170 }
171
172 if (getLogger().isDebugEnabled()) {
173 logBuffer =
174 new StringBuffer(128)
175 .append("Reading SQL resources from file: ")
176 .append(sqlFileName)
177 .append(", section ")
178 .append(this.getClass().getName())
179 .append(".");
180 getLogger().debug(logBuffer.toString());
181 }
182
183
184 Map sqlParameters = new HashMap();
185 if (tableName != null) {
186 sqlParameters.put("table", tableName);
187 }
188
189 sqlQueries = new SqlResources();
190 sqlQueries.init(sqlFile, this.getClass().getName(),
191 conn, sqlParameters);
192
193
194 DatabaseMetaData dbMetaData = conn.getMetaData();
195
196
197
198 if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
199
200
201 createStatement =
202 conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
203 createStatement.execute();
204
205 if (getLogger().isInfoEnabled()) {
206 logBuffer =
207 new StringBuffer(64)
208 .append("JdbcVirtalUserTable: Created table '")
209 .append(tableName)
210 .append("'.");
211 getLogger().info(logBuffer.toString());
212 }
213 }
214
215
216 } finally {
217 theJDBCUtil.closeJDBCStatement(createStatement);
218 theJDBCUtil.closeJDBCConnection(conn);
219 }
220 }
221
222
223
224
225 private final JDBCUtil theJDBCUtil = new JDBCUtil() {
226 protected void delegatedLog(String logString) {
227 getLogger().debug("JDBCVirtualUserTable: " + logString);
228 }
229 };
230
231 public void setDataSourceComponent(DataSourceComponent dataSourceComponent) {
232 this.dataSourceComponent = dataSourceComponent;
233 }
234
235
236 public void setFileSystem(FileSystem fileSystem) {
237 this.fileSystem = fileSystem;
238 }
239
240
241
242
243 protected List getDomainListInternal() {
244 List domains = new ArrayList();
245 Connection conn = null;
246 PreparedStatement mappingStmt = null;
247
248 try {
249 conn = dataSourceComponent.getConnection();
250 mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("selectDomains", true));
251
252 ResultSet mappingRS = null;
253 try {
254 mappingRS = mappingStmt.executeQuery();
255 while (mappingRS.next()) {
256 String domain = mappingRS.getString(1).toLowerCase();
257 if(domains.contains(domains) == false) {
258 domains.add(domain);
259 }
260 }
261 } finally {
262 theJDBCUtil.closeJDBCResultSet(mappingRS);
263 }
264
265 } catch (SQLException sqle) {
266 getLogger().error("Error accessing database", sqle);
267 } finally {
268 theJDBCUtil.closeJDBCStatement(mappingStmt);
269 theJDBCUtil.closeJDBCConnection(conn);
270 }
271 if (domains.size() == 0) {
272 return null;
273 } else {
274 return domains;
275 }
276 }
277
278
279
280
281 public boolean containsDomain(String domain) {
282 Connection conn = null;
283 PreparedStatement mappingStmt = null;
284
285 try {
286 conn = dataSourceComponent.getConnection();
287 mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("selectDomain", true));
288
289 ResultSet mappingRS = null;
290 try {
291 mappingStmt.setString(1, domain);
292 mappingRS = mappingStmt.executeQuery();
293 if (mappingRS.next()) {
294 return true;
295 }
296 } finally {
297 theJDBCUtil.closeJDBCResultSet(mappingRS);
298 }
299
300 } catch (SQLException sqle) {
301 getLogger().error("Error accessing database", sqle);
302 } finally {
303 theJDBCUtil.closeJDBCStatement(mappingStmt);
304 theJDBCUtil.closeJDBCConnection(conn);
305 }
306 return false;
307 }
308
309
310
311
312 protected boolean addDomainInternal(String domain) {
313 Connection conn = null;
314 PreparedStatement mappingStmt = null;
315
316 try {
317 conn = dataSourceComponent.getConnection();
318 mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("addDomain", true));
319
320 ResultSet mappingRS = null;
321 try {
322 mappingStmt.setString(1, domain);
323 if (mappingStmt.executeUpdate() > 0) {
324 return true;
325 }
326 } finally {
327 theJDBCUtil.closeJDBCResultSet(mappingRS);
328 }
329
330 } catch (SQLException sqle) {
331 getLogger().error("Error accessing database", sqle);
332 } finally {
333 theJDBCUtil.closeJDBCStatement(mappingStmt);
334 theJDBCUtil.closeJDBCConnection(conn);
335 }
336 return false;
337 }
338
339
340
341
342 protected boolean removeDomainInternal(String domain) {
343 Connection conn = null;
344 PreparedStatement mappingStmt = null;
345
346 try {
347 conn = dataSourceComponent.getConnection();
348 mappingStmt = conn.prepareStatement(sqlQueries.getSqlString("removeDomain", true));
349
350 ResultSet mappingRS = null;
351 try {
352 mappingStmt.setString(1, domain);
353 if (mappingStmt.executeUpdate() > 0) {
354 return true;
355 }
356 } finally {
357 theJDBCUtil.closeJDBCResultSet(mappingRS);
358 }
359
360 } catch (SQLException sqle) {
361 getLogger().error("Error accessing database", sqle);
362 } finally {
363 theJDBCUtil.closeJDBCStatement(mappingStmt);
364 theJDBCUtil.closeJDBCConnection(conn);
365 }
366 return false;
367 }
368 }