Skip to content

Commit 8ec711f

Browse files
committed
Views has been ported from JSP to Thymeleaf.
Fix GH #17
1 parent 681913b commit 8ec711f

Some content is hidden

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

50 files changed

+1819
-1109
lines changed

NEWS.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
0.3 (not released yet)
2+
- views has been ported from JSP to Thymeleaf
3+
- rejection of Apache Tiles
24
- implemented sending of mail with activation key
35
- started using feature flags with Togglz
46
- added localization support for countries

pom.xml

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
<javax.mail.version>1.5.2</javax.mail.version>
2727
<javax.persistence.version>1.0.1.Final</javax.persistence.version>
2828
<servlet.api.version>3.0.20100224</servlet.api.version>
29-
<jstl.version>1.2</jstl.version>
3029
<commons.lang.version>3.3.2</commons.lang.version>
3130
<commons.beanutils.version>1.9.2</commons.beanutils.version>
3231
<commons.io.version>2.4</commons.io.version>
3332
<commons.collections.version>3.2.1</commons.collections.version>
3433
<commons.dbcp.version>1.4</commons.dbcp.version>
35-
<tiles.version>2.2.2</tiles.version>
34+
<thymeleaf.version>2.1.3.RELEASE</thymeleaf.version>
35+
<thymeleaf.security.version>2.1.1.RELEASE</thymeleaf.security.version>
3636
<liquibase.version>3.2.0</liquibase.version>
3737
<liquibase.slf4j.version>1.2.1</liquibase.slf4j.version>
3838
<togglz.version>2.0.1.Final</togglz.version>
@@ -86,13 +86,6 @@
8686
<scope>provided</scope>
8787
</dependency>
8888

89-
<dependency>
90-
<groupId>javax.servlet</groupId>
91-
<artifactId>jstl</artifactId>
92-
<version>${jstl.version}</version>
93-
<scope>runtime</scope>
94-
</dependency>
95-
9689
<!-- @Inject -->
9790
<dependency>
9891
<groupId>javax.inject</groupId>
@@ -183,13 +176,6 @@
183176
<scope>runtime</scope>
184177
</dependency>
185178

186-
<dependency>
187-
<groupId>org.springframework.security</groupId>
188-
<artifactId>spring-security-taglibs</artifactId>
189-
<version>${spring.security.version}</version>
190-
<scope>runtime</scope>
191-
</dependency>
192-
193179
<dependency>
194180
<groupId>org.hibernate</groupId>
195181
<artifactId>hibernate-core</artifactId>
@@ -238,14 +224,18 @@
238224
<scope>test</scope>
239225
</dependency>
240226

241-
<!-- For Tiles template engine -->
242227
<dependency>
243-
<groupId>org.apache.tiles</groupId>
244-
<artifactId>tiles-jsp</artifactId>
245-
<version>${tiles.version}</version>
246-
<scope>runtime</scope>
228+
<groupId>org.thymeleaf</groupId>
229+
<artifactId>thymeleaf-spring3</artifactId>
230+
<version>${thymeleaf.version}</version>
247231
</dependency>
248232

233+
<dependency>
234+
<groupId>org.thymeleaf.extras</groupId>
235+
<artifactId>thymeleaf-extras-springsecurity3</artifactId>
236+
<version>${thymeleaf.security.version}</version>
237+
</dependency>
238+
249239
<!-- For running database migration during application's startup time -->
250240
<dependency>
251241
<groupId>org.liquibase</groupId>

src/main/config/checkstyle-suppressions.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +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" />
1011

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

src/main/config/pmd.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
<!-- For rules description see http://pmd.sourceforge.net/rules/index.html -->
1111

12-
<rule ref="rulesets/jsp/basic.xml" />
1312
<rule ref="rulesets/java/design.xml">
1413
<exclude name="ImmutableField" />
1514
</rule>

src/main/config/test-override-web.xml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,6 @@
1212
<param-value>test</param-value>
1313
</context-param>
1414

