Skip to content

Commit e15f227

Browse files
committed
1 parent a33e004 commit e15f227

14 files changed

+229
-1
lines changed

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="72" />
10+
<suppress checks="LineLength" files="Url.java" lines="73" />
1111
<suppress checks="LineLength" files="ErrorController.java" lines="73" />
1212
<suppress checks="LineLength" files="SecurityConfig.java" lines="35,36,40" />
1313

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

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public final class Url {
3737

3838
public static final String INDEX_PAGE = "/";
3939
public static final String ROBOTS_TXT = "/robots.txt";
40+
public static final String SITEMAP_XML = "/sitemap.xml";
4041

4142
public static final String REGISTRATION_PAGE = "/account/register";
4243

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

+5
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,9 @@ public SiteController getSiteController() {
100100
);
101101
}
102102

103+
@Bean
104+
public SitemapController getSitemapController() {
105+
return new SitemapController(servicesConfig.getSeriesService());
106+
}
107+
103108
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public void getRobotsText(HttpServletResponse response) {
5555
writer.println("Disallow: " + Url.UNAUTHORIZED_PAGE);
5656
writer.println("Disallow: " + Url.NOT_FOUND_PAGE);
5757
writer.println("Disallow: " + Url.INTERNAL_ERROR_PAGE);
58+
writer.println("Sitemap: " + Url.PUBLIC_URL + Url.SITEMAP_XML);
5859
} catch (IOException ex) {
5960
LOG.error("Can't return robots.txt: {}", ex.getMessage());
6061
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (C) 2009-2015 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+
import java.text.DateFormat;
23+
import java.text.SimpleDateFormat;
24+
import java.util.Locale;
25+
26+
import javax.servlet.http.HttpServletResponse;
27+
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
import org.springframework.stereotype.Controller;
32+
import org.springframework.web.bind.annotation.RequestMapping;
33+
34+
import ru.mystamps.web.service.dto.SitemapInfoDto;
35+
import ru.mystamps.web.service.SeriesService;
36+
import ru.mystamps.web.Url;
37+
38+
import lombok.RequiredArgsConstructor;
39+
40+
@Controller
41+
@RequiredArgsConstructor
42+
public class SitemapController {
43+
private static final Logger LOG = LoggerFactory.getLogger(SitemapController.class);
44+
45+
// TODO: convert dates to UTC and omit server-specific timezone part
46+
// According to http://www.w3.org/TR/NOTE-datetime
47+
private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mmXXX";
48+
49+
private final SeriesService seriesService;
50+
51+
@RequestMapping(Url.SITEMAP_XML)
52+
public void getSitemapXml(HttpServletResponse response) {
53+
response.setContentType("application/xml");
54+
response.setCharacterEncoding("UTF-8");
55+
56+
DateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT, Locale.ENGLISH);
57+
58+
try {
59+
PrintWriter writer = response.getWriter();
60+
61+
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
62+
writer.println("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
63+
64+
writer.print("\t<url>\t\t<loc>");
65+
writer.print(Url.PUBLIC_URL);
66+
writer.print(Url.INDEX_PAGE);
67+
writer.println("</loc>\t</url>");
68+
69+
for (SitemapInfoDto item : seriesService.findAllForSitemap()) {
70+
writer.println("\t<url>");
71+
72+
writer.print("\t\t<loc>");
73+
writer.print(createLocEntry(item));
74+
writer.println("</loc>");
75+
76+
writer.print("\t\t<lastmod>");
77+
writer.print(createLastModEntry(dateFormatter, item));
78+
writer.println("</lastmod>");
79+
80+
writer.println("\t</url>");
81+
}
82+
83+
writer.println("</urlset>");
84+
} catch (IOException ex) {
85+
LOG.error("Can't return sitemap.xml: {}", ex.getMessage());
86+
}
87+
}
88+
89+
private static String createLocEntry(SitemapInfoDto item) {
90+
return Url.PUBLIC_URL + Url.INFO_SERIES_PAGE.replace("{id}", String.valueOf(item.getId()));
91+
}
92+
93+
private static String createLastModEntry(DateFormat dateFormatter, SitemapInfoDto item) {
94+
return dateFormatter.format(item.getUpdatedAt());
95+
}
96+
97+
}
98+

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

+2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
package ru.mystamps.web.dao;
1919

2020
import ru.mystamps.web.service.dto.SeriesInfoDto;
21+
import ru.mystamps.web.service.dto.SitemapInfoDto;
2122

2223
public interface JdbcSeriesDao {
24+
Iterable<SitemapInfoDto> findAllForSitemap();
2325
Iterable<SeriesInfoDto> findLastAdded(int quantity, String lang);
2426
long countAllStamps();
2527
long countSeriesOfCollection(Integer collectionId);

src/main/java/ru/mystamps/web/dao/impl/JdbcSeriesDaoImpl.java

+16
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,21 @@
2929

3030
import ru.mystamps.web.dao.JdbcSeriesDao;
3131
import ru.mystamps.web.service.dto.SeriesInfoDto;
32+
import ru.mystamps.web.service.dto.SitemapInfoDto;
3233

3334
public class JdbcSeriesDaoImpl implements JdbcSeriesDao {
3435

36+
private static final RowMapper<SitemapInfoDto> SITEMAP_INFO_DTO_ROW_MAPPER =
37+
new SitemapInfoDtoRowMapper();
38+
3539
private static final RowMapper<SeriesInfoDto> SERIES_INFO_DTO_ROW_MAPPER =
3640
new SeriesInfoDtoRowMapper();
3741

3842
private final NamedParameterJdbcTemplate jdbcTemplate;
3943

44+
@Value("${series.find_all_for_sitemap}")
45+
private String findAllForSitemapSql;
46+
4047
@Value("${series.find_last_added_sql}")
4148
private String findLastAddedSeriesSql;
4249

@@ -53,6 +60,15 @@ public JdbcSeriesDaoImpl(DataSource dataSource) {
5360
jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
5461
}
5562

63+
@Override
64+
public Iterable<SitemapInfoDto> findAllForSitemap() {
65+
return jdbcTemplate.query(
66+
findAllForSitemapSql,
67+
Collections.<String, Object>emptyMap(),
68+
SITEMAP_INFO_DTO_ROW_MAPPER
69+
);
70+
}
71+
5672
@Override
5773
public Iterable<SeriesInfoDto> findLastAdded(int quantity, String lang) {
5874
Map<String, Object> params = new HashMap<>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (C) 2009-2015 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.impl;
19+
20+
import java.sql.ResultSet;
21+
import java.sql.SQLException;
22+
import java.util.Date;
23+
24+
import org.springframework.jdbc.core.RowMapper;
25+
26+
import ru.mystamps.web.service.dto.SitemapInfoDto;
27+
28+
class SitemapInfoDtoRowMapper implements RowMapper<SitemapInfoDto> {
29+
30+
@Override
31+
public SitemapInfoDto mapRow(ResultSet resultSet, int i) throws SQLException {
32+
Integer id = resultSet.getInt("id");
33+
Date updatedAt = resultSet.getTimestamp("updated_at");
34+
35+
return new SitemapInfoDto(id, updatedAt);
36+
}
37+
38+
}

src/main/java/ru/mystamps/web/service/SeriesService.java

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import ru.mystamps.web.entity.User;
2525
import ru.mystamps.web.service.dto.AddSeriesDto;
2626
import ru.mystamps.web.service.dto.SeriesInfoDto;
27+
import ru.mystamps.web.service.dto.SitemapInfoDto;
2728

2829
@SuppressWarnings("PMD.TooManyMethods")
2930
public interface SeriesService {
@@ -40,4 +41,5 @@ public interface SeriesService {
4041
Iterable<SeriesInfoDto> findBy(Country country, String lang);
4142
Iterable<SeriesInfoDto> findBy(Collection collection, String lang);
4243
Iterable<SeriesInfoDto> findRecentlyAdded(int quantity, String lang);
44+
Iterable<SitemapInfoDto> findAllForSitemap();
4345
}

src/main/java/ru/mystamps/web/service/SeriesServiceImpl.java

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import ru.mystamps.web.entity.YvertCatalog;
4646
import ru.mystamps.web.service.dto.AddSeriesDto;
4747
import ru.mystamps.web.service.dto.SeriesInfoDto;
48+
import ru.mystamps.web.service.dto.SitemapInfoDto;
4849
import ru.mystamps.web.util.CatalogUtils;
4950

5051
@RequiredArgsConstructor
@@ -223,6 +224,12 @@ public Iterable<SeriesInfoDto> findRecentlyAdded(int quantity, String lang) {
223224
return jdbcSeriesDao.findLastAdded(quantity, lang);
224225
}
225226

227+
@Override
228+
@Transactional(readOnly = true)
229+
public Iterable<SitemapInfoDto> findAllForSitemap() {
230+
return jdbcSeriesDao.findAllForSitemap();
231+
}
232+
226233
private static void setDateOfReleaseIfProvided(AddSeriesDto dto, Series series) {
227234
if (dto.getYear() == null) {
228235
return;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (C) 2009-2015 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.service.dto;
19+
20+
import java.util.Date;
21+
22+
import lombok.Getter;
23+
import lombok.RequiredArgsConstructor;
24+
import lombok.ToString;
25+
26+
@Getter
27+
@ToString
28+
@RequiredArgsConstructor
29+
public class SitemapInfoDto {
30+
private final Integer id;
31+
private final Date updatedAt;
32+
}

src/main/resources/sql/series_dao_queries.properties

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
series.find_all_for_sitemap = \
2+
SELECT s.id, s.updated_at \
3+
FROM series s
4+
15
series.find_last_added_sql = \
26
SELECT s.id \
37
, s.release_day \

src/test/groovy/ru/mystamps/web/service/SeriesServiceImplTest.groovy

+17
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import ru.mystamps.web.entity.Series
3535
import ru.mystamps.web.entity.User
3636
import ru.mystamps.web.entity.YvertCatalog
3737
import ru.mystamps.web.model.AddSeriesForm
38+
import ru.mystamps.web.service.dto.SitemapInfoDto
3839
import ru.mystamps.web.tests.DateUtils
3940

4041
class SeriesServiceImplTest extends Specification {
@@ -944,4 +945,20 @@ class SeriesServiceImplTest extends Specification {
944945
) >> []
945946
}
946947

948+
//
949+
// Tests for findAllForSitemap()
950+
//
951+
952+
def "findAllForSitemap() should call dao and returns result"() {
953+
given:
954+
Iterable<SitemapInfoDto> expectedResult =
955+
Collections.singletonList(TestObjects.createSitemapInfoDto())
956+
when:
957+
Iterable<SitemapInfoDto> result = service.findAllForSitemap()
958+
then:
959+
1 * jdbcSeriesDao.findAllForSitemap() >> expectedResult
960+
and:
961+
result == expectedResult
962+
}
963+
947964
}

src/test/java/ru/mystamps/web/service/TestObjects.java

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import ru.mystamps.web.entity.User;
2828
import ru.mystamps.web.entity.UsersActivation;
2929
import ru.mystamps.web.service.dto.DbImageDto;
30+
import ru.mystamps.web.service.dto.SitemapInfoDto;
3031

3132
final class TestObjects {
3233
public static final String TEST_COUNTRY_EN_NAME = "Somewhere";
@@ -128,4 +129,8 @@ public static Category createCategory() {
128129
category.getMetaInfo().setUpdatedBy(owner);
129130
return category;
130131
}
132+
133+
public static SitemapInfoDto createSitemapInfoDto() {
134+
return new SitemapInfoDto(1, new Date());
135+
}
131136
}

0 commit comments

Comments
 (0)