diff --git a/pom.xml b/pom.xml index 94048192cfb4d281ba39b11178affa09fdd0a228..a44ed1231cad9369f4f2fa1282d6c3197832eb4c 100644 --- a/pom.xml +++ b/pom.xml @@ -142,12 +142,6 @@ <version>0.0.1-SNAPSHOT</version> <type>war</type> </dependency> - <dependency> - <groupId>org.dojotoolkit</groupId> - <artifactId>dojo-war</artifactId> - <version>1.8.0</version> - <type>war</type> - </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> diff --git a/src/main/java/de/thm/arsnova/controller/QuestionController.java b/src/main/java/de/thm/arsnova/controller/QuestionController.java index 58af4be1671b54e875879448f7a7d362017cf551..44deca320d080ce81c33d17922a41f11f1a15607 100644 --- a/src/main/java/de/thm/arsnova/controller/QuestionController.java +++ b/src/main/java/de/thm/arsnova/controller/QuestionController.java @@ -34,6 +34,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import de.thm.arsnova.entities.Answer; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.Question; import de.thm.arsnova.exceptions.NotFoundException; import de.thm.arsnova.services.IQuestionService; @@ -261,13 +262,14 @@ public class QuestionController extends AbstractController { @RequestMapping(value = "/session/{sessionKey}/interposed", method = RequestMethod.GET) @ResponseBody - public final List<Question> getInterposedQuestions( + public final List<InterposedQuestion> getInterposedQuestions( @PathVariable final String sessionKey, final HttpServletResponse response ) { return questionService.getInterposedQuestions(sessionKey); } +<<<<<<< HEAD @RequestMapping(value = "/session/{sessionKey}/interposed/{documentId}", method = RequestMethod.GET) @ResponseBody public final Question getInterposedQuestion( @@ -276,6 +278,28 @@ public class QuestionController extends AbstractController { final HttpServletResponse response ) { return questionService.getInterposedQuestion(sessionKey, documentId); +======= + + @RequestMapping(value = "/session/{sessionkey}/interposed", method = RequestMethod.POST) + @ResponseBody + public final void postInterposedQuestion( + @PathVariable final String sessionkey, + @RequestBody final InterposedQuestion question, + final HttpServletResponse response + ) { + if (!sessionkey.equals(question.getSession())) { + response.setStatus(HttpStatus.PRECONDITION_FAILED.value()); + return; + } + + if (questionService.saveQuestion(question)) { + response.setStatus(HttpStatus.CREATED.value()); + return; + } + + response.setStatus(HttpStatus.BAD_REQUEST.value()); + return; +>>>>>>> 83eba294f9a7f8a8250127f8b5673aff0fc04663 } } diff --git a/src/main/java/de/thm/arsnova/controller/SessionController.java b/src/main/java/de/thm/arsnova/controller/SessionController.java index 26d2300cf503c1298c0452720a7afbe04aac7f3d..00adecaca30c00940754079bc52678d80bf37474 100644 --- a/src/main/java/de/thm/arsnova/controller/SessionController.java +++ b/src/main/java/de/thm/arsnova/controller/SessionController.java @@ -66,7 +66,9 @@ public class SessionController extends AbstractController { User u = userService.getCurrentUser(); LOGGER.info("authorize session: " + socketid + ", user is: " + u); response.setStatus(u != null ? HttpStatus.CREATED.value() : HttpStatus.UNAUTHORIZED.value()); - userService.putUser2SessionID(UUID.fromString(socketid), u); + if(u != null) { + userService.putUser2SocketId(UUID.fromString(socketid), u); + } } @RequestMapping(value = "/session/{sessionkey}", method = RequestMethod.GET) diff --git a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java index 40434a63a96b0953680897d8e97f8be3661a2347..9488fedb810338c227312e3c63d3af7ec80c80b0 100644 --- a/src/main/java/de/thm/arsnova/dao/CouchDBDao.java +++ b/src/main/java/de/thm/arsnova/dao/CouchDBDao.java @@ -57,6 +57,7 @@ import com.fourspaces.couchdb.ViewResults; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.PossibleAnswer; import de.thm.arsnova.entities.Question; @@ -541,11 +542,30 @@ public class CouchDBDao implements IDatabaseDao { q.put("noCorrect", question.isNoCorrect()); try { database.saveDocument(q); + return true; } catch (IOException e) { LOGGER.error("Could not save question {}", question); } return false; } + + @Override + public final boolean saveQuestion(final Session session, final InterposedQuestion question) { + Document q = new Document(); + q.put("type", "interposed_question"); + q.put("sessionId", session.get_id()); + q.put("subject", question.getSubject()); + q.put("text", question.getText()); + q.put("timestamp", System.currentTimeMillis()); + q.put("read", false); + try { + database.saveDocument(q); + return true; + } catch (IOException e) { + LOGGER.error("Could not save interposed question {}", question); + } + return false; + } @Override public final Question getQuestion(final String id, final String sessionKey) { @@ -596,9 +616,12 @@ public class CouchDBDao implements IDatabaseDao { if (results.getJSONArray("rows").optJSONObject(0) != null) { JSONObject json = results.getJSONArray("rows").optJSONObject(0).optJSONObject("value"); loggedIn = (LoggedIn) JSONObject.toBean(json, LoggedIn.class); - Collection<VisitedSession> visitedSessions = JSONArray.toCollection( - json.getJSONArray("visitedSessions"), VisitedSession.class); - loggedIn.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + JSONArray vs = json.optJSONArray("visitedSessions"); + if(vs != null) { + Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, + VisitedSession.class); + loggedIn.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + } } loggedIn.setUser(user.getUsername()); @@ -620,9 +643,12 @@ public class CouchDBDao implements IDatabaseDao { this.getDatabase().saveDocument(doc); LoggedIn l = (LoggedIn) JSONObject.toBean(doc.getJSONObject(), LoggedIn.class); - Collection<VisitedSession> visitedSessions = JSONArray.toCollection( - doc.getJSONObject().getJSONArray("visitedSessions"), VisitedSession.class); - l.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + JSONArray vs = doc.getJSONObject().optJSONArray("visitedSessions"); + if(vs != null) { + Collection<VisitedSession> visitedSessions = JSONArray.toCollection(vs, + VisitedSession.class); + l.setVisitedSessions(new ArrayList<VisitedSession>(visitedSessions)); + } return l; } catch (UnsupportedEncodingException e) { return null; @@ -892,6 +918,7 @@ public class CouchDBDao implements IDatabaseDao { @Override public final int countActiveUsers(Session session, long since) { + if (session == null) throw new NotFoundException(); try { View view = new View("logged_in/count"); view.setStartKey( @@ -1019,7 +1046,7 @@ public class CouchDBDao implements IDatabaseDao { } @Override - public List<Question> getInterposedQuestions(String sessionKey) { + public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { Session s = this.getSessionFromKeyword(sessionKey); if (s == null) { throw new NotFoundException(); @@ -1032,14 +1059,15 @@ public class CouchDBDao implements IDatabaseDao { if (questions == null || questions.isEmpty()) { return null; } - List<Question> result = new ArrayList<Question>(); + List<InterposedQuestion> result = new ArrayList<InterposedQuestion>(); + LOGGER.debug("{}", questions.getResults()); for (Document document : questions.getResults()) { - Question question = (Question) JSONObject.toBean( + InterposedQuestion question = (InterposedQuestion) JSONObject.toBean( document.getJSONObject().getJSONObject("value"), - Question.class + InterposedQuestion.class ); - question.setQuestionType("interposed_question"); - question.setSession(s.get_id()); + question.setSession(sessionKey); + question.set_id(document.getId()); result.add(question); } return result; diff --git a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java index ad03cf43263fc95198e7130177cd8ece7f0fda96..1a83084bf17aa0df4abcdc455f0de75b3a263326 100644 --- a/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java +++ b/src/main/java/de/thm/arsnova/dao/IDatabaseDao.java @@ -24,6 +24,7 @@ import java.util.List; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; @@ -47,6 +48,8 @@ public interface IDatabaseDao { boolean sessionKeyAvailable(String keyword); boolean saveQuestion(Session session, Question question); + + boolean saveQuestion(Session session, InterposedQuestion question); Question getQuestion(String id, String sessionKey); @@ -84,7 +87,7 @@ public interface IDatabaseDao { int getInterposedCount(String sessionKey); - List<Question> getInterposedQuestions(String sessionKey); + List<InterposedQuestion> getInterposedQuestions(String sessionKey); void vote(String menu); diff --git a/src/main/java/de/thm/arsnova/entities/InterposedQuestion.java b/src/main/java/de/thm/arsnova/entities/InterposedQuestion.java new file mode 100644 index 0000000000000000000000000000000000000000..477cf799b2216dd5b222b105525fa417722923bd --- /dev/null +++ b/src/main/java/de/thm/arsnova/entities/InterposedQuestion.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2012 THM webMedia + * + * This file is part of ARSnova. + * + * ARSnova is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ARSnova is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +package de.thm.arsnova.entities; + +public class InterposedQuestion { + + private String _id; + private String _rev; + private String type; + private String subject; + private String text; + private String session; + private long timestamp; + private boolean read; + + public String get_id() { + return _id; + } + public void set_id(String _id) { + this._id = _id; + } + public String get_rev() { + return _rev; + } + public void set_rev(String _rev) { + this._rev = _rev; + } + public boolean isRead() { + return read; + } + public void setRead(boolean read) { + this.read = read; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getSubject() { + return subject; + } + public void setSubject(String subject) { + this.subject = subject; + } + public String getText() { + return text; + } + public void setText(String text) { + this.text = text; + } + public String getSession() { + return session; + } + public void setSession(String session) { + this.session = session; + } + public long getTimestamp() { + return timestamp; + } + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + +} diff --git a/src/main/java/de/thm/arsnova/entities/Question.java b/src/main/java/de/thm/arsnova/entities/Question.java index 803c3a99f44db6ebbffc9246b1ccb2dcf34e34c0..e10266e989e8e64241d2238f42049bd4fc1dd137 100644 --- a/src/main/java/de/thm/arsnova/entities/Question.java +++ b/src/main/java/de/thm/arsnova/entities/Question.java @@ -23,6 +23,7 @@ import java.util.List; public class Question { private String type; + private String questionType; private String subject; private String text; private boolean active; @@ -45,11 +46,11 @@ public class Question { } public final String getQuestionType() { - return type; + return questionType; } public final void setQuestionType(final String questionType) { - this.type = questionType; + this.questionType = questionType; } public final String getSubject() { diff --git a/src/main/java/de/thm/arsnova/services/FeedbackService.java b/src/main/java/de/thm/arsnova/services/FeedbackService.java index 5085a298d7bd2b354424ae3caae22c958631b4a8..53a0ee4f793ebd5cca1061025b17b78ed6f55410 100644 --- a/src/main/java/de/thm/arsnova/services/FeedbackService.java +++ b/src/main/java/de/thm/arsnova/services/FeedbackService.java @@ -102,9 +102,7 @@ public class FeedbackService implements IFeedbackService { public final boolean saveFeedback(final String keyword, final int value, final User user) { boolean result = databaseDao.saveFeedback(keyword, value, user); if (result) { - HashSet<String> set = new HashSet<String>(); - set.add(keyword); - this.server.reportUpdatedFeedbackForSessions(set); + this.server.reportUpdatedFeedbackForSession(keyword); } return result; } @@ -130,7 +128,10 @@ public class FeedbackService implements IFeedbackService { this.server.reportDeletedFeedback(e.getKey(), e.getValue()); } } - this.server.reportUpdatedFeedbackForSessions(allAffectedSessions); + for(String session : allAffectedSessions) { + this.server.reportUpdatedFeedbackForSession(session); + } + } @Override diff --git a/src/main/java/de/thm/arsnova/services/IQuestionService.java b/src/main/java/de/thm/arsnova/services/IQuestionService.java index f97af720e0a075103ee67641abd34d62ac7347d4..c835a577aa060f2857529143ed7b9c2664d1be75 100644 --- a/src/main/java/de/thm/arsnova/services/IQuestionService.java +++ b/src/main/java/de/thm/arsnova/services/IQuestionService.java @@ -22,10 +22,13 @@ package de.thm.arsnova.services; import java.util.List; import de.thm.arsnova.entities.Answer; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.Question; public interface IQuestionService { boolean saveQuestion(Question question); + + boolean saveQuestion(InterposedQuestion question); Question getQuestion(String id, String sessionkey); @@ -56,4 +59,7 @@ public interface IQuestionService { List<Question> getInterposedQuestions(String sessionKey); Question getInterposedQuestion(String sessionKey, String documentId); + + List<InterposedQuestion> getInterposedQuestions(String sessionKey); + } diff --git a/src/main/java/de/thm/arsnova/services/IUserService.java b/src/main/java/de/thm/arsnova/services/IUserService.java index 68180f18c7f8c1ff5d35096a2661f927186ada81..a045c91e0b21cc8e7949b3e62bd20aae88dc0205 100644 --- a/src/main/java/de/thm/arsnova/services/IUserService.java +++ b/src/main/java/de/thm/arsnova/services/IUserService.java @@ -29,13 +29,13 @@ import de.thm.arsnova.entities.User; public interface IUserService { User getCurrentUser(); - User getUser2SessionID(UUID sessionID); + User getUser2SocketId(UUID socketId); - void putUser2SessionID(UUID sessionID, User user); + void putUser2SocketId(UUID socketId, User user); - void removeUser2SessionID(UUID sessionID); + void removeUser2SocketId(UUID socketId); - Set<Map.Entry<UUID, User>> users2Session(); + Set<Map.Entry<UUID, User>> socketId2User(); boolean isUserInSession(User user, String keyword); diff --git a/src/main/java/de/thm/arsnova/services/QuestionService.java b/src/main/java/de/thm/arsnova/services/QuestionService.java index 74a72a84e9db6bd130336e8c68aae3d927f5f03a..214e13c0825f08ff7ee3c48e6b7a208c986f9351 100644 --- a/src/main/java/de/thm/arsnova/services/QuestionService.java +++ b/src/main/java/de/thm/arsnova/services/QuestionService.java @@ -27,22 +27,16 @@ import org.springframework.stereotype.Service; import de.thm.arsnova.annotation.Authenticated; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.Answer; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; import de.thm.arsnova.exceptions.NoContentException; -import de.thm.arsnova.socket.ARSnovaSocketIOServer; @Service public class QuestionService implements IQuestionService { @Autowired - ARSnovaSocketIOServer server; - - @Autowired - IDatabaseDao databaseDao; - - @Autowired - IUserService userService; + private IDatabaseDao databaseDao; public void setDatabaseDao(IDatabaseDao databaseDao) { this.databaseDao = databaseDao; @@ -52,8 +46,9 @@ public class QuestionService implements IQuestionService { @Authenticated public List<Question> getSkillQuestions(String sessionkey) { List<Question> result = databaseDao.getSkillQuestions(sessionkey); - if (result == null || result.size() == 0) + if (result == null || result.size() == 0) { throw new NoContentException(); + } return result; } @@ -70,6 +65,14 @@ public class QuestionService implements IQuestionService { return this.databaseDao.saveQuestion(session, question); } + @Override + @Authenticated + public boolean saveQuestion(InterposedQuestion question) { + Session session = this.databaseDao.getSessionFromKeyword(question.getSession()); + return this.databaseDao.saveQuestion(session, question); + } + + @Override @Authenticated public Question getQuestion(String id, String sessionKey) { @@ -139,7 +142,7 @@ public class QuestionService implements IQuestionService { @Override @Authenticated - public List<Question> getInterposedQuestions(String sessionKey) { + public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { return databaseDao.getInterposedQuestions(sessionKey); } diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java index 60902a5b0d099d59eb0a86a085f5c60b0ab22f96..617c7cb9e19e9f919173d5c8be94dd66f25e5849 100644 --- a/src/main/java/de/thm/arsnova/services/UserService.java +++ b/src/main/java/de/thm/arsnova/services/UserService.java @@ -75,30 +75,31 @@ public class UserService implements IUserService, InitializingBean, DisposableBe user = new User(token); } - if (user == null || user.getUsername().equals("anonymous")) + if (user == null || user.getUsername().equals("anonymous")) { throw new UnauthorizedException(); + } return user; } @Override - public User getUser2SessionID(UUID sessionID) { - return socketid2user.get(sessionID); + public User getUser2SocketId(UUID socketId) { + return socketid2user.get(socketId); } @Override - public void putUser2SessionID(UUID sessionID, User user) { - socketid2user.put(sessionID, user); + public void putUser2SocketId(UUID socketId, User user) { + socketid2user.put(socketId, user); } @Override - public Set<Map.Entry<UUID, User>> users2Session() { + public Set<Map.Entry<UUID, User>> socketId2User() { return socketid2user.entrySet(); } @Override - public void removeUser2SessionID(UUID sessionID) { - socketid2user.remove(sessionID); + public void removeUser2SocketId(UUID socketId) { + socketid2user.remove(socketId); } @Override diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java index 2b23b251cbf808e86ed8d1d50983f1cb99a59d2c..896c9f991a8599975c192e50053b89e6cc0f308e 100644 --- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java +++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java @@ -82,7 +82,7 @@ public class ARSnovaSocketIOServer { * do a check if user is in the session, for which he * would give a feedback */ - User u = userService.getUser2SessionID(client + User u = userService.getUser2SocketId(client .getSessionId()); if (u == null || userService.isUserInSession(u, @@ -91,23 +91,11 @@ public class ARSnovaSocketIOServer { } feedbackService.saveFeedback(data.getSessionkey(), data.getValue(), u); - + /** - * collect a list of users which are in the current - * session iterate over all connected clients and if - * send feedback, if user is in current session + * send feedback back to clients */ - List<String> users = userService.getUsersInSession(data - .getSessionkey()); - de.thm.arsnova.entities.Feedback fb = feedbackService - .getFeedback(data.getSessionkey()); - - for (SocketIOClient c : server.getAllClients()) { - u = userService.getUser2SessionID(c.getSessionId()); - if (u != null && users.contains(u.getUsername())) { - c.sendEvent("updateFeedback", fb.getValues()); - } - } + reportUpdatedFeedbackForSession(data.getSessionkey()); } }); @@ -133,7 +121,7 @@ public class ARSnovaSocketIOServer { public void onDisconnect(SocketIOClient client) { logger.info("addDisconnectListener.onDisconnect: Client: {}", new Object[] { client }); - userService.removeUser2SessionID(client.getSessionId()); + userService.removeUser2SocketId(client.getSessionId()); } }); @@ -210,7 +198,7 @@ public class ARSnovaSocketIOServer { private List<UUID> findConnectionIdForUser(String username) { List<UUID> result = new ArrayList<UUID>(); - for (Entry<UUID, User> e : userService.users2Session()) { + for (Entry<UUID, User> e : userService.socketId2User()) { if (e.getValue().getUsername().equals(username)) { result.add(e.getKey()); } @@ -218,12 +206,22 @@ public class ARSnovaSocketIOServer { return result; } - public void reportUpdatedFeedbackForSessions(Set<String> allAffectedSessions) { - for (String sessionKey : allAffectedSessions) { - de.thm.arsnova.entities.Feedback fb = feedbackService - .getFeedback(sessionKey); - server.getBroadcastOperations().sendEvent("updateFeedback", - fb.getValues()); + public void reportUpdatedFeedbackForSession(String session) { + /** + * collect a list of users which are in the current + * session iterate over all connected clients and if + * send feedback, if user is in current session + */ + List<String> users = userService.getUsersInSession(session); + de.thm.arsnova.entities.Feedback fb = feedbackService.getFeedback(session); + + for (SocketIOClient c : server.getAllClients()) { + User u = userService.getUser2SocketId(c.getSessionId()); + if (u != null && users.contains(u.getUsername())) { + logger.info("sending out to client {}, username is: {}, current session is: {}", + new Object[] {c.getSessionId(), u.getUsername(), session}); + c.sendEvent("updateFeedback", fb.getValues()); + } } } } \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 314db1edf82524518681b789ec702b9afd007622..1b105c9f190c0dc6b25eb1d96103005eaf661480 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -73,4 +73,8 @@ <error-code>500</error-code> <location>/error/500.html</location> </error-page> -</web-app> \ No newline at end of file + + <session-config> + <session-timeout>0</session-timeout> + </session-config> +</web-app> diff --git a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java index d9b5a5a382f1b9a53a3338509fde71d178837a49..1446cc8a814621ff793ac9a1b87c41c519aa5b0c 100644 --- a/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java +++ b/src/test/java/de/thm/arsnova/dao/StubDatabaseDao.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import de.thm.arsnova.entities.Answer; import de.thm.arsnova.entities.Feedback; import de.thm.arsnova.entities.FoodVote; +import de.thm.arsnova.entities.InterposedQuestion; import de.thm.arsnova.entities.LoggedIn; import de.thm.arsnova.entities.Question; import de.thm.arsnova.entities.Session; @@ -283,7 +284,7 @@ public class StubDatabaseDao implements IDatabaseDao { } @Override - public List<Question> getInterposedQuestions(String sessionKey) { + public List<InterposedQuestion> getInterposedQuestions(String sessionKey) { // TODO Auto-generated method stub return null; } @@ -323,4 +324,10 @@ public class StubDatabaseDao implements IDatabaseDao { // TODO Auto-generated method stub return 0; } + + @Override + public boolean saveQuestion(Session session, InterposedQuestion question) { + // TODO Auto-generated method stub + return false; + } }