15-
<servlet id="jsp">
16-
<servlet-name>jsp</servlet-name>
17-
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
18-
<!-- Check for JSP modification on every access -->
19-
<init-param>
20-
<param-name>development</param-name>
21-
<param-value>true</param-value>
22-
</init-param>
23-
</servlet>
24-
2515
<!--
2616
Web console for managing H2 database.
2717

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
*/
1818
package ru.mystamps.web;
1919

20+
import java.util.HashMap;
21+
import java.util.Map;
22+
2023
import ru.mystamps.web.service.ImageService;
2124

2225
/**
@@ -60,7 +63,40 @@ public final class Url {
6063
public static final String UNAUTHORIZED_PAGE = "/error/401";
6164
public static final String NOT_FOUND_PAGE = "/error/404";
6265

66+
// resources
67+
public static final String FAVICON_ICO = "/favicon.ico";
68+
public static final String MAIN_CSS = "/static/styles/main.css";
69+
public static final String BOOTSTRAP_CSS = "/public/bootstrap/css/bootstrap.min.css";
70+
public static final String BOOTSTRAP_RESPONSIVE_CSS = "/public/bootstrap/css/bootstrap-responsive.min.css";
71+
public static final String BOOTSTRAP_JS = "/public/bootstrap/js/bootstrap.min.js";
72+
public static final String JQUERY_JS = "/public/jquery/jquery.min.js";
73+
public static final String CATALOG_UTILS_JS = "/public/js/CatalogUtils.js";
74+
6375
private Url() {
6476
}
6577

78+
public static Map<String, String> asMap() {
79+
// There is not all urls but only those which used on views
80+
Map<String, String> map = new HashMap<>();
81+
map.put("AUTHENTICATION_PAGE", AUTHENTICATION_PAGE);
82+
map.put("LOGIN_PAGE", LOGIN_PAGE);
83+
map.put("LOGOUT_PAGE", LOGOUT_PAGE);
84+
map.put("ACTIVATE_ACCOUNT_PAGE", ACTIVATE_ACCOUNT_PAGE);
85+
map.put("REGISTRATION_PAGE", REGISTRATION_PAGE);
86+
map.put("ADD_SERIES_PAGE", ADD_SERIES_PAGE);
87+
map.put("INFO_SERIES_PAGE", INFO_SERIES_PAGE);
88+
map.put("ADD_CATEGORY_PAGE", ADD_CATEGORY_PAGE);
89+
map.put("INFO_CATEGORY_PAGE", INFO_CATEGORY_PAGE);
90+
map.put("ADD_COUNTRY_PAGE", ADD_COUNTRY_PAGE);
91+
map.put("INFO_COUNTRY_PAGE", INFO_COUNTRY_PAGE);
92+
map.put("FAVICON_ICO", FAVICON_ICO);
93+
map.put("MAIN_CSS", MAIN_CSS);
94+
map.put("BOOTSTRAP_CSS", BOOTSTRAP_CSS);
95+
map.put("BOOTSTRAP_RESPONSIVE_CSS", BOOTSTRAP_RESPONSIVE_CSS);
96+
map.put("BOOTSTRAP_JS", BOOTSTRAP_JS);
97+
map.put("JQUERY_JS", JQUERY_JS);
98+
map.put("CATALOG_UTILS_JS", CATALOG_UTILS_JS);
99+
return map;
100+
}
101+
66102
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public NotFoundErrorController getNotFoundErrorController() {
6161
return new NotFoundErrorController(servicesConfig.getSiteService());
6262
}
6363

64+
@Bean
65+
public RobotsTxtController getRobotsTxtController() {
66+
return new RobotsTxtController();
67+
}
68+
6469
@Bean
6570
public SeriesController getSeriesController() {
6671
return new SeriesController(

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

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.context.annotation.Import;
2727
import org.springframework.context.MessageSource;
2828
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
29+
import org.springframework.core.env.Environment;
2930
import org.springframework.data.repository.support.DomainClassConverter;
3031
import org.springframework.format.support.FormattingConversionService;
3132
import org.springframework.scheduling.annotation.EnableScheduling;
@@ -40,9 +41,13 @@
4041
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
4142
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
4243
import org.springframework.web.servlet.ViewResolver;
43-
import org.springframework.web.servlet.view.tiles2.TilesConfigurer;
44-
import org.springframework.web.servlet.view.UrlBasedViewResolver;
45-
import org.springframework.web.servlet.view.tiles2.TilesView;
44+
45+
import org.thymeleaf.extras.springsecurity3.dialect.SpringSecurityDialect;
46+
import org.thymeleaf.spring3.SpringTemplateEngine;
47+
import org.thymeleaf.spring3.view.ThymeleafView;
48+
import org.thymeleaf.spring3.view.ThymeleafViewResolver;
49+
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
50+
import org.thymeleaf.templateresolver.TemplateResolver;
4651

4752
import ru.mystamps.web.support.spring.security.CustomUserDetailsArgumentResolver;
4853
import ru.mystamps.web.Url;
@@ -54,14 +59,16 @@
5459
@Import(ControllersConfig.class)
5560
public class MvcConfig extends WebMvcConfigurerAdapter {
5661

62+
@Inject
63+
private Environment env;
64+
5765
@Override
5866
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
5967
configurer.enable();
6068
}
6169

6270
@Override
6371
public void addViewControllers(ViewControllerRegistry registry) {
64-
registry.addViewController(Url.ROBOTS_TXT).setViewName("site/robots");
6572
registry.addViewController(Url.AUTHENTICATION_PAGE);
6673
registry.addViewController(Url.UNAUTHORIZED_PAGE);
6774
}
@@ -103,21 +110,26 @@ public Validator getValidator() {
103110
}
104111

105112
@Bean
106-
public TilesConfigurer getTilesConfigurer() {
107-
TilesConfigurer configurer = new TilesConfigurer();
108-
109-
configurer.setDefinitions(new String[]{
110-
"/WEB-INF/tiles/tiles.xml"
111-
});
112-
113-
return configurer;
114-
}
115-
116-
@Bean
117-
public ViewResolver getViewResolver() {
118-
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
113+
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
114+
public ViewResolver getThymeleafViewResolver() throws Exception {
115+
TemplateResolver templateResolver = new ServletContextTemplateResolver();
116+
templateResolver.setTemplateMode("HTML5");
117+
templateResolver.setPrefix("/WEB-INF/views/");
118+
templateResolver.setSuffix(".html");
119+
templateResolver.setCharacterEncoding("UTF-8");
120+
templateResolver.setCacheable(env.acceptsProfiles("prod"));
121+
122+
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
123+
templateEngine.setTemplateResolver(templateResolver);
124+
templateEngine.setTemplateEngineMessageSource(getMessageSource());
125+
templateEngine.addDialect(new SpringSecurityDialect());
126+
templateEngine.afterPropertiesSet();
119127

120-
viewResolver.setViewClass(TilesView.class);
128+
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
129+
viewResolver.setTemplateEngine(templateEngine);
130+
viewResolver.setContentType("text/html; charset=UTF-8");
131+
viewResolver.setStaticVariables(Url.asMap());
132+
viewResolver.setViewClass(ThymeleafView.class);
121133

122134
return viewResolver;
123135
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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.io.IOException;
21+
import java.io.PrintWriter;
22+
23+
import javax.servlet.http.HttpServletResponse;
24+
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
import org.springframework.stereotype.Controller;
29+
import org.springframework.web.bind.annotation.RequestMapping;
30+
import org.springframework.web.bind.annotation.RequestMethod;
31+
32+
import ru.mystamps.web.Url;
33+
34+
@Controller
35+
public class RobotsTxtController {
36+
private static final Logger LOG = LoggerFactory.getLogger(RobotsTxtController.class);
37+
38+
@RequestMapping(value = Url.ROBOTS_TXT, method = RequestMethod.GET)
39+
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
40+
public void getRobotsText(HttpServletResponse response) {
41+
response.setContentType("text/plain");
42+
response.setCharacterEncoding("UTF-8");
43+
44+
try {
45+
PrintWriter writer = response.getWriter();
46+
47+
writer.println("# robots.txt for " + Url.PUBLIC_URL);
48+
writer.println("User-Agent: *");
49+
writer.println("Disallow: " + Url.REGISTRATION_PAGE);
50+
writer.println("Disallow: " + Url.ACTIVATE_ACCOUNT_PAGE);
51+
writer.println("Disallow: " + Url.AUTHENTICATION_PAGE);
52+
writer.println("Disallow: " + Url.LOGIN_PAGE);
53+
writer.println("Disallow: " + Url.ADD_COUNTRY_PAGE);
54+
writer.println("Disallow: " + Url.ADD_SERIES_PAGE);
55+
writer.println("Disallow: " + Url.ADD_CATEGORY_PAGE);
56+
writer.println("Disallow: " + Url.UNAUTHORIZED_PAGE);
57+
writer.println("Disallow: " + Url.NOT_FOUND_PAGE);
58+
} catch (IOException ex) {
59+
LOG.error("Can't return robots.txt: {}", ex.getMessage());
60+
}
61+
}
62+
63+
}
64+

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

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import ru.mystamps.web.support.spring.security.SecurityContextUtils;
5858
import ru.mystamps.web.util.CatalogUtils;
5959
import ru.mystamps.web.util.LocaleUtils;
60-
import ru.mystamps.web.validation.ValidationRules;
6160

6261
@Controller
6362
@RequiredArgsConstructor
@@ -66,27 +65,13 @@ public class SeriesController {
6665
private static final Integer SINCE_YEAR = 1840;
6766
private static final Integer CURRENT_YEAR = new GregorianCalendar().get(Calendar.YEAR);
6867

69-
private static final Map<Integer, Integer> DAYS;
70-
private static final Map<Integer, Integer> MONTHS;
7168
private static final Map<Integer, Integer> YEARS;
7269

7370
private final CategoryService categoryService;
7471
private final CountryService countryService;
7572
private final SeriesService seriesService;
7673

7774
static {
78-
DAYS = new LinkedHashMap<>(ValidationRules.MAX_DAYS_IN_MONTH);
79-
for (int i = 1; i <= ValidationRules.MAX_DAYS_IN_MONTH; i++) {
80-
Integer day = Integer.valueOf(i);
81-
DAYS.put(day, day);
82-
}
83-
84-
MONTHS = new LinkedHashMap<>(ValidationRules.MAX_MONTHS_IN_YEAR);
85-
for (int i = 1; i <= ValidationRules.MAX_MONTHS_IN_YEAR; i++) {
86-
Integer month = Integer.valueOf(i);
87-
MONTHS.put(month, month);
88-
}
89-
9075
YEARS = new LinkedHashMap<>();
9176
for (Integer i = CURRENT_YEAR; i >= SINCE_YEAR; i--) {
9277
YEARS.put(i, i);
@@ -103,16 +88,6 @@ protected void initBinder(WebDataBinder binder) {
10388
binder.registerCustomEditor(String.class, "comment", new StringTrimmerEditor(true));
10489
}
10590

106-
@ModelAttribute("days")
107-
public Map<Integer, Integer> getDays() {
108-
return DAYS;
109-
}
110-
111-
@ModelAttribute("months")
112-
public Map<Integer, Integer> getMonths() {
113-
return MONTHS;
114-
}
115-
11691
@ModelAttribute("years")
11792
public Map<Integer, Integer> getYears() {
11893
return YEARS;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
*/
1818
package ru.mystamps.web.entity;
1919

20+
import java.text.DecimalFormat;
21+
import java.text.NumberFormat;
22+
import java.util.Locale;
23+
2024
import javax.persistence.Column;
2125
import javax.persistence.Embeddable;
2226
import javax.persistence.Enumerated;
@@ -54,5 +58,14 @@ public String toString() {
5458
.append(currency)
5559
.toString();
5660
}
61+
62+
// used to emulate <fmt:formatNumber pattern="###.##" />
63+
public String getFormattedValue() {
64+
NumberFormat formatter = NumberFormat.getInstance(Locale.ENGLISH);
65+
if (formatter instanceof DecimalFormat) {
66+
((DecimalFormat)formatter).applyPattern("###.##");
67+
}
68+
return formatter.format(value.doubleValue());
69+
}
5770

5871
}

0 commit comments

Comments
 (0)