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 }