View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.userrepository;
21  
22  import org.apache.james.services.User;
23  import org.apache.mailet.MailAddress;
24  
25  import java.sql.PreparedStatement;
26  import java.sql.ResultSet;
27  import java.sql.SQLException;
28  
29  /***
30   * A Jdbc-backed UserRepository which handles User instances
31   * of the <CODE>DefaultJamesUser</CODE> class, or any superclass.
32   * 
33   */
34  public class JamesUsersJdbcRepository extends AbstractJdbcUsersRepository
35  {
36      /***
37       * Reads properties for a User from an open ResultSet.
38       * 
39       * @param rsUsers A ResultSet with a User record in the current row.
40       * @return A User instance
41       * @throws SQLException
42       *                   if an exception occurs reading from the ResultSet
43       */
44      protected User readUserFromResultSet(ResultSet rsUsers) throws SQLException 
45      {
46          // Get the column values
47          String username = rsUsers.getString(1);
48          String pwdHash = rsUsers.getString(2);
49          String pwdAlgorithm = rsUsers.getString(3);
50          boolean useForwarding = rsUsers.getBoolean(4);
51          String forwardingDestination = rsUsers.getString(5);
52          boolean useAlias = rsUsers.getBoolean(6);
53          String alias = rsUsers.getString(7);
54  
55          MailAddress forwardAddress = null;
56          if ( forwardingDestination != null ) {
57              try {
58                  forwardAddress = new MailAddress(forwardingDestination);
59              }
60              catch (javax.mail.internet.ParseException pe) {
61                  StringBuffer exceptionBuffer =
62                      new StringBuffer(256)
63                          .append("Invalid mail address in database: ")
64                          .append(forwardingDestination)
65                          .append(", for user ")
66                          .append(username)
67                          .append(".");
68                  throw new RuntimeException(exceptionBuffer.toString());
69              }
70          }
71  
72          // Build a DefaultJamesUser with these values, and add to the list.
73          DefaultJamesUser user = new DefaultJamesUser(username, pwdHash, pwdAlgorithm);
74          user.setForwarding(useForwarding);
75          user.setForwardingDestination(forwardAddress);
76          user.setAliasing(useAlias);
77          user.setAlias(alias);
78  
79          return user;
80      }
81  
82      /***
83       * Set parameters of a PreparedStatement object with 
84       * property values from a User instance.
85       * 
86       * @param user       a User instance, which should be an implementation class which
87       *                   is handled by this Repostory implementation.
88       * @param userInsert a PreparedStatement initialised with SQL taken from the "insert" SQL definition.
89       * @throws SQLException
90       *                   if an exception occurs while setting parameter values.
91       */
92      protected void setUserForInsertStatement(User user, 
93                                               PreparedStatement userInsert) 
94          throws SQLException {
95          setUserForStatement(user, userInsert, false);
96      }
97  
98      /***
99       * Set parameters of a PreparedStatement object with
100      * property values from a User instance.
101      * 
102      * @param user       a User instance, which should be an implementation class which
103      *                   is handled by this Repostory implementation.
104      * @param userUpdate a PreparedStatement initialised with SQL taken from the "update" SQL definition.
105      * @throws SQLException
106      *                   if an exception occurs while setting parameter values.
107      */
108     protected void setUserForUpdateStatement(User user, 
109                                              PreparedStatement userUpdate) 
110         throws SQLException {
111         setUserForStatement(user, userUpdate, true);
112     }
113 
114     /***
115      * Sets the data for the prepared statement to match the information
116      * in the user object.
117      *
118      * @param user the user whose data is to be stored in the PreparedStatement.
119      * @param stmt the PreparedStatement to be modified.
120      * @param userNameLast whether the user id is the last or the first column
121      */
122     private void setUserForStatement(User user, PreparedStatement stmt,
123                                      boolean userNameLast) throws SQLException {
124         // Determine column offsets to use, based on username column pos.
125         int nameIndex = 1;
126         int colOffset = 1;
127         if ( userNameLast ) {
128             nameIndex = 7;
129             colOffset = 0;
130         }
131 
132         // Can handle instances of DefaultJamesUser and DefaultUser.
133         DefaultJamesUser jamesUser;
134         if (user instanceof DefaultJamesUser) {
135             jamesUser = (DefaultJamesUser)user;
136         }
137         else if ( user instanceof DefaultUser ) {
138             DefaultUser aUser = (DefaultUser)user;
139             jamesUser = new DefaultJamesUser(aUser.getUserName(),
140                                              aUser.getHashedPassword(),
141                                              aUser.getHashAlgorithm());
142         } 
143         // Can't handle any other implementations.
144         else {
145             throw new RuntimeException("An unknown implementation of User was " + 
146                                        "found. This implementation cannot be " + 
147                                        "persisted to a UsersJDBCRepsitory.");
148         }
149 
150         // Get the user details to save.
151         stmt.setString(nameIndex, jamesUser.getUserName());
152         stmt.setString(1 + colOffset, jamesUser.getHashedPassword());
153         stmt.setString(2 + colOffset, jamesUser.getHashAlgorithm());
154         stmt.setInt(3 + colOffset, (jamesUser.getForwarding() ? 1 : 0));
155 
156         MailAddress forwardAddress = jamesUser.getForwardingDestination();
157         String forwardDestination = null;
158         if ( forwardAddress != null ) {
159             forwardDestination = forwardAddress.toString();
160         }
161         stmt.setString(4 + colOffset, forwardDestination);
162         stmt.setInt(5 + colOffset, (jamesUser.getAliasing() ? 1 : 0));
163         stmt.setString(6 + colOffset, jamesUser.getAlias());
164     }
165     
166     
167     
168     /***
169      * @see org.apache.james.services.UsersRepository#addUser(java.lang.String, java.lang.String)
170      */
171     public boolean addUser(String username, String password)  {
172         User newbie = new DefaultJamesUser(username, "SHA");
173         newbie.setPassword(password);
174         return addUser(newbie);
175     }
176 
177 }