diff --git a/resources/WEB-INF/jsp/email.jsp b/resources/WEB-INF/jsp/email.jsp
new file mode 100644
index 0000000..e3c4048
--- /dev/null
+++ b/resources/WEB-INF/jsp/email.jsp
@@ -0,0 +1,26 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+ Charm Profiles
+ <%@ include file="style.html" %>
+
+
+ <%@ include file="header.jsp" %>
+
+
${requestScope.wordBundle.getWord("email-warning")}
+
+
+ <%@ include file="footer.jsp" %>
+
+
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/error400.jsp b/resources/WEB-INF/jsp/error400.jsp
new file mode 100644
index 0000000..6c495ba
--- /dev/null
+++ b/resources/WEB-INF/jsp/error400.jsp
@@ -0,0 +1,15 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+ Charm Bad Request
+ <%@ include file="style.html" %>
+
+
+ <%@ include file="header.jsp" %>
+
+
400 - ${requestScope.wordBundle.getWord("page-bad-request")}
+
+ <%@ include file="footer.jsp" %>
+
+
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/error404.jsp b/resources/WEB-INF/jsp/error404.jsp
new file mode 100644
index 0000000..a880cd5
--- /dev/null
+++ b/resources/WEB-INF/jsp/error404.jsp
@@ -0,0 +1,15 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+ Charm Not Found
+ <%@ include file="style.html" %>
+
+
+ <%@ include file="header.jsp" %>
+
+
404 - ${requestScope.wordBundle.getWord("page-not-found")}
+
+ <%@ include file="footer.jsp" %>
+
+
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/footer.jsp b/resources/WEB-INF/jsp/footer.jsp
index 6bdce1e..127c7d9 100644
--- a/resources/WEB-INF/jsp/footer.jsp
+++ b/resources/WEB-INF/jsp/footer.jsp
@@ -1,5 +1,5 @@
-
+<%@ page contentType="text/html;charset=UTF-8" %>
- All rights reserved 2024
+ ${requestScope.wordBundle.getWord("all-rights-reserved")} 2024
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/header.jsp b/resources/WEB-INF/jsp/header.jsp
index 681bdf6..e62fc07 100644
--- a/resources/WEB-INF/jsp/header.jsp
+++ b/resources/WEB-INF/jsp/header.jsp
@@ -1,14 +1,9 @@
<%@ page contentType="text/html;charset=UTF-8" %>
Charm <3
+
-
-
-
- My current language: ${cookie["lang"].value}
-
-
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/profile.jsp b/resources/WEB-INF/jsp/profile.jsp
index d4b5069..6b941c9 100644
--- a/resources/WEB-INF/jsp/profile.jsp
+++ b/resources/WEB-INF/jsp/profile.jsp
@@ -1,66 +1,59 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
- Charm Profile
-
-
-<%@ include file="header.jsp" %>
-
-<%@ include file="footer.jsp" %>
-
+
+ Charm Profile
+ <%@ include file="style.html" %>
+
+
+ <%@ include file="header.jsp" %>
+
+ <%@ include file="footer.jsp" %>
+
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/profiles.jsp b/resources/WEB-INF/jsp/profiles.jsp
index 2aa5102..922c73b 100644
--- a/resources/WEB-INF/jsp/profiles.jsp
+++ b/resources/WEB-INF/jsp/profiles.jsp
@@ -3,12 +3,7 @@
Charm Profiles
-
+ <%@ include file="style.html" %>
<%@ include file="header.jsp" %>
@@ -20,14 +15,30 @@
${requestScope.wordBundle.getWord("name")} |
${requestScope.wordBundle.getWord("surname")} |
${requestScope.wordBundle.getWord("age")} |
+ ${requestScope.wordBundle.getWord("status")} |
- ${profile.id} |
- ${profile.email} |
- ${profile.name} |
- ${profile.surname} |
- ${profile.age} |
+ ${profile.id} |
+ ${profile.email} |
+ ${profile.name} |
+ ${profile.surname} |
+ ${profile.age} |
+
+
+ |
diff --git a/resources/WEB-INF/jsp/registration.jsp b/resources/WEB-INF/jsp/registration.jsp
new file mode 100644
index 0000000..3d7546e
--- /dev/null
+++ b/resources/WEB-INF/jsp/registration.jsp
@@ -0,0 +1,26 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+
+
+ Charm Registration
+ <%@ include file="style.html" %>
+
+
+ <%@ include file="header.jsp" %>
+
+ <%@ include file="footer.jsp" %>
+
+
\ No newline at end of file
diff --git a/resources/WEB-INF/jsp/style.html b/resources/WEB-INF/jsp/style.html
new file mode 100644
index 0000000..0837443
--- /dev/null
+++ b/resources/WEB-INF/jsp/style.html
@@ -0,0 +1,57 @@
+
+
+
+
\ No newline at end of file
diff --git a/resources/WEB-INF/web.xml b/resources/WEB-INF/web.xml
index 2a3867d..76c1445 100644
--- a/resources/WEB-INF/web.xml
+++ b/resources/WEB-INF/web.xml
@@ -20,4 +20,13 @@
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
+
+
+ 404
+ /WEB-INF/jsp/error404.jsp
+
+
+ 400
+ /WEB-INF/jsp/error400.jsp
+
diff --git a/resources/words.properties b/resources/words.properties
index d3206f1..ac8383d 100644
--- a/resources/words.properties
+++ b/resources/words.properties
@@ -1,13 +1,21 @@
about=About
+active=Active
age=Age
all-rights-reserved=All rights reserved
birth-date=Birth date
+confirm-password=Confirm password
delete=Delete
email=Email
+email-warning=Changing your mail may have negative effects
female=Female
gender=Gender
+inactive=Inactive
male=Male
name=Name
other=Other
+page-bad-request=Bad request
+page-not-found=Page not found
+password=Password
save=Save
+status=Status
surname=Surname
\ No newline at end of file
diff --git a/resources/words_en.properties b/resources/words_en.properties
index d3206f1..ac8383d 100644
--- a/resources/words_en.properties
+++ b/resources/words_en.properties
@@ -1,13 +1,21 @@
about=About
+active=Active
age=Age
all-rights-reserved=All rights reserved
birth-date=Birth date
+confirm-password=Confirm password
delete=Delete
email=Email
+email-warning=Changing your mail may have negative effects
female=Female
gender=Gender
+inactive=Inactive
male=Male
name=Name
other=Other
+page-bad-request=Bad request
+page-not-found=Page not found
+password=Password
save=Save
+status=Status
surname=Surname
\ No newline at end of file
diff --git a/resources/words_ru.properties b/resources/words_ru.properties
index ec51110..1cf55c7 100644
--- a/resources/words_ru.properties
+++ b/resources/words_ru.properties
@@ -1,13 +1,21 @@
about=\u041E \u0441\u0435\u0431\u0435
+active=\u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0439
age=\u0412\u043E\u0437\u0440\u0430\u0441\u0442
all-rights-reserved=\u0412\u0441\u0435 \u043F\u0440\u0430\u0432\u0430 \u0437\u0430\u0449\u0438\u0449\u0435\u043D\u044B
birth-date=\u0414\u0430\u0442\u0430 \u0440\u043E\u0436\u0434\u0435\u043D\u0438\u044F
+confirm-password=\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043F\u0430\u0440\u043E\u043B\u044C
delete=\u0423\u0434\u0430\u043B\u0438\u0442\u044C
email=\u041F\u043E\u0447\u0442\u0430
+email-warning=\u0421\u043C\u0435\u043D\u0430 \u043F\u043E\u0447\u0442\u044B \u043C\u043E\u0436\u0435\u0442 \u043F\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043A \u043D\u0435\u0436\u0435\u043B\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u043C \u043F\u043E\u0441\u043B\u0435\u0434\u0441\u0442\u0432\u0438\u044F\u043C
female=\u0416\u0435\u043D\u0449\u0438\u043D\u0430
gender=\u041F\u043E\u043B
+inactive=\u041D\u0435\u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439
male=\u041C\u0443\u0436\u0447\u0438\u043D\u0430
name=\u0418\u043C\u044F
other=\u0414\u0440\u0443\u0433\u043E\u0435
+page-bad-request=\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 \u0437\u0430\u043F\u0440\u043E\u0441
+page-not-found=\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u0430
+password=\u041F\u0430\u0440\u043E\u043B\u044C
save=\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C
+status=\u0421\u0442\u0430\u0442\u0443\u0441
surname=\u0424\u0430\u043C\u0438\u043B\u0438\u044F
\ No newline at end of file
diff --git a/src/ru/charm/back/controller/EmailController.java b/src/ru/charm/back/controller/EmailController.java
new file mode 100644
index 0000000..13dc7f9
--- /dev/null
+++ b/src/ru/charm/back/controller/EmailController.java
@@ -0,0 +1,52 @@
+ package ru.charm.back.controller;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import ru.charm.back.dto.ProfileGetDto;
+import ru.charm.back.dto.ProfileUpdateDto;
+import ru.charm.back.mapper.RequestToProfileUpdateDtoMapper;
+import ru.charm.back.model.Gender;
+import ru.charm.back.model.Profile;
+import ru.charm.back.model.exception.DuplicateEmailException;
+import ru.charm.back.service.ProfileService;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.Optional;
+
+import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+
+@WebServlet("/email")
+public class EmailController extends HttpServlet {
+ private final ProfileService service = ProfileService.getInstance();
+ private final RequestToProfileUpdateDtoMapper requestToProfileUpdateDtoMapper = RequestToProfileUpdateDtoMapper.getInstance();
+
+ @Override
+ protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+
+ String sId = req.getParameter("id");
+ String forwardUri = "/notFound";
+ if (sId != null) {
+ Optional optProfileGetDto = service.findById(Long.parseLong(sId));
+ if (optProfileGetDto.isPresent()) {
+ req.setAttribute("profile", optProfileGetDto.get());
+ forwardUri = "/WEB-INF/jsp/email.jsp";
+ }
+ }
+ req.getRequestDispatcher(forwardUri).forward(req, resp);
+ }
+
+ @Override
+ protected void doPut (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ ProfileUpdateDto dto = requestToProfileUpdateDtoMapper.map(req, new ProfileUpdateDto());
+ try {
+ service.update(dto);
+ resp.sendRedirect(String.format("/profile?id=%s", dto.getId()));
+ } catch (DuplicateEmailException e) {
+ resp.sendError(SC_BAD_REQUEST);
+ }
+ }
+}
diff --git a/src/ru/charm/back/controller/ProfileController.java b/src/ru/charm/back/controller/ProfileController.java
index bb03feb..450bcdf 100644
--- a/src/ru/charm/back/controller/ProfileController.java
+++ b/src/ru/charm/back/controller/ProfileController.java
@@ -6,73 +6,47 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import ru.charm.back.dto.ProfileGetDto;
-import ru.charm.back.model.Gender;
-import ru.charm.back.model.Profile;
+import ru.charm.back.dto.ProfileUpdateDto;
+import ru.charm.back.mapper.RequestToProfileUpdateDtoMapper;
import ru.charm.back.service.ProfileService;
import java.io.IOException;
-import java.time.LocalDate;
import java.util.Optional;
+import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+
@WebServlet("/profile")
public class ProfileController extends HttpServlet {
private final ProfileService service = ProfileService.getInstance();
+ private final RequestToProfileUpdateDtoMapper requestToProfileUpdateDtoMapper = RequestToProfileUpdateDtoMapper.getInstance();
+
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String sId = req.getParameter("id");
- String forwardUri = "/notFound";
+ String forwardUri = null;
if (sId != null) {
- Optional optProfileGetDto = service.findById(Long.parseLong(sId));
- if (optProfileGetDto.isPresent()) {
- req.setAttribute("profile", optProfileGetDto.get());
+ Optional optProfileDto = service.findById(Long.parseLong(sId));
+ if (optProfileDto.isPresent()) {
+ req.setAttribute("profile", optProfileDto.get());
forwardUri = "/WEB-INF/jsp/profile.jsp";
}
} else {
req.setAttribute("profiles", service.findAll());
forwardUri = "/WEB-INF/jsp/profiles.jsp";
}
- req.getRequestDispatcher(forwardUri).forward(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- Profile profile = getProfile(req);
- service.save(profile);
- resp.sendRedirect(String.format("/profile?id=%s", profile.getId()));
- }
-
- @Override
- protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- Profile profile = getProfile(req);
- service.update(profile);
- resp.sendRedirect(String.format("/profile?id=%s", profile.getId()));
-
- }
-
- @Override
- protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String sId = req.getParameter("id");
- if (!sId.isBlank()) {
- service.delete(Long.parseLong(sId));
+ if (forwardUri == null) {
+ resp.sendError(SC_NOT_FOUND);
+ } else {
+ req.getRequestDispatcher(forwardUri).forward(req, resp);
}
- resp.sendRedirect("/registration");
}
- private Profile getProfile(HttpServletRequest req) {
- Profile profile = new Profile();
- String sId = req.getParameter("id");
-
- if (!sId.isBlank()) {
- profile.setId(Long.parseLong(sId));
- }
-
- profile.setEmail(req.getParameter("email"));
- profile.setName(req.getParameter("name"));
- profile.setSurname(req.getParameter("surname"));
- profile.setAbout(req.getParameter("about"));
- profile.setGender(Gender.valueOf(req.getParameter("gender")));
- profile.setBirthday(LocalDate.parse(req.getParameter("birthDate")));
- return profile;
+ @Override
+ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ ProfileUpdateDto dto = requestToProfileUpdateDtoMapper.map(req);
+ service.update(dto);
+ String referer = req.getHeader("referer");
+ resp.sendRedirect(referer);
}
-}
+}
\ No newline at end of file
diff --git a/src/ru/charm/back/dao/ProfileDao.java b/src/ru/charm/back/dao/ProfileDao.java
index a340367..c74329b 100644
--- a/src/ru/charm/back/dao/ProfileDao.java
+++ b/src/ru/charm/back/dao/ProfileDao.java
@@ -2,41 +2,49 @@ package ru.charm.back.dao;
import ru.charm.back.model.Gender;
import ru.charm.back.model.Profile;
+import ru.charm.back.model.Status;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
public class ProfileDao {
- private final ConcurrentHashMap storage;
- private final AtomicLong idStorage;
private static final ProfileDao INSTANCE = new ProfileDao();
+ private final AtomicLong idStorage;
+ private final ConcurrentHashMap storage;
+
private ProfileDao() {
this.storage = new ConcurrentHashMap<>();
Profile profile = new Profile();
profile.setId(1L);
profile.setEmail("ivanov@mail.ru");
+ profile.setPassword("123");
profile.setName("Ivan");
profile.setSurname("Ivanov");
+ profile.setBirthDate(LocalDate.parse("2001-12-03"));
profile.setAbout("I am QA");
profile.setGender(Gender.MALE);
- profile.setBirthday(LocalDate.parse("2000-01-01"));
+ profile.setStatus(Status.ACTIVE);
this.storage.put(1L, profile);
Profile profile1 = new Profile();
profile1.setId(2L);
profile1.setEmail("sidorova@mail.ru");
+ profile1.setPassword("456");
profile1.setName("Elena");
profile1.setSurname("Sidorova");
+ profile1.setBirthDate(LocalDate.parse("1999-09-01"));
profile1.setAbout("I am Java Dev");
- profile1.setBirthday(LocalDate.parse("2000-01-01"));
profile1.setGender(Gender.FEMALE);
+ profile1.setStatus(Status.INACTIVE);
this.storage.put(2L, profile1);
- this.idStorage = new AtomicLong(2L);
+ this.idStorage = new AtomicLong(3L);
}
public static ProfileDao getInstance() {
@@ -44,30 +52,32 @@ public class ProfileDao {
}
public Profile save(Profile profile) {
- long id = idStorage.incrementAndGet();
- profile.setId(id);
- storage.put(id, profile);
-
+ profile.setId(idStorage.getAndIncrement());
+ storage.put(profile.getId(), profile);
return profile;
}
public Optional findById(Long id) {
+ if (id == null) return Optional.empty();
return Optional.ofNullable(storage.get(id));
}
- public void update(Profile profile) {
- Long id = profile.getId();
- if (id == null) {
- return;
- }
- storage.put(id, profile);
- }
-
public List findAll() {
return new ArrayList<>(storage.values());
}
- public Boolean delete(Long id) {
+ public void update(Profile profile) {
+ Long id = profile.getId();
+ if (id == null) return;
+ storage.put(id, profile);
+ }
+
+ public boolean delete(Long id) {
+ if (id == null) return false;
return storage.remove(id) != null;
}
+
+ public Set getAllEmails() {
+ return storage.values().stream().map(Profile::getEmail).collect(Collectors.toSet());
+ }
}
diff --git a/src/ru/charm/back/dto/ProfileGetDto.java b/src/ru/charm/back/dto/ProfileGetDto.java
index a1569e3..9b572af 100644
--- a/src/ru/charm/back/dto/ProfileGetDto.java
+++ b/src/ru/charm/back/dto/ProfileGetDto.java
@@ -1,34 +1,20 @@
package ru.charm.back.dto;
import ru.charm.back.model.Gender;
+import ru.charm.back.model.Status;
import java.time.LocalDate;
-public class ProfileGetDto {
+public class ProfileGetDto {
private Long id;
private String email;
private String name;
private String surname;
+ private LocalDate birthDate;
+ private Integer age;
private String about;
private Gender gender;
- private LocalDate birthDate;
- private int age;
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- public LocalDate getBirthDate() {
- return birthDate;
- }
-
- public void setBirthDate(LocalDate birthDate) {
- this.birthDate = birthDate;
- }
+ private Status status;
public Long getId() {
return id;
@@ -62,6 +48,22 @@ public class ProfileGetDto {
this.surname = surname;
}
+ public LocalDate getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(LocalDate birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
public String getAbout() {
return about;
}
@@ -78,14 +80,11 @@ public class ProfileGetDto {
this.gender = gender;
}
- @Override
- public String toString() {
- return "Profile{" +
- "id=" + id +
- ", email='" + email + '\'' +
- ", name='" + name + '\'' +
- ", surname='" + surname + '\'' +
- ", about='" + about + '\'' +
- '}';
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
}
}
diff --git a/src/ru/charm/back/dto/ProfileUpdateDto.java b/src/ru/charm/back/dto/ProfileUpdateDto.java
new file mode 100644
index 0000000..7f51187
--- /dev/null
+++ b/src/ru/charm/back/dto/ProfileUpdateDto.java
@@ -0,0 +1,91 @@
+package ru.charm.back.dto;
+
+
+import ru.charm.back.model.Gender;
+import ru.charm.back.model.Status;
+
+import java.time.LocalDate;
+
+public class ProfileUpdateDto {
+ private Long id;
+ private String email;
+ private String password;
+ private String name;
+ private String surname;
+ private LocalDate birthDate;
+ private String about;
+ private Gender gender;
+ private Status status;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+
+ public LocalDate getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(LocalDate birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public String getAbout() {
+ return about;
+ }
+
+ public void setAbout(String about) {
+ this.about = about;
+ }
+
+ public Gender getGender() {
+ return gender;
+ }
+
+ public void setGender(Gender gender) {
+ this.gender = gender;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+}
diff --git a/src/ru/charm/back/dto/RegistrationDto.java b/src/ru/charm/back/dto/RegistrationDto.java
new file mode 100644
index 0000000..ffeac3f
--- /dev/null
+++ b/src/ru/charm/back/dto/RegistrationDto.java
@@ -0,0 +1,22 @@
+package ru.charm.back.dto;
+
+public class RegistrationDto {
+ private String email;
+ private String password;
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/src/ru/charm/back/mapper/Mapper.java b/src/ru/charm/back/mapper/Mapper.java
index c87d933..1142af3 100644
--- a/src/ru/charm/back/mapper/Mapper.java
+++ b/src/ru/charm/back/mapper/Mapper.java
@@ -3,4 +3,5 @@ package ru.charm.back.mapper;
public interface Mapper {
To map(From from);
+ To map(From from, To to);
}
diff --git a/src/ru/charm/back/mapper/ProfileGetDtoMapper.java b/src/ru/charm/back/mapper/ProfileGetDtoMapper.java
deleted file mode 100644
index 3efe777..0000000
--- a/src/ru/charm/back/mapper/ProfileGetDtoMapper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package ru.charm.back.mapper;
-
-import ru.charm.back.dto.ProfileGetDto;
-import ru.charm.back.model.Profile;
-
-import java.time.LocalDate;
-import java.time.temporal.ChronoUnit;
-
-public class ProfileGetDtoMapper implements Mapper {
- private static final ProfileGetDtoMapper INSTANCE = new ProfileGetDtoMapper();
-
-
- public static ProfileGetDtoMapper getInstance() {
- return INSTANCE;
- }
-
- @Override
- public ProfileGetDto map(Profile profile) {
- ProfileGetDto dto = new ProfileGetDto();
-
- dto.setId(profile.getId());
- dto.setEmail(profile.getEmail());
- dto.setName(profile.getName());
- dto.setSurname(profile.getSurname());
- dto.setBirthDate(profile.getBirthday());
- dto.setAge(Math.toIntExact(ChronoUnit.YEARS.between(profile.getBirthday(), LocalDate.now())));
- dto.setGender(profile.getGender());
- dto.setAbout(profile.getAbout());
-
- return dto;
- }
-}
diff --git a/src/ru/charm/back/mapper/ProfileToProfileGetDtoMapper.java b/src/ru/charm/back/mapper/ProfileToProfileGetDtoMapper.java
new file mode 100644
index 0000000..b8453b8
--- /dev/null
+++ b/src/ru/charm/back/mapper/ProfileToProfileGetDtoMapper.java
@@ -0,0 +1,41 @@
+package ru.charm.back.mapper;
+
+
+import ru.charm.back.dto.ProfileGetDto;
+import ru.charm.back.model.Profile;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoUnit;
+
+public class ProfileToProfileGetDtoMapper implements Mapper {
+
+ private static final ProfileToProfileGetDtoMapper INSTANCE = new ProfileToProfileGetDtoMapper();
+
+ private ProfileToProfileGetDtoMapper() {
+ }
+
+ public static ProfileToProfileGetDtoMapper getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public ProfileGetDto map(Profile profile) {
+ return map(profile, new ProfileGetDto());
+ }
+
+ @Override
+ public ProfileGetDto map(Profile profile, ProfileGetDto dto) {
+ dto.setId(profile.getId());
+ dto.setEmail(profile.getEmail());
+ dto.setName(profile.getName());
+ dto.setSurname(profile.getSurname());
+ dto.setBirthDate(profile.getBirthDate());
+ if (profile.getBirthDate() != null) {
+ dto.setAge(Math.toIntExact(ChronoUnit.YEARS.between(profile.getBirthDate(), LocalDate.now())));
+ }
+ dto.setAbout(profile.getAbout());
+ dto.setGender(profile.getGender());
+ dto.setStatus(profile.getStatus());
+ return dto;
+ }
+}
diff --git a/src/ru/charm/back/mapper/ProfileUpdateDtoToProfileMapper.java b/src/ru/charm/back/mapper/ProfileUpdateDtoToProfileMapper.java
new file mode 100644
index 0000000..acd697b
--- /dev/null
+++ b/src/ru/charm/back/mapper/ProfileUpdateDtoToProfileMapper.java
@@ -0,0 +1,49 @@
+package ru.charm.back.mapper;
+
+
+import ru.charm.back.dto.ProfileUpdateDto;
+import ru.charm.back.model.Profile;
+
+public class ProfileUpdateDtoToProfileMapper implements Mapper {
+
+ private static final ProfileUpdateDtoToProfileMapper INSTANCE = new ProfileUpdateDtoToProfileMapper();
+
+ private ProfileUpdateDtoToProfileMapper() {
+ }
+
+ public static ProfileUpdateDtoToProfileMapper getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public Profile map(ProfileUpdateDto dto) {
+ return map(dto, new Profile());
+ }
+
+ @Override
+ public Profile map(ProfileUpdateDto dto, Profile profile) {
+ profile.setId(dto.getId());
+ if (dto.getEmail() != null) {
+ profile.setEmail(dto.getEmail());
+ }
+ if (dto.getName() != null) {
+ profile.setName(dto.getName());
+ }
+ if (dto.getSurname() != null) {
+ profile.setSurname(dto.getSurname());
+ }
+ if (dto.getBirthDate() != null) {
+ profile.setBirthDate(dto.getBirthDate());
+ }
+ if (dto.getAbout() != null) {
+ profile.setAbout(dto.getAbout());
+ }
+ if (dto.getGender() != null) {
+ profile.setGender(dto.getGender());
+ }
+ if (dto.getStatus() != null) {
+ profile.setStatus(dto.getStatus());
+ }
+ return profile;
+ }
+}
diff --git a/src/ru/charm/back/mapper/RegistrationDtoToProfileMapper.java b/src/ru/charm/back/mapper/RegistrationDtoToProfileMapper.java
new file mode 100644
index 0000000..5de88fe
--- /dev/null
+++ b/src/ru/charm/back/mapper/RegistrationDtoToProfileMapper.java
@@ -0,0 +1,30 @@
+package ru.charm.back.mapper;
+
+import ru.charm.back.dto.RegistrationDto;
+import ru.charm.back.model.Profile;
+import ru.charm.back.model.Status;
+
+public class RegistrationDtoToProfileMapper implements Mapper {
+
+ private static final RegistrationDtoToProfileMapper INSTANCE = new RegistrationDtoToProfileMapper();
+
+ private RegistrationDtoToProfileMapper() {
+ }
+
+ public static RegistrationDtoToProfileMapper getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public Profile map(RegistrationDto dto) {
+ return map(dto, new Profile());
+ }
+
+ @Override
+ public Profile map(RegistrationDto dto, Profile profile) {
+ profile.setEmail(dto.getEmail());
+ profile.setPassword(dto.getPassword());
+ profile.setStatus(Status.INACTIVE);
+ return profile;
+ }
+}
diff --git a/src/ru/charm/back/mapper/RequestToProfileUpdateDtoMapper.java b/src/ru/charm/back/mapper/RequestToProfileUpdateDtoMapper.java
new file mode 100644
index 0000000..3ae8a3f
--- /dev/null
+++ b/src/ru/charm/back/mapper/RequestToProfileUpdateDtoMapper.java
@@ -0,0 +1,55 @@
+package ru.charm.back.mapper;
+
+import jakarta.servlet.http.HttpServletRequest;
+import ru.charm.back.dto.ProfileUpdateDto;
+import ru.charm.back.model.Gender;
+import ru.charm.back.model.Status;
+
+import java.time.LocalDate;
+
+import static ru.charm.back.utils.StringUtils.isBlank;
+
+public class RequestToProfileUpdateDtoMapper implements Mapper {
+
+ private static final RequestToProfileUpdateDtoMapper INSTANCE = new RequestToProfileUpdateDtoMapper();
+
+ private RequestToProfileUpdateDtoMapper() {
+ }
+
+ public static RequestToProfileUpdateDtoMapper getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public ProfileUpdateDto map(HttpServletRequest req) {
+ return map(req, new ProfileUpdateDto());
+ }
+
+ @Override
+ public ProfileUpdateDto map(HttpServletRequest req, ProfileUpdateDto dto) {
+ String id = req.getParameter("id");
+ if (!isBlank(id)) {
+ dto.setId(Long.parseLong(id));
+ }
+ String email = req.getParameter("email");
+ if (!isBlank(email)) {
+ dto.setEmail(email);
+ }
+ dto.setName(req.getParameter("name"));
+ dto.setSurname(req.getParameter("surname"));
+ String birthDate = req.getParameter("birthDate");
+ if (!isBlank(birthDate)) {
+ dto.setBirthDate(LocalDate.parse(birthDate));
+ }
+ dto.setAbout(req.getParameter("about"));
+ String gender = req.getParameter("gender");
+ if (!isBlank(gender)) {
+ dto.setGender(Gender.valueOf(gender));
+ }
+ String status = req.getParameter("status");
+ if (!isBlank(status)) {
+ dto.setStatus(Status.valueOf(status));
+ }
+ return dto;
+ }
+}
diff --git a/src/ru/charm/back/mapper/RequestToRegistrationDtoMapper.java b/src/ru/charm/back/mapper/RequestToRegistrationDtoMapper.java
new file mode 100644
index 0000000..6d2aae8
--- /dev/null
+++ b/src/ru/charm/back/mapper/RequestToRegistrationDtoMapper.java
@@ -0,0 +1,28 @@
+package ru.charm.back.mapper;
+
+import jakarta.servlet.http.HttpServletRequest;
+import ru.charm.back.dto.RegistrationDto;
+
+public class RequestToRegistrationDtoMapper implements Mapper {
+
+ private static final RequestToRegistrationDtoMapper INSTANCE = new RequestToRegistrationDtoMapper();
+
+ private RequestToRegistrationDtoMapper() {
+ }
+
+ public static RequestToRegistrationDtoMapper getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public RegistrationDto map(HttpServletRequest req) {
+ return map(req, new RegistrationDto());
+ }
+
+ @Override
+ public RegistrationDto map(HttpServletRequest req, RegistrationDto dto) {
+ dto.setEmail(req.getParameter("email"));
+ dto.setPassword(req.getParameter("password"));
+ return dto;
+ }
+}
diff --git a/src/ru/charm/back/model/Profile.java b/src/ru/charm/back/model/Profile.java
index 77d6a93..588bfe3 100644
--- a/src/ru/charm/back/model/Profile.java
+++ b/src/ru/charm/back/model/Profile.java
@@ -5,19 +5,13 @@ import java.time.LocalDate;
public class Profile {
private Long id;
private String email;
+ private String password;
private String name;
private String surname;
+ private LocalDate birthDate;
private String about;
private Gender gender;
- private LocalDate birthday;
-
- public LocalDate getBirthday() {
- return birthday;
- }
-
- public void setBirthday(LocalDate birthday) {
- this.birthday = birthday;
- }
+ private Status status;
public Long getId() {
return id;
@@ -35,6 +29,14 @@ public class Profile {
this.email = email;
}
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
public String getName() {
return name;
}
@@ -51,6 +53,14 @@ public class Profile {
this.surname = surname;
}
+ public LocalDate getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(LocalDate birthDate) {
+ this.birthDate = birthDate;
+ }
+
public String getAbout() {
return about;
}
@@ -67,14 +77,11 @@ public class Profile {
this.gender = gender;
}
- @Override
- public String toString() {
- return "Profile{" +
- "id=" + id +
- ", email='" + email + '\'' +
- ", name='" + name + '\'' +
- ", surname='" + surname + '\'' +
- ", about='" + about + '\'' +
- '}';
+ public Status getStatus() {
+ return status;
}
-}
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+}
\ No newline at end of file
diff --git a/src/ru/charm/back/model/Status.java b/src/ru/charm/back/model/Status.java
new file mode 100644
index 0000000..0b369c7
--- /dev/null
+++ b/src/ru/charm/back/model/Status.java
@@ -0,0 +1,5 @@
+package ru.charm.back.model;
+
+public enum Status {
+ ACTIVE, INACTIVE
+}
diff --git a/src/ru/charm/back/model/exception/DuplicateEmailException.java b/src/ru/charm/back/model/exception/DuplicateEmailException.java
new file mode 100644
index 0000000..b1f52c4
--- /dev/null
+++ b/src/ru/charm/back/model/exception/DuplicateEmailException.java
@@ -0,0 +1,4 @@
+package ru.charm.back.model.exception;
+
+public class DuplicateEmailException extends RuntimeException {
+}
diff --git a/src/ru/charm/back/service/ProfileService.java b/src/ru/charm/back/service/ProfileService.java
index a177d95..389bdfd 100644
--- a/src/ru/charm/back/service/ProfileService.java
+++ b/src/ru/charm/back/service/ProfileService.java
@@ -2,47 +2,68 @@ package ru.charm.back.service;
import ru.charm.back.dao.ProfileDao;
import ru.charm.back.dto.ProfileGetDto;
-import ru.charm.back.mapper.ProfileGetDtoMapper;
-import ru.charm.back.model.Profile;
+import ru.charm.back.dto.ProfileUpdateDto;
+import ru.charm.back.dto.RegistrationDto;
+import ru.charm.back.mapper.ProfileToProfileGetDtoMapper;
+import ru.charm.back.mapper.ProfileUpdateDtoToProfileMapper;
+import ru.charm.back.mapper.RegistrationDtoToProfileMapper;
+import ru.charm.back.model.exception.DuplicateEmailException;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
public class ProfileService {
+
private static final ProfileService INSTANCE = new ProfileService();
+
private final ProfileDao dao = ProfileDao.getInstance();
- private final ProfileGetDtoMapper profileGetDtoMapper = ProfileGetDtoMapper.getInstance();
+ private final ProfileToProfileGetDtoMapper profileToProfileGetDtoMapper = ProfileToProfileGetDtoMapper.getInstance();
- public static ProfileService getInstance() {
- return INSTANCE;
+ private final ProfileUpdateDtoToProfileMapper profileUpdateDtoToProfileMapper = ProfileUpdateDtoToProfileMapper.getInstance();
+
+ private final RegistrationDtoToProfileMapper registrationDtoToProfileMapper = RegistrationDtoToProfileMapper.getInstance();
+
+ private ProfileService() {
}
- public Profile save(Profile profile) {
- return dao.save(profile);
+ public static ProfileService getInstance() {
+ return INSTANCE;
+ }
+
+ public Long save(RegistrationDto dto) {
+ return dao.save(registrationDtoToProfileMapper.map(dto)).getId();
}
public Optional findById(Long id) {
- if (id == null) {
- return Optional.empty();
- }
-
- return dao.findById(id).map(profileGetDtoMapper::map);
- }
-
- public Boolean delete(Long id) {
- if (id == null) {
- return false;
- }
-
- return dao.delete(id);
- }
-
- public void update(Profile profile) {
- dao.update(profile);
+ return dao.findById(id).map(profileToProfileGetDtoMapper::map);
}
public List findAll() {
- return dao.findAll().stream().map(profileGetDtoMapper::map).toList();
+ return dao.findAll().stream().map(profileToProfileGetDtoMapper::map).toList();
}
-}
+
+ public void update(ProfileUpdateDto dto) {
+ dao.findById(dto.getId())
+ .ifPresent(profile -> {
+ checkEmail(profile.getEmail(), dto.getEmail());
+ dao.update(profileUpdateDtoToProfileMapper.map(dto, profile));
+ }
+ );
+ }
+
+ private void checkEmail(String oldEmail, String newEmail) {
+ if (newEmail == null) return;
+ Set emails = dao.getAllEmails();
+ if (!Objects.equals(oldEmail, newEmail) &&
+ emails.contains(newEmail)) {
+ throw new DuplicateEmailException();
+ }
+ }
+
+ public boolean delete(Long id) {
+ return dao.delete(id);
+ }
+}
\ No newline at end of file
diff --git a/src/ru/charm/back/utils/StringUtils.java b/src/ru/charm/back/utils/StringUtils.java
new file mode 100644
index 0000000..13713ae
--- /dev/null
+++ b/src/ru/charm/back/utils/StringUtils.java
@@ -0,0 +1,7 @@
+package ru.charm.back.utils;
+
+public class StringUtils {
+ public static boolean isBlank(String str) {
+ return str == null || str.isBlank();
+ }
+}