From 26a359bf1d62428d0107251aa4ae817c1631dcfe Mon Sep 17 00:00:00 2001
From: Julian Hochstetter <julian.hochstetter@mni.thm.de>
Date: Fri, 26 Oct 2012 09:48:03 +0200
Subject: [PATCH] Task #4038: getUnansweredSkillQuestions Task #4027:
 getQuestionById fixes if a list of answers exist which could not morphed by
 self

---
 .../controller/QuestionController.java        | 26 +++++---
 .../java/de/thm/arsnova/dao/CouchDBDao.java   | 59 +++++++++++++++++--
 .../java/de/thm/arsnova/dao/IDatabaseDao.java |  5 +-
 .../de/thm/arsnova/entities/Question.java     |  2 +-
 .../arsnova/services/IQuestionService.java    |  3 +-
 .../thm/arsnova/services/QuestionService.java | 10 +++-
 .../de/thm/arsnova/dao/StubDatabaseDao.java   | 10 +++-
 7 files changed, 93 insertions(+), 22 deletions(-)

diff --git a/src/main/java/de/thm/arsnova/controller/QuestionController.java b/src/main/java/de/thm/arsnova/controller/QuestionController.java
index ea0c749d..7b38deb0 100644
--- a/src/main/java/de/thm/arsnova/controller/QuestionController.java
+++ b/src/main/java/de/thm/arsnova/controller/QuestionController.java
@@ -31,7 +31,6 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
 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 de.thm.arsnova.entities.Question;
