import com.jivesoftware.base.*;

import com.jivesoftware.base.ext.SimpleUserAdapter;

import javax.sql.DataSource;
import java.sql.*;

/**
 * A sample User implementation that extends the SimpleUserAdapter class. 
 * It uses a custom database table ("person"). This table contains a unique 
 * user id, unique username, first name, last name, and email address for 
 * each user in the system. The table doesn't contain Jive specific fields 
 * and properties are loaded from the Jive database.
 */
public class CustomUser extends SimpleUserAdapter {

    // Example database select methods for loading user data.
 
    private static final String EXT_FIND_BY_USERNAME =
        "SELECT id, login, firstName, lastName, email FROM person WHERE username=?";
    private static final String EXT_FIND_BY_ID =
        "SELECT id, login, firstName, lastName, email FROM person WHERE id=?";

    /**
     * Load a user by id.
     *
     * @param id the user id.
     * @param dataSource data source connected to the database that contains the
     *      user information.
     * @throws UserNotFoundException if the user could not be loaded.
     */
    public CustomUser(long id, DataSource dataSource) throws UserNotFoundException {
        if (id < 1) {
            throw new UserNotFoundException();
        }
        this.ID = id;
        loadFromDb(dataSource);
    }

    /**
     * Load a user by username.
     *
     * @param username the username.
     * @param dataSource data source connected to the database that contains the
     *      user information.  
     * @throws UserNotFoundException if the user could not be loaded.
     */
    public CustomUser(String username, DataSource dataSource) throws UserNotFoundException {
        if (username == null) {
            throw new UserNotFoundException("Username is null");
        }
        this.username = username;
        loadFromDb(dataSource);
    }

    /**
     * Loads all user fields from the external user database.
     *
     * @param dataSource data source connected to the database that contains the
     *      user information.
     * @throws UserNotFoundException if the user could not be loaded.
     */
    private void loadFromDb(DataSource dataSource) throws UserNotFoundException {
        Connection con = null;
        PreparedStatement pstmt = null;
        try {
            con = dataSource.getConnection();
            if (ID > 0){
                pstmt = con.prepareStatement(EXT_FIND_BY_ID);
                pstmt.setLong(1, ID);
            }
            else {
                pstmt = con.prepareStatement(EXT_FIND_BY_USERNAME);
                pstmt.setString(1, username);
            }
            ResultSet rs = pstmt.executeQuery();

            if (!rs.next()) {
                throw new UserNotFoundException();
            }
            this.ID = rs.getLong("id");
            this.username = rs.getString("login");
            // Jive uses a single name field. Therefore, we just concatenate
            // the firstName and lastName fields together.
            this.name = rs.getString("firstName") + " " + rs.getString("lastName");
            this.email = rs.getString("email");
        }
        catch (SQLException sqle) {
            Log.error(sqle);
        }
        finally {
            try { if (pstmt != null) { pstmt.close(); } }
            catch (Exception e) { Log.error(e); }
            try { if (con != null) { con.close(); } }
            catch (Exception e) { Log.error(e); }
        }
    }
}

