From 9fc360d6c416809e538fb2fcd4b4e81fbaae4632 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dennis=20Sch=C3=B6nhof?= <dennis.schoenhof@mni.thm.de>
Date: Sun, 7 Feb 2016 15:44:39 +0100
Subject: [PATCH] freetext questions are saved

---
 .../java/de/thm/arsnova/dao/CouchDBDao.java   |  24 +++-
 .../java/de/thm/arsnova/entities/Answer.java  |  27 +++++
 .../de/thm/arsnova/entities/Question.java     | 107 ++++++++++++++++++
 .../arsnova/entities/transport/Answer.java    |  38 +++++++
 .../thm/arsnova/services/QuestionService.java |  10 ++
 5 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
index 77910b97..ed97cb29 100644
--- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
+++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java
@@ -561,6 +561,13 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		question.updateRoundManagementState();
 		q.put("type", "skill_question");
 		q.put("questionType", question.getQuestionType());
+		q.put("ignoreCaseSensitive", question.isIgnoreCaseSensitive());
+		q.put("ignoreWhitespaces", question.isIgnoreWhitespaces());
+		q.put("ignorePunctuation", question.isIgnorePunctuation());
+		q.put("fixedAnswer", question.isFixedAnswer());
+		q.put("strictMode", question.isStrictMode());
+		q.put("rating", question.getRating());
+		q.put("correctAnswer", question.getCorrectAnswer());
 		q.put("questionVariant", question.getQuestionVariant());
 		q.put("sessionId", session.get_id());
 		q.put("subject", question.getSubject());
@@ -634,6 +641,13 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 			q.put("piRoundFinished", question.isPiRoundFinished());
 			q.put("piRoundActive", question.isPiRoundActive());
 			q.put("showStatistic", question.isShowStatistic());
+			q.put("ignoreCaseSensitive", question.isIgnoreCaseSensitive());
+			q.put("ignoreWhitespaces", question.isIgnoreWhitespaces());
+			q.put("ignorePunctuation", question.isIgnorePunctuation());
+			q.put("fixedAnswer", question.isFixedAnswer());
+			q.put("strictMode", question.isStrictMode());
+			q.put("rating", question.getRating());
+			q.put("correctAnswer", question.getCorrectAnswer());
 			q.put("showAnswer", question.isShowAnswer());
 			q.put("abstention", question.isAbstention());
 			q.put("image", question.getImage());
@@ -1400,6 +1414,9 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 		a.put("questionVariant", answer.getQuestionVariant());
 		a.put("questionValue", answer.getQuestionValue());
 		a.put("answerText", answer.getAnswerText());
+		a.put("answerTextRaw", answer.getAnswerTextRaw());
+		a.put("freeTextScore", answer.getFreeTextScore());
+		a.put("successfulFreeTextAnswer", answer.isSuccessfulFreeTextAnswer());
 		a.put("timestamp", answer.getTimestamp());
 		a.put("user", user.getUsername());
 		a.put("piRound", answer.getPiRound());
@@ -1452,6 +1469,9 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 			final Document a = database.getDocument(answer.get_id());
 			a.put("answerSubject", answer.getAnswerSubject());
 			a.put("answerText", answer.getAnswerText());
+			a.put("answerTextRaw", answer.getAnswerTextRaw());
+			a.put("freeTextScore", answer.getFreeTextScore());
+			a.put("successfulFreeTextAnswer", answer.isSuccessfulFreeTextAnswer());
 			a.put("timestamp", answer.getTimestamp());
 			a.put("abstention", answer.isAbstention());
 			a.put("questionValue", answer.getQuestionValue());
@@ -1563,7 +1583,7 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 	}
 
 	@Override
