Skip to content

Commit 227b9a5

Browse files
committed
Implemented possibility to user to add series to his collection.
Fix #144 (GH #2)
1 parent 1bd2fa8 commit 227b9a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+802
-22
lines changed

NEWS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
0.3 (not released yet)
2+
- implemented possibility to user to add series to his collection
23
- views has been ported from JSP to Thymeleaf
34
- rejection of Apache Tiles
45
- implemented sending of mail with activation key

pom.xml

+8-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<commons.dbcp.version>1.4</commons.dbcp.version>
3434
<thymeleaf.version>2.1.3.RELEASE</thymeleaf.version>
3535
<thymeleaf.security.version>2.1.1.RELEASE</thymeleaf.security.version>
36+
<thymeleaf.togglz.version>1.0.0.RELEASE</thymeleaf.togglz.version>
3637
<liquibase.version>3.2.0</liquibase.version>
3738
<liquibase.slf4j.version>1.2.1</liquibase.slf4j.version>
3839
<togglz.version>2.0.1.Final</togglz.version>
@@ -235,7 +236,13 @@
235236
<artifactId>thymeleaf-extras-springsecurity3</artifactId>
236237
<version>${thymeleaf.security.version}</version>
237238
</dependency>
238-
239+
240+
<dependency>
241+
<groupId>com.github.heneke.thymeleaf</groupId>
242+
<artifactId>thymeleaf-extras-togglz</artifactId>
243+
<version>${thymeleaf.togglz.version}</version>
244+
</dependency>
245+
239246
<!-- For running database migration during application's startup time -->
240247
<dependency>
241248
<groupId>org.liquibase</groupId>

src/main/config/checkstyle-suppressions.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<suppress checks="LineLength" files="AbstractPageWithForm.java" lines="27,28,33" />
99
<suppress checks="LineLength" files="Form.java" lines="31,32,37" />
10-
<suppress checks="LineLength" files="Url.java" lines="70" />
10+
<suppress checks="LineLength" files="Url.java" lines="72" />
1111

1212
<!-- false positives due to Lombok usage -->
1313
<suppress checks="HideUtilityClassConstructor" files="ru.mystamps.web.model" />

