From 79714dc6b5350ca762c89bad992a09f33b8b16d4 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Thu, 11 Jun 2015 12:53:52 +0300 Subject: [PATCH 01/17] patch1.3 --- pom.xml | 3 +- .../java/ru/javawebinar/topjava/Main.java | 20 ++++++++- .../javawebinar/topjava/model/UserMeal.java | 33 ++++++++++++++ .../topjava/model/UserMealWithExceed.java | 34 +++++++++++++++ .../ru/javawebinar/topjava/util/TimeUtil.java | 13 ++++++ .../topjava/util/UserMealsUtil.java | 43 +++++++++++++++++++ src/main/webapp/WEB-INF/web.xml | 18 ++++++++ src/main/webapp/index.html | 10 +++++ src/main/webapp/userList.jsp | 9 ++++ 9 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMeal.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/TimeUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.html create mode 100644 src/main/webapp/userList.jsp diff --git a/pom.xml b/pom.xml index c8a1c78..3f1e378 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ ru.javawebinar topjava - jar + war 1.0-SNAPSHOT @@ -13,6 +13,7 @@ 1.8 + UTF-8 UTF-8 diff --git a/src/main/java/ru/javawebinar/topjava/Main.java b/src/main/java/ru/javawebinar/topjava/Main.java index 319e86c..8cc4da5 100644 --- a/src/main/java/ru/javawebinar/topjava/Main.java +++ b/src/main/java/ru/javawebinar/topjava/Main.java @@ -1,14 +1,30 @@ package ru.javawebinar.topjava; +import java.util.function.Consumer; + /** * User: gkislin * Date: 15.01.2015 * * @link http://javawebinar.ru/topjava/ - * @link http://caloriesmng.herokuapp.com/ */ public class Main { public static void main(String[] args) { - System.out.format("Hello Topjava!"); + execute(() -> { + System.out.println("Hello Topjava!"); + }); + consume(System.out::println, "Hello Topjava!"); + } + + private static void execute(Runnable runnable) { + System.out.println("Start runner"); + runnable.run(); + System.out.println("End runner"); + } + + private static void consume(Consumer consumer, String out) { + System.out.println("Start consume"); + consumer.accept(out); + System.out.println("End consume"); } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java new file mode 100644 index 0000000..fde5448 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -0,0 +1,33 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +/** + * GKislin + * 11.01.2015. + */ +public class UserMeal { + protected final LocalDateTime dateTime; + + protected final String description; + + protected final int calories; + + public UserMeal(LocalDateTime dateTime, String description, int calories) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public String getDescription() { + return description; + } + + public int getCalories() { + return calories; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java new file mode 100644 index 0000000..66c3569 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java @@ -0,0 +1,34 @@ +package ru.javawebinar.topjava.model; + +import java.time.LocalDateTime; + +/** + * GKislin + * 11.01.2015. + */ +public class UserMealWithExceed { + protected final LocalDateTime dateTime; + + protected final String description; + + protected final int calories; + + protected final boolean exceed; + + public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) { + this.dateTime = dateTime; + this.description = description; + this.calories = calories; + this.exceed = exceed; + } + + @Override + public String toString() { + return "UserMealWithExceed{" + + "dateTime=" + dateTime + + ", description='" + description + '\'' + + ", calories=" + calories + + ", exceed=" + exceed + + '}'; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java new file mode 100644 index 0000000..02399b7 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/TimeUtil.java @@ -0,0 +1,13 @@ +package ru.javawebinar.topjava.util; + +import java.time.LocalTime; + +/** + * GKislin + * 07.01.2015. + */ +public class TimeUtil { + public static boolean isBetween(LocalTime lt, LocalTime startTime, LocalTime endTime) { + return lt.compareTo(startTime) >= 0 && lt.compareTo(endTime) <= 0; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java new file mode 100644 index 0000000..a73ab79 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -0,0 +1,43 @@ +package ru.javawebinar.topjava.util; + +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.model.UserMealWithExceed; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * GKislin + * 31.05.2015. + */ +public class UserMealsUtil { + public static void main(String[] args) { + List mealList = Arrays.asList( + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000), + new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) + ); + List filteredMealsWithExceeded = getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); + filteredMealsWithExceeded.forEach(System.out::println); + } + + public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { + Map caloriesSumByDate = mealList.stream().collect(Collectors.groupingBy(um -> um.getDateTime().toLocalDate(), + Collectors.summingInt(UserMeal::getCalories))); + + return mealList.stream() + .filter(um->TimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime)) + .map(um->new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), + caloriesSumByDate.get(um.getDateTime().toLocalDate())> caloriesPerDay)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..4517d28 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,18 @@ + + + + Archetype Created Web Application + + + userServlet + ru.javawebinar.topjava.web.UserServlet + 0 + + + userServlet + /users + + + diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html new file mode 100644 index 0000000..1937333 --- /dev/null +++ b/src/main/webapp/index.html @@ -0,0 +1,10 @@ + + + + + Top Java. + + +

Приложение вебинара "Top Java."

+ + \ No newline at end of file diff --git a/src/main/webapp/userList.jsp b/src/main/webapp/userList.jsp new file mode 100644 index 0000000..c6b1205 --- /dev/null +++ b/src/main/webapp/userList.jsp @@ -0,0 +1,9 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + User list + + +

User list

+ + From ef4fc001c52616287293487ee5ee218fbb49d8a0 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Thu, 11 Jun 2015 13:02:04 +0300 Subject: [PATCH 02/17] patch1.3(modiff1) --- pom.xml | 5 +++++ .../ru/javawebinar/topjava/web/UserServlet.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/web/UserServlet.java diff --git a/pom.xml b/pom.xml index 3f1e378..72ca85a 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,11 @@ + + javax.servlet + javax.servlet-api + 3.0.1 + diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java new file mode 100644 index 0000000..637b5d0 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -0,0 +1,16 @@ +package ru.javawebinar.topjava.web; + +import java.io.IOException; + +/** + * Created by senior on 11.06.15. + */ +public class UserServlet extends javax.servlet.http.HttpServlet { + protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { + + } + + protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { + + } +} From b034dc2066b61f1e03a7909eb8e8fa68a066bc9c Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Thu, 11 Jun 2015 13:20:14 +0300 Subject: [PATCH 03/17] patch1.4 --- .../ru/javawebinar/topjava/web/UserServlet.java | 16 +++++++++------- src/main/webapp/WEB-INF/web.xml | 10 +++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java index 637b5d0..389759e 100644 --- a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -1,16 +1,18 @@ package ru.javawebinar.topjava.web; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** - * Created by senior on 11.06.15. + * User: gkislin + * Date: 19.08.2014 */ -public class UserServlet extends javax.servlet.http.HttpServlet { - protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { - - } - - protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { +public class UserServlet extends HttpServlet { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + request.getRequestDispatcher("/userList.jsp").forward(request, response); } } diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 4517d28..bc1b0d3 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,9 +1,9 @@ - + - - Archetype Created Web Application + Archetype Created Web Application userServlet From b1b2845132e5c6cd67efaf6f869c77c973563b43 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Thu, 11 Jun 2015 13:53:56 +0300 Subject: [PATCH 04/17] patch1.5 --- pom.xml | 2 +- src/main/java/ru/javawebinar/topjava/web/UserServlet.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 72ca85a..ac9d31e 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ topjava - install + package org.apache.maven.plugins diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java index 389759e..70ce24c 100644 --- a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -13,6 +13,7 @@ public class UserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - request.getRequestDispatcher("/userList.jsp").forward(request, response); +// request.getRequestDispatcher("/userList.jsp").forward(request, response); + response.sendRedirect("userList.jsp"); } } From 8ccf9a71c408e3abf3ad32467bd5b44204762af2 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 12 Jun 2015 06:32:29 +0300 Subject: [PATCH 05/17] patch1.6 --- .gitignore | 1 + pom.xml | 33 +++++++++ .../ru/javawebinar/topjava/LoggerWrapper.java | 72 +++++++++++++++++++ .../javawebinar/topjava/web/UserServlet.java | 5 ++ src/main/resources/logback.xml | 33 +++++++++ 5 files changed, 144 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/LoggerWrapper.java create mode 100644 src/main/resources/logback.xml diff --git a/.gitignore b/.gitignore index c5d12da..62617a9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ out target *.iml atlassian-ide-plugin.xml +log diff --git a/pom.xml b/pom.xml index ac9d31e..091c7c1 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,10 @@ UTF-8 UTF-8 + + + 1.1.2 + 1.7.7 @@ -35,11 +39,40 @@ + + + org.slf4j + slf4j-api + ${slf4j.version} + compile + + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + + org.slf4j + jul-to-slf4j + ${slf4j.version} + runtime + + + + ch.qos.logback + logback-classic + ${logback.version} + runtime + javax.servlet javax.servlet-api 3.0.1 + diff --git a/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java new file mode 100644 index 0000000..d2862a1 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java @@ -0,0 +1,72 @@ +package ru.javawebinar.topjava; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * User: gkislin + * Date: 22.01.14 + */ +public class LoggerWrapper { + + private Logger logger; + + public LoggerWrapper(Logger logger) { + this.logger = logger; + } + + public static LoggerWrapper get(Class aClass) { + return new LoggerWrapper(LoggerFactory.getLogger(aClass)); + } + + public void debug(String msg) { + logger.debug(msg); + } + + public void info(String msg, Object... arguments) { + logger.info(msg, arguments); + } + + public void warn(String msg) { + logger.warn(msg); + } + + public void warn(String msg, Throwable t) { + logger.warn(msg, t); + } + + public void error(String msg) { + logger.error(msg); + } + + public void error(String msg, Throwable t) { + logger.error(msg, t); + } + + public boolean isDebug() { + return logger.isDebugEnabled(); + } + + public IllegalStateException getIllegalStateException(String msg) { + return getIllegalStateException(msg, null); + } + + public IllegalStateException getIllegalStateException(String msg, Throwable e) { + logger.error(msg, e); + return new IllegalStateException(msg, e); + } + + public IllegalArgumentException getIllegalArgumentException(String msg) { + return getIllegalArgumentException(msg, null); + } + + public IllegalArgumentException getIllegalArgumentException(String msg, Throwable e) { + logger.error(msg, e); + return new IllegalArgumentException(msg, e); + } + + public UnsupportedOperationException getUnsupportedOperationException(String msg) { + logger.error(msg); + return new UnsupportedOperationException(msg); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java index 70ce24c..eb2188b 100644 --- a/src/main/java/ru/javawebinar/topjava/web/UserServlet.java +++ b/src/main/java/ru/javawebinar/topjava/web/UserServlet.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.web; +import ru.javawebinar.topjava.LoggerWrapper; + import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -11,8 +13,11 @@ * Date: 19.08.2014 */ public class UserServlet extends HttpServlet { + private static final LoggerWrapper LOG = LoggerWrapper.get(UserServlet.class); protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + LOG.debug("redirect to userList"); + // request.getRequestDispatcher("/userList.jsp").forward(request, response); response.sendRedirect("userList.jsp"); } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..4ee2916 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,33 @@ + + + + + true + + + + + + + ${TOPJAVA_ROOT}/log/topjava.log + + + UTF-8 + %date %-5level %logger{0} [%file:%line] %msg%n + + + + + + UTF-8 + %-5level %logger{0} [%file:%line] %msg%n + + + + + + + + + + From 0b8cec003496101bd4963e0ab82d0f5e3851346e Mon Sep 17 00:00:00 2001 From: "javawebinar@yandex.ru" Date: Sun, 21 Jun 2015 12:43:59 +0300 Subject: [PATCH 06/17] 1_HW1 patch --- .../javawebinar/topjava/web/MealServlet.java | 22 +++++++++++++++++++ src/main/webapp/WEB-INF/web.xml | 9 ++++++++ src/main/webapp/index.html | 4 ++++ src/main/webapp/mealList.jsp | 13 +++++++++++ src/main/webapp/userList.jsp | 4 ++++ 5 files changed, 52 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/web/MealServlet.java create mode 100644 src/main/webapp/mealList.jsp diff --git a/src/main/java/ru/javawebinar/topjava/web/MealServlet.java b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java new file mode 100644 index 0000000..1b72b09 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/MealServlet.java @@ -0,0 +1,22 @@ +package ru.javawebinar.topjava.web; + +import ru.javawebinar.topjava.LoggerWrapper; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * User: gkislin + * Date: 19.08.2014 + */ +public class MealServlet extends HttpServlet { + private static final LoggerWrapper LOG = LoggerWrapper.get(MealServlet.class); + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + LOG.debug("redirect to mealList"); + response.sendRedirect("mealList.jsp"); + } +} diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index bc1b0d3..495e101 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -15,4 +15,13 @@ /users + + mealServlet + ru.javawebinar.topjava.web.MealServlet + 0 + + + mealServlet + /meals + diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 1937333..962ff06 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -6,5 +6,9 @@

Приложение вебинара "Top Java."

+ \ No newline at end of file diff --git a/src/main/webapp/mealList.jsp b/src/main/webapp/mealList.jsp new file mode 100644 index 0000000..78331f9 --- /dev/null +++ b/src/main/webapp/mealList.jsp @@ -0,0 +1,13 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Meal list + + +

Meal list

+ + + diff --git a/src/main/webapp/userList.jsp b/src/main/webapp/userList.jsp index c6b1205..0ee783c 100644 --- a/src/main/webapp/userList.jsp +++ b/src/main/webapp/userList.jsp @@ -5,5 +5,9 @@

User list

+ From f4c5ad6e1552d280c92cd5ed68a8ec84d719f11b Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Sun, 21 Jun 2015 16:35:51 +0300 Subject: [PATCH 07/17] 1_App_layers patch --- config/tomcat/setenv.bat | 4 + .../ru/javawebinar/topjava/LoggedUser.java | 16 ++++ .../ru/javawebinar/topjava/LoggerWrapper.java | 8 +- .../javawebinar/topjava/model/BaseEntity.java | 29 +++++++ .../topjava/model/NamedEntity.java | 31 +++++++ .../ru/javawebinar/topjava/model/Role.java | 10 +++ .../ru/javawebinar/topjava/model/User.java | 80 +++++++++++++++++++ .../repository/UserMealRepository.java | 8 ++ .../topjava/repository/UserRepository.java | 24 ++++++ .../topjava/service/UserMealService.java | 8 ++ .../topjava/service/UserMealServiceImpl.java | 13 +++ .../topjava/service/UserService.java | 26 ++++++ .../topjava/service/UserServiceImpl.java | 41 ++++++++++ .../topjava/util/exception/ExceptionUtil.java | 29 +++++++ .../util/exception/NotFoundException.java | 11 +++ .../web/meal/UserMealRestController.java | 12 +++ .../web/user/AdminUserRestController.java | 47 +++++++++++ .../topjava/web/user/UserRestController.java | 34 ++++++++ 18 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 config/tomcat/setenv.bat create mode 100644 src/main/java/ru/javawebinar/topjava/LoggedUser.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/BaseEntity.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/NamedEntity.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/Role.java create mode 100644 src/main/java/ru/javawebinar/topjava/model/User.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/UserRepository.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserMealService.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserService.java create mode 100644 src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java create mode 100644 src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java diff --git a/config/tomcat/setenv.bat b/config/tomcat/setenv.bat new file mode 100644 index 0000000..ebbd659 --- /dev/null +++ b/config/tomcat/setenv.bat @@ -0,0 +1,4 @@ +rem run tomcat with JMX ability +rem Run Tomcat as admin +rem for remote connection add -Djava.rmi.server.hostname=TomcatServer_IP +set CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false diff --git a/src/main/java/ru/javawebinar/topjava/LoggedUser.java b/src/main/java/ru/javawebinar/topjava/LoggedUser.java new file mode 100644 index 0000000..9a51cd8 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/LoggedUser.java @@ -0,0 +1,16 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.model.Role; + +import java.util.Set; + +/** + * GKislin + * 06.03.2015. + */ +public class LoggedUser { + + public static int id() { + return 1; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java index d2862a1..642bb6c 100644 --- a/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java +++ b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java @@ -2,6 +2,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.javawebinar.topjava.util.exception.NotFoundException; /** * User: gkislin @@ -69,4 +70,9 @@ public UnsupportedOperationException getUnsupportedOperationException(String msg logger.error(msg); return new UnsupportedOperationException(msg); } -} + + public NotFoundException getNotFoundException(String reason) { + logger.error("No data found"); + return new NotFoundException(reason); + } +} \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java new file mode 100644 index 0000000..aca94ed --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java @@ -0,0 +1,29 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class BaseEntity { + + protected Integer id; + + public BaseEntity() { + } + + protected BaseEntity(Integer id) { + this.id = id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public boolean isNew() { + return (this.id == null); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java new file mode 100644 index 0000000..ca92e39 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java @@ -0,0 +1,31 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class NamedEntity extends BaseEntity { + + protected String name; + + public NamedEntity() { + } + + protected NamedEntity(Integer id, String name) { + super(id); + this.name = name; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/model/Role.java b/src/main/java/ru/javawebinar/topjava/model/Role.java new file mode 100644 index 0000000..f0de2b4 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/Role.java @@ -0,0 +1,10 @@ +package ru.javawebinar.topjava.model; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public enum Role { + ROLE_USER, + ROLE_ADMIN +} diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java new file mode 100644 index 0000000..9f0e293 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -0,0 +1,80 @@ +package ru.javawebinar.topjava.model; + +import java.util.Date; +import java.util.EnumSet; +import java.util.Set; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class User extends NamedEntity { + + private String email; + + private String password; + + private boolean enabled = true; + + private Date registered; + + private Set roles; + + public User() { + } + + public User(Integer id, String name, String email, String password, Role role, Role... roles) { + super(id, name); + this.email = email; + this.password = password; + this.enabled = true; + this.roles = EnumSet.of(role, roles); + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPassword(String password) { + this.password = password; + } + + public Date getRegistered() { + return registered; + } + + public void setRegistered(Date registered) { + this.registered = registered; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isEnabled() { + return enabled; + } + + public Set getRoles() { + return roles; + } + + public String getPassword() { + return password; + } + + @Override + public String toString() { + return "User (" + + "id=" + id + + ", email=" + email + + ", name=" + name + + ", enabled=" + enabled + + ", roles=" + roles + + ')'; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java new file mode 100644 index 0000000..2877486 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java @@ -0,0 +1,8 @@ +package ru.javawebinar.topjava.repository; + +/** + * GKislin + * 06.03.2015. + */ +public interface UserMealRepository { +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java new file mode 100644 index 0000000..24c1c45 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/UserRepository.java @@ -0,0 +1,24 @@ +package ru.javawebinar.topjava.repository; + +import ru.javawebinar.topjava.model.User; + +import java.util.List; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public interface UserRepository { + User save(User user); + + // false if not found + boolean delete(int id); + + // null if not found + User get(int id); + + // null if not found + User getByEmail(String email); + + List getAll(); +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java new file mode 100644 index 0000000..b17fec8 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java @@ -0,0 +1,8 @@ +package ru.javawebinar.topjava.service; + +/** + * GKislin + * 15.06.2015. + */ +public interface UserMealService { +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java new file mode 100644 index 0000000..5730b8b --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java @@ -0,0 +1,13 @@ +package ru.javawebinar.topjava.service; + +import ru.javawebinar.topjava.repository.UserMealRepository; + +/** + * GKislin + * 06.03.2015. + */ +public class UserMealServiceImpl implements UserMealService { + + private UserMealRepository repository; + +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserService.java b/src/main/java/ru/javawebinar/topjava/service/UserService.java new file mode 100644 index 0000000..9f8d9d5 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserService.java @@ -0,0 +1,26 @@ +package ru.javawebinar.topjava.service; + + +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.List; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public interface UserService { + + public User save(User user); + + public void delete(int id) throws NotFoundException; + + public User get(int id) throws NotFoundException; + + public User getByEmail(String email) throws NotFoundException; + + public List getAll(); + + public void update(User user) throws NotFoundException; +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java new file mode 100644 index 0000000..b3d674f --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -0,0 +1,41 @@ +package ru.javawebinar.topjava.service; + +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; +import ru.javawebinar.topjava.util.exception.ExceptionUtil; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.List; + +/** + * GKislin + * 06.03.2015. + */ +public class UserServiceImpl implements UserService { + + private UserRepository repository; + + public User save(User user) { + return repository.save(user); + } + + public void delete(int id) { + ExceptionUtil.check(repository.delete(id), id); + } + + public User get(int id) throws NotFoundException { + return ExceptionUtil.check(repository.get(id), id); + } + + public User getByEmail(String email) throws NotFoundException { + return ExceptionUtil.check(repository.getByEmail(email), "email=" + email); + } + + public List getAll() { + return repository.getAll(); + } + + public void update(User user) throws NotFoundException { + ExceptionUtil.check(repository.save(user), user.getId()); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java b/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java new file mode 100644 index 0000000..295aada --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/exception/ExceptionUtil.java @@ -0,0 +1,29 @@ +package ru.javawebinar.topjava.util.exception; + + +import ru.javawebinar.topjava.LoggerWrapper; + +/** + * User: gkislin + * Date: 14.05.2014 + */ +public class ExceptionUtil { + private static final LoggerWrapper LOG = LoggerWrapper.get(ExceptionUtil.class); + + public static void check(boolean found, int id) { + check(found, "id=" + id); + } + + public static T check(T object, int id) { + return check(object, "id=" + id); + } + + public static T check(T object, String msg) { + check(object != null, msg); + return object; + } + + public static void check(boolean found, String msg) { + if (!found) throw LOG.getNotFoundException("Not found entity with " + msg); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java b/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java new file mode 100644 index 0000000..7a770f0 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/exception/NotFoundException.java @@ -0,0 +1,11 @@ +package ru.javawebinar.topjava.util.exception; + +/** + * User: gkislin + * Date: 19.08.2014 + */ +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java new file mode 100644 index 0000000..51e64a2 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java @@ -0,0 +1,12 @@ +package ru.javawebinar.topjava.web.meal; + +import ru.javawebinar.topjava.service.UserMealServiceImpl; + +/** + * GKislin + * 06.03.2015. + */ +public class UserMealRestController { + private UserMealServiceImpl service; + +} diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java new file mode 100644 index 0000000..d2c557a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.web.user; + +import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.service.UserService; + +import java.util.List; + +/** + * GKislin + * 06.03.2015. + */ +public class AdminUserRestController { + private static final LoggerWrapper LOG = LoggerWrapper.get(UserRestController.class); + + private UserService service; + + public List getAll() { + LOG.info("getAll"); + return service.getAll(); + } + + public User get(int id) { + LOG.info("get " + id); + return service.get(id); + } + + public User create(User user) { + LOG.info("create " + user); + return service.save(user); + } + + public void delete(int id) { + LOG.info("delete " + id); + service.delete(id); + } + + public void update(User user) { + LOG.info("update " + user); + service.update(user); + } + + public User getByMail(String email) { + LOG.info("getByEmail " + email); + return service.getByEmail(email); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java new file mode 100644 index 0000000..79e2e49 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java @@ -0,0 +1,34 @@ +package ru.javawebinar.topjava.web.user; + +import ru.javawebinar.topjava.LoggedUser; +import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.service.UserService; + +/** + * GKislin + * 06.03.2015. + */ +public class UserRestController { + private static final LoggerWrapper LOG = LoggerWrapper.get(UserRestController.class); + + private UserService service; + + public User get() { + int id = LoggedUser.id(); + LOG.info("get", id); + return service.get(id); + } + + public void delete() { + int id = LoggedUser.id(); + LOG.info("delete {}", id); + service.delete(id); + } + + public void update(User user) { + int id = LoggedUser.id(); + LOG.info("update"); + service.update(user); + } +} \ No newline at end of file From 9d41aab370103419b25f40792eeacf0d3a900063 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 26 Jun 2015 16:41:45 +0300 Subject: [PATCH 08/17] 3_Add_spring_dependency patch --- pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pom.xml b/pom.xml index 091c7c1..ae34acc 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,8 @@ UTF-8 UTF-8 + 4.1.6.RELEASE + 1.1.2 1.7.7 @@ -73,6 +75,18 @@ 3.0.1 + + + org.springframework + spring-context + ${spring.version} + + + commons-logging + commons-logging + + + From bb62cc0f4777d4314aeabe29a1342cca86dfaacb Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 26 Jun 2015 17:24:18 +0300 Subject: [PATCH 09/17] 5 patch --- .../ru/javawebinar/topjava/SpringMain.java | 23 ++++++++++ .../mock/MockUserMealRepositoryImpl.java | 8 ++++ .../mock/MockUserRepositoryImpl.java | 46 +++++++++++++++++++ .../topjava/service/UserServiceImpl.java | 4 ++ src/main/resources/spring/spring-app.xml | 10 ++++ 5 files changed, 91 insertions(+) create mode 100644 src/main/java/ru/javawebinar/topjava/SpringMain.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java create mode 100644 src/main/resources/spring/spring-app.xml diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java new file mode 100644 index 0000000..0638943 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -0,0 +1,23 @@ +package ru.javawebinar.topjava; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.service.UserService; + +import java.util.Arrays; + +/** + * User: gkislin + * Date: 22.08.2014 + */ +public class SpringMain { + public static void main(String[] args) { + ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + UserService userService = appCtx.getBean(UserService.class); + System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + appCtx.close(); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java new file mode 100644 index 0000000..a5b0d59 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java @@ -0,0 +1,8 @@ +package ru.javawebinar.topjava.repository.mock; + +/** + * GKislin + * 15.06.2015. + */ +public class MockUserMealRepositoryImpl { +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java new file mode 100644 index 0000000..6805a9f --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -0,0 +1,46 @@ +package ru.javawebinar.topjava.repository.mock; + +import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import java.util.Collections; +import java.util.List; + +/** + * GKislin + * 15.06.2015. + */ +public class MockUserRepositoryImpl implements UserRepository { + private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); + + @Override + public boolean delete(int id) { + LOG.info("delete " + id); + return true; + } + + @Override + public User save(User user) { + LOG.info("save " + user); + return user; + } + + @Override + public User get(int id) { + LOG.info("get " + id); + return null; + } + + @Override + public List getAll() { + LOG.info("getAll"); + return Collections.emptyList(); + } + + @Override + public User getByEmail(String email) { + LOG.info("getByEmail " + email); + return null; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index b3d674f..eb54d0b 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -15,6 +15,10 @@ public class UserServiceImpl implements UserService { private UserRepository repository; + public void setRepository(UserRepository repository) { + this.repository = repository; + } + public User save(User user) { return repository.save(user); } diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml new file mode 100644 index 0000000..7b4fa16 --- /dev/null +++ b/src/main/resources/spring/spring-app.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file From 66276561e7e3cddf0cc50038722d2f573d68f0e4 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 26 Jun 2015 17:25:28 +0300 Subject: [PATCH 10/17] 6_Add_annotation_processing patch --- .../ru/javawebinar/topjava/SpringMain.java | 13 ++++++----- .../mock/MockUserRepositoryImpl.java | 2 ++ .../topjava/service/UserServiceImpl.java | 4 ++++ .../web/user/AdminUserRestController.java | 4 ++++ .../topjava/web/user/UserRestController.java | 4 ++++ src/main/resources/spring/spring-app.xml | 23 +++++++++++++++---- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java index 0638943..edd565f 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -4,7 +4,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; -import ru.javawebinar.topjava.service.UserService; +import ru.javawebinar.topjava.web.user.AdminUserRestController; import java.util.Arrays; @@ -14,10 +14,11 @@ */ public class SpringMain { public static void main(String[] args) { - ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); - System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); - UserService userService = appCtx.getBean(UserService.class); - System.out.println(userService.save(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); - appCtx.close(); + // java 7 Automatic resource management + try(ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { + System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); + AdminUserRestController adminUserController = appCtx.getBean(AdminUserRestController.class); + System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + } } } diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java index 6805a9f..cf2649b 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -1,5 +1,6 @@ package ru.javawebinar.topjava.repository.mock; +import org.springframework.stereotype.Repository; import ru.javawebinar.topjava.LoggerWrapper; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; @@ -11,6 +12,7 @@ * GKislin * 15.06.2015. */ +@Repository public class MockUserRepositoryImpl implements UserRepository { private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index eb54d0b..7573cc8 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; import ru.javawebinar.topjava.util.exception.ExceptionUtil; @@ -11,8 +13,10 @@ * GKislin * 06.03.2015. */ +@Service public class UserServiceImpl implements UserService { + @Autowired private UserRepository repository; public void setRepository(UserRepository repository) { diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java index d2c557a..7ba6585 100644 --- a/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/user/AdminUserRestController.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.web.user; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; import ru.javawebinar.topjava.LoggerWrapper; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.service.UserService; @@ -10,9 +12,11 @@ * GKislin * 06.03.2015. */ +@Controller public class AdminUserRestController { private static final LoggerWrapper LOG = LoggerWrapper.get(UserRestController.class); + @Autowired private UserService service; public List getAll() { diff --git a/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java b/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java index 79e2e49..ff19da4 100644 --- a/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/user/UserRestController.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.web.user; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; import ru.javawebinar.topjava.LoggedUser; import ru.javawebinar.topjava.LoggerWrapper; import ru.javawebinar.topjava.model.User; @@ -9,9 +11,11 @@ * GKislin * 06.03.2015. */ +@Controller public class UserRestController { private static final LoggerWrapper LOG = LoggerWrapper.get(UserRestController.class); + @Autowired private UserService service; public User get() { diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 7b4fa16..c285b26 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -1,10 +1,23 @@ + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - + + + + + + + + + - - - \ No newline at end of file From 63ec599f5682b6e8c09b3c79cc1208aadca25b44 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 26 Jun 2015 18:01:57 +0300 Subject: [PATCH 11/17] 1_HW02 patch --- .../ru/javawebinar/topjava/LoggedUser.java | 8 +-- .../ru/javawebinar/topjava/SpringMain.java | 15 ++++- .../javawebinar/topjava/model/UserMeal.java | 31 +++++++-- .../repository/UserMealRepository.java | 25 +++++++ .../mock/MockUserMealRepositoryImpl.java | 57 +++++++++++++++- .../topjava/service/UserMealService.java | 24 +++++++ .../topjava/service/UserMealServiceImpl.java | 43 ++++++++++++ .../topjava/service/UserService.java | 12 ++-- .../topjava/service/UserServiceImpl.java | 4 -- .../{model => to}/UserMealWithExceed.java | 7 +- .../topjava/util/UserMealsUtil.java | 19 +----- .../web/meal/UserMealRestController.java | 66 ++++++++++++++++++- 12 files changed, 267 insertions(+), 44 deletions(-) rename src/main/java/ru/javawebinar/topjava/{model => to}/UserMealWithExceed.java (77%) diff --git a/src/main/java/ru/javawebinar/topjava/LoggedUser.java b/src/main/java/ru/javawebinar/topjava/LoggedUser.java index 9a51cd8..462aba7 100644 --- a/src/main/java/ru/javawebinar/topjava/LoggedUser.java +++ b/src/main/java/ru/javawebinar/topjava/LoggedUser.java @@ -1,9 +1,5 @@ package ru.javawebinar.topjava; -import ru.javawebinar.topjava.model.Role; - -import java.util.Set; - /** * GKislin * 06.03.2015. @@ -13,4 +9,8 @@ public class LoggedUser { public static int id() { return 1; } + + public static int getCaloriesPerDay() { + return 2000; + } } diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/main/java/ru/javawebinar/topjava/SpringMain.java index edd565f..7d7ce38 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/main/java/ru/javawebinar/topjava/SpringMain.java @@ -4,9 +4,15 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.to.UserMealWithExceed; +import ru.javawebinar.topjava.web.meal.UserMealRestController; import ru.javawebinar.topjava.web.user.AdminUserRestController; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.Month; import java.util.Arrays; +import java.util.List; /** * User: gkislin @@ -15,10 +21,17 @@ public class SpringMain { public static void main(String[] args) { // java 7 Automatic resource management - try(ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { + try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); AdminUserRestController adminUserController = appCtx.getBean(AdminUserRestController.class); System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); + System.out.println(); + UserMealRestController mealController = appCtx.getBean(UserMealRestController.class); + List filteredMealsWithExceeded = + mealController.getBetween( + LocalDate.of(2015, Month.MAY, 30), LocalTime.of(7, 0), + LocalDate.of(2015, Month.MAY, 31), LocalTime.of(11, 0)); + filteredMealsWithExceeded.forEach(System.out::println); } } } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java index fde5448..11eb5a1 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -6,14 +6,20 @@ * GKislin * 11.01.2015. */ -public class UserMeal { - protected final LocalDateTime dateTime; +public class UserMeal extends BaseEntity{ + protected LocalDateTime dateTime; - protected final String description; + protected String description; - protected final int calories; + protected int calories; - public UserMeal(LocalDateTime dateTime, String description, int calories) { + private User user; + + public UserMeal() { + } + + public UserMeal(Integer id, LocalDateTime dateTime, String description, int calories) { + super(id); this.dateTime = dateTime; this.description = description; this.calories = calories; @@ -30,4 +36,17 @@ public String getDescription() { public int getCalories() { return calories; } -} + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + @Override + public String toString() { + return "Meal(" + id + ", " + dateTime + ", '" + description + "', calories:" + calories + ')'; + } +} \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java index 2877486..89e7303 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java +++ b/src/main/java/ru/javawebinar/topjava/repository/UserMealRepository.java @@ -1,8 +1,33 @@ package ru.javawebinar.topjava.repository; +import ru.javawebinar.topjava.model.UserMeal; + +import ru.javawebinar.topjava.model.UserMeal; + +import java.time.LocalDateTime; +import java.util.List; + /** * GKislin * 06.03.2015. */ public interface UserMealRepository { + // null if updated meal do not belong to userId + UserMeal save(UserMeal userMeal, int userId); + + // false if meal do not belong to userId + boolean delete(int id, int userId); + + // null if meal do not belong to userId + UserMeal get(int id, int userId); + + // ORDERED DATE, TIME + List getAll(int userId); + + void deleteAll(int userId); + + List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId); + + + } diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java index a5b0d59..a348c8f 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java @@ -1,8 +1,63 @@ package ru.javawebinar.topjava.repository.mock; +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; + +import java.time.LocalDateTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + /** * GKislin * 15.06.2015. */ -public class MockUserMealRepositoryImpl { +@Repository +public class MockUserMealRepositoryImpl implements UserMealRepository { + private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); + private static final List mealList = Arrays.asList( + new UserMeal(1, LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500), + new UserMeal(2, LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000), + new UserMeal(3, LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500), + new UserMeal(4, LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500), + new UserMeal(5, LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000), + new UserMeal(6, LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) + ); + + @Override + public boolean delete(int id, int userId) { + LOG.info("delete {} for User {}", id, userId); + return true; + } + + @Override + public UserMeal save(UserMeal meal, int userId) { + LOG.info("save {} for User {}", meal, userId); + return meal; + } + + @Override + public UserMeal get(int id, int userId) { + LOG.info("get {} for User {}", id, userId); + return null; + } + + @Override + public List getAll(int userId) { + LOG.info("getAll for User {}", userId); + return mealList; + } + + @Override + public void deleteAll(int userId) { + LOG.info("deleteAll for User {}", userId); + } + + @Override + public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { + LOG.info("getBetween {} - {} for User {}", startDate, endDate, userId); + return mealList; + } } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java index b17fec8..9507e1c 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserMealService.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealService.java @@ -1,8 +1,32 @@ package ru.javawebinar.topjava.service; +import ru.javawebinar.topjava.model.UserMeal; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + /** * GKislin * 15.06.2015. */ public interface UserMealService { + UserMeal get(int id, int userId); + + void delete(int id, int userId); + + default List getBetweenDates(LocalDate startDate, LocalDate endDate, int userId) { + return getBetweenDateTimes(LocalDateTime.of(startDate, LocalTime.MIN), LocalDateTime.of(endDate, LocalTime.MAX), userId); + } + + List getBetweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId); + + List getAll(int userId); + + void deleteAll(int userId); + + UserMeal update(UserMeal meal, int userId); + + UserMeal save(UserMeal meal, int userId); } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java index 5730b8b..f8e2384 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserMealServiceImpl.java @@ -1,13 +1,56 @@ package ru.javawebinar.topjava.service; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; +import ru.javawebinar.topjava.util.exception.ExceptionUtil; + +import java.time.LocalDateTime; +import java.util.List; /** * GKislin * 06.03.2015. */ +@Service public class UserMealServiceImpl implements UserMealService { + @Autowired private UserMealRepository repository; + @Override + public UserMeal get(int id, int userId) { + return ExceptionUtil.check(repository.get(id, userId), id); + } + + @Override + public void delete(int id, int userId) { + ExceptionUtil.check(repository.delete(id, userId), id); + } + + @Override + public List getBetweenDateTimes(LocalDateTime startDate, LocalDateTime endDate, int userId) { + return repository.getBetween(startDate, endDate, userId); + } + + @Override + public List getAll(int userId) { + return repository.getAll(userId); + } + + @Override + public void deleteAll(int userId) { + repository.deleteAll(userId); + } + + @Override + public UserMeal update(UserMeal meal, int userId) { + return ExceptionUtil.check(repository.save(meal, userId), meal.getId()); + } + + @Override + public UserMeal save(UserMeal meal, int userId) { + return repository.save(meal, userId); + } } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserService.java b/src/main/java/ru/javawebinar/topjava/service/UserService.java index 9f8d9d5..1d8dab0 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserService.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserService.java @@ -12,15 +12,15 @@ */ public interface UserService { - public User save(User user); + User save(User user); - public void delete(int id) throws NotFoundException; + void delete(int id) throws NotFoundException; - public User get(int id) throws NotFoundException; + User get(int id) throws NotFoundException; - public User getByEmail(String email) throws NotFoundException; + User getByEmail(String email) throws NotFoundException; - public List getAll(); + List getAll(); - public void update(User user) throws NotFoundException; + void update(User user) throws NotFoundException; } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index 7573cc8..1a4ae71 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -19,10 +19,6 @@ public class UserServiceImpl implements UserService { @Autowired private UserRepository repository; - public void setRepository(UserRepository repository) { - this.repository = repository; - } - public User save(User user) { return repository.save(user); } diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java b/src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java similarity index 77% rename from src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java rename to src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java index 66c3569..f2773a1 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMealWithExceed.java +++ b/src/main/java/ru/javawebinar/topjava/to/UserMealWithExceed.java @@ -1,4 +1,4 @@ -package ru.javawebinar.topjava.model; +package ru.javawebinar.topjava.to; import java.time.LocalDateTime; @@ -7,6 +7,8 @@ * 11.01.2015. */ public class UserMealWithExceed { + protected final Integer id; + protected final LocalDateTime dateTime; protected final String description; @@ -15,7 +17,8 @@ public class UserMealWithExceed { protected final boolean exceed; - public UserMealWithExceed(LocalDateTime dateTime, String description, int calories, boolean exceed) { + public UserMealWithExceed(Integer id, LocalDateTime dateTime, String description, int calories, boolean exceed) { + this.id = id; this.dateTime = dateTime; this.description = description; this.calories = calories; diff --git a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java index a73ab79..969515b 100644 --- a/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java +++ b/src/main/java/ru/javawebinar/topjava/util/UserMealsUtil.java @@ -1,13 +1,10 @@ package ru.javawebinar.topjava.util; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.model.UserMealWithExceed; +import ru.javawebinar.topjava.to.UserMealWithExceed; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.LocalTime; -import java.time.Month; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -17,18 +14,6 @@ * 31.05.2015. */ public class UserMealsUtil { - public static void main(String[] args) { - List mealList = Arrays.asList( - new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500), - new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000), - new UserMeal(LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500), - new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500), - new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000), - new UserMeal(LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) - ); - List filteredMealsWithExceeded = getFilteredMealsWithExceeded(mealList, LocalTime.of(7, 0), LocalTime.of(12, 0), 2000); - filteredMealsWithExceeded.forEach(System.out::println); - } public static List getFilteredMealsWithExceeded(List mealList, LocalTime startTime, LocalTime endTime, int caloriesPerDay) { Map caloriesSumByDate = mealList.stream().collect(Collectors.groupingBy(um -> um.getDateTime().toLocalDate(), @@ -36,7 +21,7 @@ public static List getFilteredMealsWithExceeded(ListTimeUtil.isBetween(um.getDateTime().toLocalTime(), startTime, endTime)) - .map(um->new UserMealWithExceed(um.getDateTime(), um.getDescription(), um.getCalories(), + .map(um->new UserMealWithExceed(um.getId(), um.getDateTime(), um.getDescription(), um.getCalories(), caloriesSumByDate.get(um.getDateTime().toLocalDate())> caloriesPerDay)) .collect(Collectors.toList()); } diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java index 51e64a2..3a0e126 100644 --- a/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java +++ b/src/main/java/ru/javawebinar/topjava/web/meal/UserMealRestController.java @@ -1,12 +1,72 @@ package ru.javawebinar.topjava.web.meal; -import ru.javawebinar.topjava.service.UserMealServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import ru.javawebinar.topjava.LoggedUser; +import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.service.UserMealService; +import ru.javawebinar.topjava.to.UserMealWithExceed; +import ru.javawebinar.topjava.util.UserMealsUtil; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; /** * GKislin * 06.03.2015. */ +@Controller public class UserMealRestController { - private UserMealServiceImpl service; + private static final LoggerWrapper LOG = LoggerWrapper.get(UserMealRestController.class); + + @Autowired + private UserMealService service; + + public UserMeal get(int id) { + int userId = LoggedUser.id(); + LOG.info("get meal {} for User {}", id, userId); + return service.get(id, userId); + } + + public void delete(int id) { + int userId = LoggedUser.id(); + LOG.info("delete meal {} for User {}", id, userId); + service.delete(id, userId); + } + + public List getAll() { + int userId = LoggedUser.id(); + LOG.info("getAll for User {}", userId); + return UserMealsUtil.getFilteredMealsWithExceeded( + service.getAll(userId), LocalTime.MIN, LocalTime.MAX, LoggedUser.getCaloriesPerDay() + ); + } + + public void deleteAll() { + int userId = LoggedUser.id(); + LOG.info("deleteAll for User {}", userId); + service.deleteAll(userId); + } + + public void update(UserMeal meal) { + int userId = LoggedUser.id(); + LOG.info("update {} for User {}", meal, userId); + service.update(meal, userId); + } + + public UserMeal create(UserMeal meal) { + int userId = LoggedUser.id(); + LOG.info("create {} for User {}", meal, userId); + return service.save(meal, userId); + } -} + public List getBetween(LocalDate startDate, LocalTime startTime, LocalDate endDate, LocalTime endTime) { + int userId = LoggedUser.id(); + LOG.info("getBetween dates {} - {} for time {} - {} for User {}", startDate, endDate, startTime, endTime, userId); + return UserMealsUtil.getFilteredMealsWithExceeded( + service.getBetweenDates(startDate, endDate, userId), startTime, endTime, LoggedUser.getCaloriesPerDay() + ); + } +} \ No newline at end of file From 1f70d633115df63a1b7e7ce31f207ad2efb90f1e Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Sat, 27 Jun 2015 18:10:12 +0300 Subject: [PATCH 12/17] 2_ patch --- .../repository/mock/MockUserRepositoryImpl.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java index cf2649b..fac9643 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -5,6 +5,8 @@ import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; import java.util.Collections; import java.util.List; @@ -16,6 +18,16 @@ public class MockUserRepositoryImpl implements UserRepository { private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); + @PostConstruct + public void postConstruct() { + LOG.info("+++ PostConstruct"); + } + + @PreDestroy + public void preDestroy() { + LOG.info("+++ PreDestroy"); + } + @Override public boolean delete(int id) { LOG.info("delete " + id); From 4e9328cc395d298693e13de2cc8355a13d772ee5 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Sat, 27 Jun 2015 18:36:27 +0300 Subject: [PATCH 13/17] 3_Add_Junit patch --- pom.xml | 11 ++++++ .../ru/javawebinar/topjava/LoggerWrapper.java | 2 +- .../mock/MockUserMealRepositoryImpl.java | 0 .../mock/MockUserRepositoryImpl.java | 2 +- .../topjava/web/mock/UserAdminMockTest.java | 38 +++++++++++++++++++ 5 files changed, 51 insertions(+), 2 deletions(-) rename src/{main => test}/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java (100%) rename src/{main => test}/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java (98%) create mode 100644 src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java diff --git a/pom.xml b/pom.xml index ae34acc..4d8c277 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,9 @@ 1.1.2 1.7.7 + + + 4.12 @@ -87,6 +90,14 @@ + + + + junit + junit + ${junit.version} + test + diff --git a/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java index 642bb6c..8ab6153 100644 --- a/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java +++ b/src/main/java/ru/javawebinar/topjava/LoggerWrapper.java @@ -72,7 +72,7 @@ public UnsupportedOperationException getUnsupportedOperationException(String msg } public NotFoundException getNotFoundException(String reason) { - logger.error("No data found"); + logger.error(reason); return new NotFoundException(reason); } } \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java similarity index 100% rename from src/main/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java rename to src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java diff --git a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java similarity index 98% rename from src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java rename to src/test/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java index fac9643..0935c96 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java +++ b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserRepositoryImpl.java @@ -31,7 +31,7 @@ public void preDestroy() { @Override public boolean delete(int id) { LOG.info("delete " + id); - return true; + return id != 0; } @Override diff --git a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java new file mode 100644 index 0000000..80dfc97 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java @@ -0,0 +1,38 @@ +package ru.javawebinar.topjava.web.mock; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import ru.javawebinar.topjava.util.exception.NotFoundException; +import ru.javawebinar.topjava.web.user.AdminUserRestController; + +import java.util.Arrays; + +public class UserAdminMockTest { + private static ConfigurableApplicationContext appCtx; + private static AdminUserRestController controller; + + @BeforeClass + public static void beforeClass() { + appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + System.out.println("\n" + Arrays.toString(appCtx.getBeanDefinitionNames()) + "\n"); + controller = appCtx.getBean(AdminUserRestController.class); + } + + @AfterClass + public static void afterClass() { + appCtx.close(); + } + + @Test + public void testDelete() throws Exception { + controller.delete(7); + } + + @Test(expected = NotFoundException.class) + public void testDeleteNotFound() throws Exception { + controller.delete(0); + } +} \ No newline at end of file From be4ab934a541e515101a301a6e32c6e8a73b62ae Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Sun, 28 Jun 2015 18:55:26 +0300 Subject: [PATCH 14/17] 3_final patch --- pom.xml | 19 ++++ .../javawebinar/topjava/model/BaseEntity.java | 21 +++++ .../ru/javawebinar/topjava/model/User.java | 22 +++-- .../jdbc/JdbcUserMealRepositoryImpl.java | 47 ++++++++++ .../jdbc/JdbcUserRepositoryImpl.java | 87 ++++++++++++++++++ .../javawebinar/topjava/util/DbPopulator.java | 28 ++++++ src/main/resources/db/initDB.sql | 24 +++++ src/main/resources/db/populateDB.sql | 13 +++ src/main/resources/db/postgres.properties | 10 ++ src/main/resources/spring/spring-app.xml | 2 +- src/main/resources/spring/spring-db.xml | 29 ++++++ .../ru/javawebinar/topjava/MealTestData.java | 14 +++ .../ru/javawebinar/topjava/UserTestData.java | 74 +++++++++++++++ .../topjava/matcher/ModelMatcher.java | 34 +++++++ .../topjava/service/UserServiceTest.java | 91 +++++++++++++++++++ .../web/mock/UserAdminSpringMockTest.java | 38 ++++++++ src/test/resources/logback-test.xml | 21 +++++ 17 files changed, 566 insertions(+), 8 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/util/DbPopulator.java create mode 100644 src/main/resources/db/initDB.sql create mode 100644 src/main/resources/db/populateDB.sql create mode 100644 src/main/resources/db/postgres.properties create mode 100644 src/main/resources/spring/spring-db.xml create mode 100644 src/test/java/ru/javawebinar/topjava/MealTestData.java create mode 100644 src/test/java/ru/javawebinar/topjava/UserTestData.java create mode 100644 src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java create mode 100644 src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java create mode 100644 src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java create mode 100644 src/test/resources/logback-test.xml diff --git a/pom.xml b/pom.xml index 4d8c277..aa5b733 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,18 @@ + + + org.postgresql + postgresql + 9.4-1201-jdbc41 + + + org.springframework + spring-jdbc + ${spring.version} + + junit @@ -98,6 +110,13 @@ ${junit.version} test + + org.springframework + spring-test + ${spring.version} + test + + diff --git a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java index aca94ed..9a82d14 100644 --- a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java +++ b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java @@ -1,10 +1,15 @@ package ru.javawebinar.topjava.model; +import ru.javawebinar.topjava.LoggerWrapper; + /** * User: gkislin * Date: 22.08.2014 */ public class BaseEntity { + protected static final LoggerWrapper LOG = LoggerWrapper.get(BaseEntity.class); + + public static final int START_SEQ = 100000; protected Integer id; @@ -26,4 +31,20 @@ public Integer getId() { public boolean isNew() { return (this.id == null); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BaseEntity that = (BaseEntity) o; + if (id == null || that.id == null) { + throw LOG.getIllegalStateException("Equals '" + this + "' and '" + that + "' with null id"); + } + return id.equals(that.id); + } + + @Override + public int hashCode() { + return (id == null) ? 0 : id; + } } diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java index 9f0e293..afe79ab 100644 --- a/src/main/java/ru/javawebinar/topjava/model/User.java +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -10,25 +10,33 @@ */ public class User extends NamedEntity { - private String email; + protected String email; - private String password; + protected String password; - private boolean enabled = true; + protected boolean enabled = true; - private Date registered; + protected Date registered; - private Set roles; + protected Set roles; public User() { } public User(Integer id, String name, String email, String password, Role role, Role... roles) { + this(id, name, email, password, true, EnumSet.of(role, roles)); + } + + public User(User u) { + this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.isEnabled(), u.getRoles()); + } + + public User(Integer id, String name, String email, String password, boolean enabled, Set roles) { super(id, name); this.email = email; this.password = password; - this.enabled = true; - this.roles = EnumSet.of(role, roles); + this.enabled = enabled; + this.roles = roles; } public String getEmail() { diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java new file mode 100644 index 0000000..dd70854 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.repository.jdbc; + +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * User: gkislin + * Date: 26.08.2014 + */ + +@Repository +public class JdbcUserMealRepositoryImpl implements UserMealRepository { + + @Override + public UserMeal save(UserMeal UserMeal, int userId) { + return null; + } + + @Override + public boolean delete(int id, int userId) { + return false; + } + + @Override + public UserMeal get(int id, int userId) { + return null; + } + + @Override + public List getAll(int userId) { + return null; + } + + @Override + public void deleteAll(int userId) { + + } + + @Override + public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { + return null; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java new file mode 100644 index 0000000..35120f2 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepositoryImpl.java @@ -0,0 +1,87 @@ +package ru.javawebinar.topjava.repository.jdbc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import javax.sql.DataSource; +import java.util.List; + +/** + * User: gkislin + * Date: 26.08.2014 + */ + +@Repository +public class JdbcUserRepositoryImpl implements UserRepository { + + private static final BeanPropertyRowMapper ROW_MAPPER = BeanPropertyRowMapper.newInstance(User.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertUser; + + @Autowired + public JdbcUserRepositoryImpl(DataSource dataSource) { + this.insertUser = new SimpleJdbcInsert(dataSource) + .withTableName("USERS") + .usingGeneratedKeyColumns("id"); + } + + @Override + public User save(User user) { + MapSqlParameterSource map = new MapSqlParameterSource() + .addValue("id", user.getId()) + .addValue("name", user.getName()) + .addValue("email", user.getEmail()) + .addValue("password", user.getPassword()) + .addValue("registered", user.getRegistered()) + .addValue("enabled", user.isEnabled()); + + if (user.isNew()) { + Number newKey = insertUser.executeAndReturnKey(map); + user.setId(newKey.intValue()); + } else { + namedParameterJdbcTemplate.update( + "UPDATE users SET name=:name, email=:email, password=:password, " + + "registered=:registered, enabled=:enabled WHERE id=:id", map); + } + return user; + } + + @Override + public boolean delete(int id) { + return jdbcTemplate.update("DELETE FROM users WHERE id=?", id) != 0; + } + + @Override + public User get(int id) { + return jdbcTemplate.queryForObject( + "SELECT id, name, email, password, registered, enabled FROM users WHERE id=?", + ROW_MAPPER, id); + } + + @Override + public User getByEmail(String email) { + return jdbcTemplate.queryForObject( + "SELECT id, name, email, password, registered, enabled FROM users WHERE email=?", + ROW_MAPPER, email); + } + + @Override + public List getAll() { + return jdbcTemplate.query( + "SELECT id, name, email, password, registered, enabled FROM users ORDER BY name, email", + ROW_MAPPER); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java b/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java new file mode 100644 index 0000000..8d4a6cc --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java @@ -0,0 +1,28 @@ +package ru.javawebinar.topjava.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +import javax.sql.DataSource; + +/** + * User: gkislin + * Date: 26.08.2014 + */ +public class DbPopulator extends ResourceDatabasePopulator { + private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader(); + + @Autowired + private DataSource dataSource; + + public DbPopulator(String scriptLocation) { + super(RESOURCE_LOADER.getResource(scriptLocation)); + } + + public void execute() { + DatabasePopulatorUtils.execute(this, dataSource); + } +} diff --git a/src/main/resources/db/initDB.sql b/src/main/resources/db/initDB.sql new file mode 100644 index 0000000..90ceea8 --- /dev/null +++ b/src/main/resources/db/initDB.sql @@ -0,0 +1,24 @@ +DROP TABLE IF EXISTS USER_ROLES; +DROP TABLE IF EXISTS USERS; +DROP SEQUENCE IF EXISTS GLOBAL_SEQ; + +CREATE SEQUENCE GLOBAL_SEQ START 100000; + +CREATE TABLE USERS +( + id INTEGER PRIMARY KEY DEFAULT nextval('GLOBAL_SEQ'), + name VARCHAR, + email VARCHAR NOT NULL, + password VARCHAR NOT NULL, + registered TIMESTAMP DEFAULT now(), + enabled BOOL DEFAULT TRUE +); +CREATE UNIQUE INDEX unique_email ON USERS (email); + +CREATE TABLE USER_ROLES +( + user_id INTEGER NOT NULL, + role VARCHAR, + CONSTRAINT user_roles_idx UNIQUE (user_id, role), + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE +); diff --git a/src/main/resources/db/populateDB.sql b/src/main/resources/db/populateDB.sql new file mode 100644 index 0000000..d7439bb --- /dev/null +++ b/src/main/resources/db/populateDB.sql @@ -0,0 +1,13 @@ +DELETE FROM user_roles; +DELETE FROM users; +ALTER SEQUENCE global_seq RESTART WITH 100000; + +-- password +INSERT INTO users (name, email, password) +VALUES ('User', 'user@yandex.ru', 'password'); +-- admin +INSERT INTO users (name, email, password) +VALUES ('Admin', 'admin@gmail.com', 'admin'); + +INSERT INTO user_roles (role, user_id) VALUES ('ROLE_USER', 100000); +INSERT INTO user_roles (role, user_id) VALUES ('ROLE_ADMIN', 100001); diff --git a/src/main/resources/db/postgres.properties b/src/main/resources/db/postgres.properties new file mode 100644 index 0000000..47bcf62 --- /dev/null +++ b/src/main/resources/db/postgres.properties @@ -0,0 +1,10 @@ +#database.url=jdbc:postgresql://ec2-54-217-202-110.eu-west-1.compute.amazonaws.com:5432/dehm6lvm8bink0?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory +#database.username=wegxlfzjjgxaxy +#database.password=SSQyKKE_e93kiUCR-ehzMcKCxZ + +database.init=true +database.driverClassName=org.postgresql.Driver + +database.url=jdbc:postgresql://localhost:5432/topjava +database.username=test_user +database.password=test_user diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index c285b26..756c97f 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -14,7 +14,7 @@ - + diff --git a/src/main/resources/spring/spring-db.xml b/src/main/resources/spring/spring-db.xml new file mode 100644 index 0000000..ac0b25c --- /dev/null +++ b/src/main/resources/spring/spring-db.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/ru/javawebinar/topjava/MealTestData.java b/src/test/java/ru/javawebinar/topjava/MealTestData.java new file mode 100644 index 0000000..ac44047 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/MealTestData.java @@ -0,0 +1,14 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.matcher.ModelMatcher; +import ru.javawebinar.topjava.model.UserMeal; + +/** + * GKislin + * 13.03.2015. + */ +public class MealTestData { + + public static final ModelMatcher MATCHER = new ModelMatcher<>(UserMeal::toString); + +} diff --git a/src/test/java/ru/javawebinar/topjava/UserTestData.java b/src/test/java/ru/javawebinar/topjava/UserTestData.java new file mode 100644 index 0000000..7f5489b --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/UserTestData.java @@ -0,0 +1,74 @@ +package ru.javawebinar.topjava; + +import ru.javawebinar.topjava.matcher.ModelMatcher; +import ru.javawebinar.topjava.model.BaseEntity; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; + +import java.util.EnumSet; +import java.util.Objects; +import java.util.Set; + +/** + * User: gkislin + * Date: 26.08.2014 + */ +public class UserTestData { + + public static final TestUser USER = new TestUser(BaseEntity.START_SEQ, "User", "user@yandex.ru", "password", true, Role.ROLE_USER); + public static final User ADMIN = new TestUser(BaseEntity.START_SEQ + 1, "Admin", "admin@gmail.com", "admin", true, Role.ROLE_ADMIN); + + public static class TestUser extends User { + + public TestUser(User u) { + this(u.getId(), u.getName(), u.getEmail(), u.getPassword(), u.isEnabled(), u.getRoles()); + } + + public TestUser(String name, String email, String password, Role role, Role... roles) { + this(null, name, email, password, true, EnumSet.of(role, roles)); + } + + public TestUser(Integer id, String name, String email, String password, boolean enabled, Role role, Role... roles) { + this(id, name, email, password, enabled, EnumSet.of(role, roles)); + } + + public TestUser(Integer id, String name, String email, String password, boolean enabled, Set roles) { + super(id, name, email, password, enabled, roles); + } + + public User asUser() { + return new User(this); + } + + @Override + public String toString() { + return "User (" + + "id=" + id + + ", email=" + email + + ", name=" + name + + ", enabled=" + enabled + + ", password=" + password + + ", authorities=" + roles + + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TestUser that = (TestUser) o; + + return Objects.equals(this.password, that.password) + && Objects.equals(this.id, that.id) + && Objects.equals(this.name, that.name) + && Objects.equals(this.email, that.email) + && Objects.equals(this.enabled, that.enabled); +// && Objects.equals(this.roles, that.roles); + } + } + + public static final ModelMatcher MATCHER = new ModelMatcher<>( + u -> ((u instanceof TestUser) ? (TestUser) u : new TestUser(u))); + +} diff --git a/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java b/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java new file mode 100644 index 0000000..b92c2e4 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/matcher/ModelMatcher.java @@ -0,0 +1,34 @@ +package ru.javawebinar.topjava.matcher; + +import org.junit.Assert; + +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * GKislin + * 06.01.2015. + * + * @param : entity + * @param : testEntity, converter result for compare + */ +public class ModelMatcher { + protected Function entityConverter; + + public ModelMatcher(Function entityConverter) { + this.entityConverter = entityConverter; + } + + public void assertEquals(T expected, T actual) { + Assert.assertEquals(entityConverter.apply(expected), entityConverter.apply(actual)); + } + + public void assertListEquals(List expected, List actual) { + Assert.assertEquals(map(expected, entityConverter), map(actual, entityConverter)); + } + + public static List map(List list, Function converter) { + return list.stream().map(converter).collect(Collectors.toList()); + } +} diff --git a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java new file mode 100644 index 0000000..dd8b93b --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java @@ -0,0 +1,91 @@ +package ru.javawebinar.topjava.service; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import ru.javawebinar.topjava.UserTestData.*; +import ru.javawebinar.topjava.model.BaseEntity; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.DbPopulator; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static ru.javawebinar.topjava.UserTestData.*; + +@ContextConfiguration({ + "classpath:spring/spring-app.xml", + "classpath:spring/spring-db.xml" +}) +@RunWith(SpringJUnit4ClassRunner.class) +public class UserServiceTest { + + @Autowired + protected UserService service; + + @Autowired + private DbPopulator dbPopulator; + + @Before + public void setUp() throws Exception { + dbPopulator.execute(); + } + + @Test + public void testSave() throws Exception { + TestUser tu = new TestUser("New", "new@gmail.com", "newPass", Role.ROLE_USER); + User created = service.save(tu.asUser()); + tu.setId(created.getId()); + MATCHER.assertListEquals(Arrays.asList(ADMIN, tu, USER), service.getAll()); + } + + @Test(expected = DataAccessException.class) + public void testDuplicateMailSave() throws Exception { + service.save(new TestUser("Duplicate", "user@yandex.ru", "newPass", Role.ROLE_USER).asUser()); + } + + @Test + public void testDelete() throws Exception { + service.delete(BaseEntity.START_SEQ); + MATCHER.assertListEquals(Collections.singletonList(ADMIN), service.getAll()); + } + + @Test(expected = NotFoundException.class) + public void testNotFoundDelete() throws Exception { + service.delete(1); + } + + @Test + public void testGet() throws Exception { + User user = service.get(BaseEntity.START_SEQ); + MATCHER.assertEquals(USER, user); + } + + @Test + public void testGetByEmail() throws Exception { + User user = service.getByEmail("user@yandex.ru"); + MATCHER.assertEquals(USER, user); + + } + + @Test + public void testGetAll() throws Exception { + List all = service.getAll(); + MATCHER.assertListEquals(Arrays.asList(ADMIN, USER), all); + } + + @Test + public void testUpdate() throws Exception { + TestUser updated = new TestUser(USER); + updated.setName("UpdatedName"); + service.update(updated.asUser()); + MATCHER.assertEquals(updated, service.get(BaseEntity.START_SEQ)); + } +} \ No newline at end of file diff --git a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java new file mode 100644 index 0000000..54916d6 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java @@ -0,0 +1,38 @@ +package ru.javawebinar.topjava.web.mock; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import ru.javawebinar.topjava.model.Role; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.util.exception.NotFoundException; +import ru.javawebinar.topjava.web.user.AdminUserRestController; + +/** + * GKislin + * 13.03.2015. + */ +@ContextConfiguration("classpath:spring/spring-app.xml") +@RunWith(SpringJUnit4ClassRunner.class) +public class UserAdminSpringMockTest { + + @Autowired + private AdminUserRestController controller; + + @Test + public void testCreate() throws Exception { + controller.create(new User(null, "Name", "email@ya.ru", "password", Role.ROLE_USER)); + } + + @Test + public void testDelete() throws Exception { + controller.delete(7); + } + + @Test(expected = NotFoundException.class) + public void testDeleteNotFound() throws Exception { + controller.delete(0); + } +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..80c3802 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,21 @@ + + + + true + + + + + UTF-8 + %-5level %logger{0} - %msg%n + + + + + + + + + + + \ No newline at end of file From ea660d533705f0d9ac01432480e257e3c116227e Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Wed, 8 Jul 2015 15:09:09 +0300 Subject: [PATCH 15/17] 1 --- .../jdbc/JdbcUserMealRepositoryImpl.java | 73 +++++++++++--- src/main/resources/db/initDB.sql | 24 +++-- src/main/resources/db/populateDB.sql | 9 ++ .../ru/javawebinar/topjava/MealTestData.java | 29 +++++- .../ru/javawebinar/topjava/UserTestData.java | 4 + .../mock/MockUserMealRepositoryImpl.java | 15 +-- .../topjava/service/UserMealServiceTest.java | 99 +++++++++++++++++++ .../topjava/service/UserServiceTest.java | 7 +- 8 files changed, 225 insertions(+), 35 deletions(-) create mode 100644 src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java index dd70854..b8c0e7d 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java @@ -1,9 +1,19 @@ package ru.javawebinar.topjava.repository.jdbc; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.support.DataAccessUtils; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.stereotype.Repository; +import org.springframework.util.CollectionUtils; import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; +import javax.sql.DataSource; +import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.List; @@ -15,33 +25,74 @@ @Repository public class JdbcUserMealRepositoryImpl implements UserMealRepository { + private static final RowMapper ROW_MAPPER = + (rs, rowNum) -> + new UserMeal(rs.getInt("id"), rs.getTimestamp("dateTime").toLocalDateTime(), rs.getString("description"), rs.getInt("calories")); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert insertUserMeal; + + @Autowired + public JdbcUserMealRepositoryImpl(DataSource dataSource) { + this.insertUserMeal = new SimpleJdbcInsert(dataSource) + .withTableName("meals") + .usingGeneratedKeyColumns("id"); + } + @Override - public UserMeal save(UserMeal UserMeal, int userId) { - return null; + public UserMeal save(UserMeal userMeal, int userId) { + MapSqlParameterSource map = new MapSqlParameterSource() + .addValue("id", userMeal.getId()) + .addValue("description", userMeal.getDescription()) + .addValue("calories", userMeal.getCalories()) + .addValue("datetime", Timestamp.valueOf(userMeal.getDateTime())) + .addValue("user_id", userId); + + if (userMeal.isNew()) { + Number newId = insertUserMeal.executeAndReturnKey(map); + userMeal.setId(newId.intValue()); + } else { + if (namedParameterJdbcTemplate.update( + "UPDATE meals SET description=:description, calories=:calories, datetime=:datetime " + + " WHERE id=:id AND user_id=:user_id", map) == 0) { + return null; + } + } + return userMeal; } @Override public boolean delete(int id, int userId) { - return false; + return jdbcTemplate.update("DELETE FROM meals WHERE id=? AND user_id=?", id, userId) != 0; } @Override - public UserMeal get(int id, int userId) { - return null; + public void deleteAll(int userId) { + jdbcTemplate.update("DELETE FROM meals WHERE user_id=?", userId); } @Override - public List getAll(int userId) { - return null; + public UserMeal get(int id, int userId) { + List userMeals = jdbcTemplate.query( + "SELECT * FROM meals WHERE id = ? AND user_id = ?", ROW_MAPPER, id, userId); + return CollectionUtils.isEmpty(userMeals) ? null : DataAccessUtils.requiredSingleResult(userMeals); } @Override - public void deleteAll(int userId) { - + public List getAll(int userId) { + return jdbcTemplate.query( + "SELECT * FROM meals WHERE user_id=? ORDER BY dateTime DESC", ROW_MAPPER, userId); } @Override public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { - return null; + return jdbcTemplate.query( + "SELECT * FROM meals WHERE user_id=? AND dateTime BETWEEN ? AND ? ORDER BY dateTime DESC", + ROW_MAPPER, userId, Timestamp.valueOf(startDate), Timestamp.valueOf(endDate)); } -} +} \ No newline at end of file diff --git a/src/main/resources/db/initDB.sql b/src/main/resources/db/initDB.sql index 90ceea8..a2fde81 100644 --- a/src/main/resources/db/initDB.sql +++ b/src/main/resources/db/initDB.sql @@ -1,12 +1,13 @@ -DROP TABLE IF EXISTS USER_ROLES; -DROP TABLE IF EXISTS USERS; -DROP SEQUENCE IF EXISTS GLOBAL_SEQ; +DROP TABLE IF EXISTS user_roles; +DROP TABLE IF EXISTS meals; +DROP TABLE IF EXISTS users; +DROP SEQUENCE IF EXISTS global_seq; -CREATE SEQUENCE GLOBAL_SEQ START 100000; +CREATE SEQUENCE global_seq START 100000; -CREATE TABLE USERS +CREATE TABLE users ( - id INTEGER PRIMARY KEY DEFAULT nextval('GLOBAL_SEQ'), + id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'), name VARCHAR, email VARCHAR NOT NULL, password VARCHAR NOT NULL, @@ -15,10 +16,19 @@ CREATE TABLE USERS ); CREATE UNIQUE INDEX unique_email ON USERS (email); -CREATE TABLE USER_ROLES +CREATE TABLE user_roles ( user_id INTEGER NOT NULL, role VARCHAR, CONSTRAINT user_roles_idx UNIQUE (user_id, role), FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ); + +CREATE TABLE meals ( + id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'), + user_id INTEGER NOT NULL, + datetime TIMESTAMP, + description TEXT, + calories INT, + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE +); diff --git a/src/main/resources/db/populateDB.sql b/src/main/resources/db/populateDB.sql index d7439bb..af9099a 100644 --- a/src/main/resources/db/populateDB.sql +++ b/src/main/resources/db/populateDB.sql @@ -1,4 +1,5 @@ DELETE FROM user_roles; +DELETE FROM meals; DELETE FROM users; ALTER SEQUENCE global_seq RESTART WITH 100000; @@ -11,3 +12,11 @@ VALUES ('Admin', 'admin@gmail.com', 'admin'); INSERT INTO user_roles (role, user_id) VALUES ('ROLE_USER', 100000); INSERT INTO user_roles (role, user_id) VALUES ('ROLE_ADMIN', 100001); + +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 10:00:00', 'Завтрак', 500, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 13:00:00', 'Обед', 1000, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-30 20:00:00', 'Ужин', 500, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 10:00:00', 'Завтрак', 500, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 13:00:00', 'Обед', 1000, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-05-31 20:00:00', 'Ужин', 510, 100000); +INSERT INTO meals (datetime, description, calories, user_id) VALUES ('2015-06-01 14:00:00', 'Админ-Ланч', 2001, 100001); diff --git a/src/test/java/ru/javawebinar/topjava/MealTestData.java b/src/test/java/ru/javawebinar/topjava/MealTestData.java index ac44047..e6eddc7 100644 --- a/src/test/java/ru/javawebinar/topjava/MealTestData.java +++ b/src/test/java/ru/javawebinar/topjava/MealTestData.java @@ -3,12 +3,39 @@ import ru.javawebinar.topjava.matcher.ModelMatcher; import ru.javawebinar.topjava.model.UserMeal; +import java.time.LocalDateTime; +import java.time.Month; +import java.util.Arrays; +import java.util.List; + +import static java.time.LocalDateTime.of; +import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ; + /** * GKislin * 13.03.2015. */ public class MealTestData { + public static final int MEAL1_ID = START_SEQ + 2; + public static final int ADMIN_MEAL_ID = START_SEQ + 8; - public static final ModelMatcher MATCHER = new ModelMatcher<>(UserMeal::toString); + public static final UserMeal MEAL1 = new UserMeal(MEAL1_ID, LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500); + public static final UserMeal MEAL2 = new UserMeal(START_SEQ + 3, LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000); + public static final UserMeal MEAL3 = new UserMeal(START_SEQ + 4, LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500); + public static final UserMeal MEAL4 = new UserMeal(START_SEQ + 5, LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500); + public static final UserMeal MEAL5 = new UserMeal(START_SEQ + 6, LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000); + public static final UserMeal MEAL6 = new UserMeal(START_SEQ + 7, LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510); + public static final UserMeal ADMIN_MEAL = new UserMeal(ADMIN_MEAL_ID, LocalDateTime.of(2015, Month.JUNE, 1, 14, 0), "Админ-Ланч", 2001); + + public static final List USER_MEALS = Arrays.asList(MEAL6, MEAL5, MEAL4, MEAL3, MEAL2, MEAL1); + public static UserMeal getCreated() { + return new UserMeal(null, of(2015, Month.JUNE, 1, 18, 0), "Созданный ужин", 300); + } + + public static UserMeal getUpdated() { + return new UserMeal(MEAL1_ID, MEAL1.getDateTime(), "Обновленный завтрак", 200); + } + + public static final ModelMatcher MATCHER = new ModelMatcher<>(UserMeal::toString); } diff --git a/src/test/java/ru/javawebinar/topjava/UserTestData.java b/src/test/java/ru/javawebinar/topjava/UserTestData.java index 7f5489b..6bf625f 100644 --- a/src/test/java/ru/javawebinar/topjava/UserTestData.java +++ b/src/test/java/ru/javawebinar/topjava/UserTestData.java @@ -9,11 +9,15 @@ import java.util.Objects; import java.util.Set; +import static ru.javawebinar.topjava.model.BaseEntity.START_SEQ; + /** * User: gkislin * Date: 26.08.2014 */ public class UserTestData { + public static final int USER_ID = START_SEQ; + public static final int ADMIN_ID = START_SEQ + 1; public static final TestUser USER = new TestUser(BaseEntity.START_SEQ, "User", "user@yandex.ru", "password", true, Role.ROLE_USER); public static final User ADMIN = new TestUser(BaseEntity.START_SEQ + 1, "Admin", "admin@gmail.com", "admin", true, Role.ROLE_ADMIN); diff --git a/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java index a348c8f..b97a31d 100644 --- a/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java +++ b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java @@ -2,12 +2,11 @@ import org.springframework.stereotype.Repository; import ru.javawebinar.topjava.LoggerWrapper; +import ru.javawebinar.topjava.MealTestData; import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; import java.time.LocalDateTime; -import java.time.Month; -import java.util.Arrays; import java.util.List; /** @@ -17,14 +16,6 @@ @Repository public class MockUserMealRepositoryImpl implements UserMealRepository { private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); - private static final List mealList = Arrays.asList( - new UserMeal(1, LocalDateTime.of(2015, Month.MAY, 30, 10, 0), "Завтрак", 500), - new UserMeal(2, LocalDateTime.of(2015, Month.MAY, 30, 13, 0), "Обед", 1000), - new UserMeal(3, LocalDateTime.of(2015, Month.MAY, 30, 20, 0), "Ужин", 500), - new UserMeal(4, LocalDateTime.of(2015, Month.MAY, 31, 10, 0), "Завтрак", 500), - new UserMeal(5, LocalDateTime.of(2015, Month.MAY, 31, 13, 0), "Обед", 1000), - new UserMeal(6, LocalDateTime.of(2015, Month.MAY, 31, 20, 0), "Ужин", 510) - ); @Override public boolean delete(int id, int userId) { @@ -47,7 +38,7 @@ public UserMeal get(int id, int userId) { @Override public List getAll(int userId) { LOG.info("getAll for User {}", userId); - return mealList; + return MealTestData.USER_MEALS; } @Override @@ -58,6 +49,6 @@ public void deleteAll(int userId) { @Override public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { LOG.info("getBetween {} - {} for User {}", startDate, endDate, userId); - return mealList; + return MealTestData.USER_MEALS; } } diff --git a/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java new file mode 100644 index 0000000..07ee5f9 --- /dev/null +++ b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java @@ -0,0 +1,99 @@ +package ru.javawebinar.topjava.service; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import ru.javawebinar.topjava.MealTestData; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.util.DbPopulator; +import ru.javawebinar.topjava.util.exception.NotFoundException; + +import java.time.LocalDate; +import java.time.Month; +import java.util.Arrays; + +import static ru.javawebinar.topjava.MealTestData.*; +import static ru.javawebinar.topjava.UserTestData.ADMIN_ID; +import static ru.javawebinar.topjava.UserTestData.USER_ID; + +@ContextConfiguration({ + "classpath:spring/spring-app.xml", + "classpath:spring/spring-db.xml" +}) +@RunWith(SpringJUnit4ClassRunner.class) +public class UserMealServiceTest { + + @Autowired + protected UserMealService service; + + @Autowired + private DbPopulator dbPopulator; + + @Before + public void setUp() throws Exception { + dbPopulator.execute(); + } + + @Test + public void testDelete() throws Exception { + service.delete(MealTestData.MEAL1_ID, USER_ID); + MATCHER.assertListEquals(Arrays.asList(MEAL6, MEAL5, MEAL4, MEAL3, MEAL2), service.getAll(USER_ID)); + } + + @Test(expected = NotFoundException.class) + public void testDeleteNotFound() throws Exception { + service.delete(MEAL1_ID, 1); + } + + @Test + public void testSave() throws Exception { + UserMeal created = getCreated(); + service.save(created, USER_ID); + MATCHER.assertListEquals(Arrays.asList(created, MEAL6, MEAL5, MEAL4, MEAL3, MEAL2, MEAL1), service.getAll(USER_ID)); + } + + @Test + public void testGet() throws Exception { + UserMeal actual = service.get(ADMIN_MEAL_ID, ADMIN_ID); + MATCHER.assertEquals(ADMIN_MEAL, actual); + } + + @Test(expected = NotFoundException.class) + public void testGetNotFound() throws Exception { + service.get(MEAL1_ID, ADMIN_ID); + } + + @Test + public void testUpdate() throws Exception { + UserMeal updated = getUpdated(); + service.update(updated, USER_ID); + MATCHER.assertEquals(updated, service.get(MEAL1_ID, USER_ID)); + } + + @Test(expected = NotFoundException.class) + public void testNotFoundUpdate() throws Exception { + UserMeal item = service.get(MEAL1_ID, USER_ID); + service.update(item, ADMIN_ID); + } + + @Test + public void testGetAll() throws Exception { + MATCHER.assertListEquals(USER_MEALS, service.getAll(USER_ID)); + } + + @Test + public void testGetBetween() throws Exception { + MATCHER.assertListEquals(Arrays.asList(MEAL3, MEAL2, MEAL1), + service.getBetweenDates(LocalDate.of(2015, Month.MAY, 30), LocalDate.of(2015, Month.MAY, 30), USER_ID)); + } + + @Test + public void testDeleteAll() throws Exception { + service.deleteAll(USER_ID); + Assert.assertEquals(0, service.getAll(USER_ID).size()); + } +} \ No newline at end of file diff --git a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java index dd8b93b..b8b528c 100644 --- a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java +++ b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java @@ -8,7 +8,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import ru.javawebinar.topjava.UserTestData.*; -import ru.javawebinar.topjava.model.BaseEntity; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.util.DbPopulator; @@ -53,7 +52,7 @@ public void testDuplicateMailSave() throws Exception { @Test public void testDelete() throws Exception { - service.delete(BaseEntity.START_SEQ); + service.delete(USER_ID); MATCHER.assertListEquals(Collections.singletonList(ADMIN), service.getAll()); } @@ -64,7 +63,7 @@ public void testNotFoundDelete() throws Exception { @Test public void testGet() throws Exception { - User user = service.get(BaseEntity.START_SEQ); + User user = service.get(USER_ID); MATCHER.assertEquals(USER, user); } @@ -86,6 +85,6 @@ public void testUpdate() throws Exception { TestUser updated = new TestUser(USER); updated.setName("UpdatedName"); service.update(updated.asUser()); - MATCHER.assertEquals(updated, service.get(BaseEntity.START_SEQ)); + MATCHER.assertEquals(updated, service.get(USER_ID)); } } \ No newline at end of file From 499fb222486700b9cb8d7371e57f179fd45e5fd4 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Wed, 15 Jul 2015 13:37:59 +0300 Subject: [PATCH 16/17] lesson_4 --- pom.xml | 23 +++++- .../javawebinar/topjava/model/BaseEntity.java | 7 ++ .../topjava/model/NamedEntity.java | 8 +++ .../ru/javawebinar/topjava/model/User.java | 28 ++++++++ .../javawebinar/topjava/model/UserMeal.java | 5 +- .../jpa/JpaUserMealRepositoryImpl.java | 47 ++++++++++++ .../repository/jpa/JpaUserRepositoryImpl.java | 71 +++++++++++++++++++ .../javawebinar/topjava/util/DbPopulator.java | 28 -------- src/main/resources/db/hsqldb.properties | 12 ++++ src/main/resources/db/initDB_hsql.sql | 35 +++++++++ .../db/{initDB.sql => initDB_postgres.sql} | 0 src/main/resources/db/postgres.properties | 1 + src/main/resources/spring/spring-app.xml | 2 - src/main/resources/spring/spring-db.xml | 57 ++++++++++++--- .../ru/javawebinar/topjava/SpringMain.java | 2 +- .../mock/MockUserMealRepositoryImpl.java | 2 +- .../topjava/service/UserMealServiceTest.java | 13 +--- .../topjava/service/UserServiceTest.java | 13 +--- .../topjava/web/mock/UserAdminMockTest.java | 2 +- .../web/mock/UserAdminSpringMockTest.java | 2 +- src/test/resources/spring/mock.xml | 7 ++ 21 files changed, 299 insertions(+), 66 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserRepositoryImpl.java delete mode 100644 src/main/java/ru/javawebinar/topjava/util/DbPopulator.java create mode 100644 src/main/resources/db/hsqldb.properties create mode 100644 src/main/resources/db/initDB_hsql.sql rename src/main/resources/db/{initDB.sql => initDB_postgres.sql} (100%) rename src/{main => test}/java/ru/javawebinar/topjava/SpringMain.java (95%) create mode 100644 src/test/resources/spring/mock.xml diff --git a/pom.xml b/pom.xml index aa5b733..a8a95f2 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,10 @@ 4.12 + + + 4.3.8.Final + 5.1.3.Final @@ -97,11 +101,28 @@ postgresql 9.4-1201-jdbc41 + + org.hsqldb + hsqldb + 2.3.2 + test + + org.springframework - spring-jdbc + spring-orm ${spring.version} + + org.hibernate + hibernate-entitymanager + ${hibernate.version} + + + org.hibernate + hibernate-validator + ${hibernate-validator.version} + diff --git a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java index 9a82d14..caa126f 100644 --- a/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java +++ b/src/main/java/ru/javawebinar/topjava/model/BaseEntity.java @@ -2,15 +2,22 @@ import ru.javawebinar.topjava.LoggerWrapper; +import javax.persistence.*; + /** * User: gkislin * Date: 22.08.2014 */ +@MappedSuperclass +@Access(AccessType.FIELD) public class BaseEntity { protected static final LoggerWrapper LOG = LoggerWrapper.get(BaseEntity.class); public static final int START_SEQ = 100000; + @Id + @SequenceGenerator(name = "global_seq", sequenceName = "global_seq", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "global_seq") protected Integer id; public BaseEntity() { diff --git a/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java index ca92e39..e593d37 100644 --- a/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java +++ b/src/main/java/ru/javawebinar/topjava/model/NamedEntity.java @@ -1,11 +1,19 @@ package ru.javawebinar.topjava.model; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; + /** * User: gkislin * Date: 22.08.2014 */ +@MappedSuperclass public class NamedEntity extends BaseEntity { + @NotEmpty + @Column(name = "name", nullable = false) protected String name; public NamedEntity() { diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java index afe79ab..2c32725 100644 --- a/src/main/java/ru/javawebinar/topjava/model/User.java +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -1,5 +1,10 @@ package ru.javawebinar.topjava.model; +import org.hibernate.validator.constraints.Email; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.persistence.*; import java.util.Date; import java.util.EnumSet; import java.util.Set; @@ -8,16 +13,39 @@ * User: gkislin * Date: 22.08.2014 */ +@Entity +@Table(name = "USERS", uniqueConstraints = {@UniqueConstraint(columnNames = "email", name = "unique_email")}) +@NamedQueries({ + @NamedQuery(name = User.DELETE, query = "DELETE FROM User u WHERE u.id=:id"), + @NamedQuery(name = User.BY_EMAIL, query = "SELECT u FROM User u LEFT JOIN FETCH u.roles WHERE u.email=?1"), + @NamedQuery(name = User.ALL_SORTED, query = "SELECT u FROM User u LEFT JOIN FETCH u.roles ORDER BY u.name, u.email"), +}) public class User extends NamedEntity { + public static final String DELETE = "User.delete"; + public static final String ALL_SORTED = "User.getAllSorted"; + public static final String BY_EMAIL = "User.getByEmail"; + + @Column(name = "email", nullable = false, unique = true) + @Email + @NotEmpty protected String email; + @Column(name = "password", nullable = false) + @NotEmpty + @Length(min = 5) protected String password; + @Column(name = "enabled", nullable = false) protected boolean enabled = true; + @Column(name = "registered", columnDefinition = "timestamp default now()") protected Date registered; + @Enumerated(EnumType.STRING) + @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id")) + @Column(name = "role") + @ElementCollection(fetch = FetchType.EAGER) protected Set roles; public User() { diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java index 11eb5a1..b48f98b 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -1,5 +1,7 @@ package ru.javawebinar.topjava.model; +import javax.persistence.FetchType; +import javax.persistence.ManyToOne; import java.time.LocalDateTime; /** @@ -13,6 +15,7 @@ public class UserMeal extends BaseEntity{ protected int calories; + @ManyToOne(fetch = FetchType.LAZY) private User user; public UserMeal() { @@ -49,4 +52,4 @@ public void setUser(User user) { public String toString() { return "Meal(" + id + ", " + dateTime + ", '" + description + "', calories:" + calories + ')'; } -} \ No newline at end of file +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java new file mode 100644 index 0000000..bc8ae08 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.repository.jpa; + +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * User: gkislin + * Date: 26.08.2014 + */ + +@Repository +public class JpaUserMealRepositoryImpl implements UserMealRepository { + + @Override + public UserMeal save(UserMeal userMeal, int userId) { + return null; + } + + @Override + public boolean delete(int id, int userId) { + return false; + } + + @Override + public UserMeal get(int id, int userId) { + return null; + } + + @Override + public List getAll(int userId) { + return null; + } + + @Override + public void deleteAll(int userId) { + + } + + @Override + public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserRepositoryImpl.java new file mode 100644 index 0000000..6ffc1c8 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserRepositoryImpl.java @@ -0,0 +1,71 @@ +package ru.javawebinar.topjava.repository.jpa; + +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +/** + * User: gkislin + * Date: 29.08.2014 + */ +@Repository +@Transactional(readOnly = true) +public class JpaUserRepositoryImpl implements UserRepository { + +/* + @Autowired + private SessionFactory sessionFactory; + + private Session openSession() { + return sessionFactory.getCurrentSession(); + } +*/ + + @PersistenceContext + private EntityManager em; + + @Override + @Transactional + public User save(User user) { + if (user.isNew()) { + em.persist(user); + } else { + em.merge(user); + } + return user; + } + + @Override + public User get(int id) { + return em.find(User.class, id); + } + + @Override + @Transactional + public boolean delete(int id) { + +/* + User ref = em.getReference(User.class, id); + em.remove(ref); + + TypedQuery query = em.createQuery("DELETE FROM User u WHERE u.id=:id", User.class); + return query.setParameter("id", id).executeUpdate() != 0; +*/ + return em.createNamedQuery(User.DELETE).setParameter("id", id).executeUpdate() != 0; + } + + @Override + public User getByEmail(String email) { + return em.createNamedQuery(User.BY_EMAIL, User.class).setParameter(1, email).getSingleResult(); + } + + @Override + public List getAll() { + return em.createNamedQuery(User.ALL_SORTED, User.class).getResultList(); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java b/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java deleted file mode 100644 index 8d4a6cc..0000000 --- a/src/main/java/ru/javawebinar/topjava/util/DbPopulator.java +++ /dev/null @@ -1,28 +0,0 @@ -package ru.javawebinar.topjava.util; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.ResourceLoader; -import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; - -import javax.sql.DataSource; - -/** - * User: gkislin - * Date: 26.08.2014 - */ -public class DbPopulator extends ResourceDatabasePopulator { - private static final ResourceLoader RESOURCE_LOADER = new DefaultResourceLoader(); - - @Autowired - private DataSource dataSource; - - public DbPopulator(String scriptLocation) { - super(RESOURCE_LOADER.getResource(scriptLocation)); - } - - public void execute() { - DatabasePopulatorUtils.execute(this, dataSource); - } -} diff --git a/src/main/resources/db/hsqldb.properties b/src/main/resources/db/hsqldb.properties new file mode 100644 index 0000000..972e02e --- /dev/null +++ b/src/main/resources/db/hsqldb.properties @@ -0,0 +1,12 @@ +#database.url=jdbc:hsqldb:file:D:/temp/topjava +database.url=jdbc:hsqldb:mem:topjava + +database.username=sa +database.password= +database.driverClassName=org.hsqldb.jdbcDriver + +database.init=true +jdbc.initLocation=initDB_hsql.sql +jpa.showSql=true +hibernate.format_sql=true +hibernate.use_sql_comments=true diff --git a/src/main/resources/db/initDB_hsql.sql b/src/main/resources/db/initDB_hsql.sql new file mode 100644 index 0000000..6c05ea1 --- /dev/null +++ b/src/main/resources/db/initDB_hsql.sql @@ -0,0 +1,35 @@ +DROP TABLE user_roles IF EXISTS; +DROP TABLE meals IF EXISTS; +DROP TABLE users IF EXISTS; +DROP SEQUENCE global_seq IF EXISTS; + +CREATE SEQUENCE GLOBAL_SEQ AS INTEGER START WITH 100000; + +CREATE TABLE users +( + id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY, + name VARCHAR(255), + email VARCHAR(255) NOT NULL, + password VARCHAR(255) NOT NULL, + registered TIMESTAMP DEFAULT now(), + enabled BOOLEAN DEFAULT TRUE +); +CREATE UNIQUE INDEX user_email_key ON USERS ( email ); + +CREATE TABLE user_roles +( + user_id INTEGER NOT NULL, + role VARCHAR(255), + CONSTRAINT user_roles_idx UNIQUE (user_id, role), + FOREIGN KEY ( user_id ) REFERENCES USERS ( id ) ON DELETE CASCADE +); + +CREATE TABLE meals +( + id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY, + datetime TIMESTAMP, + description VARCHAR(255), + calories INT, + user_id INTEGER NOT NULL, + FOREIGN KEY ( user_id ) REFERENCES USERS ( id ) ON DELETE CASCADE +); diff --git a/src/main/resources/db/initDB.sql b/src/main/resources/db/initDB_postgres.sql similarity index 100% rename from src/main/resources/db/initDB.sql rename to src/main/resources/db/initDB_postgres.sql diff --git a/src/main/resources/db/postgres.properties b/src/main/resources/db/postgres.properties index 47bcf62..269bc2a 100644 --- a/src/main/resources/db/postgres.properties +++ b/src/main/resources/db/postgres.properties @@ -3,6 +3,7 @@ #database.password=SSQyKKE_e93kiUCR-ehzMcKCxZ database.init=true +jdbc.initLocation=initDB_postgres.sql database.driverClassName=org.postgresql.Driver database.url=jdbc:postgresql://localhost:5432/topjava diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 756c97f..5ba07c0 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -14,8 +14,6 @@ - - diff --git a/src/main/resources/spring/spring-db.xml b/src/main/resources/spring/spring-db.xml index ac0b25c..76f072a 100644 --- a/src/main/resources/spring/spring-db.xml +++ b/src/main/resources/spring/spring-db.xml @@ -1,14 +1,21 @@ + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> - + + - - - + + + + + + - - - + + + + + + + + + + - - + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/ru/javawebinar/topjava/SpringMain.java b/src/test/java/ru/javawebinar/topjava/SpringMain.java similarity index 95% rename from src/main/java/ru/javawebinar/topjava/SpringMain.java rename to src/test/java/ru/javawebinar/topjava/SpringMain.java index 7d7ce38..305a378 100644 --- a/src/main/java/ru/javawebinar/topjava/SpringMain.java +++ b/src/test/java/ru/javawebinar/topjava/SpringMain.java @@ -21,7 +21,7 @@ public class SpringMain { public static void main(String[] args) { // java 7 Automatic resource management - try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml")) { + try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml","spring/mock.xml")) { System.out.println(Arrays.toString(appCtx.getBeanDefinitionNames())); AdminUserRestController adminUserController = appCtx.getBean(AdminUserRestController.class); System.out.println(adminUserController.create(new User(1, "userName", "email", "password", Role.ROLE_ADMIN))); diff --git a/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java index b97a31d..1f0d0c9 100644 --- a/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java +++ b/src/test/java/ru/javawebinar/topjava/repository/mock/MockUserMealRepositoryImpl.java @@ -15,7 +15,7 @@ */ @Repository public class MockUserMealRepositoryImpl implements UserMealRepository { - private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserRepositoryImpl.class); + private static final LoggerWrapper LOG = LoggerWrapper.get(MockUserMealRepositoryImpl.class); @Override public boolean delete(int id, int userId) { diff --git a/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java index 07ee5f9..cbe151e 100644 --- a/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java +++ b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java @@ -1,15 +1,15 @@ package ru.javawebinar.topjava.service; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import ru.javawebinar.topjava.MealTestData; import ru.javawebinar.topjava.model.UserMeal; -import ru.javawebinar.topjava.util.DbPopulator; import ru.javawebinar.topjava.util.exception.NotFoundException; import java.time.LocalDate; @@ -25,19 +25,12 @@ "classpath:spring/spring-db.xml" }) @RunWith(SpringJUnit4ClassRunner.class) +@Sql(scripts = "classpath:db/populateDB.sql", config = @SqlConfig(encoding = "UTF-8")) public class UserMealServiceTest { @Autowired protected UserMealService service; - @Autowired - private DbPopulator dbPopulator; - - @Before - public void setUp() throws Exception { - dbPopulator.execute(); - } - @Test public void testDelete() throws Exception { service.delete(MealTestData.MEAL1_ID, USER_ID); diff --git a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java index b8b528c..8669204 100644 --- a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java +++ b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java @@ -1,16 +1,16 @@ package ru.javawebinar.topjava.service; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import ru.javawebinar.topjava.UserTestData.*; import ru.javawebinar.topjava.model.Role; import ru.javawebinar.topjava.model.User; -import ru.javawebinar.topjava.util.DbPopulator; import ru.javawebinar.topjava.util.exception.NotFoundException; import java.util.Arrays; @@ -24,19 +24,12 @@ "classpath:spring/spring-db.xml" }) @RunWith(SpringJUnit4ClassRunner.class) +@Sql(scripts = "classpath:db/populateDB.sql", config = @SqlConfig(encoding = "UTF-8")) public class UserServiceTest { @Autowired protected UserService service; - @Autowired - private DbPopulator dbPopulator; - - @Before - public void setUp() throws Exception { - dbPopulator.execute(); - } - @Test public void testSave() throws Exception { TestUser tu = new TestUser("New", "new@gmail.com", "newPass", Role.ROLE_USER); diff --git a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java index 80dfc97..bb1fbfb 100644 --- a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java +++ b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminMockTest.java @@ -16,7 +16,7 @@ public class UserAdminMockTest { @BeforeClass public static void beforeClass() { - appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml"); + appCtx = new ClassPathXmlApplicationContext("spring/spring-app.xml", "spring/mock.xml"); System.out.println("\n" + Arrays.toString(appCtx.getBeanDefinitionNames()) + "\n"); controller = appCtx.getBean(AdminUserRestController.class); } diff --git a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java index 54916d6..9b1868c 100644 --- a/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java +++ b/src/test/java/ru/javawebinar/topjava/web/mock/UserAdminSpringMockTest.java @@ -14,7 +14,7 @@ * GKislin * 13.03.2015. */ -@ContextConfiguration("classpath:spring/spring-app.xml") +@ContextConfiguration({"classpath:spring/spring-app.xml", "classpath:spring/mock.xml"}) @RunWith(SpringJUnit4ClassRunner.class) public class UserAdminSpringMockTest { diff --git a/src/test/resources/spring/mock.xml b/src/test/resources/spring/mock.xml new file mode 100644 index 0000000..c7c9f62 --- /dev/null +++ b/src/test/resources/spring/mock.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file From 989a0916fd3854bf0b41bbb3aa99b6ffdfbe1dd8 Mon Sep 17 00:00:00 2001 From: SeniorJava Date: Fri, 7 Aug 2015 16:56:06 +0300 Subject: [PATCH 17/17] Lesson 5 --- pom.xml | 74 +++- .../ru/javawebinar/topjava/model/User.java | 4 +- .../javawebinar/topjava/model/UserMeal.java | 36 +- .../converter/LocalDateTimeConverter.java | 24 + .../DataJpaUserMealRepositoryImpl.java | 45 ++ .../datajpa/DataJpaUserRepositoryImpl.java | 47 ++ .../datajpa/ProxyUserRepository.java | 37 ++ .../jdbc/JdbcUserMealRepositoryImpl.java | 3 +- .../jpa/JpaUserMealRepositoryImpl.java | 57 ++- .../topjava/service/UserService.java | 2 + .../topjava/service/UserServiceImpl.java | 11 + src/main/resources/cache/ehcache.xml | 28 ++ src/main/resources/cache/ehcache.xsd | 419 ++++++++++++++++++ src/main/resources/db/initDB_hsql.sql | 4 +- src/main/resources/db/initDB_postgres.sql | 4 +- src/main/resources/spring/spring-app.xml | 1 + src/main/resources/spring/spring-db.xml | 49 +- src/main/resources/spring/spring-tools.xml | 24 + .../topjava/service/UserMealServiceTest.java | 22 +- .../topjava/service/UserServiceTest.java | 8 + 20 files changed, 850 insertions(+), 49 deletions(-) create mode 100644 src/main/java/ru/javawebinar/topjava/model/converter/LocalDateTimeConverter.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserMealRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserRepositoryImpl.java create mode 100644 src/main/java/ru/javawebinar/topjava/repository/datajpa/ProxyUserRepository.java create mode 100644 src/main/resources/cache/ehcache.xml create mode 100644 src/main/resources/cache/ehcache.xsd create mode 100644 src/main/resources/spring/spring-tools.xml diff --git a/pom.xml b/pom.xml index a8a95f2..50ca237 100644 --- a/pom.xml +++ b/pom.xml @@ -13,11 +13,13 @@ 1.8 + 7.0.57 UTF-8 UTF-8 4.1.6.RELEASE + 1.8.1.RELEASE 1.1.2 @@ -29,6 +31,8 @@ 4.3.8.Final 5.1.3.Final + + 2.6.11 @@ -85,7 +89,7 @@ org.springframework - spring-context + spring-context-support ${spring.version} @@ -97,21 +101,9 @@ - org.postgresql - postgresql - 9.4-1201-jdbc41 - - - org.hsqldb - hsqldb - 2.3.2 - test - - - - org.springframework - spring-orm - ${spring.version} + org.springframework.data + spring-data-jpa + ${spring-data-jpa.version} org.hibernate @@ -124,6 +116,19 @@ ${hibernate-validator.version} + + + net.sf.ehcache + ehcache-core + ${ehcache.version} + + + commons-logging + commons-logging + + + + junit @@ -141,8 +146,45 @@ + + hsqldb + + + org.hsqldb + hsqldb + 2.3.2 + + + + + postgres + + + org.postgresql + postgresql + 9.4-1201-jdbc41 + + + org.apache.tomcat + tomcat-jdbc + ${tomcat.version} + + + + true + + + + + org.springframework + spring-framework-bom + ${spring.version} + pom + import + + diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java index 2c32725..913cb8a 100644 --- a/src/main/java/ru/javawebinar/topjava/model/User.java +++ b/src/main/java/ru/javawebinar/topjava/model/User.java @@ -14,7 +14,7 @@ * Date: 22.08.2014 */ @Entity -@Table(name = "USERS", uniqueConstraints = {@UniqueConstraint(columnNames = "email", name = "unique_email")}) +@Table(name = "users", uniqueConstraints = {@UniqueConstraint(columnNames = "email", name = "unique_email")}) @NamedQueries({ @NamedQuery(name = User.DELETE, query = "DELETE FROM User u WHERE u.id=:id"), @NamedQuery(name = User.BY_EMAIL, query = "SELECT u FROM User u LEFT JOIN FETCH u.roles WHERE u.email=?1"), @@ -40,7 +40,7 @@ public class User extends NamedEntity { protected boolean enabled = true; @Column(name = "registered", columnDefinition = "timestamp default now()") - protected Date registered; + protected Date registered = new Date(); @Enumerated(EnumType.STRING) @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id")) diff --git a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java index b48f98b..27f2c51 100644 --- a/src/main/java/ru/javawebinar/topjava/model/UserMeal.java +++ b/src/main/java/ru/javawebinar/topjava/model/UserMeal.java @@ -1,21 +1,53 @@ package ru.javawebinar.topjava.model; -import javax.persistence.FetchType; -import javax.persistence.ManyToOne; +import org.hibernate.validator.constraints.NotEmpty; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; import java.time.LocalDateTime; /** * GKislin * 11.01.2015. */ +@NamedQueries({ + @NamedQuery(name = UserMeal.GET, query = "SELECT m FROM UserMeal m WHERE m.id=:id AND m.user.id=:userId"), + @NamedQuery(name = UserMeal.ALL_SORTED, query = "SELECT m FROM UserMeal m WHERE m.user.id=:userId ORDER BY m.dateTime DESC"), + @NamedQuery(name = UserMeal.DELETE_ALL, query = "DELETE FROM UserMeal i WHERE i.user.id=:userId"), + @NamedQuery(name = UserMeal.DELETE, query = "DELETE FROM UserMeal m WHERE m.id=:id AND m.user.id=:userId"), + @NamedQuery(name = UserMeal.GET_BETWEEN, + query = "SELECT m from UserMeal m WHERE m.user.id=:userId "+ + " AND m.dateTime BETWEEN :startDate AND :endDate ORDER BY m.dateTime DESC"), + +// @NamedQuery(name = UserMeal.UPDATE, query = "UPDATE UserMeal m SET m.dateTime = :datetime, m.calories= :calories," + +// "m.description=:desc where m.id=:id and m.user.id=:userId") +}) + +@Entity +@Table(name = "meals") public class UserMeal extends BaseEntity{ + public static final String GET = "UserMeal.get"; + public static final String ALL_SORTED = "UserMeal.getAll"; + public static final String DELETE = "UserMeal.delete"; + public static final String DELETE_ALL = "UserMeal.deleteAll"; + public static final String GET_BETWEEN = "UserMeal.getBetween"; +// public static final String UPDATE = "UserMeal.update"; + + @Column(name = "time", nullable = false) + @NotNull protected LocalDateTime dateTime; + @Column(name = "description", nullable = false) + @NotEmpty protected String description; + @Column(name = "calories") protected int calories; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + @NotNull +// http://stackoverflow.com/questions/9887242/using-postgresql-why-doesnt-hibernate-jpa-create-cascade-constraints/9925761#9925761 private User user; public UserMeal() { diff --git a/src/main/java/ru/javawebinar/topjava/model/converter/LocalDateTimeConverter.java b/src/main/java/ru/javawebinar/topjava/model/converter/LocalDateTimeConverter.java new file mode 100644 index 0000000..eaf8917 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/model/converter/LocalDateTimeConverter.java @@ -0,0 +1,24 @@ +package ru.javawebinar.topjava.model.converter; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import java.sql.Timestamp; +import java.time.LocalDateTime; + +/** + * GKislin + * 08.01.2015. + * @link https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa + */ +@Converter(autoApply = true) +public class LocalDateTimeConverter implements AttributeConverter { + @Override + public Timestamp convertToDatabaseColumn(LocalDateTime ldt) { + return Timestamp.valueOf(ldt); + } + + @Override + public LocalDateTime convertToEntityAttribute(Timestamp ts) { + return ts.toLocalDateTime(); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserMealRepositoryImpl.java new file mode 100644 index 0000000..aef2d31 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserMealRepositoryImpl.java @@ -0,0 +1,45 @@ +package ru.javawebinar.topjava.repository.datajpa; + +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.UserMeal; +import ru.javawebinar.topjava.repository.UserMealRepository; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * GKislin + * 27.03.2015. + */ +@Repository +public class DataJpaUserMealRepositoryImpl implements UserMealRepository{ + @Override + public UserMeal save(UserMeal userMeal, int userId) { + return null; + } + + @Override + public boolean delete(int id, int userId) { + return false; + } + + @Override + public UserMeal get(int id, int userId) { + return null; + } + + @Override + public List getAll(int userId) { + return null; + } + + @Override + public void deleteAll(int userId) { + + } + + @Override + public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { + return null; + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserRepositoryImpl.java new file mode 100644 index 0000000..139946a --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/datajpa/DataJpaUserRepositoryImpl.java @@ -0,0 +1,47 @@ +package ru.javawebinar.topjava.repository.datajpa; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Repository; +import ru.javawebinar.topjava.model.User; +import ru.javawebinar.topjava.repository.UserRepository; + +import java.util.List; + +/** + * GKislin + * 27.03.2015. + */ + +@Repository +public class DataJpaUserRepositoryImpl implements UserRepository { + private static final Sort SORT_NAME_EMAIL = new Sort("name", "email"); + + @Autowired + private ProxyUserRepository proxy; + + @Override + public User save(User user) { + return proxy.save(user); + } + + @Override + public boolean delete(int id) { + return proxy.delete(id) != 0; + } + + @Override + public User get(int id) { + return proxy.findOne(id); + } + + @Override + public User getByEmail(String email) { + return proxy.getByEmail(email); + } + + @Override + public List getAll() { + return proxy.findAll(SORT_NAME_EMAIL); + } +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/datajpa/ProxyUserRepository.java b/src/main/java/ru/javawebinar/topjava/repository/datajpa/ProxyUserRepository.java new file mode 100644 index 0000000..092d847 --- /dev/null +++ b/src/main/java/ru/javawebinar/topjava/repository/datajpa/ProxyUserRepository.java @@ -0,0 +1,37 @@ +package ru.javawebinar.topjava.repository.datajpa; + +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; +import ru.javawebinar.topjava.model.User; + +import java.util.List; + +/** + * GKislin + * 27.03.2015. + */ +@Transactional(readOnly = true) +public interface ProxyUserRepository extends JpaRepository { + + @Transactional + @Modifying +// @Query(name = User.DELETE) + @Query("DELETE FROM User u WHERE u.id=:id") + int delete(@Param("id") int id); + + @Override + @Transactional + User save(User user); + + @Override + User findOne(Integer id); + + @Override + List findAll(Sort sort); + + User getByEmail(String email); +} diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java index b8c0e7d..739cea4 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserMealRepositoryImpl.java @@ -8,7 +8,6 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.stereotype.Repository; -import org.springframework.util.CollectionUtils; import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; @@ -80,7 +79,7 @@ public void deleteAll(int userId) { public UserMeal get(int id, int userId) { List userMeals = jdbcTemplate.query( "SELECT * FROM meals WHERE id = ? AND user_id = ?", ROW_MAPPER, id, userId); - return CollectionUtils.isEmpty(userMeals) ? null : DataAccessUtils.requiredSingleResult(userMeals); + return DataAccessUtils.singleResult(userMeals); } @Override diff --git a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java index bc8ae08..fe180a7 100644 --- a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java +++ b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaUserMealRepositoryImpl.java @@ -1,9 +1,14 @@ package ru.javawebinar.topjava.repository.jpa; +import org.springframework.dao.support.DataAccessUtils; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; +import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.model.UserMeal; import ru.javawebinar.topjava.repository.UserMealRepository; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; import java.time.LocalDateTime; import java.util.List; @@ -13,35 +18,73 @@ */ @Repository +@Transactional(readOnly = true) public class JpaUserMealRepositoryImpl implements UserMealRepository { + @PersistenceContext + private EntityManager em; + @Override + @Transactional public UserMeal save(UserMeal userMeal, int userId) { - return null; + User ref = em.getReference(User.class, userId); + userMeal.setUser(ref); + + if (userMeal.isNew()) { + em.persist(userMeal); + } else { + if (get(userMeal.getId(), userId) == null) return null; + em.merge(userMeal); +/* + if (em.createNamedQuery(UserMeal.UPDATE) + .setParameter("datetime", userMeal.getDateTime()) + .setParameter("calories", userMeal.getCalories()) + .setParameter("desc", userMeal.getDescription()) + .setParameter("id", userMeal.getId()) + .setParameter("userId", userId).executeUpdate() == 0) { + return null; + } +*/ + } + return userMeal; } @Override + @Transactional public boolean delete(int id, int userId) { - return false; + return em.createNamedQuery(UserMeal.DELETE) + .setParameter("id", id) + .setParameter("userId", userId) + .executeUpdate() != 0; } @Override public UserMeal get(int id, int userId) { - return null; + List userMeals = em.createNamedQuery(UserMeal.GET, UserMeal.class) + .setParameter("id", id) + .setParameter("userId", userId) + .getResultList(); + return DataAccessUtils.singleResult(userMeals); } @Override public List getAll(int userId) { - return null; + return em.createNamedQuery(UserMeal.ALL_SORTED, UserMeal.class) + .setParameter("userId", userId) + .getResultList(); } @Override + @Transactional public void deleteAll(int userId) { - + em.createNamedQuery(UserMeal.DELETE_ALL).setParameter("userId", userId).executeUpdate(); } @Override public List getBetween(LocalDateTime startDate, LocalDateTime endDate, int userId) { - return null; + return em.createNamedQuery(UserMeal.GET_BETWEEN, UserMeal.class) + .setParameter("userId", userId) + .setParameter("startDate", startDate) + .setParameter("endDate", endDate).getResultList(); } -} \ No newline at end of file +} diff --git a/src/main/java/ru/javawebinar/topjava/service/UserService.java b/src/main/java/ru/javawebinar/topjava/service/UserService.java index 1d8dab0..52cbec5 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserService.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserService.java @@ -23,4 +23,6 @@ public interface UserService { List getAll(); void update(User user) throws NotFoundException; + + public void evictCache(); } diff --git a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java index 1a4ae71..15e24ae 100644 --- a/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java +++ b/src/main/java/ru/javawebinar/topjava/service/UserServiceImpl.java @@ -1,6 +1,8 @@ package ru.javawebinar.topjava.service; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import ru.javawebinar.topjava.model.User; import ru.javawebinar.topjava.repository.UserRepository; @@ -19,10 +21,12 @@ public class UserServiceImpl implements UserService { @Autowired private UserRepository repository; + @CacheEvict(value = "users", allEntries = true) public User save(User user) { return repository.save(user); } + @CacheEvict(value = "users", allEntries = true) public void delete(int id) { ExceptionUtil.check(repository.delete(id), id); } @@ -35,11 +39,18 @@ public User getByEmail(String email) throws NotFoundException { return ExceptionUtil.check(repository.getByEmail(email), "email=" + email); } + @Cacheable("users") public List getAll() { return repository.getAll(); } + @CacheEvict(value = "users", allEntries = true) public void update(User user) throws NotFoundException { ExceptionUtil.check(repository.save(user), user.getId()); } + + @CacheEvict(value = "users", allEntries = true) + @Override + public void evictCache() { + } } diff --git a/src/main/resources/cache/ehcache.xml b/src/main/resources/cache/ehcache.xml new file mode 100644 index 0000000..8d42001 --- /dev/null +++ b/src/main/resources/cache/ehcache.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/src/main/resources/cache/ehcache.xsd b/src/main/resources/cache/ehcache.xsd new file mode 100644 index 0000000..bfc19dd --- /dev/null +++ b/src/main/resources/cache/ehcache.xsd @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/db/initDB_hsql.sql b/src/main/resources/db/initDB_hsql.sql index 6c05ea1..f6856a8 100644 --- a/src/main/resources/db/initDB_hsql.sql +++ b/src/main/resources/db/initDB_hsql.sql @@ -27,8 +27,8 @@ CREATE TABLE user_roles CREATE TABLE meals ( id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY, - datetime TIMESTAMP, - description VARCHAR(255), + datetime TIMESTAMP NOT NULL, + description VARCHAR(255) NOT NULL, calories INT, user_id INTEGER NOT NULL, FOREIGN KEY ( user_id ) REFERENCES USERS ( id ) ON DELETE CASCADE diff --git a/src/main/resources/db/initDB_postgres.sql b/src/main/resources/db/initDB_postgres.sql index a2fde81..36a2207 100644 --- a/src/main/resources/db/initDB_postgres.sql +++ b/src/main/resources/db/initDB_postgres.sql @@ -27,8 +27,8 @@ CREATE TABLE user_roles CREATE TABLE meals ( id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'), user_id INTEGER NOT NULL, - datetime TIMESTAMP, - description TEXT, + datetime TIMESTAMP NOT NULL, + description TEXT NOT NULL, calories INT, FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ); diff --git a/src/main/resources/spring/spring-app.xml b/src/main/resources/spring/spring-app.xml index 5ba07c0..995ebf9 100644 --- a/src/main/resources/spring/spring-app.xml +++ b/src/main/resources/spring/spring-app.xml @@ -11,6 +11,7 @@ --> + diff --git a/src/main/resources/spring/spring-db.xml b/src/main/resources/spring/spring-db.xml index 76f072a..44cd573 100644 --- a/src/main/resources/spring/spring-db.xml +++ b/src/main/resources/spring/spring-db.xml @@ -4,27 +4,22 @@ xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" + xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> + http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> - - + + - + - - - - - - - + + --> + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-tools.xml b/src/main/resources/spring/spring-tools.xml new file mode 100644 index 0000000..784de2d --- /dev/null +++ b/src/main/resources/spring/spring-tools.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java index cbe151e..743ad91 100644 --- a/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java +++ b/src/test/java/ru/javawebinar/topjava/service/UserMealServiceTest.java @@ -1,9 +1,12 @@ package ru.javawebinar.topjava.service; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; @@ -26,8 +29,12 @@ }) @RunWith(SpringJUnit4ClassRunner.class) @Sql(scripts = "classpath:db/populateDB.sql", config = @SqlConfig(encoding = "UTF-8")) +@ActiveProfiles("postgres") public class UserMealServiceTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Autowired protected UserMealService service; @@ -37,8 +44,10 @@ public void testDelete() throws Exception { MATCHER.assertListEquals(Arrays.asList(MEAL6, MEAL5, MEAL4, MEAL3, MEAL2), service.getAll(USER_ID)); } - @Test(expected = NotFoundException.class) + // @Test(expected = NotFoundException.class) + @Test public void testDeleteNotFound() throws Exception { + thrown.expect(NotFoundException.class); service.delete(MEAL1_ID, 1); } @@ -55,8 +64,10 @@ public void testGet() throws Exception { MATCHER.assertEquals(ADMIN_MEAL, actual); } - @Test(expected = NotFoundException.class) + // @Test(expected = NotFoundException.class) + @Test public void testGetNotFound() throws Exception { + thrown.expect(NotFoundException.class); service.get(MEAL1_ID, ADMIN_ID); } @@ -67,9 +78,12 @@ public void testUpdate() throws Exception { MATCHER.assertEquals(updated, service.get(MEAL1_ID, USER_ID)); } - @Test(expected = NotFoundException.class) + // @Test(expected = NotFoundException.class) + @Test public void testNotFoundUpdate() throws Exception { UserMeal item = service.get(MEAL1_ID, USER_ID); + thrown.expect(NotFoundException.class); + thrown.expectMessage("Not found entity with id=" + MEAL1_ID); service.update(item, ADMIN_ID); } @@ -89,4 +103,4 @@ public void testDeleteAll() throws Exception { service.deleteAll(USER_ID); Assert.assertEquals(0, service.getAll(USER_ID).size()); } -} \ No newline at end of file +} diff --git a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java index 8669204..23e3c5c 100644 --- a/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java +++ b/src/test/java/ru/javawebinar/topjava/service/UserServiceTest.java @@ -1,9 +1,11 @@ package ru.javawebinar.topjava.service; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.SqlConfig; @@ -25,11 +27,17 @@ }) @RunWith(SpringJUnit4ClassRunner.class) @Sql(scripts = "classpath:db/populateDB.sql", config = @SqlConfig(encoding = "UTF-8")) +@ActiveProfiles("postgres") public class UserServiceTest { @Autowired protected UserService service; + @Before + public void setUp() throws Exception { + service.evictCache(); + } + @Test public void testSave() throws Exception { TestUser tu = new TestUser("New", "new@gmail.com", "newPass", Role.ROLE_USER);