-	@Caching(evict = { @CacheEvict("sessions"), @CacheEvict(cacheNames="sessions", key="#p0.keyword") })
+	@Caching(evict = { @CacheEvict("sessions"), @CacheEvict(cacheNames = "sessions", key = "#p0.keyword") })
 	public void deleteSession(final Session session) {
 		try {
 			deleteDocument(session.get_id());
@@ -2145,6 +2165,8 @@ public class CouchDBDao implements IDatabaseDao, ApplicationEventPublisherAware
 					answerDoc.put("questionVariant", a.getQuestionVariant());
 					answerDoc.put("questionValue", a.getQuestionValue());
 					answerDoc.put("answerText", a.getAnswerText());
+					answerDoc.put("answerTextRaw", a.getAnswerTextRaw());
+					answerDoc.put("freeTextScore", a.getFreeTextScore());
 					answerDoc.put("timestamp", a.getTimestamp());
 					answerDoc.put("piRound", a.getPiRound());
 					answerDoc.put("abstention", a.isAbstention());
diff --git a/src/main/java/de/thm/arsnova/entities/Answer.java b/src/main/java/de/thm/arsnova/entities/Answer.java
index a923e80f..f85d2f52 100644
--- a/src/main/java/de/thm/arsnova/entities/Answer.java
+++ b/src/main/java/de/thm/arsnova/entities/Answer.java
@@ -37,7 +37,10 @@ public class Answer implements Serializable {
 	private String sessionId;
 	private String questionId;
 	private String answerText;
+	private String answerTextRaw;
 	private String answerSubject;
+	private double freeTextScore;
+	private boolean successfulFreeTextAnswer;
 	private String questionVariant;
 	private int questionValue;
 	private int piRound;
@@ -108,6 +111,14 @@ public class Answer implements Serializable {
 		this.answerText = answerText;
 	}
 
+	public final String getAnswerTextRaw() {
+		return this.answerTextRaw;
+	}
+
+	public final void setAnswerTextRaw(final String answerTextRaw) {
+		this.answerTextRaw = answerTextRaw;
+	}
+
 	@ApiModelProperty(required = true, value = "the answer subject")
 	public final String getAnswerSubject() {
 		return answerSubject;
@@ -117,6 +128,22 @@ public class Answer implements Serializable {
 		this.answerSubject = answerSubject;
 	}
 
+	public final double getFreeTextScore() {
+		return this.freeTextScore;
+	}
+
+	public final void setFreeTextScore(final double freeTextScore) {
+		this.freeTextScore = freeTextScore;
+	}
+
+	public final boolean isSuccessfulFreeTextAnswer() {
+		return this.successfulFreeTextAnswer;
+	}
+
+	public final void setSuccessfulFreeTextAnswer(final boolean successfulFreeTextAnswer) {
+		this.successfulFreeTextAnswer = successfulFreeTextAnswer;
+	}
+
 	@ApiModelProperty(required = true, value = "the peer instruction round nr.")
 	public int getPiRound() {
 		return piRound;
diff --git a/src/main/java/de/thm/arsnova/entities/Question.java b/src/main/java/de/thm/arsnova/entities/Question.java
index 7d4aa2ab..42c16736 100644
--- a/src/main/java/de/thm/arsnova/entities/Question.java
+++ b/src/main/java/de/thm/arsnova/entities/Question.java
@@ -55,6 +55,13 @@ public class Question implements Serializable {
 	private boolean showStatistic; // sic
 	private boolean showAnswer;
 	private boolean abstention;
+	private boolean ignoreCaseSensitive;
+	private boolean ignoreWhitespaces;
+	private boolean ignorePunctuation;
+	private boolean fixedAnswer;
+	private boolean strictMode;
+	private double rating;
+	private String correctAnswer;
 	private String _id;
 	private String _rev;
 
@@ -310,6 +317,62 @@ public class Question implements Serializable {
 		this.abstention = abstention;
 	}
 
+	public boolean isIgnoreCaseSensitive() {
+		return ignoreCaseSensitive;
+	}
+
+	public void setIgnoreCaseSensitive(final boolean ignoreCaseSensitive) {
+		this.ignoreCaseSensitive = ignoreCaseSensitive;
+	}
+
+	public boolean isIgnoreWhitespaces() {
+		return ignoreWhitespaces;
+	}
+
+	public void setIgnoreWhitespaces(final boolean ignoreWhitespaces) {
+		this.ignoreWhitespaces = ignoreWhitespaces;
+	}
+
+	public boolean isIgnorePunctuation() {
+		return ignorePunctuation;
+	}
+
+	public void setIgnorePunctuation(final boolean ignorePunctuation) {
+		this.ignorePunctuation = ignorePunctuation;
+	}
+
+	public boolean isFixedAnswer() {
+		return this.fixedAnswer;
+	}
+
+	public void setFixedAnswer(final boolean fixedAnswer) {
+		this.fixedAnswer = fixedAnswer;
+	}
+
+	public boolean isStrictMode() {
+		return this.strictMode;
+	}
+
+	public void setStrictMode(final boolean strictMode) {
+		this.strictMode = strictMode;
+	}
+
+	public final double getRating() {
+		return this.rating;
+	}
+
+	public final void setRating(final double rating) {
+		this.rating = rating;
+	}
+
+	public final String getCorrectAnswer() {
+		return correctAnswer;
+	}
+
+	public final void setCorrectAnswer(final String correctAnswer) {
+		this.correctAnswer = correctAnswer;
+	}
+
 	@ApiModelProperty(required = true, value = "the couchDB ID")
 	public final String get_id() {
 		return _id;
@@ -599,6 +662,50 @@ public class Question implements Serializable {
 		}
 	}
 
+	public String checkCaseSensitive(String answerText) {
+		if (this.isIgnoreCaseSensitive()) {
+			this.setCorrectAnswer(this.getCorrectAnswer().toLowerCase());
+			return answerText.toLowerCase();
+		}
+		return answerText;
+	}
+	public String checkWhitespaces(String answerText) {
+		if (this.isIgnoreWhitespaces()) {
+			this.setCorrectAnswer(this.getCorrectAnswer().replaceAll("[\\s]", ""));
+			return answerText.replaceAll("[\\s]", "");
+		}
+		return answerText;
+	}
+	public String checkPunctuation(String answerText) {
+		if (this.isIgnorePunctuation()) {
+			this.setCorrectAnswer(this.getCorrectAnswer().replaceAll("\\p{Punct}", ""));
+			return answerText.replaceAll("\\p{Punct}", "");
+		}
+		return answerText;
+	}
+
+	public void checkTextStricktOptions(Answer answer) {
+		answer.setAnswerTextRaw(this.checkCaseSensitive(answer.getAnswerTextRaw()));
+		answer.setAnswerTextRaw(this.checkPunctuation(answer.getAnswerTextRaw()));
+		answer.setAnswerTextRaw(this.checkWhitespaces(answer.getAnswerTextRaw()));
+	}
+
+	public double evaluateCorrectAnswerFixedText(String answerTextRaw) {
+		if (answerTextRaw != null) {
+			if (answerTextRaw.equals(this.getCorrectAnswer())) {
+				return this.getRating();
+			}
+		}
+		return 0;
+	}
+
+	public boolean isSuccessfulFreeTextAnswer(String answerTextRaw) {
+		if (answerTextRaw != null) {
+			return answerTextRaw.equals(this.getCorrectAnswer());
+		}
+		return false;
+	}
+
 	public void updateRoundStartVariables(Date start, Date end) {
 		if (this.getPiRound() == 1 && this.isPiRoundFinished()) {
 			this.setPiRound(2);
diff --git a/src/main/java/de/thm/arsnova/entities/transport/Answer.java b/src/main/java/de/thm/arsnova/entities/transport/Answer.java
index 89d705a6..4b321430 100644
--- a/src/main/java/de/thm/arsnova/entities/transport/Answer.java
+++ b/src/main/java/de/thm/arsnova/entities/transport/Answer.java
@@ -35,7 +35,12 @@ public class Answer implements Serializable {
 
 	private String answerSubject;
 
+	private String answerSubjectRaw;
+
 	private String answerText;
+	private String answerTextRaw;
+	private double freeTextScore;
+	private boolean successfulFreeTextAnswer;
 
 	private String answerImage;
 
@@ -70,6 +75,38 @@ public class Answer implements Serializable {
 		this.answerSubject = answerSubject;
 	}
 
+	public final String getAnswerTextRaw() {
+		return this.answerTextRaw;
+	}
+
+	public final void setAnswerTextRaw(final String answerTextRaw) {
+		this.answerTextRaw = answerTextRaw;
+	}
+
+	public final String getAnswerSubjectRaw() {
+		return this.answerSubjectRaw;
+	}
+
+	public final void setAnswerSubjectRaw(final String answerSubjectRaw) {
+		this.answerSubjectRaw = answerSubjectRaw;
+	}
+
+	public final double getFreeTextScore() {
+		return this.freeTextScore;
+	}
+
+	public final void setFreeTextScore(final double freeTextScore) {
+		this.freeTextScore = freeTextScore;
+	}
+
+	public final boolean isSuccessfulFreeTextAnswer() {
+		return this.successfulFreeTextAnswer;
+	}
+
+	public final void setSuccessfulFreeTextAnswer(final boolean successfulFreeTextAnswer) {
+		this.successfulFreeTextAnswer = successfulFreeTextAnswer;
+	}
+
 	@ApiModelProperty(required = true, value = "abstention")
 	public boolean isAbstention() {
 		return abstention;
@@ -85,6 +122,7 @@ public class Answer implements Serializable {
 		de.thm.arsnova.entities.Answer theAnswer = new de.thm.arsnova.entities.Answer();
 		theAnswer.setAnswerSubject(this.getAnswerSubject());
 		theAnswer.setAnswerText(this.getAnswerText());
+		theAnswer.setAnswerTextRaw(this.getAnswerTextRaw());
 		theAnswer.setSessionId(question.getSessionId());
 		theAnswer.setUser(user.getUsername());
 		theAnswer.setQuestionId(question.get_id());
diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java
index 4b4f4135..46075a80 100644
--- a/src/main/java/de/thm/arsnova/services/QuestionService.java
+++ b/src/main/java/de/thm/arsnova/services/QuestionService.java
@@ -732,6 +732,15 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis
 		Answer theAnswer = answer.generateAnswerEntity(user, question);
 		if ("freetext".equals(question.getQuestionType())) {
 			imageUtils.generateThumbnailImage(theAnswer);
+			theAnswer.setAnswerTextRaw(new String(theAnswer.getAnswerText()));
+
+			if (question.isStrictMode()) {
+				question.checkTextStricktOptions(theAnswer);
+			}
+			if (question.isFixedAnswer()) {
+				theAnswer.setFreeTextScore(question.evaluateCorrectAnswerFixedText(theAnswer.getAnswerTextRaw()));
+				theAnswer.setSuccessfulFreeTextAnswer(question.isSuccessfulFreeTextAnswer(theAnswer.getAnswerTextRaw()));
+			}
 		}
 
 		return databaseDao.saveAnswer(theAnswer, user, question, getSession(question.getSessionKeyword()));
@@ -749,6 +758,7 @@ public class QuestionService implements IQuestionService, ApplicationEventPublis
 		final Question question = getQuestion(answer.getQuestionId());
 		if ("freetext".equals(question.getQuestionType())) {
 			imageUtils.generateThumbnailImage(realAnswer);
+			question.checkTextStricktOptions(realAnswer);
 		}
 		final Answer result = databaseDao.updateAnswer(realAnswer);
 		final Session session = databaseDao.getSessionFromKeyword(question.getSessionKeyword());
-- 
GitLab