@@ -58,11 +57,10 @@ public class QuestionController extends AbstractController {
 	@RequestMapping(value="/session/{sessionkey}/question/{questionId}", method=RequestMethod.GET)
 	@ResponseBody
 	public Question getQuestion(@PathVariable String sessionkey, @PathVariable String questionId, HttpServletResponse response) {
-		Question question = questionService.getQuestion(questionId);
-		if (question != null && question.getSession().equals(sessionkey)) {
+		Question question = questionService.getQuestion(questionId, sessionkey);
+		if (question != null) {
 			return question;
-		}
-		
+		}		
 		response.setStatus(HttpStatus.NOT_FOUND.value());
 		return null;
 	}
@@ -102,7 +100,7 @@ public class QuestionController extends AbstractController {
 		return questions;
 	}
 	
-	@RequestMapping("/session/{sessionKey}/questionids")
+	@RequestMapping(value="/session/{sessionKey}/questionids", method=RequestMethod.GET)
 	@ResponseBody
 	public List<String> getQuestionIds(@PathVariable String sessionKey, HttpServletResponse response) {
 		List<String> questions = questionService.getQuestionIds(sessionKey);
@@ -110,13 +108,23 @@ public class QuestionController extends AbstractController {
 			throw new NotFoundException();
 		}
 		logger.info(questions.toString());
-		return questions;
-		
+		return questions;		
 	}
 	
-	@RequestMapping(value="/session/{sessionKey}/questions/{questiondId}", method=RequestMethod.DELETE)
+	@RequestMapping(value="/session/{sessionKey}/questions/{questionId}", method=RequestMethod.DELETE)
 	@ResponseBody
 	public void deleteAnswersAndQuestion(@PathVariable String sessionKey, @PathVariable String questionId, HttpServletResponse response) {
 		questionService.deleteQuestion(sessionKey, questionId);
 	}
+	
+	@RequestMapping(value="/session/{sessionKey}/questions/unanswered", method=RequestMethod.GET)
+	@ResponseBody
+	public List<String> getUnAnsweredSkillQuestions(@PathVariable String sessionKey, HttpServletResponse response) {
+		List<String> answers = questionService.getUnAnsweredQuestions(sessionKey);
+		if(answers == null || answers.isEmpty()) {
+			throw new NotFoundException();
+		}
+		logger.info(answers.toString());
+		return answers;
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index a0090fa7..13bf4c74 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -496,7 +496,11 @@ public class CouchDBDao implements IDatabaseDao {
 	
 	
 	@Override
-	public Question getQuestion(String id) {
+	public Question getQuestion(String id, String sessionKey) {
+		Session s = this.getSessionFromKeyword(sessionKey);
+		if(s == null) {
+			throw new NotFoundException();
+		}
 		try {
 			View view = new View("skill_question/by_id");
 			view.setKey(URLEncoder.encode("\"" + id + "\"", "UTF-8"));
@@ -506,10 +510,16 @@ public class CouchDBDao implements IDatabaseDao {
 				return null;
 			}
 			
-			return (Question) JSONObject.toBean(
-					results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"),
-					Question.class
-			);
+			Question q = (Question) JSONObject.toBean(results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"), Question.class);
+			JSONArray possibleAnswers = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value").getJSONArray("possibleAnswers");
+			Collection<PossibleAnswer> answers = JSONArray.toCollection(possibleAnswers, PossibleAnswer.class);
+			q.setPossibleAnswers(new ArrayList<PossibleAnswer>(answers));
+			
+			if(s.get_id().equals(q.getSessionId())) {
+				return q;
+			} else {
+				throw new UnauthorizedException();
+			}
 		} catch (IOException e) {
 			logger.error("Could not get question with id {}", id);
 		}
@@ -632,4 +642,43 @@ public class CouchDBDao implements IDatabaseDao {
 			logger.error("Could not delete question and its answers with id {}", questionId);
 		} 
 	}
+
+	@Override
+	public List<String> getUnAnsweredQuestions(String sessionKey) {
+		User user = userService.getCurrentUser();
+		if(user == null) {
+			throw new UnauthorizedException();
+		}
+		
+		Session s = this.getSessionFromKeyword(sessionKey);
+		if(s == null) {
+			throw new NotFoundException();
+		}
+		
+		try {
+			View view = new View("answer/by_user");
+			view.setKey("[" + URLEncoder.encode("\"" + user.getUsername() + "\",\"" + s.get_id()+ "\"", "UTF-8") + "]");
+			ViewResults anseweredQuestions = this.getDatabase().view(view);
+
+			List<String> answered = new ArrayList<String>();
+			for (Document d : anseweredQuestions.getResults()) {
+				answered.add(d.getString("value"));
+			}
+
+			List<String> questions = this.getQuestionIds(sessionKey);
+			List<String> unanswered = new ArrayList<String>();
+			for(String questionId : questions) {
+				if(!answered.contains(questionId)) {
+					unanswered.add(questionId);
+				}
+			}
+			return unanswered;
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		
+		return null;
+	}
 }
diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
index 3744d44e..63a357f4 100644
--- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
+++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java
@@ -22,8 +22,8 @@ package de.thm.arsnova.dao;
 import java.util.List;
 
 import de.thm.arsnova.entities.Feedback;
-import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.LoggedIn;
+import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 
@@ -38,7 +38,7 @@ public interface IDatabaseDao {
 	public boolean sessionKeyAvailable(String keyword);
 	
 	public boolean saveQuestion(Session session, Question question);
-	public Question getQuestion(String id);
+	public Question getQuestion(String id, String sessionKey);
 	List<Question> getSkillQuestions(String session);
 	public int getSkillQuestionCount(String sessionkey);
 	
@@ -46,4 +46,5 @@ public interface IDatabaseDao {
 	public void updateSessionOwnerActivity(Session session);
 	public List<String> getQuestionIds(String sessionKey);
 	public void deleteQuestion(String sessionKey, String questionId);
+	public List<String> getUnAnsweredQuestions(String sessionKey);
 }
\ No newline at end of file
diff --git a/src/main/java/de/thm/arsnova/entities/Question.java b/src/main/java/de/thm/arsnova/entities/Question.java
index b72a3787..0ed8fadb 100644
--- a/src/main/java/de/thm/arsnova/entities/Question.java
+++ b/src/main/java/de/thm/arsnova/entities/Question.java
@@ -152,7 +152,7 @@ public class Question {
 
 	@Override
 	public String toString() {
-		return "Question type '" + this.questionType + "': " + this.subject + ";\n" + this.text +
+		return "Question type '" + this.questionType + "': " + this.subject + ", session: " + session + ";\n" + this.text +
 				this.possibleAnswers;
 	}
 }
diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java
index 80297730..ee1aa11a 100644
--- a/src/main/java/de/thm/arsnova/services/IQuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java
@@ -26,9 +26,10 @@ import de.thm.arsnova.entities.Question;
 
 public interface IQuestionService {
 	public boolean saveQuestion(Question question);
-	public Question getQuestion(String id);
+	public Question getQuestion(String id, String sessionkey);
 	public List<Question> getSkillQuestions(String sessionkey);
 	public int getSkillQuestionCount(String sessionkey);
 	public List<String> getQuestionIds(String sessionKey);
 	public void deleteQuestion(String sessionKey, String questionId);
+	public List<String> getUnAnsweredQuestions(String sessionKey);
 }
\ No newline at end of file
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 9b1c551f..279318e3 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -65,8 +65,8 @@ public class QuestionService implements IQuestionService {
 	
 	@Override
 	@Authenticated
-	public Question getQuestion(String id) {
-		return databaseDao.getQuestion(id);
+	public Question getQuestion(String id, String sessionKey) {
+		return databaseDao.getQuestion(id, sessionKey);
 	}
 	
 	@Override
@@ -81,4 +81,10 @@ public class QuestionService implements IQuestionService {
 		databaseDao.deleteQuestion(sessionKey, questionId);
 		
 	}
+
+	@Override
+	@Authenticated
+	public List<String> getUnAnsweredQuestions(String sessionKey) {
+		return databaseDao.getUnAnsweredQuestions(sessionKey);
+	}
 }
diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
index df870222..5b746a10 100644
--- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
+++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java
@@ -10,8 +10,8 @@ import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
 import de.thm.arsnova.entities.Feedback;
-import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.LoggedIn;
+import de.thm.arsnova.entities.Question;
 import de.thm.arsnova.entities.Session;
 import de.thm.arsnova.entities.User;
 import de.thm.arsnova.exceptions.ForbiddenException;
@@ -128,7 +128,7 @@ public class StubDatabaseDao implements IDatabaseDao {
 	}
 
 	@Override
-	public Question getQuestion(String id) {
+	public Question getQuestion(String id, String sesseionKey) {
 		// Simply ... no such question ;-)
 		return null;
 	}
@@ -175,4 +175,10 @@ public class StubDatabaseDao implements IDatabaseDao {
 		
 	}
 
+	@Override
+	public List<String> getUnAnsweredQuestions(String sessionKey) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 }
-- 
GitLab