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.transport.mailets;
23
24 import org.apache.avalon.cornerstone.services.datasources.DataSourceSelector;
25 import org.apache.avalon.excalibur.datasource.DataSourceComponent;
26 import org.apache.avalon.framework.service.ServiceManager;
27 import org.apache.james.Constants;
28 import org.apache.james.util.sql.JDBCUtil;
29 import org.apache.mailet.base.GenericMailet;
30 import org.apache.mailet.Mail;
31 import org.apache.mailet.MailAddress;
32 import org.apache.mailet.MailetException;
33
34 import javax.mail.MessagingException;
35 import javax.mail.internet.ParseException;
36
37 import java.sql.Connection;
38 import java.sql.DatabaseMetaData;
39 import java.sql.PreparedStatement;
40 import java.sql.ResultSet;
41 import java.sql.SQLException;
42 import java.util.Collection;
43 import java.util.Iterator;
44 import java.util.Vector;
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class JDBCAlias extends GenericMailet {
59
60 protected DataSourceComponent datasource;
61 protected String query = null;
62
63
64 private final JDBCUtil theJDBCUtil =
65 new JDBCUtil() {
66 protected void delegatedLog(String logString) {
67 log("JDBCAlias: " + logString);
68 }
69 };
70
71
72
73
74 public void init() throws MessagingException {
75 String mappingsURL = getInitParameter("mappings");
76
77 String datasourceName = mappingsURL.substring(5);
78 int pos = datasourceName.indexOf("/");
79 String tableName = datasourceName.substring(pos + 1);
80 datasourceName = datasourceName.substring(0, pos);
81
82 Connection conn = null;
83 if (getInitParameter("source_column") == null) {
84 throw new MailetException("source_column not specified for JDBCAlias");
85 }
86 if (getInitParameter("target_column") == null) {
87 throw new MailetException("target_column not specified for JDBCAlias");
88 }
89 try {
90 ServiceManager componentManager = (ServiceManager)getMailetContext().getAttribute(Constants.AVALON_COMPONENT_MANAGER);
91
92 DataSourceSelector datasources = (DataSourceSelector)componentManager.lookup(DataSourceSelector.ROLE);
93
94 datasource = (DataSourceComponent)datasources.select(datasourceName);
95
96 conn = datasource.getConnection();
97
98
99 DatabaseMetaData dbMetaData = conn.getMetaData();
100
101
102 if (!(theJDBCUtil.tableExists(dbMetaData, tableName))) {
103 StringBuffer exceptionBuffer =
104 new StringBuffer(128)
105 .append("Could not find table '")
106 .append(tableName)
107 .append("' in datasource '")
108 .append(datasourceName)
109 .append("'");
110 throw new MailetException(exceptionBuffer.toString());
111 }
112
113
114 StringBuffer queryBuffer =
115 new StringBuffer(128)
116 .append("SELECT ")
117 .append(getInitParameter("target_column"))
118 .append(" FROM ")
119 .append(tableName)
120 .append(" WHERE ")
121 .append(getInitParameter("source_column"))
122 .append(" = ?");
123 query = queryBuffer.toString();
124 } catch (MailetException me) {
125 throw me;
126 } catch (Exception e) {
127 throw new MessagingException("Error initializing JDBCAlias", e);
128 } finally {
129 theJDBCUtil.closeJDBCConnection(conn);
130 }
131 }
132
133 public void service(Mail mail) throws MessagingException {
134
135
136 Connection conn = null;
137 PreparedStatement mappingStmt = null;
138 ResultSet mappingRS = null;
139
140 Collection recipients = mail.getRecipients();
141 Collection recipientsToRemove = new Vector();
142 Collection recipientsToAdd = new Vector();
143 try {
144 conn = datasource.getConnection();
145 mappingStmt = conn.prepareStatement(query);
146
147
148 for (Iterator i = recipients.iterator(); i.hasNext(); ) {
149 try {
150 MailAddress source = (MailAddress)i.next();
151 mappingStmt.setString(1, source.toString());
152 mappingRS = mappingStmt.executeQuery();
153 if (!mappingRS.next()) {
154
155 continue;
156 }
157 try {
158 String targetString = mappingRS.getString(1);
159 MailAddress target = new MailAddress(targetString);
160
161
162 recipientsToRemove.add(source);
163 recipientsToAdd.add(target);
164 } catch (ParseException pe) {
165
166 StringBuffer exceptionBuffer =
167 new StringBuffer(128)
168 .append("There is an invalid alias from ")
169 .append(source)
170 .append(" to ")
171 .append(mappingRS.getString(1));
172 log(exceptionBuffer.toString());
173 continue;
174 }
175 } finally {
176 ResultSet localRS = mappingRS;
177
178 mappingRS = null;
179 theJDBCUtil.closeJDBCResultSet(localRS);
180 }
181 }
182 } catch (SQLException sqle) {
183 throw new MessagingException("Error accessing database", sqle);
184 } finally {
185 theJDBCUtil.closeJDBCStatement(mappingStmt);
186 theJDBCUtil.closeJDBCConnection(conn);
187 }
188
189 recipients.removeAll(recipientsToRemove);
190 recipients.addAll(recipientsToAdd);
191 }
192
193
194
195
196
197
198 public String getMailetInfo() {
199 return "JDBC aliasing mailet";
200 }
201
202 }