package com.huixinpn.dionysus.controller.question;
import com.huixinpn.dionysus.controller.util.PagingHelper;
import com.huixinpn.dionysus.controller.util.Utils;
import com.huixinpn.dionysus.domain.question.Answer;
import com.huixinpn.dionysus.domain.question.QTag;
import com.huixinpn.dionysus.domain.question.Question;
import com.huixinpn.dionysus.domain.user.User;
import com.huixinpn.dionysus.dto.EntityCollectionData;
import com.huixinpn.dionysus.dto.EntityPageData;
import com.huixinpn.dionysus.dto.question.AnswerData;
import com.huixinpn.dionysus.dto.question.QTagData;
import com.huixinpn.dionysus.dto.question.QuestionData;
import com.huixinpn.dionysus.repository.question.AnswerRepository;
import com.huixinpn.dionysus.repository.question.QTagRepository;
import com.huixinpn.dionysus.repository.question.QuestionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collection;
@RestController
@RequestMapping(value = "/controllers/questions")
public class QuestionController {
@Autowired
QuestionRepository questionRepository;
@Autowired
AnswerRepository answerRepository;
@Autowired
QTagRepository qTagRepository;
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET)
public EntityPageData<QuestionData> getAllQuestions(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findAll(paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = {"", "/"}, method = RequestMethod.POST)
public ResponseEntity<String> createQuestion(@RequestBody QuestionData data) {
Question q = new Question();
q.setTitle(data.getTitle());
q.setDescription(data.getDescription());
String tagsInput = data.getTagsInput();
String[] tags = tagsInput.split(",");
Collection<QTag> tagEntities = new ArrayList<>();
for (String tag : tags) {
QTag entity = qTagRepository.findByName(tag);
if (entity == null) {
entity = new QTag();
entity.setName(tag);
}
tagEntities.add(entity);
}
q.setTags(tagEntities);
Question added = questionRepository.save(q);
return new ResponseEntity<>(Utils.wrapSaveResult(added.getId()), HttpStatus.OK);
}
@RequestMapping(value = "/me", method = RequestMethod.GET)
public EntityPageData<QuestionData> myQuestions(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
User login = (User) authentication.getPrincipal();
Page<Question> questions = questionRepository.findByAuthor(login, paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/bytag/{id}", method = RequestMethod.GET)
public EntityPageData<QuestionData> findQuestionsByTag(@PathVariable Long id, @RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findByTag(new QTag(id), paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/bytagName/{name}", method = RequestMethod.GET)
public EntityPageData<QuestionData> findQuestionsByTagName(@PathVariable String name, @RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findByTagName(name, paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/byauthor/{id}", method = RequestMethod.GET)
public EntityPageData<QuestionData> findQuestionsByAuthor(@PathVariable Long id, @RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findByAuthor(new User(id), paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/byDate", method = RequestMethod.GET)
public EntityPageData<QuestionData> findQuestionsByDate(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findLatestQueations(paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/bySize", method = RequestMethod.GET)
public EntityPageData<QuestionData> findQuestionsBySizeOfAnswers(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest paging = PagingHelper.getPageRequest(page, size);
Page<Question> questions = questionRepository.findPopularQueations(paging);
return new EntityPageData<>(questions, QuestionData.class);
}
@RequestMapping(value = "/latest", method = RequestMethod.GET)
public Collection<QuestionData> getLatestQuestions(@RequestParam(value = "N") Integer n) {
PageRequest page = PagingHelper.getPageRequest(0, n);
Page<Question> latest = questionRepository.findLatestQueations(page);
return new EntityPageData<>(latest, QuestionData.class).getContent();
}
@RequestMapping(value = "/popular", method = RequestMethod.GET)
public Collection<QuestionData> getPopularQuestions(@RequestParam(value = "N") Integer n) {
PageRequest page = PagingHelper.getPageRequest(0, n);
Page<Question> popular = questionRepository.findPopularQueations(page);
return new EntityPageData<>(popular, QuestionData.class).getContent();
}
@RequestMapping(value = "/answered", method = RequestMethod.GET)
public EntityPageData<QuestionData> getAllAnswered(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest pageRequest = PagingHelper.getPageRequest(page, size);
Page<Question> popular = questionRepository.findAllAnswered(pageRequest);
return new EntityPageData<>(popular, QuestionData.class);
}
@RequestMapping(value = "/unanswered", method = RequestMethod.GET)
public EntityPageData<QuestionData> getAllUnanswered(@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "size", required = false) Integer size) {
PageRequest pageRequest = PagingHelper.getPageRequest(page, size);
Page<Question> popular = questionRepository.findAllUnanswered(pageRequest);
return new EntityPageData<>(popular, QuestionData.class);
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public QuestionData getQuestion(@PathVariable Long id) {
Question question = questionRepository.findOne(id);
return new QuestionData(question);
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public ResponseEntity<String> updateQuestion(@PathVariable Long id, @RequestBody QuestionData data) {
Question q = questionRepository.findOne(id);
q.setTitle(data.getTitle());
q.setDescription(data.getDescription());
String tagsInput = data.getTagsInput();
String[] tags = tagsInput.split(",");
Collection<QTag> tagEntities = new ArrayList<>();
for (String tag : tags) {
QTag entity = qTagRepository.findByName(tag);
if (entity == null) {
entity = new QTag();
entity.setName(tag);
}
tagEntities.add(entity);
}
q.setTags(tagEntities);
questionRepository.save(q);
return new ResponseEntity(Utils.EMPTY_JSON_OBJECT, HttpStatus.OK);
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public ResponseEntity<String> deleteQuestion(@PathVariable Long id) {
questionRepository.delete(id);
return new ResponseEntity(Utils.EMPTY_JSON_OBJECT, HttpStatus.OK);
}
@RequestMapping(value = "/{id}/answers", method = RequestMethod.GET)
public Collection<AnswerData> getAnswers(@PathVariable Long id) {
Question question = questionRepository.findOne(id);
Collection<Answer> reordered = new ArrayList<>();
Collection<Answer> answeredByUser = new ArrayList<>();
Collection<Answer> answers = question.getAnswers();
for (Answer answer : answers) {
if (answer.getCreatedBy().isConsultant()) {
reordered.add(answer);
} else {
answeredByUser.add(answer);
}
}
reordered.addAll(answeredByUser);
return new EntityCollectionData<>(reordered, AnswerData.class).toDTOCollection();
}
@RequestMapping(value = "/{id}/answers", method = RequestMethod.POST)
public AnswerData addAnswer(@PathVariable Long id, @RequestBody AnswerData data) {
Answer answer = new Answer();
answer.setQuestion(new Question(id));
data.update(answer);
Answer added = answerRepository.save(answer);
return new AnswerData(added);
}
@RequestMapping(value = "/answers/{id}", method = RequestMethod.DELETE)
public ResponseEntity<String> deleteAnswer(@PathVariable Long id) {
answerRepository.delete(id);
return new ResponseEntity(Utils.EMPTY_JSON_OBJECT, HttpStatus.OK);
}
@RequestMapping(value = "/answers/{id}", method = RequestMethod.PUT)
public ResponseEntity<String> updateAnswer(@PathVariable Long id, @RequestBody AnswerData data) {
Answer updating = answerRepository.findOne(id);
data.update(updating);
Answer updated = answerRepository.save(updating);
return new ResponseEntity(Utils.EMPTY_JSON_OBJECT, HttpStatus.OK);
}
@RequestMapping(value = "/tags", method = RequestMethod.GET)
public Collection<QTagData> getTags() {
return new EntityCollectionData<QTagData>(qTagRepository.findAll(), QTagData.class).toDTOCollection();
}
@RequestMapping(value = "/tags/autocomplete", method = RequestMethod.GET)
public Collection<String> getAutocmpleteTags() {
Collection<QTagData> tags = new EntityCollectionData<QTagData>(qTagRepository.findAll(), QTagData.class).toDTOCollection();
Collection<String> result = new ArrayList<>();
for (QTagData tag : tags) {
result.add(tag.getName());
}
return result;
}
@RequestMapping(value = "/tags/topN", method = RequestMethod.GET)
public Collection<QTagData> getTopNTags(@RequestParam(value = "N") Integer n) {
PageRequest page = PagingHelper.getPageRequest(0, n);
return new EntityPageData<>(qTagRepository.findTopNTag(page), QTagData.class).getContent();
}
}