Refactor HaloUtils

pull/137/head
johnniang 2019-03-22 19:04:57 +08:00
parent 1ddb1043d4
commit 2b7753bccf
14 changed files with 282 additions and 139 deletions

View File

@ -36,7 +36,7 @@ public class Comment extends BaseEntity {
/**
*
*/
@Column(name = "email", columnDefinition = "varchar(50) default ''")
@Column(name = "email", columnDefinition = "varchar(255) default ''")
private String email;
/**

View File

@ -7,6 +7,7 @@ import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import javax.persistence.*;
import lombok.NoArgsConstructor;
/**
* Setting entity.
@ -20,6 +21,7 @@ import javax.persistence.*;
@Data
@ToString
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Option extends BaseEntity {
@Id
@ -44,6 +46,11 @@ public class Option extends BaseEntity {
@Column(name = "option_source", columnDefinition = "varchar(127) default 'system'")
private String optionSource;
public Option(String optionKey, String optionValue) {
this.optionKey = optionKey;
this.optionValue = optionValue;
}
@Override
public void prePersist() {
super.prePersist();

View File

@ -149,7 +149,13 @@ public enum BlogProperties implements ValueEnum<String> {
/**
*
*/
ATTACH_LOC("attach_loc");
ATTACH_LOC("attach_loc"),
/**
* Zone.
*/
QINIU_ZONE("qiniu_zone");
private String value;

View File

@ -0,0 +1,44 @@
package cc.ryanc.halo.model.params;
import cc.ryanc.halo.model.dto.base.InputConverter;
import cc.ryanc.halo.model.entity.Comment;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
/**
* @author johnniang
* @date 3/22/19
*/
@Data
public class CommentParam implements InputConverter<Comment> {
@NotBlank(message = "Comment author name must not be blank")
@Size(max = 50, message = "Length of comment author name must not be more than {max}")
private String author;
@NotBlank(message = "Comment email must not be blank")
@Email(message = "Comment email's format is incorrect")
@Size(max = 255, message = "Length of comment email must not be more than {max}")
private String email;
@Size(max = 127, message = "Length of comment author url must not be more than {max}")
private String authorUrl;
@NotBlank(message = "Comment content must not be blank")
@Size(max = 1023, message = "Length of comment content must not be more than {max}")
private String content;
@Size(max = 512, message = "Length of comment user agent must not be more than {max}")
private String userAgent;
@Min(value = 1, message = "Post id must not be less than {value}")
private Integer postId;
@Min(value = 0, message = "Comment parent id must not be less than {value}")
private Long parentId = 0L;
}

View File

@ -36,6 +36,7 @@ public class HaloConst {
/**
* All of the options
*/
@Deprecated
public final static ConcurrentMap<String, String> OPTIONS = new ConcurrentHashMap<>();
/**

View File

@ -5,6 +5,7 @@ import cc.ryanc.halo.model.entity.Option;
import cc.ryanc.halo.model.enums.BlogProperties;
import cc.ryanc.halo.model.params.OptionParam;
import cc.ryanc.halo.service.base.CrudService;
import com.qiniu.common.Zone;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
@ -19,6 +20,10 @@ import java.util.Optional;
*/
public interface OptionService extends CrudService<Option, Integer> {
int DEFAULT_POST_PAGE_SIZE = 10;
int DEFAULT_COMMENT_PAGE_SIZE = 10;
/**
* Save one option
*
@ -101,4 +106,27 @@ public interface OptionService extends CrudService<Option, Integer> {
*/
@NonNull
Optional<String> getByProperty(@NonNull BlogProperties property);
/**
* Gets post page size.
*
* @return page size
*/
int getPostPageSize();
/**
* Gets comment page size.
*
* @return page size
*/
int getCommentPageSize();
/**
* Get quniu zone.
*
* @return qiniu zone
*/
@NonNull
Zone getQiniuZone();
}

View File

@ -8,6 +8,8 @@ import cc.ryanc.halo.repository.OptionRepository;
import cc.ryanc.halo.service.OptionService;
import cc.ryanc.halo.service.base.AbstractCrudService;
import cc.ryanc.halo.utils.ServiceUtils;
import com.qiniu.common.Zone;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
@ -24,6 +26,7 @@ import java.util.stream.Collectors;
* @author : RYAN0UP
* @date : 2019-03-14
*/
@Slf4j
@Service
public class OptionServiceImpl extends AbstractCrudService<Option, Integer> implements OptionService {
@ -148,4 +151,56 @@ public class OptionServiceImpl extends AbstractCrudService<Option, Integer> impl
return getByKey(property.getValue());
}
@Override
public int getPostPageSize() {
try {
return getByProperty(BlogProperties.INDEX_POSTS).map(Integer::valueOf).orElse(DEFAULT_POST_PAGE_SIZE);
} catch (NumberFormatException e) {
log.error(BlogProperties.INDEX_POSTS + " option was not a number format", e);
return DEFAULT_POST_PAGE_SIZE;
}
}
@Override
public int getCommentPageSize() {
try {
return getByProperty(BlogProperties.INDEX_COMMENTS).map(Integer::valueOf).orElse(DEFAULT_COMMENT_PAGE_SIZE);
} catch (NumberFormatException e) {
log.error(BlogProperties.INDEX_COMMENTS + " option was not a number format", e);
return DEFAULT_COMMENT_PAGE_SIZE;
}
}
@Override
public Zone getQiniuZone() {
return getByProperty(BlogProperties.QINIU_ZONE).map(qiniuZone -> {
Zone zone;
switch (qiniuZone) {
case "z0":
zone = Zone.zone0();
break;
case "z1":
zone = Zone.zone1();
break;
case "z2":
zone = Zone.zone2();
break;
case "na0":
zone = Zone.zoneNa0();
break;
case "as0":
zone = Zone.zoneAs0();
break;
default:
// Default is detecting zone automatically
zone = Zone.autoZone();
}
return zone;
}).orElseGet(Zone::autoZone);
}
}

View File

@ -1,9 +1,6 @@
package cc.ryanc.halo.utils;
import cc.ryanc.halo.model.enums.BlogProperties;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.qiniu.common.Zone;
import io.github.biezhi.ome.OhMyEmail;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -28,8 +25,6 @@ import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import static cc.ryanc.halo.model.support.HaloConst.OPTIONS;
/**
* <pre>
*
@ -89,59 +84,6 @@ public class HaloUtils {
return machineAddress.getHostAddress();
}
/**
* Gets default page size.
*
* @return default page size
*/
public static int getDefaultPageSize(int pageSize) {
if (StrUtil.isNotBlank(OPTIONS.get(BlogProperties.INDEX_POSTS))) {
return Integer.parseInt(OPTIONS.get(BlogProperties.INDEX_POSTS));
}
return pageSize;
}
/**
* Gets default qiniuyun zone.
*
* @return qiniuyun zone
*/
@NonNull
public static Zone getDefaultQiniuZone() {
// Get zone from setting
String qiniuZone = OPTIONS.get("qiniu_zone");
if (StrUtil.isBlank(qiniuZone)) {
return Zone.autoZone();
}
Zone zone;
switch (qiniuZone) {
case "z0":
zone = Zone.zone0();
break;
case "z1":
zone = Zone.zone1();
break;
case "z2":
zone = Zone.zone2();
break;
case "na0":
zone = Zone.zoneNa0();
break;
case "as0":
zone = Zone.zoneAs0();
break;
default:
// Default is detecting zone automatically
zone = Zone.autoZone();
}
return zone;
}
// /**
// * 获取备份文件信息
// *

View File

@ -1,14 +1,25 @@
package cc.ryanc.halo.web.controller.admin.api;
import cc.ryanc.halo.model.dto.CommentOutputDTO;
import cc.ryanc.halo.model.entity.Comment;
import cc.ryanc.halo.model.enums.BlogProperties;
import cc.ryanc.halo.model.enums.CommentStatus;
import cc.ryanc.halo.model.params.CommentParam;
import cc.ryanc.halo.model.support.HaloConst;
import cc.ryanc.halo.model.vo.CommentVO;
import cc.ryanc.halo.service.CommentService;
import cc.ryanc.halo.utils.HaloUtils;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import static org.springframework.data.domain.Sort.Direction.DESC;
@ -40,4 +51,17 @@ public class CommentController {
@PathVariable("status") CommentStatus status) {
return commentService.pageBy(status, pageable);
}
@PostMapping
public CommentOutputDTO createBy(@Valid @RequestBody CommentParam commentParam, HttpServletRequest request) {
Comment comment = commentParam.convertTo();
// Set some default value
comment.setGavatarMd5(SecureUtil.md5(comment.getEmail()));
comment.setIpAddress(ServletUtil.getClientIP(request));
// commentService.createBy(comment)
return null;
}
}

