package at.fhj.itm.business;
import java.sql.SQLException;
import java.util.Date;
import javax.sql.DataSource;
import org.apache.log4j.Logger;
import at.fhj.itm.dao.DAOException;
import at.fhj.itm.dao.UserDAO;
import at.fhj.itm.model.Location;
import at.fhj.itm.model.User;
import at.fhj.itm.util.EmailUtil;
import at.fhj.itm.util.JsfUtil;
import at.fhj.itm.util.RandomUtil;
import at.fhj.itm.util.Validator;
/**
*
* @author Boensch, Schuster ({@link #Login}, ForgotPassword)
* @author Seidl, Tagger (Registration)
*/
public class ServiceUserImpl extends ServiceAbstract implements ServiceUser {
private final Logger logger = Logger.getLogger(ServiceAbstract.class);
private final UserDAO userDAO;
private JsfUtil jsfUtil;
private RandomUtil randUtil;
private EmailUtil mailUtil;
public ServiceUserImpl(UserDAO userDAO, DataSource datasource, JsfUtil jsfUtil, RandomUtil randUtil, EmailUtil mailUtil) {
super(datasource);
Validator.validateNotNull(userDAO, "userDAO");
this.userDAO = userDAO;
this.jsfUtil = jsfUtil;
this.randUtil = randUtil;
this.mailUtil = mailUtil;
}
public final UserDAO getUserDAO() {
return userDAO;
}
/**
* Using the passed values, the User will be retrieved from the UserDAO. If
* no user was found null will be returned. It also attemps to update the
* lastLoginDate for this user. The logged in User will be returned.
*
* @param email
* e-mail string
* @param password
* password string
* @return the User that matches the passed values, or null if non was found
* @throws ServiceException if a database error occured
*/
@Override
public User doLogin(String email, String password) {
User user = null;
try {
begin();
user = getUserDAO().userValid(email, password, getConnection());
commit();
} catch (DAOException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} catch (SQLException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} finally {
closeConnection();
}
if (user == null)
return null;
user.setLastLoginDate(new Date());
try {
updateUser(user, "s last login date");
} catch (ServiceException e) {
logger.error(
"Failed to set lastlogindate for user " + user.getId(), e);
}
jsfUtil.userLoggedIn(user);
return user;
}
/**
* Creates an {@link User} instance with the data input into the registration form
* and stores it into the database.
* @param firstName - the user's first name
* @param lastName - the user's last name
* @param username - the user's user name
* @param password - the user's password
* @param firstName - the user's first name
* @param email - the user's email address
* @param phone - the user's phone number
* @param zip - the user's zip code
* @param city - the user's city
* @return true if the user is successfully stored into the database<br/>
* false if a ServiceException occured
* @throws ServiceException if a database error occurred
*/
public boolean doRegistration(final String firstName, final String lastName, final String username,
final String password, final String email, final String phone, final int zip, final String city)
{
Location loc = new Location(zip, city);
User user = new User(-1, firstName, lastName, username, password, email, phone, loc,
new java.util.Date(), this.randUtil.getRandSessionID());
try
{
boolean updateSuccess = this.updateUser(user, "'s registration data!");
this.mailUtil.sendRegConfirmation(email, username);
return updateSuccess;
}catch(ServiceException e)
{
logger.error("Error during the registration process!", e);
return false;
}
}
/**
* Opens a new transaction to update the user. If an Exception occurs, a
* rollback is done and a {@link ServiceException} with the updateReason in
* the message is thrown.
*
* @param user
* the User to update
* @param updateReason
* the reason for the update inserted in the error message
* @return true if the update was successfully committed
* @throws ServiceException
* if the update failed.
*/
private boolean updateUser(final User user, String updateReason) {
try {
begin();
userDAO.update(user, getConnection());
commit();
return true;
} catch (DAOException e) {
tryRollbackAndLogFailure();
throw new ServiceException("Can't update User" + updateReason, e);
} catch (SQLException e) {
tryRollbackAndLogFailure();
throw new ServiceException("Can't update User" + updateReason, e);
} finally {
closeConnection();
}
}
@Override
public void doLogout(User user) {
jsfUtil.userLoggedOut();
}
/*
* For ForgotPassword
*/
/**
* Using the passed values, the User will be retrieved from the UserDAO. If
* no user was found null will be returned, otherwise the user is prepared
* for recovering. The sessionID for the user is returned.
*
* @param email
* the e-mail string
* @param phone
* the string representing a phone-number
* @return the sessionID for User that matches the passed values, or null if
* the user was not identified.
* @throws ServiceException if a database error occured
*/
@Override
public String recoverUserPassword(String email, String phone) {
User user = null;
try {
begin();
user = getUserDAO().getUserWithEmailAndPhone(email, phone, getConnection());
commit();
} catch (DAOException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} catch (SQLException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} finally {
closeConnection();
}
if (user == null)
return null;
user.setLastLoginDate(null);
user.setSessionID(this.randUtil.getRandSessionID());
updateUser(user, " for password recovery: sessionID, last login Date");
return user.getSessionID();
}
/**
* Using the passed sessionId, the User will be retrieved from the UserDAO.
* If the user was not identified or the user was not prepared properly for
* recovery the operation fails and returns false. Otherwise the password
* for the user is set, the sessionID replaced by a new one and true is
* returned.
*
* @param newPassword
* the new password
* @param sessionId
* the sessionId of the user to modify
* @return true if the password for the user was updated successfully.
* @throws ServiceException if a database error occured
*/
@Override
public boolean setPassword(String newPassword, String sessionId) {
User user = null;
try {
begin();
user = getUserDAO().getUserForSessionId(sessionId, getConnection());
commit();
} catch (DAOException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} catch (SQLException e) {
throw new ServiceException("Error in retrieving user with email and password", e);
} finally {
closeConnection();
}
if (user == null)
return false;
if (user.getLastLoginDate() != null) {
return false;
}
user.setPassword(newPassword);
user.setSessionID(this.randUtil.getRandSessionID());
updateUser(user, "s password!");
return true;
}
/**
* Checks if the username input by the user is already used.
*
* @param username
* the username input by the user
* @return true if the username already exists in the database
* otherwise false
* @throws ServiceException if a database error occurred
*/
@Override
public boolean checkUsername(String username)
{
try
{
this.begin();
boolean usernameUsed = this.getUserDAO().usernameAlreadyUsed(username, this.getConnection());
this.commit();
return usernameUsed;
} catch (SQLException e)
{
this.tryRollbackAndLogFailure();
throw new ServiceException("Error while checking username in database!", e);
}
catch (DAOException e)
{
this.tryRollbackAndLogFailure();
throw new ServiceException("Error while checking username in database!", e);
}
finally
{
this.closeConnection();
}
}
/**
* Checks if the email input by the user is already used.
*
* @param email
* the email input by the user
* @return true if the email already exists in the database
* otherwise false
* @throws ServiceException if a database error occured
*/
@Override
public boolean checkMail(String email)
{
try
{
this.begin();
boolean mailUsed = this.getUserDAO().mailAlreadyUsed(email, this.getConnection());
this.commit();
return mailUsed;
} catch (SQLException e)
{
this.tryRollbackAndLogFailure();
throw new ServiceException("Error while checking email in database!", e);
}
catch (DAOException e)
{
this.tryRollbackAndLogFailure();
throw new ServiceException("Error while checking email in database!", e);
}
finally
{
this.closeConnection();
}
}
}