package org.nextprot.api.user.dao.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nextprot.api.commons.exception.NextProtException; import org.nextprot.api.commons.spring.jdbc.DataSourceServiceLocator; import org.nextprot.api.commons.utils.JdbcTemplateUtils; import org.nextprot.api.commons.utils.KeyValuesJdbcBatchUpdater; import org.nextprot.api.commons.utils.SQLDictionary; import org.nextprot.api.user.dao.UserDao; import org.nextprot.api.user.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Repository; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.*; @Repository public class UserDaoImpl implements UserDao { private final Log Logger = LogFactory.getLog(UserDaoImpl.class); @Autowired private SQLDictionary sqlDictionary; @Autowired(required = false) private DataSourceServiceLocator dsLocator; @Override public long createUser(User user) { final String INSERT_USER_SQL = sqlDictionary.getSQLQuery("create-user"); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); namedParameters.addValue("user_name", user.getUsername()); namedParameters.addValue("first_name", user.getFirstName()); namedParameters.addValue("last_name", user.getLastName()); long key = JdbcTemplateUtils.insertAndGetKey(INSERT_USER_SQL, "user_id", namedParameters, new NamedParameterJdbcTemplate(dsLocator.getUserDataSource())).longValue(); if (user.getAuthorities() != null && !user.getAuthorities().isEmpty()) { insertUserAuthorities(key, user.getAuthorities()); } return key; } @Override public User getUserByUsername(String username) throws DataAccessException { Map<String, String> namedParams = new HashMap<String, String>(); namedParams.put("user_name", username); String sql = sqlDictionary.getSQLQuery("read-user-by-name"); NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()); List<User> users = template.query(sql, namedParams, new UsersExtractor()); if (users.isEmpty()) throw new EmptyResultDataAccessException(1); return users.get(0); } @Override public List<User> getUserList() { String sql = sqlDictionary.getSQLQuery("read-user-list"); return new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).query(sql, new UsersExtractor()); } @Override public void updateUser(User src) { final String UPDATE_SQL = sqlDictionary.getSQLQuery("update-user"); MapSqlParameterSource namedParameters = new MapSqlParameterSource(); // key to identify application to be updated namedParameters.addValue("user_id", src.getId()); // values to update namedParameters.addValue("user_name", src.getUsername()); namedParameters.addValue("first_name", src.getFirstName()); namedParameters.addValue("last_name", src.getLastName()); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()); int affectedRows = jdbcTemplate.update(UPDATE_SQL, namedParameters); if (affectedRows != 1){ String msg = "oops something wrong occurred" + affectedRows + " rows were affected instead of only 1."; Logger.error(msg); throw new NextProtException(msg); } if (src.getAuthorities() != null && !src.getAuthorities().isEmpty()) { // 1. delete all roles for this user if roles exist in user_roles table of src deleteUserRoles(src.getId()); // 2. insert roles with insertUserRoles(src.getKey(), src.getRoles()) insertUserAuthorities(src.getId(), src.getAuthorities()); } } private void insertUserAuthorities(final long userId, final Collection<GrantedAuthority> authorities) { String sql = sqlDictionary.getSQLQuery("create-user-roles"); KeyValuesJdbcBatchUpdater updater = new KeyValuesJdbcBatchUpdater(new JdbcTemplate(dsLocator.getUserDataSource()), userId) { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setLong(1, getKey()); ps.setString(2, getValue(i)); } }; List<String> roles = new ArrayList<String>(); for(GrantedAuthority ga : authorities){ roles.add(ga.getAuthority()); } updater.batchUpdate(sql, new ArrayList<String>(roles)); } @Override public void deleteUser(User user) { final String DELETE_SQL = sqlDictionary.getSQLQuery("delete-user"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); int affectedRows = new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).update(DELETE_SQL, params); if (affectedRows != 1){ String msg = "oops something wrong occurred" + affectedRows + " rows were affected instead of only 1."; Logger.error(msg); throw new NextProtException(msg); } } private void deleteUserRoles(final long userId) { final String DELETE_SQL = sqlDictionary.getSQLQuery("delete-user-roles"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", userId); new NamedParameterJdbcTemplate(dsLocator.getUserDataSource()).update(DELETE_SQL, params); } }