View File

@ -4,12 +4,11 @@ import cc.ryanc.halo.model.entity.Post;
import cc.ryanc.halo.model.enums.BlogProperties;
import cc.ryanc.halo.model.enums.PostStatus;
import cc.ryanc.halo.model.enums.PostType;
import cc.ryanc.halo.service.OptionService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.HaloUtils;
import cn.hutool.core.util.StrUtil;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import javafx.geometry.Pos;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@ -35,10 +34,15 @@ public class ContentFeedController {
private final PostService postService;
private final OptionService optionService;
private final FreeMarkerConfigurer freeMarker;
public ContentFeedController(PostService postService, FreeMarkerConfigurer freeMarker) {
public ContentFeedController(PostService postService,
OptionService optionService,
FreeMarkerConfigurer freeMarker) {
this.postService = postService;
this.optionService = optionService;
this.freeMarker = freeMarker;
}
@ -75,7 +79,7 @@ public class ContentFeedController {
@GetMapping(value = {"atom", "atom.xml"}, produces = "application/xml;charset=UTF-8")
@ResponseBody
public String atom(Model model) throws IOException, TemplateException {
int pageSize = HaloUtils.getDefaultPageSize(10);
int pageSize = optionService.getPostPageSize();
final Sort sort = new Sort(Sort.Direction.DESC, "createTime");
final Pageable pageable = PageRequest.of(0, pageSize, sort);
model.addAttribute("posts", buildPosts(pageable));
@ -128,10 +132,11 @@ public class ContentFeedController {
/**
* Build posts for feed
*
* @param pageable pageable
* @return List<Post>
*/
private List<Post> buildPosts(Pageable pageable){
private List<Post> buildPosts(Pageable pageable) {
final Page<Post> postsPage = postService.pageBy(PostStatus.PUBLISHED, PostType.POST, pageable).map(post -> {
if (StrUtil.isNotEmpty(post.getPassword())) {
post.setFormatContent("该文章为加密文章");

View File

@ -3,8 +3,8 @@ package cc.ryanc.halo.web.controller.content;
import cc.ryanc.halo.model.enums.PostStatus;
import cc.ryanc.halo.model.enums.PostType;
import cc.ryanc.halo.model.vo.PostListVO;
import cc.ryanc.halo.service.OptionService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.web.controller.content.base.BaseContentController;
import cn.hutool.core.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
@ -34,8 +34,12 @@ public class ContentIndexController extends BaseContentController {
private final PostService postService;
public ContentIndexController(PostService postService) {
private final OptionService optionService;
public ContentIndexController(PostService postService,
OptionService optionService) {
this.postService = postService;
this.optionService = optionService;
}
@ -65,7 +69,7 @@ public class ContentIndexController extends BaseContentController {
@SortDefault(sort = "createTime", direction = DESC)
}) Sort sort) {
log.debug("Requested index page, sort info: [{}]", sort);
int pageSize = HaloUtils.getDefaultPageSize(10);
int pageSize = optionService.getPostPageSize();
Pageable pageable = PageRequest.of(page - 1, pageSize, sort);
Page<PostListVO> posts = postService.pageListVoBy(PostStatus.PUBLISHED, PostType.POST, pageable);
int[] rainbow = PageUtil.rainbow(page, posts.getTotalPages(), 3);

View File

@ -1,13 +1,11 @@
package cc.ryanc.halo.web.controller.content;
import cc.ryanc.halo.model.entity.Tag;
import cc.ryanc.halo.model.enums.BlogProperties;
import cc.ryanc.halo.model.vo.PostListVO;
import cc.ryanc.halo.service.OptionService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.TagService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.web.controller.content.base.BaseContentController;
import cn.hutool.core.util.StrUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@ -19,7 +17,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import static cc.ryanc.halo.model.support.HaloConst.OPTIONS;
import static org.springframework.data.domain.Sort.Direction.DESC;
/**
@ -36,9 +33,14 @@ public class ContentTagController extends BaseContentController {
private final PostService postService;
public ContentTagController(TagService tagService, PostService postService) {
private final OptionService optionService;
public ContentTagController(TagService tagService,
PostService postService,
OptionService optionService) {
this.tagService = tagService;
this.postService = postService;
this.optionService = optionService;
}
/**
@ -81,7 +83,7 @@ public class ContentTagController extends BaseContentController {
if (null == tag) {
return this.renderNotFound();
}
int size = HaloUtils.getDefaultPageSize(10);
int size = optionService.getPostPageSize();
final Pageable pageable = PageRequest.of(page - 1, size, sort);
// TODO get posts by tag

View File

@ -0,0 +1,90 @@
package cc.ryanc.halo.service.impl;
import cc.ryanc.halo.model.entity.Option;
import cc.ryanc.halo.model.enums.BlogProperties;
import cc.ryanc.halo.repository.OptionRepository;
import com.qiniu.common.Zone;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Optional;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
/**
* OptionService test.
*
* @author johnniang
* @date 3/22/19
*/
@RunWith(MockitoJUnitRunner.class)
public class OptionServiceImplTest {
@Mock
private OptionRepository optionRepository;
@InjectMocks
private OptionServiceImpl optionService;
@Test
public void getQiniuAutoZoneTest() {
getQiniuZoneTest("", Zone.autoZone());
}
@Test
public void getQiniuAutoZoneOfNullOptionTest() {
getQiniuZoneTest(Zone.autoZone(), null);
}
@Test
public void getQiniuZ0ZoneTest() {
getQiniuZoneTest("z0", Zone.zone0());
}
@Test
public void getQiniuZ1ZoneTest() {
getQiniuZoneTest("z1", Zone.zone1());
}
@Test
public void getQiniuZ2ZoneTest() {
getQiniuZoneTest("z2", Zone.zone2());
}
@Test
public void getQiniuAs0ZoneTest() {
getQiniuZoneTest("as0", Zone.zoneAs0());
}
@Test
public void getQiniuNa0ZoneTest() {
getQiniuZoneTest("na0", Zone.zoneNa0());
}
private void getQiniuZoneTest(String region, Zone actualZone) {
getQiniuZoneTest(actualZone, new Option("", region));
}
private void getQiniuZoneTest(Zone actualZone, Option option) {
BlogProperties zoneProperty = BlogProperties.QINIU_ZONE;
// Given
given(optionRepository.findByOptionKey(zoneProperty.getValue())).willReturn(Optional.ofNullable(option));
// When
Zone zone = optionService.getQiniuZone();
// Then
then(optionRepository).should().findByOptionKey(zoneProperty.getValue());
assertNotNull(zone);
assertThat(zone.getRegion(), equalTo(actualZone.getRegion()));
}
}

View File

@ -1,65 +0,0 @@
package cc.ryanc.halo.utils;
import cc.ryanc.halo.model.support.HaloConst;
import com.qiniu.common.Zone;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* HaloUtils test.
*
* @author johnniang
*/
public class HaloUtilsTest {
// @Test
// public void getDefaultPageSizeTest() {
// // Get page size
// int pageSize = HaloUtils.getDefaultPageSize();
// assertEquals(HaloUtils.DEFAULT_PAGE_SIZE, pageSize);
//
// // Cover the default page size
// HaloConst.OPTIONS.put(BlogPropertiesEnum.INDEX_POSTS.getProp(), String.valueOf(5));
//
// // Get page size again
// pageSize = HaloUtils.getDefaultPageSize();
// assertEquals(5, pageSize);
// }
@Test
public void getDefaultQiniuZoneTest() {
Zone zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.autoZone().getRegion(), zone.getRegion());
// Set zone manually
HaloConst.OPTIONS.put("qiniu_zone", "z0");
// Set zone manually
zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.zone0().getRegion(), zone.getRegion());
// Set zone manually
HaloConst.OPTIONS.put("qiniu_zone", "z1");
// Set zone manually
zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.zone1().getRegion(), zone.getRegion());
// Set zone manually
HaloConst.OPTIONS.put("qiniu_zone", "z2");
// Set zone manually
zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.zone2().getRegion(), zone.getRegion());
// Set zone manually
HaloConst.OPTIONS.put("qiniu_zone", "na0");
// Set zone manually
zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.zoneNa0().getRegion(), zone.getRegion());
// Set zone manually
HaloConst.OPTIONS.put("qiniu_zone", "as0");
// Set zone manually
zone = HaloUtils.getDefaultQiniuZone();
assertEquals(Zone.zoneAs0().getRegion(), zone.getRegion());
}
}