diff --git a/README.md b/README.md
index 10f296158..7fd61b43a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://app.codacy.com/gh/JavaWebinar/topjava/dashboard)
+[](https://www.codacy.com/gh/JavaWebinar/topjava/dashboard)
Java Enterprise Online Project
===============================
@@ -11,13 +11,14 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- [Wiki](https://github.com/JavaOPs/topjava/wiki)
- [Wiki Git](https://github.com/JavaOPs/topjava/wiki/Git)
- [Wiki IDEA](https://github.com/JavaOPs/topjava/wiki/IDEA)
-- [Демо разрабатываемого приложения](http://javaops-demo.ru/topjava)
+- [Демо разрабатываемого приложения](http://topjava.herokuapp.com/)
-### 29.01: Старт проекта
-- Начало проверки [вступительного задания HW0](https://github.com/JavaOPs/topjava#-Домашнее-задание-hw0)
+### 26.05: Старт проекта
+- Начало проверки [вступительного задания](https://github.com/JavaOPs/topjava#-Домашнее-задание-hw0)
-#### 02.02 Дедлайн на сдачу HW0
-### 05.02: 1-е занятие
+#### 31.05 Дедлайн на сдачу HW0
+### 02.06: 1-е занятие
+#### 03.06 Дедлайн подачи заявки на [дипломную программу](https://javaops.ru/view/register/diploma)
- Разбор домашнего задания вступительного занятия (вместе с Optional)
- Обзор используемых в проекте технологий. Интеграция ПО
- Maven
@@ -26,7 +27,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Уровни и зависимости логгирования. JMX
- Домашнее задание 1-го занятия (HW1 + Optional)
-### 12.02: 2-е занятие
+### 09.06: 2-е занятие
- Разбор домашнего задания HW1 + Optional
- Библиотека vs Фреймворк. Стандартные библиотеки Apache Commons, Guava
- Слои приложения. Создание каркаса приложения
@@ -34,7 +35,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Пояснения к HW2. Обработка Autowired
- Домашнее задание (HW2 + Optional)
-### 19.02: 3-е занятие
+### 16.06: 3-е занятие
- Разбор домашнего задания HW2 + Optional
- Жизненный цикл Spring контекста
- Тестирование через JUnit
@@ -47,7 +48,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Логирование тестов
- Домашнее задание (HW3 + Optional)
-### 26.02: 4-е занятие
+### 23.06: 4-е занятие
- Разбор домашнего задания HW3 + Optional
- Методы улучшения качества кода
- Spring: инициализация и популирование DB
@@ -57,7 +58,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Домашнее задание (HW4 + Optional)
#### Начало выполнения [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md)
-### 05.03: 5-е занятие
+### 30.06: 5-е занятие
- Обзор JDK 9/17. Миграция Topjava с 1.8 на 17
- Разбор вопросов
- Разбор домашнего задания HW4 + Optional
@@ -68,7 +69,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Spring кэш
- Домашнее задание (HW5 + Optional)
-### 12.03: 6-е занятие
+### 07.07: 6-е занятие
- Разбор домашнего задания HW5 + Optional
- Кэш Hibernate
- Spring Web
@@ -81,7 +82,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
#### Большое ДЗ + выпускной проект + начинаем [курс BootJava](https://javaops.ru/view/bootjava) + подтягиваем "хвосты".
-### 26.03: 7-е занятие
+### 21.07: 7-е занятие
- Разбор домашнего задания HW6 + Optional
- Автогенерация DDL по модели
- Тестирование Spring MVC
@@ -92,7 +93,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Тестирование через SoapUi. UTF-8
- Домашнее задание (HW7 + Optional)
-### 02.04: 8-е занятие
+### 28.07: 8-е занятие
- Разбор домашнего задания HW7 + Optional
- WebJars. jQuery и JavaScript frameworks
- Bootstrap
@@ -101,7 +102,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Добавление Spring Security
- Домашнее задание (HW8 + Optional)
-### 09.04: 9-е занятие
+### 04.08: 9-е занятие
- Разбор домашнего задания HW8 + Optional
- Spring Binding
- Spring Validation
@@ -113,7 +114,7 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Cookie. Session
- Домашнее задание (HW9 + Optional)
-### 16.04: 10-е занятие
+### 11.08: 10-е занятие
- Разбор домашнего задания HW10 + Optional
- Кастомизация JSON (@JsonView) и валидации (groups)
- Рефакторинг: jQuery конверторы и группы валидации по умолчанию
@@ -126,22 +127,23 @@ Maven/ Spring/ Security/ JPA(Hibernate)/ REST(Jackson)/ Bootstrap(CSS)/ jQuery +
- Защита от межсайтовой подделки запросов (CSRF)
- Домашнее задание (HW10)
-### 23.04: 11-е занятие
+### 18.08: 11-е занятие
- Разбор домашнего задания HW10 + Optional
- Локализация datatables, ошибок валидации
- Защита от XSS (Cross Site Scripting)
- Обработка ошибок 404 (NotFound)
- Доступ к AuthorizedUser
- Ограничение модификации пользователей
-- Деплой приложения [на собственный выделенный сервер](https://github.com/JavaOPs/startup)
-- Домашнее задание (HW11): сокрытия полей в Swagger
-- Составление резюме. Собеседование. Разработка ПО. Возможные доработки приложения
-
-### 27.04: Миграция на Spring-Boot 3.5
-- Ревью вашего резюме
+- Деплой [приложения в Heroku](http://topjava.herokuapp.com)
+- Собеседование. Разработка ПО
+- Возможные доработки приложения
+- Домашнее задание по проекту: составление резюме
+
+### 22.08: Миграция на Spring-Boot
- Основы Spring Boot. Spring Boot maven plugin
- Lombok, база H2, ApplicationRunner
- Spring Data REST + HATEOAS
- Миграция приложения подсчета калорий на Spring Boot
-### 11.05: Дедлайн на сдачу [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md)
+### 11.09.22: Дедлайн на сдачу [выпускного проекта](https://github.com/JavaOPs/topjava/blob/master/graduation.md)
+### 21.09.22: Получение дипломов для участников [Дипломной программы](https://javaops.ru/view/register/diploma)
diff --git a/config/messages/app.properties b/config/messages/app.properties
index 979407b48..8dec4e48f 100644
--- a/config/messages/app.properties
+++ b/config/messages/app.properties
@@ -2,8 +2,8 @@ app.title=Calories management
app.stackTitle=Application stack:
app.description=Java Enterprise project with registration/authorization and role-based access rights (USER, ADMIN). \
Admin could create/edit/delete users, users - manage your profile and data (meals) via UI (AJAX) and REST with basic authorization. \
-Meals could be filtered by date and time. Meal record color depends on daily calories sum exceeding "Daily calorie limit" (editable user's profile paramets). \
-All REST interface covered with JUnit tests by Spring MVC Test and Spring Security Test.
+Meals could be filtered by date and time. Meal record color depends on daily calories sum exceeding "Daily calorie limit" (editable user's profile parameter). \
+All REST interface covered with JUnit tests by Spring MVC Test и Spring Security Test.
app.footer=Spring 5/JPA Enterprise (Topjava) internship application
app.login=Login as
app.profile=profile
diff --git a/pom.xml b/pom.xml
index d47b60047..1a9225385 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,68 +9,71 @@
1.0-SNAPSHOT
Calories Management
- https://javaops-demo.ru/topjava
+ http://topjava.herokuapp.com/
- 21
+ 17
UTF-8
UTF-8
- 5.3.39
- 5.8.16
- 2.7.18
- 2.21.2
- 9.0.113
+
+ 5.3.20
+ 2.7.1
+ 5.7.2
+
+ 2.13.3
+ 9.0.64
+
+
+ 1.2.11
+ 1.7.36
+
+
+ 42.4.0
- 5.6.15.Final
- 6.2.5.Final
+ 5.6.9.Final
+ 6.2.3.Final
3.0.1-b12
- 3.10.8
+ 3.10.0
+
+
+ 5.8.2
+ 3.23.1
+ 2.2
- 4.6.2
- 3.7.1
+ 4.6.1
+ 3.6.0
2.5.20-1
3.1.4
- 1.13.5
-
-
- 1.5.20
- 2.0.17
-
-
- 42.7.8
-
- 5.14.1
- 3.27.6
- 3.0
+ 1.11.4
topjava
package
-
- org.apache.maven.plugins
- maven-war-plugin
- 3.4.0
-
org.apache.maven.plugins
maven-compiler-plugin
- 3.14.1
+ 3.8.1
${java.version}
${java.version}
+
+ org.apache.maven.plugins
+ maven-war-plugin
+ 3.3.2
+
org.apache.maven.plugins
maven-surefire-plugin
- 3.5.4
+ 2.22.2
-Dfile.encoding=UTF-8
@@ -81,7 +84,7 @@
org.codehaus.cargo
cargo-maven3-plugin
- 1.10.26
+ 1.9.13
tomcat9x
@@ -126,6 +129,7 @@
org.slf4j
slf4j-api
${slf4j.version}
+ compile
@@ -135,14 +139,6 @@
runtime
-
-
- com.google.code.findbugs
- annotations
- 3.0.1
- compile
-
-
javax.annotation
javax.annotation-api
@@ -312,7 +308,7 @@
org.junit.jupiter
junit-jupiter-engine
- ${junit.version}
+ ${junit.jupiter.version}
test
@@ -345,7 +341,7 @@
org.junit.platform
junit-platform-launcher
- 1.14.3
+ 1.8.2
test
@@ -357,7 +353,7 @@
org.hsqldb
hsqldb
- 2.7.4
+ 2.6.1
diff --git a/src/main/java/ru/javawebinar/topjava/AuthorizedUser.java b/src/main/java/ru/javawebinar/topjava/AuthorizedUser.java
index b51930e87..2126d687b 100644
--- a/src/main/java/ru/javawebinar/topjava/AuthorizedUser.java
+++ b/src/main/java/ru/javawebinar/topjava/AuthorizedUser.java
@@ -2,7 +2,7 @@
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.to.UserTo;
-import ru.javawebinar.topjava.util.UsersUtil;
+import ru.javawebinar.topjava.util.UserUtil;
import java.io.Serial;
@@ -14,7 +14,7 @@ public class AuthorizedUser extends org.springframework.security.core.userdetail
public AuthorizedUser(User user) {
super(user.getEmail(), user.getPassword(), user.isEnabled(), true, true, true, user.getRoles());
- setTo(UsersUtil.asTo(user));
+ setTo(UserUtil.asTo(user));
}
public int getId() {
diff --git a/src/main/java/ru/javawebinar/topjava/model/AbstractBaseEntity.java b/src/main/java/ru/javawebinar/topjava/model/AbstractBaseEntity.java
index 16ae37b0f..536c5c986 100644
--- a/src/main/java/ru/javawebinar/topjava/model/AbstractBaseEntity.java
+++ b/src/main/java/ru/javawebinar/topjava/model/AbstractBaseEntity.java
@@ -1,11 +1,11 @@
package ru.javawebinar.topjava.model;
+import org.hibernate.Hibernate;
+import org.springframework.util.Assert;
import ru.javawebinar.topjava.HasId;
import javax.persistence.*;
-import static org.hibernate.proxy.HibernateProxyHelper.getClassWithoutInitializingProxy;
-
@MappedSuperclass
// http://stackoverflow.com/questions/594597/hibernate-annotations-which-is-better-field-or-property-access
@Access(AccessType.FIELD)
@@ -40,19 +40,23 @@ public Integer getId() {
@Override
public String toString() {
- return getClass().getSimpleName() + ":" + getId();
+ return getClass().getSimpleName() + ":" + id;
}
- // https://stackoverflow.com/a/78077907/548473
@Override
- public final boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClassWithoutInitializingProxy(this) != getClassWithoutInitializingProxy(o)) return false;
- return getId() != null && getId().equals(((AbstractBaseEntity) o).getId());
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || !getClass().equals(Hibernate.getClass(o))) {
+ return false;
+ }
+ AbstractBaseEntity that = (AbstractBaseEntity) o;
+ return id != null && id.equals(that.id);
}
@Override
- public final int hashCode() {
- return getClassWithoutInitializingProxy(this).hashCode();
+ public int hashCode() {
+ return id == null ? 0 : id;
}
}
\ No newline at end of file
diff --git a/src/main/java/ru/javawebinar/topjava/model/Meal.java b/src/main/java/ru/javawebinar/topjava/model/Meal.java
index 00e7e6372..ed5063121 100644
--- a/src/main/java/ru/javawebinar/topjava/model/Meal.java
+++ b/src/main/java/ru/javawebinar/topjava/model/Meal.java
@@ -27,7 +27,7 @@
// "m.description=:desc where m.id=:id and m.user.id=:userId")
})
@Entity
-@Table(name = "meal", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "date_time"}, name = "meal_unique_user_datetime_idx")})
+@Table(name = "meals", uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "date_time"}, name = "meals_unique_user_datetime_idx")})
public class Meal extends AbstractBaseEntity {
public static final String ALL_SORTED = "Meal.getAll";
public static final String DELETE = "Meal.delete";
diff --git a/src/main/java/ru/javawebinar/topjava/model/User.java b/src/main/java/ru/javawebinar/topjava/model/User.java
index 12c608d0c..00e9d5265 100644
--- a/src/main/java/ru/javawebinar/topjava/model/User.java
+++ b/src/main/java/ru/javawebinar/topjava/model/User.java
@@ -19,7 +19,7 @@
import javax.validation.constraints.Size;
import java.util.*;
-import static ru.javawebinar.topjava.util.UsersUtil.DEFAULT_CALORIES_PER_DAY;
+import static ru.javawebinar.topjava.util.UserUtil.DEFAULT_CALORIES_PER_DAY;
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@NamedQueries({
@@ -58,11 +58,11 @@ public class User extends AbstractNamedEntity {
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Enumerated(EnumType.STRING)
- @CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"),
- uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "role"}, name = "uk_user_role")})
+ @CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"),
+ uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "role"}, name = "uk_user_roles")})
@Column(name = "role")
@ElementCollection(fetch = FetchType.EAGER)
- // @Fetch(FetchMode.SUBSELECT)
+// @Fetch(FetchMode.SUBSELECT)
@BatchSize(size = 200)
@JoinColumn
@OnDelete(action = OnDeleteAction.CASCADE)
@@ -86,7 +86,7 @@ public User(User u) {
}
public User(Integer id, String name, String email, String password, int caloriesPerDay, Role... roles) {
- this(id, name, email, password, caloriesPerDay, true, new Date(), List.of(roles));
+ this(id, name, email, password, caloriesPerDay, true, new Date(), Arrays.asList((roles)));
}
public User(Integer id, String name, String email, String password, int caloriesPerDay, boolean enabled, Date registered, Collection roles) {
diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcMealRepository.java
index 775d314ed..82c80dd7b 100644
--- a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcMealRepository.java
+++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcMealRepository.java
@@ -30,7 +30,7 @@ public class JdbcMealRepository implements MealRepository {
public JdbcMealRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.insertMeal = new SimpleJdbcInsert(jdbcTemplate)
- .withTableName("meal")
+ .withTableName("meals")
.usingGeneratedKeyColumns("id");
this.jdbcTemplate = jdbcTemplate;
@@ -54,7 +54,7 @@ public Meal save(Meal meal, int userId) {
meal.setId(newId.intValue());
} else {
if (namedParameterJdbcTemplate.update("" +
- "UPDATE meal " +
+ "UPDATE meals " +
" SET description=:description, calories=:calories, date_time=:date_time " +
" WHERE id=:id AND user_id=:user_id", map) == 0) {
return null;
@@ -66,26 +66,26 @@ public Meal save(Meal meal, int userId) {
@Override
@Transactional
public boolean delete(int id, int userId) {
- return jdbcTemplate.update("DELETE FROM meal WHERE id=? AND user_id=?", id, userId) != 0;
+ return jdbcTemplate.update("DELETE FROM meals WHERE id=? AND user_id=?", id, userId) != 0;
}
@Override
public Meal get(int id, int userId) {
List meals = jdbcTemplate.query(
- "SELECT * FROM meal WHERE id = ? AND user_id = ?", ROW_MAPPER, id, userId);
+ "SELECT * FROM meals WHERE id = ? AND user_id = ?", ROW_MAPPER, id, userId);
return DataAccessUtils.singleResult(meals);
}
@Override
public List getAll(int userId) {
return jdbcTemplate.query(
- "SELECT * FROM meal WHERE user_id=? ORDER BY date_time DESC", ROW_MAPPER, userId);
+ "SELECT * FROM meals WHERE user_id=? ORDER BY date_time DESC", ROW_MAPPER, userId);
}
@Override
public List getBetweenHalfOpen(LocalDateTime startDateTime, LocalDateTime endDateTime, int userId) {
return jdbcTemplate.query(
- "SELECT * FROM meal WHERE user_id=? AND date_time >= ? AND date_time < ? ORDER BY date_time DESC",
+ "SELECT * FROM meals WHERE user_id=? AND date_time >= ? AND date_time < ? ORDER BY date_time DESC",
ROW_MAPPER, userId, startDateTime, endDateTime);
}
}
diff --git a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepository.java b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepository.java
index ca5dcc185..dda61a5f4 100644
--- a/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepository.java
+++ b/src/main/java/ru/javawebinar/topjava/repository/jdbc/JdbcUserRepository.java
@@ -90,7 +90,7 @@ public List getAll() {
List users = jdbcTemplate.query("SELECT * FROM users ORDER BY name, email", ROW_MAPPER);
Map> map = new HashMap<>();
- jdbcTemplate.query("SELECT * FROM user_role", rs -> {
+ jdbcTemplate.query("SELECT * FROM user_roles", rs -> {
map.computeIfAbsent(rs.getInt("user_id"), userId -> EnumSet.noneOf(Role.class))
.add(Role.valueOf(rs.getString("role")));
});
@@ -101,7 +101,7 @@ public List getAll() {
private void insertRoles(User u) {
Set roles = u.getRoles();
if (!CollectionUtils.isEmpty(roles)) {
- jdbcTemplate.batchUpdate("INSERT INTO user_role (user_id, role) VALUES (?, ?)", roles, roles.size(),
+ jdbcTemplate.batchUpdate("INSERT INTO user_roles (user_id, role) VALUES (?, ?)", roles, roles.size(),
(ps, role) -> {
ps.setInt(1, u.id());
ps.setString(2, role.name());
@@ -110,12 +110,12 @@ private void insertRoles(User u) {
}
private void deleteRoles(User u) {
- jdbcTemplate.update("DELETE FROM user_role WHERE user_id=?", u.getId());
+ jdbcTemplate.update("DELETE FROM user_roles WHERE user_id=?", u.getId());
}
private User setRoles(User u) {
if (u != null) {
- List roles = jdbcTemplate.queryForList("SELECT role FROM user_role WHERE user_id=?", Role.class, u.getId());
+ List roles = jdbcTemplate.queryForList("SELECT role FROM user_roles WHERE user_id=?", Role.class, u.getId());
u.setRoles(roles);
}
return u;
diff --git a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaMealRepository.java b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaMealRepository.java
index 6df9fd99f..300a920ae 100644
--- a/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaMealRepository.java
+++ b/src/main/java/ru/javawebinar/topjava/repository/jpa/JpaMealRepository.java
@@ -25,8 +25,10 @@ public Meal save(Meal meal, int userId) {
if (meal.isNew()) {
em.persist(meal);
return meal;
+ } else if (get(meal.id(), userId) == null) {
+ return null;
}
- return get(meal.id(), userId) == null ? null : em.merge(meal);
+ return em.merge(meal);
}
@Override
diff --git a/src/main/java/ru/javawebinar/topjava/service/MealService.java b/src/main/java/ru/javawebinar/topjava/service/MealService.java
index 5f759a11a..5e08c9e5a 100644
--- a/src/main/java/ru/javawebinar/topjava/service/MealService.java
+++ b/src/main/java/ru/javawebinar/topjava/service/MealService.java
@@ -11,7 +11,7 @@
import static ru.javawebinar.topjava.util.DateTimeUtil.atStartOfDayOrMin;
import static ru.javawebinar.topjava.util.DateTimeUtil.atStartOfNextDayOrMax;
-import static ru.javawebinar.topjava.util.ValidationUtil.checkNotFound;
+import static ru.javawebinar.topjava.util.ValidationUtil.checkNotFoundWithId;
@Service
public class MealService {
@@ -23,11 +23,11 @@ public MealService(MealRepository repository) {
}
public Meal get(int id, int userId) {
- return checkNotFound(repository.get(id, userId), id);
+ return checkNotFoundWithId(repository.get(id, userId), id);
}
public void delete(int id, int userId) {
- checkNotFound(repository.delete(id, userId), id);
+ checkNotFoundWithId(repository.delete(id, userId), id);
}
public List getBetweenInclusive(@Nullable LocalDate startDate, @Nullable LocalDate endDate, int userId) {
@@ -40,7 +40,7 @@ public List getAll(int userId) {
public void update(Meal meal, int userId) {
Assert.notNull(meal, "meal must not be null");
- checkNotFound(repository.save(meal, userId), meal.id());
+ checkNotFoundWithId(repository.save(meal, userId), meal.id());
}
public Meal create(Meal meal, int userId) {
@@ -49,6 +49,6 @@ public Meal create(Meal meal, int userId) {
}
public Meal getWithUser(int id, int userId) {
- return checkNotFound(repository.getWithUser(id, userId), id);
+ return checkNotFoundWithId(repository.getWithUser(id, userId), id);
}
}
\ 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 13ae1c5fa..0946273f6 100644
--- a/src/main/java/ru/javawebinar/topjava/service/UserService.java
+++ b/src/main/java/ru/javawebinar/topjava/service/UserService.java
@@ -14,12 +14,13 @@
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.repository.UserRepository;
import ru.javawebinar.topjava.to.UserTo;
-import ru.javawebinar.topjava.util.UsersUtil;
+import ru.javawebinar.topjava.util.UserUtil;
import java.util.List;
-import static ru.javawebinar.topjava.util.UsersUtil.prepareToSave;
+import static ru.javawebinar.topjava.util.UserUtil.prepareToSave;
import static ru.javawebinar.topjava.util.ValidationUtil.checkNotFound;
+import static ru.javawebinar.topjava.util.ValidationUtil.checkNotFoundWithId;
@Service("userService")
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@@ -41,11 +42,11 @@ public User create(User user) {
@CacheEvict(value = "users", allEntries = true)
public void delete(int id) {
- checkNotFound(repository.delete(id), id);
+ checkNotFoundWithId(repository.delete(id), id);
}
public User get(int id) {
- return checkNotFound(repository.get(id), id);
+ return checkNotFoundWithId(repository.get(id), id);
}
public User getByEmail(String email) {
@@ -61,16 +62,15 @@ public List getAll() {
@CacheEvict(value = "users", allEntries = true)
public void update(User user) {
Assert.notNull(user, "user must not be null");
-// checkNotFound : check works only for JDBC, disabled
+// checkNotFoundWithId : check works only for JDBC, disabled
prepareAndSave(user);
}
-
@CacheEvict(value = "users", allEntries = true)
@Transactional
public void update(UserTo userTo) {
User user = get(userTo.id());
- prepareAndSave(UsersUtil.updateFromTo(user, userTo));
+ prepareAndSave(UserUtil.updateFromTo(user, userTo));
}
@CacheEvict(value = "users", allEntries = true)
@@ -95,6 +95,6 @@ private User prepareAndSave(User user) {
}
public User getWithMeals(int id) {
- return checkNotFound(repository.getWithMeals(id), id);
+ return checkNotFoundWithId(repository.getWithMeals(id), id);
}
}
\ No newline at end of file
diff --git a/src/main/java/ru/javawebinar/topjava/to/UserTo.java b/src/main/java/ru/javawebinar/topjava/to/UserTo.java
index 217d7390a..6f63cfa59 100644
--- a/src/main/java/ru/javawebinar/topjava/to/UserTo.java
+++ b/src/main/java/ru/javawebinar/topjava/to/UserTo.java
@@ -1,7 +1,7 @@
package ru.javawebinar.topjava.to;
import org.hibernate.validator.constraints.Range;
-import ru.javawebinar.topjava.util.UsersUtil;
+import ru.javawebinar.topjava.util.UserUtil;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
@@ -29,7 +29,7 @@ public class UserTo extends BaseTo implements Serializable {
@Range(min = 10, max = 10000)
@NotNull
- private Integer caloriesPerDay = UsersUtil.DEFAULT_CALORIES_PER_DAY;
+ private Integer caloriesPerDay = UserUtil.DEFAULT_CALORIES_PER_DAY;
public UserTo() {
}
diff --git a/src/main/java/ru/javawebinar/topjava/util/DateTimeUtil.java b/src/main/java/ru/javawebinar/topjava/util/DateTimeUtil.java
index 09052faa5..1fb662b11 100644
--- a/src/main/java/ru/javawebinar/topjava/util/DateTimeUtil.java
+++ b/src/main/java/ru/javawebinar/topjava/util/DateTimeUtil.java
@@ -7,6 +7,7 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
public class DateTimeUtil {
public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm";
@@ -24,7 +25,7 @@ public static LocalDateTime atStartOfDayOrMin(LocalDate localDate) {
}
public static LocalDateTime atStartOfNextDayOrMax(LocalDate localDate) {
- return localDate != null ? localDate.plusDays(1).atStartOfDay() : MAX_DATE;
+ return localDate != null ? localDate.plus(1, ChronoUnit.DAYS).atStartOfDay() : MAX_DATE;
}
public static String toString(LocalDateTime ldt) {
diff --git a/src/main/java/ru/javawebinar/topjava/util/UsersUtil.java b/src/main/java/ru/javawebinar/topjava/util/UserUtil.java
similarity index 97%
rename from src/main/java/ru/javawebinar/topjava/util/UsersUtil.java
rename to src/main/java/ru/javawebinar/topjava/util/UserUtil.java
index bdb4291f7..a0700dd49 100644
--- a/src/main/java/ru/javawebinar/topjava/util/UsersUtil.java
+++ b/src/main/java/ru/javawebinar/topjava/util/UserUtil.java
@@ -5,7 +5,7 @@
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.to.UserTo;
-public class UsersUtil {
+public class UserUtil {
public static final int DEFAULT_CALORIES_PER_DAY = 2000;
diff --git a/src/main/java/ru/javawebinar/topjava/util/ValidationUtil.java b/src/main/java/ru/javawebinar/topjava/util/ValidationUtil.java
index e300f00c3..6c91f95fd 100644
--- a/src/main/java/ru/javawebinar/topjava/util/ValidationUtil.java
+++ b/src/main/java/ru/javawebinar/topjava/util/ValidationUtil.java
@@ -1,5 +1,6 @@
package ru.javawebinar.topjava.util;
+
import org.springframework.core.NestedExceptionUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
@@ -34,12 +35,12 @@ public static void validate(T bean) {
}
}
- public static T checkNotFound(T object, int id) {
- checkNotFound(object != null, id);
+ public static T checkNotFoundWithId(T object, int id) {
+ checkNotFoundWithId(object != null, id);
return object;
}
- public static void checkNotFound(boolean found, int id) {
+ public static void checkNotFoundWithId(boolean found, int id) {
checkNotFound(found, "id=" + id);
}
@@ -54,7 +55,7 @@ public static void checkNotFound(boolean found, String msg) {
}
}
- public static void checkIsNew(HasId bean) {
+ public static void checkNew(HasId bean) {
if (!bean.isNew()) {
throw new IllegalRequestDataException(bean + " must be new (id=null)");
}
diff --git a/src/main/java/ru/javawebinar/topjava/web/ExceptionInfoHandler.java b/src/main/java/ru/javawebinar/topjava/web/ExceptionInfoHandler.java
index 5b7e95758..aa841a06f 100644
--- a/src/main/java/ru/javawebinar/topjava/web/ExceptionInfoHandler.java
+++ b/src/main/java/ru/javawebinar/topjava/web/ExceptionInfoHandler.java
@@ -25,12 +25,12 @@
@RestControllerAdvice(annotations = RestController.class)
@Order(Ordered.HIGHEST_PRECEDENCE + 5)
public class ExceptionInfoHandler {
- private static final Logger log = LoggerFactory.getLogger(ExceptionInfoHandler.class);
+ private static Logger log = LoggerFactory.getLogger(ExceptionInfoHandler.class);
// http://stackoverflow.com/a/22358422/548473
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
@ExceptionHandler(NotFoundException.class)
- public ErrorInfo notFoundError(HttpServletRequest req, NotFoundException e) {
+ public ErrorInfo handleError(HttpServletRequest req, NotFoundException e) {
return logAndGetErrorInfo(req, e, false, DATA_NOT_FOUND);
}
@@ -42,13 +42,13 @@ public ErrorInfo conflict(HttpServletRequest req, DataIntegrityViolationExceptio
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY) // 422
@ExceptionHandler({IllegalRequestDataException.class, MethodArgumentTypeMismatchException.class, HttpMessageNotReadableException.class})
- public ErrorInfo validationError(HttpServletRequest req, Exception e) {
+ public ErrorInfo illegalRequestDataError(HttpServletRequest req, Exception e) {
return logAndGetErrorInfo(req, e, false, VALIDATION_ERROR);
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
- public ErrorInfo internalError(HttpServletRequest req, Exception e) {
+ public ErrorInfo handleError(HttpServletRequest req, Exception e) {
return logAndGetErrorInfo(req, e, true, APP_ERROR);
}
diff --git a/src/main/java/ru/javawebinar/topjava/web/converter/DateTimeFormatters.java b/src/main/java/ru/javawebinar/topjava/web/converter/DateTimeFormatters.java
index 15448ce8c..bc4409869 100644
--- a/src/main/java/ru/javawebinar/topjava/web/converter/DateTimeFormatters.java
+++ b/src/main/java/ru/javawebinar/topjava/web/converter/DateTimeFormatters.java
@@ -7,12 +7,15 @@
import java.time.format.DateTimeFormatter;
import java.util.Locale;
+import static ru.javawebinar.topjava.util.DateTimeUtil.parseLocalDate;
+import static ru.javawebinar.topjava.util.DateTimeUtil.parseLocalTime;
+
public class DateTimeFormatters {
public static class LocalDateFormatter implements Formatter {
@Override
public LocalDate parse(String text, Locale locale) {
- return LocalDate.parse(text);
+ return parseLocalDate(text);
}
@Override
@@ -25,7 +28,7 @@ public static class LocalTimeFormatter implements Formatter {
@Override
public LocalTime parse(String text, Locale locale) {
- return LocalTime.parse(text);
+ return parseLocalTime(text);
}
@Override
diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/AbstractMealController.java b/src/main/java/ru/javawebinar/topjava/web/meal/AbstractMealController.java
index 1931f998f..ec601c187 100644
--- a/src/main/java/ru/javawebinar/topjava/web/meal/AbstractMealController.java
+++ b/src/main/java/ru/javawebinar/topjava/web/meal/AbstractMealController.java
@@ -15,7 +15,7 @@
import java.util.List;
import static ru.javawebinar.topjava.util.ValidationUtil.assureIdConsistent;
-import static ru.javawebinar.topjava.util.ValidationUtil.checkIsNew;
+import static ru.javawebinar.topjava.util.ValidationUtil.checkNew;
public abstract class AbstractMealController {
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -44,7 +44,7 @@ public List getAll() {
public Meal create(Meal meal) {
int userId = SecurityUtil.authUserId();
log.info("create {} for user {}", meal, userId);
- checkIsNew(meal);
+ checkNew(meal);
return service.create(meal, userId);
}
diff --git a/src/main/java/ru/javawebinar/topjava/web/meal/MealRestController.java b/src/main/java/ru/javawebinar/topjava/web/meal/MealRestController.java
index 54d827d28..af1da8138 100644
--- a/src/main/java/ru/javawebinar/topjava/web/meal/MealRestController.java
+++ b/src/main/java/ru/javawebinar/topjava/web/meal/MealRestController.java
@@ -56,7 +56,6 @@ public ResponseEntity createWithLocation(@RequestBody Meal meal) {
return ResponseEntity.created(uriOfNewResource).body(created);
}
- @Override
@GetMapping("/filter")
public List getBetween(
@RequestParam @Nullable LocalDate startDate,
@@ -65,4 +64,4 @@ public List getBetween(
@RequestParam @Nullable LocalTime endTime) {
return super.getBetween(startDate, startTime, endDate, endTime);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java
index 7317c3eb2..532e17816 100644
--- a/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java
+++ b/src/main/java/ru/javawebinar/topjava/web/user/AbstractUserController.java
@@ -6,12 +6,12 @@
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.service.UserService;
import ru.javawebinar.topjava.to.UserTo;
-import ru.javawebinar.topjava.util.UsersUtil;
+import ru.javawebinar.topjava.util.UserUtil;
import java.util.List;
import static ru.javawebinar.topjava.util.ValidationUtil.assureIdConsistent;
-import static ru.javawebinar.topjava.util.ValidationUtil.checkIsNew;
+import static ru.javawebinar.topjava.util.ValidationUtil.checkNew;
public abstract class AbstractUserController {
protected final Logger log = LoggerFactory.getLogger(getClass());
@@ -31,13 +31,13 @@ public User get(int id) {
public User create(UserTo userTo) {
log.info("create {}", userTo);
- checkIsNew(userTo);
- return service.create(UsersUtil.createNewFromTo(userTo));
+ checkNew(userTo);
+ return service.create(UserUtil.createNewFromTo(userTo));
}
public User create(User user) {
log.info("create {}", user);
- checkIsNew(user);
+ checkNew(user);
return service.create(user);
}
diff --git a/src/main/java/ru/javawebinar/topjava/web/user/AdminUIController.java b/src/main/java/ru/javawebinar/topjava/web/user/AdminUIController.java
index ec66952e5..0f5218560 100644
--- a/src/main/java/ru/javawebinar/topjava/web/user/AdminUIController.java
+++ b/src/main/java/ru/javawebinar/topjava/web/user/AdminUIController.java
@@ -36,6 +36,7 @@ public void delete(@PathVariable int id) {
}
@PostMapping
+ @ResponseStatus(HttpStatus.NO_CONTENT)
public ResponseEntity createOrUpdate(@Valid UserTo userTo, BindingResult result) {
if (result.hasErrors()) {
// TODO change to exception handler
diff --git a/src/main/resources/db/initDB.sql b/src/main/resources/db/initDB.sql
index 4bf3d8446..7644dc610 100644
--- a/src/main/resources/db/initDB.sql
+++ b/src/main/resources/db/initDB.sql
@@ -1,5 +1,5 @@
-DROP TABLE IF EXISTS user_role;
-DROP TABLE IF EXISTS meal;
+DROP TABLE IF EXISTS user_roles;
+DROP TABLE IF EXISTS meals;
DROP TABLE IF EXISTS users;
DROP SEQUENCE IF EXISTS global_seq;
@@ -17,7 +17,7 @@ CREATE TABLE users
);
CREATE UNIQUE INDEX users_unique_email_idx ON users (email);
-CREATE TABLE user_role
+CREATE TABLE user_roles
(
user_id INTEGER NOT NULL,
role VARCHAR NOT NULL,
@@ -25,7 +25,7 @@ CREATE TABLE user_role
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
-CREATE TABLE meal
+CREATE TABLE meals
(
id INTEGER PRIMARY KEY DEFAULT nextval('global_seq'),
user_id INTEGER NOT NULL,
@@ -34,4 +34,4 @@ CREATE TABLE meal
calories INT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);
-CREATE UNIQUE INDEX meal_unique_user_datetime_idx ON meal (user_id, date_time);
\ No newline at end of file
+CREATE UNIQUE INDEX meals_unique_user_datetime_idx ON meals (user_id, date_time);
\ 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 9e0e195e6..f2bb54b1e 100644
--- a/src/main/resources/db/initDB_hsql.sql
+++ b/src/main/resources/db/initDB_hsql.sql
@@ -1,5 +1,5 @@
-DROP TABLE user_role IF EXISTS;
-DROP TABLE meal IF EXISTS;
+DROP TABLE user_roles IF EXISTS;
+DROP TABLE meals IF EXISTS;
DROP TABLE users IF EXISTS;
DROP SEQUENCE global_seq IF EXISTS;
@@ -18,7 +18,7 @@ CREATE TABLE users
CREATE UNIQUE INDEX users_unique_email_idx
ON USERS (email);
-CREATE TABLE user_role
+CREATE TABLE user_roles
(
user_id INTEGER NOT NULL,
role VARCHAR(255) NOT NULL,
@@ -26,7 +26,7 @@ CREATE TABLE user_role
FOREIGN KEY (user_id) REFERENCES USERS (id) ON DELETE CASCADE
);
-CREATE TABLE meal
+CREATE TABLE meals
(
id INTEGER GENERATED BY DEFAULT AS SEQUENCE GLOBAL_SEQ PRIMARY KEY,
date_time TIMESTAMP NOT NULL,
@@ -35,5 +35,5 @@ CREATE TABLE meal
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES USERS (id) ON DELETE CASCADE
);
-CREATE UNIQUE INDEX meal_unique_user_datetime_idx
- ON meal (user_id, date_time)
\ No newline at end of file
+CREATE UNIQUE INDEX meals_unique_user_datetime_idx
+ ON meals (user_id, date_time)
\ No newline at end of file
diff --git a/src/main/resources/db/populateDB.sql b/src/main/resources/db/populateDB.sql
index 8d66cc0e5..8265d3655 100644
--- a/src/main/resources/db/populateDB.sql
+++ b/src/main/resources/db/populateDB.sql
@@ -1,5 +1,5 @@
-DELETE FROM user_role;
-DELETE FROM meal;
+DELETE FROM user_roles;
+DELETE FROM meals;
DELETE FROM users;
ALTER SEQUENCE global_seq RESTART WITH 100000;
@@ -8,12 +8,12 @@ VALUES ('User', 'user@yandex.ru', '{noop}password', 2005),
('Admin', 'admin@gmail.com', '{noop}admin', 1900),
('Guest', 'guest@gmail.com', '{noop}guest', 2000);
-INSERT INTO user_role (role, user_id)
+INSERT INTO user_roles (role, user_id)
VALUES ('USER', 100000),
('ADMIN', 100001),
('USER', 100001);
-INSERT INTO meal (date_time, description, calories, user_id)
+INSERT INTO meals (date_time, description, calories, user_id)
VALUES ('2020-01-30 10:00:00', 'Завтрак', 500, 100000),
('2020-01-30 13:00:00', 'Обед', 1000, 100000),
('2020-01-30 20:00:00', 'Ужин', 500, 100000),
@@ -22,4 +22,4 @@ VALUES ('2020-01-30 10:00:00', 'Завтрак', 500, 100000),
('2020-01-31 13:00:00', 'Обед', 1000, 100000),
('2020-01-31 20:00:00', 'Ужин', 510, 100000),
('2020-01-31 14:00:00', 'Админ ланч', 510, 100001),
- ('2020-01-31 21:00:00', 'Админ ужин', 1500, 100001);
+ ('2020-01-31 21:00:00', 'Админ ужин', 1500, 100001);
\ No newline at end of file
diff --git a/src/main/resources/db/postgres.properties b/src/main/resources/db/postgres.properties
index c56854a9b..ba40447d4 100644
--- a/src/main/resources/db/postgres.properties
+++ b/src/main/resources/db/postgres.properties
@@ -1,3 +1,7 @@
+#database.url=jdbc:postgresql://ec2-34-248-169-69.eu-west-1.compute.amazonaws.com:5432/d1ohm99dookbqn?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.NonValidatingFactory
+#database.username=qhazsiozndzrzc
+#database.password=749f7852a65b5ec57bde033af8fde7f8b782a3ef802921acd4613b133d62559e
+
database.url=jdbc:postgresql://localhost:5432/topjava
database.username=user
database.password=password
diff --git a/src/main/resources/db/tomcat.properties b/src/main/resources/db/tomcat.properties
index e11f0725f..2e073681a 100644
--- a/src/main/resources/db/tomcat.properties
+++ b/src/main/resources/db/tomcat.properties
@@ -1,5 +1,5 @@
database.init=false
-jdbc.initLocation=classpath:db/initDB.sql
+jdbc.initLocation=initDB.sql
jpa.showSql=true
hibernate.format_sql=true
hibernate.use_sql_comments=true
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
index e2b565616..ab4cfe51e 100644
--- a/src/main/resources/logback.xml
+++ b/src/main/resources/logback.xml
@@ -30,4 +30,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/webapp/WEB-INF/jsp/fragments/headTag.jsp b/src/main/webapp/WEB-INF/jsp/fragments/headTag.jsp
index cc302e868..8c0600763 100644
--- a/src/main/webapp/WEB-INF/jsp/fragments/headTag.jsp
+++ b/src/main/webapp/WEB-INF/jsp/fragments/headTag.jsp
@@ -12,18 +12,18 @@
-
+
-
+
<%--http://stackoverflow.com/a/24070373/548473--%>
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/jsp/fragments/i18n.jsp b/src/main/webapp/WEB-INF/jsp/fragments/i18n.jsp
index 98bd60fa9..3e2ad09be 100644
--- a/src/main/webapp/WEB-INF/jsp/fragments/i18n.jsp
+++ b/src/main/webapp/WEB-INF/jsp/fragments/i18n.jsp
@@ -3,12 +3,12 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 31dcf2676..9816e2a1b 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -4,7 +4,7 @@
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
- TopJava
+ Topjava
spring.profiles.default
diff --git a/src/main/webapp/resources/images/icon-meal.png b/src/main/webapp/resources/images/icon-meal.png
index bb9dc2d73..b4fc54ad0 100644
Binary files a/src/main/webapp/resources/images/icon-meal.png and b/src/main/webapp/resources/images/icon-meal.png differ
diff --git a/src/main/webapp/resources/js/topjava.common.js b/src/main/webapp/resources/js/topjava.common.js
index 07258e129..261659f9f 100644
--- a/src/main/webapp/resources/js/topjava.common.js
+++ b/src/main/webapp/resources/js/topjava.common.js
@@ -2,16 +2,17 @@ let form;
function makeEditable(datatableOpts) {
ctx.datatableApi = $("#datatable").DataTable(
- {
- ...datatableOpts, // https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax
- "ajax": {
- "url": ctx.ajaxUrl,
- "dataSrc": ""
- },
- "paging": false,
- "info": true
- }
- );
+ // https://api.jquery.com/jquery.extend/#jQuery-extend-deep-target-object1-objectN
+ $.extend(true, datatableOpts,
+ {
+ "ajax": {
+ "url": ctx.ajaxUrl,
+ "dataSrc": ""
+ },
+ "paging": false,
+ "info": true
+ }
+ ));
form = $('#detailsForm');
$(document).ajaxError(function (event, jqXHR, options, jsExc) {
@@ -85,7 +86,7 @@ function closeNoty() {
function successNoty(key) {
closeNoty();
new Noty({
- text: ` ${i18n[key]}`,
+ text: " " + i18n[key],
type: 'success',
layout: "bottomRight",
timeout: 1000
@@ -94,13 +95,13 @@ function successNoty(key) {
function renderEditBtn(data, type, row) {
if (type === "display") {
- return ``;
+ return "";
}
}
function renderDeleteBtn(data, type, row) {
if (type === "display") {
- return ``;
+ return "";
}
}
@@ -108,7 +109,8 @@ function failNoty(jqXHR) {
closeNoty();
var errorInfo = jqXHR.responseJSON;
failedNote = new Noty({
- text: ` ${i18n['common.errorStatus']}: ${jqXHR.status}
${errorInfo.type}
${errorInfo.detail}`,
+ text: " " + i18n["common.errorStatus"] + ": " + jqXHR.status +
+ "
" + errorInfo.type + "
" + errorInfo.detail,
type: "error",
layout: "bottomRight"
});
diff --git a/src/main/webapp/resources/js/topjava.meals.js b/src/main/webapp/resources/js/topjava.meals.js
index 73ab323b4..0b3e8e7e8 100644
--- a/src/main/webapp/resources/js/topjava.meals.js
+++ b/src/main/webapp/resources/js/topjava.meals.js
@@ -10,7 +10,7 @@ const ctx = {
data: $("#filter").serialize()
}).done(updateTableByData);
}
-};
+}
function clearFilter() {
$("#filter")[0].reset();
@@ -21,11 +21,15 @@ function clearFilter() {
$.ajaxSetup({
converters: {
"text json": function (stringData) {
- return JSON.parse(stringData,
- function (key, value) {
- return (key === 'dateTime') ? value.substring(0, 16).replace('T', ' ') : value;
- }
- );
+ var json = JSON.parse(stringData);
+ if (typeof json === 'object') {
+ $(json).each(function () {
+ if (this.hasOwnProperty('dateTime')) {
+ this.dateTime = this.dateTime.substr(0, 16).replace('T', ' ');
+ }
+ });
+ }
+ return json;
}
}
});
@@ -67,13 +71,10 @@ $(function () {
// http://xdsoft.net/jqplugins/datetimepicker/
var startDate = $('#startDate');
var endDate = $('#endDate');
- const dateOptions = {
+ startDate.datetimepicker({
timepicker: false,
format: 'Y-m-d',
formatDate: 'Y-m-d',
- };
- startDate.datetimepicker({
- ...dateOptions,
onShow: function (ct) {
this.setOptions({
maxDate: endDate.val() ? endDate.val() : false
@@ -81,7 +82,9 @@ $(function () {
}
});
endDate.datetimepicker({
- ...dateOptions,
+ timepicker: false,
+ format: 'Y-m-d',
+ formatDate: 'Y-m-d',
onShow: function (ct) {
this.setOptions({
minDate: startDate.val() ? startDate.val() : false
diff --git a/src/main/webapp/resources/js/topjava.users.js b/src/main/webapp/resources/js/topjava.users.js
index fb4db9efd..bb8863a8f 100644
--- a/src/main/webapp/resources/js/topjava.users.js
+++ b/src/main/webapp/resources/js/topjava.users.js
@@ -9,12 +9,12 @@ const ctx = {
}
function enable(chkbox, id) {
- const enabled = chkbox.is(":checked");
+ var enabled = chkbox.is(":checked");
// https://stackoverflow.com/a/22213543/548473
$.ajax({
url: userAjaxUrl + id,
type: "POST",
- data: `enabled=${enabled}`
+ data: "enabled=" + enabled
}).done(function () {
chkbox.closest("tr").attr("data-user-enabled", enabled);
successNoty(enabled ? "common.enabled" : "common.disabled");
@@ -34,7 +34,7 @@ $(function () {
"data": "email",
"render": function (data, type, row) {
if (type === "display") {
- return `${data}`;
+ return "" + data + "";
}
return data;
}
@@ -46,7 +46,7 @@ $(function () {
"data": "enabled",
"render": function (data, type, row) {
if (type === "display") {
- return ``;
+ return "";
}
return data;
}
diff --git a/src/test/java/ru/javawebinar/topjava/ActiveDbProfileResolver.java b/src/test/java/ru/javawebinar/topjava/ActiveDbProfileResolver.java
index 43f143cc7..da3bec700 100644
--- a/src/test/java/ru/javawebinar/topjava/ActiveDbProfileResolver.java
+++ b/src/test/java/ru/javawebinar/topjava/ActiveDbProfileResolver.java
@@ -3,17 +3,17 @@
import org.springframework.lang.NonNull;
import org.springframework.test.context.support.DefaultActiveProfilesResolver;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
//http://stackoverflow.com/questions/23871255/spring-profiles-simple-example-of-activeprofilesresolver
public class ActiveDbProfileResolver extends DefaultActiveProfilesResolver {
@Override
public @NonNull
String[] resolve(@NonNull Class> aClass) {
- // https://stackoverflow.com/a/52438829/548473
- String[] activeProfiles = super.resolve(aClass);
- String[] activeProfilesWithDb = Arrays.copyOf(activeProfiles, activeProfiles.length + 1);
- activeProfilesWithDb[activeProfiles.length] = Profiles.getActiveDbProfile();
- return activeProfilesWithDb;
+ List profiles = new ArrayList<>(Arrays.asList(super.resolve(aClass)));
+ profiles.add(Profiles.getActiveDbProfile());
+ return profiles.toArray(String[]::new);
}
}
diff --git a/src/test/java/ru/javawebinar/topjava/SpringMain.java b/src/test/java/ru/javawebinar/topjava/SpringMain.java
index a9e46b208..1aa3df136 100644
--- a/src/test/java/ru/javawebinar/topjava/SpringMain.java
+++ b/src/test/java/ru/javawebinar/topjava/SpringMain.java
@@ -1,7 +1,6 @@
package ru.javawebinar.topjava;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.context.support.GenericXmlApplicationContext;
import ru.javawebinar.topjava.model.Role;
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.to.MealTo;
@@ -20,7 +19,11 @@
public class SpringMain {
public static void main(String[] args) {
// java 7 automatic resource management (ARM)
- try (ConfigurableApplicationContext appCtx = new ClassPathXmlApplicationContext("spring/inmemory.xml")) {
+ try (GenericXmlApplicationContext appCtx = new GenericXmlApplicationContext()) {
+ appCtx.getEnvironment().setActiveProfiles(Profiles.getActiveDbProfile(), Profiles.REPOSITORY_IMPLEMENTATION);
+ appCtx.load("spring/inmemory.xml");
+ appCtx.refresh();
+
System.out.println("Bean definition names: " + Arrays.toString(appCtx.getBeanDefinitionNames()));
AdminRestController adminUserController = appCtx.getBean(AdminRestController.class);
adminUserController.create(new User(null, "userName", "email@mail.ru", "password", 2000, Role.ADMIN));
diff --git a/src/test/java/ru/javawebinar/topjava/service/AbstractServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/AbstractServiceTest.java
index b8713e6b9..fb1626c4c 100644
--- a/src/test/java/ru/javawebinar/topjava/service/AbstractServiceTest.java
+++ b/src/test/java/ru/javawebinar/topjava/service/AbstractServiceTest.java
@@ -8,8 +8,8 @@
import ru.javawebinar.topjava.ActiveDbProfileResolver;
import ru.javawebinar.topjava.TimingExtension;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static ru.javawebinar.topjava.util.ValidationUtil.getRootCause;
@SpringJUnitConfig(locations = {
"classpath:spring/spring-app.xml",
@@ -21,13 +21,14 @@
@ExtendWith(TimingExtension.class)
public abstract class AbstractServiceTest {
- // Check root cause with AssertJ: https://github.com/junit-team/junit-framework/issues/2129#issuecomment-565712630
// Check root cause in JUnit: https://github.com/junit-team/junit4/pull/778
protected void validateRootCause(Class rootExceptionClass, Runnable runnable) {
- assertThatExceptionOfType(Throwable.class)
- .isThrownBy(runnable::run)
- .satisfiesAnyOf(
- ex -> assertThat(ex).isInstanceOf(rootExceptionClass),
- ex -> assertThat(ex).hasRootCauseInstanceOf(rootExceptionClass));
+ assertThrows(rootExceptionClass, () -> {
+ try {
+ runnable.run();
+ } catch (Exception e) {
+ throw getRootCause(e);
+ }
+ });
}
}
\ No newline at end of file
diff --git a/src/test/java/ru/javawebinar/topjava/service/AbstractUserServiceTest.java b/src/test/java/ru/javawebinar/topjava/service/AbstractUserServiceTest.java
index 100d5637e..2566c1c76 100644
--- a/src/test/java/ru/javawebinar/topjava/service/AbstractUserServiceTest.java
+++ b/src/test/java/ru/javawebinar/topjava/service/AbstractUserServiceTest.java
@@ -21,7 +21,7 @@ public abstract class AbstractUserServiceTest extends AbstractServiceTest {
protected UserService service;
@Test
- void create() {
+ public void create() {
User created = service.create(getNew());
int newId = created.id();
User newUser = getNew();
diff --git a/src/test/java/ru/javawebinar/topjava/web/AbstractControllerTest.java b/src/test/java/ru/javawebinar/topjava/web/AbstractControllerTest.java
index bdddcc56a..c12f7c53e 100644
--- a/src/test/java/ru/javawebinar/topjava/web/AbstractControllerTest.java
+++ b/src/test/java/ru/javawebinar/topjava/web/AbstractControllerTest.java
@@ -33,6 +33,9 @@ public abstract class AbstractControllerTest {
private static final CharacterEncodingFilter CHARACTER_ENCODING_FILTER = new CharacterEncodingFilter();
+ @Autowired
+ public Environment env;
+
static {
CHARACTER_ENCODING_FILTER.setEncoding("UTF-8");
CHARACTER_ENCODING_FILTER.setForceEncoding(true);
@@ -40,13 +43,10 @@ public abstract class AbstractControllerTest {
private MockMvc mockMvc;
- @Autowired
- private Environment env;
-
@Autowired
private WebApplicationContext webApplicationContext;
- protected void assumeDataJpa() {
+ public void assumeDataJpa() {
Assumptions.assumeTrue(env.acceptsProfiles(org.springframework.core.env.Profiles.of(Profiles.DATAJPA)), "DATA-JPA only");
}
diff --git a/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerSpringTest.java b/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerSpringTest.java
index 7568d0f52..40af802e0 100644
--- a/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerSpringTest.java
+++ b/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerSpringTest.java
@@ -21,7 +21,7 @@ class InMemoryAdminRestControllerSpringTest {
private InMemoryUserRepository repository;
@BeforeEach
- void setup() {
+ public void setUp() {
repository.init();
}
diff --git a/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerTest.java b/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerTest.java
index c41fa0e6b..75b8a5a82 100644
--- a/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerTest.java
+++ b/src/test/java/ru/javawebinar/topjava/web/user/InMemoryAdminRestControllerTest.java
@@ -30,13 +30,13 @@ static void beforeClass() {
@AfterAll
static void afterClass() {
- // May cause during JUnit "Cache is not alive (STATUS_SHUTDOWN)" as JUnit share Spring context for speed
- // http://stackoverflow.com/questions/16281802/ehcache-shutdown-causing-an-exception-while-running-test-suite
- // appCtx.close();
+// May cause during JUnit "Cache is not alive (STATUS_SHUTDOWN)" as JUnit share Spring context for speed
+// http://stackoverflow.com/questions/16281802/ehcache-shutdown-causing-an-exception-while-running-test-suite
+// appCtx.close();
}
@BeforeEach
- void setup() {
+ public void setup() {
// re-initialize
repository.init();
}
diff --git a/src/test/java/ru/javawebinar/topjava/web/user/ProfileRestControllerTest.java b/src/test/java/ru/javawebinar/topjava/web/user/ProfileRestControllerTest.java
index 9547ccff4..ae91e2da9 100644
--- a/src/test/java/ru/javawebinar/topjava/web/user/ProfileRestControllerTest.java
+++ b/src/test/java/ru/javawebinar/topjava/web/user/ProfileRestControllerTest.java
@@ -8,7 +8,7 @@
import ru.javawebinar.topjava.model.User;
import ru.javawebinar.topjava.service.UserService;
import ru.javawebinar.topjava.to.UserTo;
-import ru.javawebinar.topjava.util.UsersUtil;
+import ru.javawebinar.topjava.util.UserUtil;
import ru.javawebinar.topjava.web.AbstractControllerTest;
import ru.javawebinar.topjava.web.json.JsonUtil;
@@ -50,7 +50,7 @@ void delete() throws Exception {
@Test
void register() throws Exception {
UserTo newTo = new UserTo(null, "newName", "newemail@ya.ru", "newPassword", 1500);
- User newUser = UsersUtil.createNewFromTo(newTo);
+ User newUser = UserUtil.createNewFromTo(newTo);
ResultActions action = perform(MockMvcRequestBuilders.post(REST_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(JsonUtil.writeValue(newTo)))
@@ -73,7 +73,7 @@ void update() throws Exception {
.andDo(print())
.andExpect(status().isNoContent());
- USER_MATCHER.assertMatch(userService.get(USER_ID), UsersUtil.updateFromTo(new User(user), updatedTo));
+ USER_MATCHER.assertMatch(userService.get(USER_ID), UserUtil.updateFromTo(new User(user), updatedTo));
}
@Test
diff --git a/src/test/resources/spring/spring-cache.xml b/src/test/resources/spring/spring-cache.xml
index 7c9dfda9a..ea51df903 100644
--- a/src/test/resources/spring/spring-cache.xml
+++ b/src/test/resources/spring/spring-cache.xml
@@ -10,10 +10,10 @@
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
-
--->