src/main/java/ru/mystamps/web/Url.java

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public final class Url {
5757
public static final String ADD_COUNTRY_PAGE = "/country/add";
5858
public static final String INFO_COUNTRY_PAGE = "/country/{id}";
5959

60+
public static final String INFO_COLLECTION_PAGE = "/collection/{id}";
61+
6062
public static final String GET_IMAGE_PAGE = ImageService.GET_IMAGE_PAGE;
6163

6264
// see also error-page definitions at src/main/webapp/WEB-INF/web.xml
@@ -89,6 +91,7 @@ public static Map<String, String> asMap() {
8991
map.put("INFO_CATEGORY_PAGE", INFO_CATEGORY_PAGE);
9092
map.put("ADD_COUNTRY_PAGE", ADD_COUNTRY_PAGE);
9193
map.put("INFO_COUNTRY_PAGE", INFO_COUNTRY_PAGE);
94+
map.put("INFO_COLLECTION_PAGE", INFO_COLLECTION_PAGE);
9295
map.put("FAVICON_ICO", FAVICON_ICO);
9396
map.put("MAIN_CSS", MAIN_CSS);
9497
map.put("BOOTSTRAP_CSS", BOOTSTRAP_CSS);

src/main/java/ru/mystamps/web/config/ControllersConfig.java

+7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ public CountryController getCountryController() {
5151
);
5252
}
5353

54+
@Bean
55+
public CollectionController getCollectionController() {
56+
return new CollectionController(servicesConfig.getSeriesService());
57+
}
58+
5459
@Bean
5560
public ImageController getImageController() {
5661
return new ImageController(servicesConfig.getImageService());
@@ -70,6 +75,7 @@ public RobotsTxtController getRobotsTxtController() {
7075
public SeriesController getSeriesController() {
7176
return new SeriesController(
7277
servicesConfig.getCategoryService(),
78+
servicesConfig.getCollectionService(),
7379
servicesConfig.getCountryService(),
7480
servicesConfig.getSeriesService()
7581
);
@@ -79,6 +85,7 @@ public SeriesController getSeriesController() {
7985
public SiteController getSiteController() {
8086
return new SiteController(
8187
servicesConfig.getCategoryService(),
88+
servicesConfig.getCollectionService(),
8289
servicesConfig.getCountryService(),
8390
servicesConfig.getSeriesService()
8491
);

src/main/java/ru/mystamps/web/config/MvcConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
4343
import org.springframework.web.servlet.ViewResolver;
4444

45+
import com.github.heneke.thymeleaf.togglz.TogglzDialect;
4546
import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
4647
import org.thymeleaf.spring3.SpringTemplateEngine;
4748
import org.thymeleaf.spring3.view.ThymeleafView;
@@ -123,6 +124,7 @@ public ViewResolver getThymeleafViewResolver() throws Exception {
123124
templateEngine.setTemplateResolver(templateResolver);
124125
templateEngine.setTemplateEngineMessageSource(getMessageSource());
125126
templateEngine.addDialect(new SpringSecurityDialect());
127+
templateEngine.addDialect(new TogglzDialect());
126128
templateEngine.afterPropertiesSet();
127129

128130
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();

src/main/java/ru/mystamps/web/config/ServicesConfig.java

+9
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public class ServicesConfig {
6161
@Inject
6262
private ImageDao imageDao;
6363

64+
@Inject
65+
private CollectionDao collectionDao;
66+
6467
@Inject
6568
private MailConfig mailConfig;
6669

@@ -80,6 +83,11 @@ public CategoryService getCategoryService() {
8083
return new CategoryServiceImpl(categoryDao);
8184
}
8285

86+
@Bean
87+
public CollectionService getCollectionService() {
88+
return new CollectionServiceImpl(collectionDao);
89+
}
90+
8391
@Bean
8492
public CronService getCronService() {
8593
return new CronServiceImpl(usersActivationDao);
@@ -117,6 +125,7 @@ public UserService getUserService() {
117125
return new UserServiceImpl(
118126
userDao,
119127
usersActivationDao,
128+
getCollectionService(),
120129
getMailService(),
121130
securityConfig.getPasswordEncoder()
122131
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (C) 2009-2014 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.controller;
19+
20+
import java.util.Locale;
21+
22+
import org.springframework.stereotype.Controller;
23+
import org.springframework.ui.Model;
24+
import org.springframework.web.bind.annotation.PathVariable;
25+
import org.springframework.web.bind.annotation.RequestMapping;
26+
import org.springframework.web.bind.annotation.RequestMethod;
27+
28+
import lombok.RequiredArgsConstructor;
29+
30+
import ru.mystamps.web.Url;
31+
import ru.mystamps.web.entity.Collection;
32+
import ru.mystamps.web.service.SeriesService;
33+
import ru.mystamps.web.util.LocaleUtils;
34+
35+
@Controller
36+
@RequiredArgsConstructor
37+
public class CollectionController {
38+
39+
private final SeriesService seriesService;
40+
41+
@RequestMapping(value = Url.INFO_COLLECTION_PAGE, method = RequestMethod.GET)
42+
public String showInfo(
43+
@PathVariable("id") Collection collection,
44+
Model model,
45+
Locale userLocale) {
46+
47+
if (collection == null) {
48+
throw new NotFoundException();
49+
}
50+
51+
model.addAttribute("ownerName", collection.getOwner().getName());
52+
53+
String lang = LocaleUtils.getLanguageOrNull(userLocale);
54+
model.addAttribute("seriesOfCollection", seriesService.findBy(collection, lang));
55+
56+
return "collection/info";
57+
}
58+
59+
}

src/main/java/ru/mystamps/web/controller/SeriesController.java

+59-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.web.bind.annotation.RequestMapping;
3838
import org.springframework.web.bind.annotation.RequestMethod;
3939
import org.springframework.web.bind.WebDataBinder;
40+
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
4041
import org.springframework.web.util.UriComponentsBuilder;
4142

4243
import lombok.RequiredArgsConstructor;
@@ -51,6 +52,7 @@
5152
import ru.mystamps.web.model.AddSeriesForm.YvertCatalogChecks;
5253
import ru.mystamps.web.entity.Series;
5354
import ru.mystamps.web.service.CategoryService;
55+
import ru.mystamps.web.service.CollectionService;
5456
import ru.mystamps.web.service.CountryService;
5557
import ru.mystamps.web.service.SeriesService;
5658
import ru.mystamps.web.service.dto.EntityInfoDto;
@@ -68,6 +70,7 @@ public class SeriesController {
6870
private static final Map<Integer, Integer> YEARS;
6971

7072
private final CategoryService categoryService;
73+
private final CollectionService collectionService;
7174
private final CountryService countryService;
7275
private final SeriesService seriesService;
7376

@@ -142,7 +145,7 @@ public String processInput(
142145
}
143146

144147
@RequestMapping(value = Url.INFO_SERIES_PAGE, method = RequestMethod.GET)
145-
public String showInfo(@PathVariable("id") Series series, Model model) {
148+
public String showInfo(@PathVariable("id") Series series, Model model, User currentUser) {
146149

147150
if (series == null) {
148151
throw new NotFoundException();
@@ -154,8 +157,63 @@ public String showInfo(@PathVariable("id") Series series, Model model) {
154157
model.addAttribute("yvertNumbers", CatalogUtils.toShortForm(series.getYvert()));
155158
model.addAttribute("gibbonsNumbers", CatalogUtils.toShortForm(series.getGibbons()));
156159

160+
model.addAttribute(
161+
"isSeriesInCollection",
162+
collectionService.isSeriesInCollection(currentUser, series)
163+
);
164+
157165
return "series/info";
158166
}
159167

168+
@RequestMapping(
169+
value = Url.INFO_SERIES_PAGE,
170+
method = RequestMethod.POST,
171+
params = "action=ADD"
172+
)
173+
public String addToCollection(
174+
@PathVariable("id") Series series,
175+
User currentUser,
176+
RedirectAttributes redirectAttributes) {
177+
178+
if (series == null) {
179+
throw new NotFoundException();
180+
}
181+
182+
Integer collectionId = collectionService.addToCollection(currentUser, series);
183+
184+
String dstUrl = UriComponentsBuilder.fromUriString(Url.INFO_COLLECTION_PAGE)
185+
.buildAndExpand(collectionId)
186+
.toString();
187+
188+
redirectAttributes.addFlashAttribute("justAddedSeries", true);
189+
190+
return "redirect:" + dstUrl;
191+
}
192+
193+
@RequestMapping(
194+
value = Url.INFO_SERIES_PAGE,
195+
method = RequestMethod.POST,
196+
params = "action=REMOVE"
197+
)
198+
public String removeFromCollection(
199+
@PathVariable("id") Series series,
200+
User currentUser,
201+
RedirectAttributes redirectAttributes) {
202+
203+
if (series == null) {
204+
throw new NotFoundException();
205+
}
206+
207+
Integer collectionId = collectionService.removeFromCollection(currentUser, series);
208+
209+
String dstUrl = UriComponentsBuilder.fromUriString(Url.INFO_COLLECTION_PAGE)
210+
.buildAndExpand(collectionId)
211+
.toString();
212+
213+
redirectAttributes.addFlashAttribute("justRemovedSeries", true);
214+
215+
return "redirect:" + dstUrl;
216+
}
217+
160218
}
161219

src/main/java/ru/mystamps/web/controller/SiteController.java

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import ru.mystamps.web.Url;
2828
import ru.mystamps.web.service.CategoryService;
29+
import ru.mystamps.web.service.CollectionService;
2930
import ru.mystamps.web.service.CountryService;
3031
import ru.mystamps.web.service.SeriesService;
3132

@@ -34,6 +35,7 @@
3435
public class SiteController {
3536

3637
private final CategoryService categoryService;
38+
private final CollectionService collectionService;
3739
private final CountryService countryService;
3840
private final SeriesService seriesService;
3941

@@ -43,6 +45,7 @@ public String showIndexPage(Model model) {
4345
model.addAttribute("countryCounter", countryService.countAll());
4446
model.addAttribute("seriesCounter", seriesService.countAll());
4547
model.addAttribute("stampsCounter", seriesService.countAllStamps());
48+
model.addAttribute("collectionsCounter", collectionService.countCollectionsOfUsers());
4649
return "site/index";
4750
}
4851

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2009-2014 Slava Semushin <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17+
*/
18+
package ru.mystamps.web.dao;
19+
20+
import org.springframework.data.jpa.repository.Query;
21+
import org.springframework.data.repository.CrudRepository;
22+
23+
import ru.mystamps.web.entity.Collection;
24+
25+
public interface CollectionDao extends CrudRepository<Collection, Integer> {
26+
@Query("SELECT COUNT(*) FROM Collection c WHERE c.series IS NOT EMPTY")
27+
int countCollectionsOfUsers();
28+
}

src/main/java/ru/mystamps/web/dao/SeriesDao.java

+22
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,26 @@ Iterable<SeriesInfoDto> findByAsSeriesInfo(
8484
@Param("country") Country country,
8585
@Param("lang") String lang
8686
);
87+
88+
@Query(
89+
"SELECT NEW ru.mystamps.web.service.dto.SeriesInfoDto("
90+
+ "s.id, "
91+
+ "cat.id, CASE WHEN (:lang = 'ru') THEN cat.nameRu ELSE cat.name END, "
92+
+ "c.id, CASE WHEN (:lang = 'ru') THEN c.nameRu ELSE c.name END, "
93+
+ "s.releaseDay, "
94+
+ "s.releaseMonth, "
95+
+ "s.releaseYear, "
96+
+ "s.quantity, "
97+
+ "s.perforated"
98+
+ ") "
99+
+ "FROM Collection coll "
100+
+ "JOIN coll.series s "
101+
+ "JOIN s.category cat "
102+
+ "LEFT JOIN s.country c "
103+
+ "WHERE coll.id = :collectionId"
104+
)
105+
Iterable<SeriesInfoDto> findByAsSeriesInfo(
106+
@Param("collectionId") Integer collectionId,
107+
@Param("lang") String lang
108+
);
87109
}

src/main/java/ru/mystamps/web/entity/Category.java

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import javax.persistence.Id;
2727
import javax.persistence.Table;
2828

29+
import lombok.EqualsAndHashCode;
2930
import lombok.Getter;
3031
import lombok.Setter;
3132

@@ -35,6 +36,7 @@
3536
@Table(name = "categories")
3637
@Getter
3738
@Setter
39+
@EqualsAndHashCode(exclude = "metaInfo")
3840
public class Category implements LocalizedEntity {
3941

4042
public static final int NAME_LENGTH = 50;

0 commit comments

Comments
 (0)