package fr.ippon.tatami.web.rest;
import com.yammer.metrics.annotation.Timed;
import fr.ippon.tatami.domain.Group;
import fr.ippon.tatami.domain.User;
import fr.ippon.tatami.repository.UserTagRepository;
import fr.ippon.tatami.security.AuthenticationService;
import fr.ippon.tatami.service.*;
import fr.ippon.tatami.service.dto.StatusDTO;
import fr.ippon.tatami.service.dto.UserDTO;
import fr.ippon.tatami.service.util.DomainUtil;
import fr.ippon.tatami.web.rest.dto.SearchResults;
import fr.ippon.tatami.web.rest.dto.Tag;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* Search engine controller.
*/
@Controller
public class SearchController {
private final Logger log = LoggerFactory.getLogger(SearchController.class);
@Inject
private AuthenticationService authenticationService;
@Inject
private SearchService searchService;
@Inject
private TimelineService timelineService;
@Inject
private UserService userService;
@Inject
private GroupService groupService;
@Inject
private TrendService trendService;
@Inject
private UserTagRepository userTagRepository;
/**
* GET /search/all?q=tatami -> search users, tags, groups for "tatami"
*/
@RequestMapping(value = "/rest/search/all",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
@Timed
public SearchResults search(@RequestParam(value = "q", required = false, defaultValue = "") String q) {
SearchResults searchResults = new SearchResults();
searchResults.setTags(this.searchRecentTags(q));
searchResults.setUsers(this.searchUsers(q));
searchResults.setGroups(this.searchGroups(q));
return searchResults;
}
/**
* GET /search/status?q=tatami -> get the status where "tatami" appears
*/
@RequestMapping(value = "/rest/search/status",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
@Timed
public Collection<StatusDTO> listStatusForUser(@RequestParam(value = "q", required = false, defaultValue = "") String query,
@RequestParam(value = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(value = "rpp", required = false, defaultValue = "20") Integer rpp) {
log.debug("REST request to search status containing these words ({}).", query);
final User currentUser = authenticationService.getCurrentUser();
String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());
List<String> line;
if (StringUtils.isNotBlank(query)) {
line = searchService.searchStatus(domain, query, page, rpp);
} else {
line = Collections.emptyList();
}
return timelineService.buildStatusList(line);
}
/**
* GET /search/tags" -> search tags<br>
*
* @return a Collection of tags matching the query
*/
@RequestMapping(value = "/rest/search/tags",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
@Timed
public Collection<Tag> searchRecentTags(@RequestParam("q") String query) {
String prefix = query.toLowerCase();
String currentLogin = authenticationService.getCurrentUser().getLogin();
String domain = DomainUtil.getDomainFromLogin(currentLogin);
Collection<String> followedTags = userTagRepository.findTags(currentLogin);
Collection<String> trends = trendService.searchTags(domain, prefix, 5);
Collection<Tag> tags = new ArrayList<Tag>();
if (query != null && !query.equals("")) {
this.log.debug("REST request to find tags starting with : {}", prefix);
for (String trend : trends) {
Tag tag = new Tag();
tag.setName(trend);
if (followedTags.contains(trend)) {
tag.setFollowed(true);
}
tags.add(tag);
}
}
return tags;
}
/**
* GET /search/groups" -> search groups<br>
*
* @return a Collection of groups matching the query
*/
@RequestMapping(value = "/rest/search/groups",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
@Timed
public Collection<Group> searchGroups(@RequestParam("q") String query) {
String prefix = query.toLowerCase();
String currentLogin = authenticationService.getCurrentUser().getLogin();
String domain = DomainUtil.getDomainFromLogin(currentLogin);
Collection<Group> groups;
if (query != null && !query.equals("")) {
this.log.debug("REST request to find groups starting with : {}", prefix);
groups = searchService.searchGroupByPrefix(domain, prefix, 5);
} else {
groups = new ArrayList<Group>();
}
return groupService.buildGroupList(groups);
}
/**
* GET /search/users" -> search user by username<br>
* Should return a collection of users matching the query.<br>
* The collection doesn't contain the current user even if he matches the query.<br>
* If nothing matches, an empty collection (but not null) is returned.<br>
*
* @param query the query
* @return a Collection of User
*/
@RequestMapping(value = "/rest/search/users",
method = RequestMethod.GET,
produces = "application/json")
@ResponseBody
@Timed
public Collection<UserDTO> searchUsers(@RequestParam("q") String query) {
String prefix = query.toLowerCase();
User currentUser = authenticationService.getCurrentUser();
String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());
Collection<String> logins = searchService.searchUserByPrefix(domain, prefix);
Collection<User> users;
if (query != null && !query.equals("")) {
this.log.debug("REST request to find users starting with : {}", prefix);
users = userService.getUsersByLogin(logins);
} else {
users = new ArrayList<User>();
}
return userService.buildUserDTOList(users);
}
}