Skip to content
Snippets Groups Projects
Commit c7d6b7ed authored by Lorenzo Ferron's avatar Lorenzo Ferron
Browse files

Rinomina e aggiunta file sorgente.

Rinominata la directory contenente i file sorgente per l'appendice. Aggiunti i
file sorgenti.
parent 410ca1f5
No related branches found
No related tags found
No related merge requests found
package com.trimaral.dao;
import com.google.i18n.phonenumbers.NumberParseException;
import com.trimaral.orm.ResultSetMapper;
import javax.sql.DataSource;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
/**
* @param <T> a DAO class
* @author Lorenzo Ferron
* @version 2019.09.07
*/
public abstract class DAO<T extends Serializable> {
protected final ResultSetMapper<T> resultSetMapper;
protected final DataSource dataSource;
protected DAO(DataSource dataSource, Class<T> clazz) {
this.dataSource = dataSource;
this.resultSetMapper = new ResultSetMapper<>(dataSource, clazz);
}
public static String getQuotedString(String s) {
return "'" + s + "'";
}
public List<T> findAll() throws SQLException, NumberParseException {
return findByCriteria(null);
}
public List<T> findByCriteria(String criteria, Object... params) throws SQLException, NumberParseException {
return resultSetMapper.findByCriteria(criteria, params);
}
public T findOneByCriteria(String criteria, Object... params) throws SQLException, NumberParseException {
resultSetMapper.getByCriteria(criteria, params);
try {
return findByCriteria(criteria, params).get(0);
} catch (IndexOutOfBoundsException e) {
return null;
}
}
public T findById(Long id) throws SQLException, NumberParseException {
return findOneByCriteria(resultSetMapper.findById(), id);
}
public void save(T item) throws SQLException, NumberParseException {
resultSetMapper.save(item, false, false);
}
public void replace(T item) throws SQLException, NumberParseException {
resultSetMapper.save(item, true, false);
}
public void update(T item) throws SQLException, NumberParseException {
resultSetMapper.update(item);
}
public void updateByCriteria(T item, String criteria, Object... params) throws SQLException, NumberParseException {
resultSetMapper.updateByCriteria(item, criteria, params);
}
public void updatesByCriteria(T[] items, String criteria, Object... params) throws SQLException, NumberParseException {
for (T item : items)
updateByCriteria(item, criteria, params);
}
public void delete(T item) throws SQLException, NumberParseException {
resultSetMapper.delete(item);
}
public void deleteByCriteria(String criteria, Object... params) throws SQLException, NumberParseException {
resultSetMapper.deleteByCriteria(criteria, params);
}
public void deleteById(Long id) throws SQLException, NumberParseException {
resultSetMapper.deleteById(id);
}
public Object customQuery(String query, Object... params) throws SQLException, NumberParseException {
return resultSetMapper.customQuery(query, params);
}
}
package com.trimaral.entity;
import com.google.common.base.Preconditions;
import com.trimaral.orm.annotations.Column;
import com.trimaral.orm.annotations.Table;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* @author Lorenzo Ferron
* @version 2019.09.05
*/
@Table(name = "login")
public class Login implements Serializable {
public static final short PASSWORD_LENGTH = 8;
@Column(name = "password")
private String password;
@Column(name = "is_valid", hasDefaultValue = true)
private Boolean isValid;
@Column(name = "login_id", isPrimaryKey = true)
private Long loginId;
@Column(name = "email")
private String email;
@Column(name = "enroll_date", hasDefaultValue = true, hold = true)
private Timestamp enrollDate;
private List<EmailConfirmation> confirmations;
public Login() {
confirmations = new ArrayList<>(0);
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Boolean getIsValid() {
return isValid;
}
public void setIsValid(Boolean isValid) {
this.isValid = isValid;
}
public Long getLoginId() {
return loginId;
}
public void setLoginId(Long loginId) {
this.loginId = loginId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
Preconditions.checkNotNull(email);
Preconditions.checkArgument(Pattern.compile("^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])$", Pattern.CASE_INSENSITIVE).matcher(email).matches());
this.email = email.trim();
}
public List<EmailConfirmation> getConfirmations() {
return confirmations;
}
public void setConfirmations(List<EmailConfirmation> confirmations) {
this.confirmations = confirmations;
}
public Timestamp getEnrollDate() {
return enrollDate;
}
public void setEnrollDate(Timestamp enrollDate) {
this.enrollDate = enrollDate;
}
}
package com.trimaral.dao;
import com.google.i18n.phonenumbers.NumberParseException;
import com.trimaral.entity.Login;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* @author Lorenzo Ferron
* @version 2019.09.05
*/
public class LoginDAO extends DAO<Login> {
public LoginDAO(DataSource dataSource) {
super(dataSource, Login.class);
}
public Login findByEmail(String email) throws SQLException, NumberParseException {
return findOneByCriteria("email = " + getQuotedString(email));
}
}
package com.trimaral.orm;
import com.google.common.base.CharMatcher;
import com.google.common.collect.ObjectArrays;
import com.google.common.primitives.Primitives;
import com.google.i18n.phonenumbers.NumberParseException;
import com.trimaral.orm.annotations.Column;
import com.trimaral.orm.annotations.Table;
import com.trimaral.orm.exceptions.AnnotationNotFoundException;
import com.trimaral.orm.exceptions.DAOException;
import com.trimaral.orm.util.ClassUtil;
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.sql.*;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
/**
* @param <T> An entity class
* @author Lorenzo Ferron
* @version 2019.09.28
*/
public class ResultSetMapper<T> {
public static final String SET_CLAUSE = " SET ";
public static final String WHERE_CLAUSE = " WHERE ";
public static final String VALUES_CLAUSE = " VALUES ";
public static final String FROM_CLAUSE = " FROM ";
public static final String SELECT_SQL = "SELECT *" + FROM_CLAUSE;
public static final String INSERT_SQL = "INSERT ";
public static final String IGNORE_SQL = "IGNORE ";
public static final String INTO_SQL = "INTO ";
public static final String UPDATE_SQL = "UPDATE ";
public static final String DELETE_SQL = "DELETE";
public static final String DELIMITER = ", ";
private static final String REPLACE_SQL = " ON DUPLICATE KEY UPDATE ";
private final DataSource dataSource;
private final Class<T> clazz;
private Table table;
private Field[] fields;
private List<Field> primaryKeyField = new ArrayList<>(0);
public ResultSetMapper(DataSource dataSource, Class<T> clazz) {
this.dataSource = dataSource;
this.clazz = clazz;
if (clazz != null) {
if (!clazz.isAnnotationPresent(Table.class))
throw new AnnotationNotFoundException();
table = clazz.getAnnotation(Table.class);
fields = ClassUtil.getAnnotatedDeclaredFields(clazz, Column.class);
for (Field field : fields)
if (field.getAnnotation(Column.class).isPrimaryKey())
primaryKeyField.add(field);
/*if (primaryKeyField.isEmpty()) {
primaryKeyFromParent(clazz.getSuperclass());
fields = ObjectArrays.concat(fields, primaryKeyField.toArray(new Field[0]), Field.class);
}*/
}
}
private static void questionMarksParamsCount(String criteria, Object[] params) {
int criteriaCount = criteria == null ? 0 : CharMatcher.is('?').countIn(criteria);
int paramsCount = params != null ? params.length : 0;
if (criteriaCount != paramsCount)
throw new DAOException("?: criteria = " + criteriaCount + "; params = " + paramsCount);
}
/*private void primaryKeyFromParent(Class<? super T> parent) {
if (parent.equals(Object.class)) // caso base
return;
Field[] parentFields = ClassUtil.getAnnotatedDeclaredFields(parent, Column.class);
for (Field field : parentFields)
if (field.getAnnotation(Column.class).isPrimaryKey())
primaryKeyField.add(field);
primaryKeyFromParent(parent.getSuperclass());
}*/
@SuppressWarnings({"unchecked"})
public <T> List<T> findByCriteria(String criteria, Object... params) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
questionMarksParamsCount(criteria, params);
String sqlStatement = SELECT_SQL + table.name();
if (criteria != null)
sqlStatement += WHERE_CLAUSE + criteria.trim();
List<T> result = new ArrayList<>(0);
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlStatement)) {
if (criteria != null) for (int i = 0; i < params.length; i++) stmt.setObject(i + 1, params[i]);
System.out.println(stmt.toString()); // For debug purpose
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
T item = (T) clazz.newInstance();
for (Field field : fields) {
Object value;
Class<?> type = field.getType();
value = type.equals(YearMonth.class) ? YearMonth.parse(rs.getString(field.getAnnotation(Column.class).name()), DateTimeFormatter.ofPattern("yyyy-MM-00")) : rs.getObject(field.getAnnotation(Column.class).name());
if (type.isPrimitive()) {
Class<?> boxed = Primitives.wrap(type);
value = boxed.cast(value);
}
field.setAccessible(true);
field.set(item, value);
field.setAccessible(false);
}
result.add(item);
}
}
} catch (IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
return result;
}
public String findById() {
if (primaryKeyField.isEmpty())
throw new NullPointerException("Primary Key is not found");
else if (primaryKeyField.size() > 1)
throw new UnsupportedOperationException("Only one primary key");
return primaryKeyField.get(0).getAnnotation(Column.class).name() + " = ?";
}
public void deleteById(Long id) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
if (primaryKeyField.isEmpty())
throw new NullPointerException("Primary Key is not found");
else if (primaryKeyField.size() > 1)
throw new UnsupportedOperationException("Only one primary key");
deleteByCriteria(primaryKeyField.get(0).getAnnotation(Column.class).name() + " = ?", id);
}
public void getByCriteria(String criteria, Object... params) {
questionMarksParamsCount(criteria, params);
}
public void update(T item) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
if (primaryKeyField.isEmpty())
throw new NullPointerException("Primary Key is not found");
StringJoiner joiner = new StringJoiner(" AND ");
Object[] params = criteriaJoiner(item, joiner);
updateByCriteria(item, joiner.toString(), params);
}
public void updateByCriteria(T item, String criteria, Object... params) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
questionMarksParamsCount(criteria, params);
StringJoiner joiner = new StringJoiner(DELIMITER);
List<Field> filteredFields = new ArrayList<>(0);
Column column;
for (Field field : fields) {
field.setAccessible(true);
column = field.getAnnotation(Column.class);
if ((field.getDeclaringClass().equals(clazz) || column.isPrimaryKey()) && !column.hold()) {
joiner.add(field.getAnnotation(Column.class).name() + " = ?");
filteredFields.add(field);
}
}
String sqlStatement = UPDATE_SQL + table.name() + SET_CLAUSE + joiner.toString() +
WHERE_CLAUSE + criteria.trim();
executeStatement(sqlStatement, item, filteredFields, params);
}
private void executeStatement(String sqlStatement, T item, List<Field> filteredFields, Object... params) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
try {
boolean keysGeneration = primaryKeyField.stream().allMatch(x -> {
try {
return x.get(item) == null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
}
});
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = keysGeneration ? conn.prepareStatement(sqlStatement, Statement.RETURN_GENERATED_KEYS) : conn.prepareStatement(sqlStatement)) {
int counter = 1;
for (Field field : filteredFields) {
if (field.getType().equals(YearMonth.class)) {
String date = ((YearMonth) field.get(item)).format(DateTimeFormatter.ofPattern("yyyy-MM-00"));
stmt.setString(counter++, field.getAnnotation(Column.class).isNullable() && "".equals(date) ? null : date);
} else
stmt.setObject(counter++, field.getAnnotation(Column.class).isNullable() && "".equals(field.get(item)) ? null : field.get(item));
}
for (Object param : params)
stmt.setObject(counter++, param);
System.out.println(stmt.toString()); // For debug purpose
int affectedRows = stmt.executeUpdate();
if (keysGeneration) {
if (affectedRows == 0)
throw new SQLException("No rows affected.");
try (ResultSet generatedKeys = stmt.getGeneratedKeys()) {
if (generatedKeys.next())
Arrays.stream(fields).filter(p -> p.getAnnotation(Column.class).isPrimaryKey()).findFirst().get().set(item, generatedKeys.getLong(1));
else
throw new SQLException("No ID obtained.");
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
filteredFields.clear();
for (Field field : fields)
field.setAccessible(false);
}
}
public void save(T item, boolean replaceMode, boolean ignore) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
try {
StringJoiner joiner = new StringJoiner(DELIMITER, " ( ", " ) ");
List<Field> filteredFields = new ArrayList<>(0);
Column column;
for (Field field : fields) {
field.setAccessible(true);
column = field.getAnnotation(Column.class);
if ((field.getDeclaringClass().equals(clazz) || column.isPrimaryKey()) && ((replaceMode || ignore) && column.isPrimaryKey() && field.get(item) != null || !(field.get(item) == null && (column.isPrimaryKey() || column.hasDefaultValue())))) {
joiner.add(field.getAnnotation(Column.class).name());
filteredFields.add(field);
}
}
String sqlStatement = INSERT_SQL;
if (ignore)
sqlStatement += IGNORE_SQL;
sqlStatement += INTO_SQL + table.name() + joiner.toString() + VALUES_CLAUSE;
joiner = new StringJoiner(DELIMITER, " (", ")");
for (int i = 0; i < filteredFields.size(); i++)
joiner.add("?");
sqlStatement += joiner.toString();
if (replaceMode) {
sqlStatement += REPLACE_SQL;
joiner = new StringJoiner(DELIMITER + " ");
for (Field field : filteredFields) {
String nameColumn = field.getAnnotation(Column.class).name();
joiner.add(nameColumn + "=" + VALUES_CLAUSE + "(" + nameColumn + ")");
}
sqlStatement += joiner.toString();
}
executeStatement(sqlStatement, item, filteredFields);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private Object[] criteriaJoiner(T item, StringJoiner joiner) {
Object[] params = new Object[0];
for (Field field : primaryKeyField) {
joiner.add(field.getAnnotation(Column.class).name() + " = ?");
field.setAccessible(true);
try {
params = ObjectArrays.concat(params, field.get(item));
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
field.setAccessible(false);
}
}
return params;
}
public void delete(T item) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
if (primaryKeyField.isEmpty())
throw new NullPointerException("Primary Key is not found");
StringJoiner joiner = new StringJoiner(" AND ");
Object[] params = criteriaJoiner(item, joiner);
deleteByCriteria(joiner.toString(), params);
}
public void deleteByCriteria(String criteria, Object... params) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
questionMarksParamsCount(criteria, params);
String sqlStatement = DELETE_SQL + FROM_CLAUSE + table.name() + WHERE_CLAUSE + criteria.trim();
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlStatement)) {
for (int i = 0; i < params.length; i++) stmt.setObject(i + 1, params[i]);
System.out.println(stmt.toString()); // For debug purpose
stmt.executeUpdate();
}
}
public Object customQuery(String query, Object... params) throws SQLException, IllegalArgumentException, NullPointerException, NumberParseException {
questionMarksParamsCount(query, params);
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
for (int i = 0; i < params.length; i++) stmt.setObject(i + 1, params[i]);
System.out.println(stmt.toString()); // For debug purpose
if (stmt.execute()) {
try (ResultSet rs = stmt.getResultSet()) {
List<T> items = new ArrayList<>(0);
while (rs.next()) {
T item = clazz.newInstance();
for (Field field : fields) {
Object value;
Class<?> type = field.getType();
value = type.equals(YearMonth.class) ? YearMonth.parse(rs.getString(field.getAnnotation(Column.class).name()), DateTimeFormatter.ofPattern("yyyy-MM-00")) : rs.getObject(field.getAnnotation(Column.class).name());
if (type.isPrimitive()) {
Class<?> boxed = Primitives.wrap(type);
value = boxed.cast(value);
}
field.setAccessible(true);
field.set(item, value);
field.setAccessible(false);
}
items.add(item);
}
return items;
}
} else {
try (ResultSet rs = stmt.getGeneratedKeys()) {
if (rs.next())
return rs.getLong(1);
}
}
} catch (IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
return null;
}
}
package com.trimaral.servlet.customer;
import com.trimaral.Roles;
import com.trimaral.dao.LoginDAO;
import com.trimaral.dao.UserRoleDAO;
import com.trimaral.entity.Login;
import com.trimaral.entity.UserRole;
import com.trimaral.utils.PasswordCreator;
import com.trimaral.utils.SMTPMXLookup;
import com.trimaral.utils.VerifyRecaptcha;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
@WebServlet(name = "Signup", urlPatterns = {"%2Fsignup"})
public class Signup extends HttpServlet {
@Resource(name = "jdbc/TrimarDB")
private DataSource dataSource;
private LoginDAO loginDAO;
@Override
public void init() throws ServletException {
loginDAO = new LoginDAO(dataSource);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String email = request.getParameter("email");
Login login = loginDAO.findByEmail(email);
if (login != null) {
request.getRequestDispatcher("/WEB-INF/pages/customer/signup.jsp?exists=true").forward(request, response);
return;
}
String newPassword = request.getParameter("newPassword");
String confirmPassword = request.getParameter("confirmPassword");
if (newPassword.length() < Login.PASSWORD_LENGTH)
throw new IllegalArgumentException("Password too short");
if (!newPassword.equals(confirmPassword))
throw new IllegalArgumentException("Passwords don't match");
if (request.getParameter("termsCheckbox") == null)
throw new IllegalArgumentException("Unchecked Terms & Conditions");
// get reCAPTCHA request param
String gRecaptchaResponse = request.getParameter("g-recaptcha-response");
boolean verify = VerifyRecaptcha.verify(gRecaptchaResponse);
if (!verify) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
if (!SMTPMXLookup.isAddressValid(email)) {
request.getRequestDispatcher("/WEB-INF/pages/customer/signup.jsp?invalid=true").forward(request, response);
return;
}
login = new Login();
login.setEmail(email);
login.setPassword(PasswordCreator.getHexPassword(newPassword));
loginDAO.save(login);
UserRole userRole = new UserRole();
userRole.setEmail(login.getEmail());
userRole.setRoleName(String.valueOf(Roles.PRIVATO));
UserRoleDAO userRoleDAO = new UserRoleDAO(dataSource);
userRoleDAO.save(userRole);
request.getSession().setAttribute("requestEmail", login);
response.sendRedirect(request.getContextPath() + "/confirm-email");
} catch (Exception e) {
throw new ServletException(e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/pages/customer/signup.jsp").forward(request, response);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment