package io.spring.application; import static java.util.stream.Collectors.toList; import io.spring.application.data.ArticleData; import io.spring.application.data.ArticleDataList; import io.spring.application.data.ArticleFavoriteCount; import io.spring.core.user.User; import io.spring.infrastructure.mybatis.readservice.ArticleFavoritesReadService; import io.spring.infrastructure.mybatis.readservice.ArticleReadService; import io.spring.infrastructure.mybatis.readservice.UserRelationshipQueryService; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ArticleQueryService { private ArticleReadService articleReadService; private UserRelationshipQueryService userRelationshipQueryService; private ArticleFavoritesReadService articleFavoritesReadService; @Autowired public ArticleQueryService( ArticleReadService articleReadService, UserRelationshipQueryService userRelationshipQueryService, ArticleFavoritesReadService articleFavoritesReadService) { this.articleReadService = articleReadService; this.userRelationshipQueryService = userRelationshipQueryService; this.articleFavoritesReadService = articleFavoritesReadService; } public Optional findById(String id, User user) { ArticleData articleData = articleReadService.findById(id); if (articleData == null) { return Optional.empty(); } else { if (user != null) { fillExtraInfo(id, user, articleData); } return Optional.of(articleData); } } public Optional findBySlug(String slug, User user) { ArticleData articleData = articleReadService.findBySlug(slug); if (articleData == null) { return Optional.empty(); } else { if (user != null) { fillExtraInfo(articleData.getId(), user, articleData); } return Optional.of(articleData); } } public CursorPager findRecentArticlesWithCursor( String tag, String author, String favoritedBy, CursorPageParameter page, User currentUser) { List articleIds = articleReadService.findArticlesWithCursor(tag, author, favoritedBy, page); if (articleIds.size() == 0) { return new CursorPager<>(new ArrayList<>(), page.getDirection(), false); } else { boolean hasExtra = articleIds.size() > page.getLimit(); if (hasExtra) { articleIds.remove(page.getLimit()); } if (!page.isNext()) { Collections.reverse(articleIds); } List articles = articleReadService.findArticles(articleIds); fillExtraInfo(articles, currentUser); return new CursorPager<>(articles, page.getDirection(), hasExtra); } } public CursorPager findUserFeedWithCursor(User user, CursorPageParameter page) { List followdUsers = userRelationshipQueryService.followedUsers(user.getId()); if (followdUsers.size() == 0) { return new CursorPager<>(new ArrayList<>(), page.getDirection(), false); } else { List articles = articleReadService.findArticlesOfAuthorsWithCursor(followdUsers, page); boolean hasExtra = articles.size() > page.getLimit(); if (hasExtra) { articles.remove(page.getLimit()); } if (!page.isNext()) { Collections.reverse(articles); } fillExtraInfo(articles, user); return new CursorPager<>(articles, page.getDirection(), hasExtra); } } public ArticleDataList findRecentArticles( String tag, String author, String favoritedBy, Page page, User currentUser) { List articleIds = articleReadService.queryArticles(tag, author, favoritedBy, page); int articleCount = articleReadService.countArticle(tag, author, favoritedBy); if (articleIds.size() == 0) { return new ArticleDataList(new ArrayList<>(), articleCount); } else { List articles = articleReadService.findArticles(articleIds); fillExtraInfo(articles, currentUser); return new ArticleDataList(articles, articleCount); } } public ArticleDataList findUserFeed(User user, Page page) { List followdUsers = userRelationshipQueryService.followedUsers(user.getId()); if (followdUsers.size() == 0) { return new ArticleDataList(new ArrayList<>(), 0); } else { List articles = articleReadService.findArticlesOfAuthors(followdUsers, page); fillExtraInfo(articles, user); int count = articleReadService.countFeedSize(followdUsers); return new ArticleDataList(articles, count); } } private void fillExtraInfo(List articles, User currentUser) { setFavoriteCount(articles); if (currentUser != null) { setIsFavorite(articles, currentUser); setIsFollowingAuthor(articles, currentUser); } } private void setIsFollowingAuthor(List articles, User currentUser) { Set followingAuthors = userRelationshipQueryService.followingAuthors( currentUser.getId(), articles.stream() .map(articleData1 -> articleData1.getProfileData().getId()) .collect(toList())); articles.forEach( articleData -> { if (followingAuthors.contains(articleData.getProfileData().getId())) { articleData.getProfileData().setFollowing(true); } }); } private void setFavoriteCount(List articles) { List favoritesCounts = articleFavoritesReadService.articlesFavoriteCount( articles.stream().map(ArticleData::getId).collect(toList())); Map countMap = new HashMap<>(); favoritesCounts.forEach( item -> { countMap.put(item.getId(), item.getCount()); }); articles.forEach( articleData -> articleData.setFavoritesCount(countMap.get(articleData.getId()))); } private void setIsFavorite(List articles, User currentUser) { Set favoritedArticles = articleFavoritesReadService.userFavorites( articles.stream().map(articleData -> articleData.getId()).collect(toList()), currentUser); articles.forEach( articleData -> { if (favoritedArticles.contains(articleData.getId())) { articleData.setFavorited(true); } }); } private void fillExtraInfo(String id, User user, ArticleData articleData) { articleData.setFavorited(articleFavoritesReadService.isUserFavorite(user.getId(), id)); articleData.setFavoritesCount(articleFavoritesReadService.articleFavoriteCount(id)); articleData .getProfileData() .setFollowing( userRelationshipQueryService.isUserFollowing( user.getId(), articleData.getProfileData().getId())); } }