Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.wallride.service.ArticleService Maven / Gradle / Ivy
/*
* Copyright 2014 Tagbangers, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wallride.service;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.MessageCodesResolver;
import org.wallride.autoconfigure.WallRideCacheConfiguration;
import org.wallride.autoconfigure.WallRideProperties;
import org.wallride.domain.*;
import org.wallride.exception.DuplicateCodeException;
import org.wallride.exception.EmptyCodeException;
import org.wallride.exception.NotNullException;
import org.wallride.exception.ServiceException;
import org.wallride.model.*;
import org.wallride.repository.*;
import org.wallride.support.AuthorizedUser;
import org.wallride.support.CodeFormatter;
import org.wallride.web.controller.admin.article.CustomFieldValueEditForm;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
@Transactional(rollbackFor=Exception.class)
public class ArticleService {
@Resource
private BlogService blogService;
@Resource
private PostRepository postRepository;
@Resource
private ArticleRepository articleRepository;
@Resource
private TagRepository tagRepository;
@Resource
private MediaRepository mediaRepository;
@Inject
private MessageCodesResolver messageCodesResolver;
@Inject
private PlatformTransactionManager transactionManager;
@Inject
private WallRideProperties wallRideProperties;
@PersistenceContext
private EntityManager entityManager;
private static Logger logger = LoggerFactory.getLogger(ArticleService.class);
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article createArticle(ArticleCreateRequest request, Post.Status status, AuthorizedUser authorizedUser) {
LocalDateTime now = LocalDateTime.now();
String code = request.getCode();
if (code == null) {
try {
code = new CodeFormatter().parse(request.getTitle(), LocaleContextHolder.getLocale());
} catch (ParseException e) {
throw new ServiceException(e);
}
}
if (!StringUtils.hasText(code)) {
if (!status.equals(Post.Status.DRAFT)) {
throw new EmptyCodeException();
}
}
if (!status.equals(Post.Status.DRAFT)) {
Post duplicate = postRepository.findOneByCodeAndLanguage(code, request.getLanguage());
if (duplicate != null) {
throw new DuplicateCodeException(code);
}
}
Article article = new Article();
if (!status.equals(Post.Status.DRAFT)) {
article.setCode(code);
article.setDraftedCode(null);
}
else {
article.setCode(null);
article.setDraftedCode(code);
}
Media cover = null;
if (request.getCoverId() != null) {
cover = entityManager.getReference(Media.class, request.getCoverId());
}
article.setCover(cover);
article.setTitle(request.getTitle());
article.setBody(request.getBody());
article.setAuthor(entityManager.getReference(User.class, authorizedUser.getId()));
LocalDateTime date = request.getDate();
if (Post.Status.PUBLISHED.equals(status)) {
if (date == null) {
date = now;
}
else if (date.isAfter(now)) {
status = Post.Status.SCHEDULED;
}
}
article.setDate(date);
article.setStatus(status);
article.setLanguage(request.getLanguage());
article.getCategories().clear();
for (long categoryId : request.getCategoryIds()) {
article.getCategories().add(entityManager.getReference(Category.class, categoryId));
}
article.getTags().clear();
Set tagNames = StringUtils.commaDelimitedListToSet(request.getTags());
if (!CollectionUtils.isEmpty(tagNames)) {
for (String tagName : tagNames) {
Tag tag = tagRepository.findOneForUpdateByNameAndLanguage(tagName, request.getLanguage());
if (tag == null) {
tag = new Tag();
tag.setName(tagName);
tag.setLanguage(request.getLanguage());
article.setCreatedAt(now);
article.setCreatedBy(authorizedUser.toString());
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
tag = tagRepository.saveAndFlush(tag);
}
article.getTags().add(tag);
}
}
article.getRelatedPosts().clear();
Set relatedPosts = new HashSet<>();
for (long relatedId : request.getRelatedPostIds()) {
relatedPosts.add(entityManager.getReference(Post.class, relatedId));
}
article.setRelatedToPosts(relatedPosts);
Seo seo = new Seo();
seo.setTitle(request.getSeoTitle());
seo.setDescription(request.getSeoDescription());
seo.setKeywords(request.getSeoKeywords());
article.setSeo(seo);
List medias = new ArrayList<>();
if (StringUtils.hasText(request.getBody())) {
// Blog blog = blogService.getBlogById(Blog.DEFAULT_ID);
String mediaUrlPrefix = wallRideProperties.getMediaUrlPrefix();
Pattern mediaUrlPattern = Pattern.compile(String.format("%s([0-9a-zA-Z\\-]+)", mediaUrlPrefix));
Matcher mediaUrlMatcher = mediaUrlPattern.matcher(request.getBody());
while (mediaUrlMatcher.find()) {
Media media = mediaRepository.findOneById(mediaUrlMatcher.group(1));
medias.add(media);
}
}
article.setMedias(medias);
article.setCreatedAt(now);
article.setCreatedBy(authorizedUser.toString());
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
article.getCustomFieldValues().clear();
if (!CollectionUtils.isEmpty(request.getCustomFieldValues())) {
for (CustomFieldValueEditForm valueForm : request.getCustomFieldValues()) {
CustomFieldValue value = new CustomFieldValue();
value.setCustomField(entityManager.getReference(CustomField.class, valueForm.getCustomFieldId()));
value.setPost(article);
if (valueForm.getFieldType().equals(CustomField.FieldType.CHECKBOX)) {
if (!ArrayUtils.isEmpty(valueForm.getTextValues())) {
value.setTextValue(String.join(",", valueForm.getTextValues()));
} else {
value.setTextValue(null);
}
} else {
value.setTextValue(valueForm.getTextValue());
}
value.setStringValue(valueForm.getStringValue());
value.setNumberValue(valueForm.getNumberValue());
value.setDateValue(valueForm.getDateValue());
value.setDatetimeValue(valueForm.getDatetimeValue());
if (!value.isEmpty()) {
article.getCustomFieldValues().add(value);
}
}
}
return articleRepository.save(article);
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article saveArticleAsDraft(ArticleUpdateRequest request, AuthorizedUser authorizedUser) {
postRepository.lock(request.getId());
Article article = articleRepository.findOneByIdAndLanguage(request.getId(), request.getLanguage());
if (!article.getStatus().equals(Post.Status.DRAFT)) {
Article draft = articleRepository.findOne(ArticleSpecifications.draft(article));
if (draft == null) {
ArticleCreateRequest createRequest = new ArticleCreateRequest.Builder()
.code(request.getCode())
.coverId(request.getCoverId())
.title(request.getTitle())
.body(request.getBody())
.authorId(request.getAuthorId())
.date(request.getDate())
.categoryIds(request.getCategoryIds())
.tags(request.getTags())
.seoTitle(request.getSeoTitle())
.seoDescription(request.getSeoDescription())
.seoKeywords(request.getSeoKeywords())
.customFieldValues(new ArrayList<>(request.getCustomFieldValues()))
.language(request.getLanguage())
.build();
draft = createArticle(createRequest, Post.Status.DRAFT, authorizedUser);
draft.setDrafted(article);
return articleRepository.save(draft);
}
else {
ArticleUpdateRequest updateRequest = new ArticleUpdateRequest.Builder()
.id(draft.getId())
.code(request.getCode())
.coverId(request.getCoverId())
.title(request.getTitle())
.body(request.getBody())
.authorId(request.getAuthorId())
.date(request.getDate())
.categoryIds(request.getCategoryIds())
.tags(request.getTags())
.seoTitle(request.getSeoTitle())
.seoDescription(request.getSeoDescription())
.seoKeywords(request.getSeoKeywords())
.customFieldValues(request.getCustomFieldValues())
.language(request.getLanguage())
.build();
return saveArticle(updateRequest, authorizedUser);
}
}
else {
return saveArticle(request, authorizedUser);
}
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article saveArticleAsPublished(ArticleUpdateRequest request, AuthorizedUser authorizedUser) {
postRepository.lock(request.getId());
Article article = articleRepository.findOneByIdAndLanguage(request.getId(), request.getLanguage());
publishArticle(article);
return saveArticle(request, authorizedUser);
}
private Article publishArticle(Article article) {
Article deleteTarget = getDraftById(article.getId());
if (deleteTarget != null) {
articleRepository.delete(deleteTarget);
}
article.setDrafted(null);
article.setStatus(Post.Status.PUBLISHED);
Article published = articleRepository.save(article);
return published;
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article saveArticleAsUnpublished(ArticleUpdateRequest request, AuthorizedUser authorizedUser) {
postRepository.lock(request.getId());
Article article = articleRepository.findOneByIdAndLanguage(request.getId(), request.getLanguage());
unpublishArticle(article);
return saveArticle(request, authorizedUser);
}
private Article unpublishArticle(Article article) {
Article deleteTarget = getDraftById(article.getId());
if (deleteTarget != null) {
articleRepository.delete(deleteTarget);
}
article.setDrafted(null);
article.setStatus(Post.Status.DRAFT);
Article unpublished = articleRepository.save(article);
return unpublished;
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article saveArticle(ArticleUpdateRequest request, AuthorizedUser authorizedUser) {
postRepository.lock(request.getId());
Article article = articleRepository.findOneByIdAndLanguage(request.getId(), request.getLanguage());
LocalDateTime now = LocalDateTime.now();
String code = request.getCode();
if (code == null) {
try {
code = new CodeFormatter().parse(request.getTitle(), LocaleContextHolder.getLocale());
} catch (ParseException e) {
throw new ServiceException(e);
}
}
if (!StringUtils.hasText(code)) {
if (!article.getStatus().equals(Post.Status.DRAFT)) {
throw new EmptyCodeException();
}
}
if (!article.getStatus().equals(Post.Status.DRAFT)) {
Post duplicate = postRepository.findOneByCodeAndLanguage(code, request.getLanguage());
if (duplicate != null && !duplicate.equals(article)) {
throw new DuplicateCodeException(code);
}
}
if (!article.getStatus().equals(Post.Status.DRAFT)) {
article.setCode(code);
article.setDraftedCode(null);
}
else {
article.setCode(null);
article.setDraftedCode(code);
}
Media cover = null;
if (request.getCoverId() != null) {
cover = entityManager.getReference(Media.class, request.getCoverId());
}
article.setCover(cover);
article.setTitle(request.getTitle());
article.setBody(request.getBody());
// User author = null;
// if (request.getAuthorId() != null) {
// author = entityManager.getReference(User.class, request.getAuthorId());
// }
// article.setAuthor(author);
LocalDateTime date = request.getDate();
if (!Post.Status.DRAFT.equals(article.getStatus())) {
if (date == null) {
date = now;
} else if (date.isAfter(now)) {
article.setStatus(Post.Status.SCHEDULED);
} else {
article.setStatus(Post.Status.PUBLISHED);
}
}
article.setDate(date);
article.setLanguage(request.getLanguage());
article.getCategories().clear();
for (long categoryId : request.getCategoryIds()) {
article.getCategories().add(entityManager.getReference(Category.class, categoryId));
}
article.getTags().clear();
Set tagNames = StringUtils.commaDelimitedListToSet(request.getTags());
if (!CollectionUtils.isEmpty(tagNames)) {
for (String tagName : tagNames) {
Tag tag = tagRepository.findOneForUpdateByNameAndLanguage(tagName, request.getLanguage());
if (tag == null) {
tag = new Tag();
tag.setName(tagName);
tag.setLanguage(request.getLanguage());
article.setCreatedAt(now);
article.setCreatedBy(authorizedUser.toString());
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
tag = tagRepository.saveAndFlush(tag);
}
article.getTags().add(tag);
}
}
article.getRelatedPosts().clear();
Set relatedPosts = new HashSet<>();
for (long relatedId : request.getRelatedPostIds()) {
relatedPosts.add(entityManager.getReference(Post.class, relatedId));
}
article.setRelatedToPosts(relatedPosts);
Seo seo = new Seo();
seo.setTitle(request.getSeoTitle());
seo.setDescription(request.getSeoDescription());
seo.setKeywords(request.getSeoKeywords());
article.setSeo(seo);
List medias = new ArrayList<>();
if (StringUtils.hasText(request.getBody())) {
// Blog blog = blogService.getBlogById(Blog.DEFAULT_ID);
String mediaUrlPrefix = wallRideProperties.getMediaUrlPrefix();
Pattern mediaUrlPattern = Pattern.compile(String.format("%s([0-9a-zA-Z\\-]+)", mediaUrlPrefix));
Matcher mediaUrlMatcher = mediaUrlPattern.matcher(request.getBody());
while (mediaUrlMatcher.find()) {
Media media = mediaRepository.findOneById(mediaUrlMatcher.group(1));
medias.add(media);
}
}
article.setMedias(medias);
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
Map valueMap = new LinkedHashMap<>();
for (CustomFieldValue value : article.getCustomFieldValues()) {
valueMap.put(value.getCustomField(), value);
}
article.getCustomFieldValues().clear();
if (!CollectionUtils.isEmpty(request.getCustomFieldValues())) {
for (CustomFieldValueEditForm valueForm : request.getCustomFieldValues()) {
CustomField customField = entityManager.getReference(CustomField.class, valueForm.getCustomFieldId());
CustomFieldValue value = valueMap.get(customField);
if (value == null) {
value = new CustomFieldValue();
}
value.setCustomField(customField);
value.setPost(article);
if (valueForm.getFieldType().equals(CustomField.FieldType.CHECKBOX)) {
if (!ArrayUtils.isEmpty(valueForm.getTextValues())) {
value.setTextValue(String.join(",", valueForm.getTextValues()));
} else {
value.setTextValue(null);
}
} else {
value.setTextValue(valueForm.getTextValue());
}
value.setStringValue(valueForm.getStringValue());
value.setNumberValue(valueForm.getNumberValue());
value.setDateValue(valueForm.getDateValue());
value.setDatetimeValue(valueForm.getDatetimeValue());
if (!value.isEmpty()) {
article.getCustomFieldValues().add(value);
}
}
}
return articleRepository.save(article);
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public Article deleteArticle(ArticleDeleteRequest request, BindingResult result) throws BindException {
postRepository.lock(request.getId());
Article article = articleRepository.findOneByIdAndLanguage(request.getId(), request.getLanguage());
articleRepository.delete(article);
return article;
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public List bulkPublishArticle(ArticleBulkPublishRequest request, AuthorizedUser authorizedUser) {
List articles = new ArrayList<>();
for (long id : request.getIds()) {
postRepository.lock(id);
Article article = articleRepository.findOneByIdAndLanguage(id, request.getLanguage());
if (article.getStatus() != Post.Status.DRAFT && request.getDate() == null) {
continue;
}
if (!StringUtils.hasText(article.getCode())) {
throw new NotNullException();
}
if (!StringUtils.hasText(article.getTitle())) {
throw new NotNullException();
}
if (!StringUtils.hasText(article.getBody())) {
throw new NotNullException();
}
LocalDateTime now = LocalDateTime.now();
LocalDateTime date = article.getDate();
if (request.getDate() != null) {
date = request.getDate();
}
if (date == null) {
date = now;
}
article.setDate(date);
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
article = publishArticle(article);
if (article.getDate().isAfter(now)) {
article.setStatus(Post.Status.SCHEDULED);
} else {
article.setStatus(Post.Status.PUBLISHED);
}
article = articleRepository.saveAndFlush(article);
articles.add(article);
}
return articles;
}
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public List bulkUnpublishArticle(ArticleBulkUnpublishRequest request, AuthorizedUser authorizedUser) {
List articles = new ArrayList<>();
for (long id : request.getIds()) {
postRepository.lock(id);
Article article = articleRepository.findOneByIdAndLanguage(id, request.getLanguage());
if (article.getStatus() == Post.Status.DRAFT) {
continue;
}
LocalDateTime now = LocalDateTime.now();
article.setUpdatedAt(now);
article.setUpdatedBy(authorizedUser.toString());
article = unpublishArticle(article);
articles.add(article);
}
return articles;
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@CacheEvict(value = WallRideCacheConfiguration.ARTICLE_CACHE, allEntries = true)
public List bulkDeleteArticle(ArticleBulkDeleteRequest bulkDeleteRequest, BindingResult result) {
List articles = new ArrayList<>();
for (long id : bulkDeleteRequest.getIds()) {
final ArticleDeleteRequest deleteRequest = new ArticleDeleteRequest.Builder()
.id(id)
.language(bulkDeleteRequest.getLanguage())
.build();
final BeanPropertyBindingResult r = new BeanPropertyBindingResult(deleteRequest, "request");
r.setMessageCodesResolver(messageCodesResolver);
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW);
Article article = null;
try {
article = transactionTemplate.execute(new TransactionCallback() {
public Article doInTransaction(TransactionStatus status) {
try {
return deleteArticle(deleteRequest, r);
}
catch (BindException e) {
throw new RuntimeException(e);
}
}
});
articles.add(article);
}
catch (Exception e) {
logger.debug("Errors: {}", r);
result.addAllErrors(r);
}
}
return articles;
}
public List getArticleIds(ArticleSearchRequest request) {
return articleRepository.searchForId(request);
}
public Page getArticles(ArticleSearchRequest request) {
Pageable pageable = new PageRequest(0, 10);
return getArticles(request, pageable);
}
@Cacheable(value = WallRideCacheConfiguration.ARTICLE_CACHE)
public Page getArticles(ArticleSearchRequest request, Pageable pageable) {
return articleRepository.search(request, pageable);
}
public List getArticles(Collection ids) {
Set results = new LinkedHashSet(articleRepository.findAllByIdIn(ids));
List articles = new ArrayList<>();
for (long id : ids) {
for (Article article : results) {
if (id == article.getId()) {
articles.add(article);
break;
}
}
}
return articles;
}
@Cacheable(value = WallRideCacheConfiguration.ARTICLE_CACHE)
public SortedSet getArticlesByCategoryCode(String language, String code, Post.Status status) {
return getArticlesByCategoryCode(language, code, status, 10);
}
@Cacheable(value = WallRideCacheConfiguration.ARTICLE_CACHE)
public SortedSet getArticlesByCategoryCode(String language, String code, Post.Status status, int size) {
ArticleSearchRequest request = new ArticleSearchRequest()
.withLanguage(language)
.withCategoryCodes(code)
.withStatus(status);
Pageable pageable = new PageRequest(0, size);
Page page = articleRepository.search(request, pageable);
return new TreeSet<>(page.getContent());
}
@Cacheable(value = WallRideCacheConfiguration.ARTICLE_CACHE)
public SortedSet getLatestArticles(String language, Post.Status status, int size) {
ArticleSearchRequest request = new ArticleSearchRequest()
.withLanguage(language)
.withStatus(status);
Pageable pageable = new PageRequest(0, size);
Page page = articleRepository.search(request, pageable);
return new TreeSet<>(page.getContent());
}
public Article getArticleById(long id) {
return articleRepository.findOneById(id);
}
public Article getArticleById(long id, String language) {
return articleRepository.findOneByIdAndLanguage(id, language);
}
@Cacheable(value = WallRideCacheConfiguration.ARTICLE_CACHE)
public Article getArticleByCode(String code, String language) {
return articleRepository.findOneByCodeAndLanguage(code, language);
}
public Article getDraftById(long id) {
return articleRepository.findOne(ArticleSpecifications.draft(entityManager.getReference(Article.class, id)));
}
public long countArticles(String language) {
return articleRepository.count(language);
}
public long countArticlesByStatus(Post.Status status, String language) {
return articleRepository.countByStatus(status, language);
}
public Map countArticlesByAuthorIdGrouped(Post.Status status, String language) {
List> results = articleRepository.countByAuthorIdGrouped(status, language);
Map counts = new HashMap<>();
for (Map row : results) {
counts.put((Long) row.get("userId"), (Long) row.get("count"));
}
return counts;
}
public Map countArticlesByCategoryIdGrouped(Post.Status status, String language) {
List> results = articleRepository.countByCategoryIdGrouped(status, language);
Map counts = new HashMap<>();
for (Map row : results) {
counts.put((Long) row.get("categoryId"), (Long) row.get("count"));
}
return counts;
}
public Map countArticlesByTagIdGrouped(Post.Status status, String language) {
List> results = articleRepository.countByTagIdGrouped(status, language);
Map counts = new HashMap<>();
for (Map row : results) {
counts.put((Long) row.get("tagId"), (Long) row.get("count"));
}
return counts;
}
}