Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieAnswerVisitDAO.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieAnswerVisitDAO.java,v diff -u -r1.7 -r1.8 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieAnswerVisitDAO.java 16 Dec 2012 08:46:41 -0000 1.7 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieAnswerVisitDAO.java 15 Aug 2013 15:13:01 -0000 1.8 @@ -29,7 +29,7 @@ public interface ScratchieAnswerVisitDAO extends DAO { - ScratchieAnswerVisitLog getScratchieAnswerLog(Long answerUid, Long userId); + ScratchieAnswerVisitLog getLog(Long answerUid, Long userId); int getLogCountTotal(Long sessionId, Long userId); Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieAnswerVisitDAOHibernate.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieAnswerVisitDAOHibernate.java,v diff -u -r1.7 -r1.8 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieAnswerVisitDAOHibernate.java 16 Dec 2012 08:46:41 -0000 1.7 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieAnswerVisitDAOHibernate.java 15 Aug 2013 15:13:01 -0000 1.8 @@ -46,7 +46,7 @@ + ScratchieAnswerVisitLog.class.getName() + " as l where l.sessionId=? and l.user.userId =? and l.scratchieAnswer.scratchieItem.uid=?"; @Override - public ScratchieAnswerVisitLog getScratchieAnswerLog(Long answerUid, Long userId) { + public ScratchieAnswerVisitLog getLog(Long answerUid, Long userId) { List list = getHibernateTemplate().find(FIND_BY_ANSWER_AND_USER, new Object[] { userId, answerUid }); if (list == null || list.size() == 0) return null; Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java,v diff -u -r1.13 -r1.14 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java 3 May 2013 16:12:18 -0000 1.13 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java 15 Aug 2013 15:13:01 -0000 1.14 @@ -215,7 +215,7 @@ * @param scratchieItemList * @param user */ - void retrieveScratched(Collection scratchieItemList, ScratchieUser user); + Set getItemsWithIndicatedScratches(Long toolSessionId, ScratchieUser user); /** * Leader has scratched the specified answer. Will store this scratch for all users in his group. Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java,v diff -u -r1.19 -r1.20 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java 29 Jul 2013 23:10:57 -0000 1.19 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java 15 Aug 2013 15:13:01 -0000 1.20 @@ -370,17 +370,17 @@ for (ScratchieAnswerVisitLog leaderLog : leaderLogs) { ScratchieAnswer answer = leaderLog.getScratchieAnswer(); - ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getScratchieAnswerLog(answer.getUid(), + ScratchieAnswerVisitLog userLog = scratchieAnswerVisitDao.getLog(answer.getUid(), user.getUserId()); // create and save new ScratchieAnswerVisitLog - if (log == null) { - log = new ScratchieAnswerVisitLog(); - log.setScratchieAnswer(answer); - log.setUser(user); - log.setSessionId(user.getSession().getSessionId()); - log.setAccessDate(leaderLog.getAccessDate()); - scratchieAnswerVisitDao.saveObject(log); + if (userLog == null) { + userLog = new ScratchieAnswerVisitLog(); + userLog.setScratchieAnswer(answer); + userLog.setUser(user); + userLog.setSessionId(user.getSession().getSessionId()); + userLog.setAccessDate(leaderLog.getAccessDate()); + scratchieAnswerVisitDao.saveObject(userLog); } } } @@ -479,7 +479,7 @@ List users = getUsersBySession(sessionId); for (ScratchieUser user : users) { - ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getScratchieAnswerLog(answerUid, user.getUserId()); + ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getLog(answerUid, user.getUserId()); if (log == null) { log = new ScratchieAnswerVisitLog(); ScratchieAnswer answer = getScratchieAnswerById(answerUid); @@ -592,7 +592,7 @@ for (ScratchieAnswer answer : (Set) item.getAnswers()) { int attemptNumber; - ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getScratchieAnswerLog(answer.getUid(), + ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getLog(answer.getUid(), user.getUserId()); if (log == null) { // -1 if there is no log @@ -609,29 +609,58 @@ } @Override - public void retrieveScratched(Collection items, ScratchieUser user) { + public Set getItemsWithIndicatedScratches(Long toolSessionId, ScratchieUser user) { + + List logs = scratchieAnswerVisitDao.getLogsByScratchieUser(user.getUid()); + // answerUid -> ScratchieAnswerVisitLog map, created to reduce number of queries to DB + HashMap answerUidToLogMap = new HashMap(); + for (ScratchieAnswerVisitLog log : logs) { + answerUidToLogMap.put(log.getScratchieAnswer().getUid(), log); + } + Scratchie scratchie = this.getScratchieBySessionId(toolSessionId); + Set items = new TreeSet(new ScratchieItemComparator()); + items.addAll(scratchie.getScratchieItems()); + for (ScratchieItem item : items) { for (ScratchieAnswer answer : (Set) item.getAnswers()) { - ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getScratchieAnswerLog(answer.getUid(), - user.getUserId()); + ScratchieAnswerVisitLog log = answerUidToLogMap.get(answer.getUid()); if (log == null) { answer.setScratched(false); } else { answer.setScratched(true); } } - item.setUnraveled(isItemUnraveled(item, user.getUserId())); + boolean isItemUnraveled = isItemUnraveled(item, user.getUserId(), answerUidToLogMap); + item.setUnraveled(isItemUnraveled); } + + return items; } - - private boolean isItemUnraveled(ScratchieItem item, Long userId) { + + /** + * Check if the specified item was unraveled by user + * + * @param item + * specified item + * @param userId + * userId + * @param answerUidToLogMap + * if this parameter is provided - uses logs from it, otherwise queries DB. (The main reason to have this + * parameter is to reduce number of queries to DB) + * @return + */ + private boolean isItemUnraveled(ScratchieItem item, Long userId, HashMap answerUidToLogMap) { boolean isItemUnraveled = false; for (ScratchieAnswer answer : (Set) item.getAnswers()) { - ScratchieAnswerVisitLog log = scratchieAnswerVisitDao.getScratchieAnswerLog(answer.getUid(), userId); + + //if answerUidToLogMap is provided then uses logs from it, otherwise queries DB + ScratchieAnswerVisitLog log = (answerUidToLogMap != null) ? answerUidToLogMap.get(answer.getUid()) + : scratchieAnswerVisitDao.getLog(answer.getUid(), userId); + if (log != null) { isItemUnraveled |= answer.isCorrect(); } @@ -666,7 +695,7 @@ int mark = 0; // add mark only if an item was unraveled - if (isItemUnraveled(item, userId)) { + if (isItemUnraveled(item, userId, null)) { int attempts = scratchieAnswerVisitDao.getLogCountPerItem(sessionId, userId, item.getUid()); mark += item.getAnswers().size() - attempts; @@ -1316,7 +1345,7 @@ mark = (attempts == 0) ? -1 : getUserMarkPerItem(scratchie, item, sessionId, groupLeader.getUserId()); - isFirstChoice = (attempts == 1) && isItemUnraveled(item, groupLeader.getUserId()); + isFirstChoice = (attempts == 1) && isItemUnraveled(item, groupLeader.getUserId(), null); } newItem.setUid(item.getUid()); Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningAction.java,v diff -u -r1.16 -r1.17 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningAction.java 3 May 2013 16:12:18 -0000 1.16 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningAction.java 15 Aug 2013 15:13:01 -0000 1.17 @@ -74,6 +74,8 @@ public class LearningAction extends Action { private static Logger log = Logger.getLogger(LearningAction.class); + + private static IScratchieService service; @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, @@ -117,23 +119,20 @@ */ private ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - - // save toolContentID into HTTPSession + initializeScratchieService(); + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, true); Long toolSessionId = new Long(request.getParameter(ScratchieConstants.PARAM_TOOL_SESSION_ID)); - // get back the scratchie and item list and display them on page - IScratchieService service = getScratchieService(); Scratchie scratchie = service.getScratchieBySessionId(toolSessionId); ScratchieUser user = null; if (mode != null && mode.isTeacher()) { // monitoring mode - user is specified in URL // scratchieUser may be null if the user was force completed. - user = getSpecifiedUser(service, toolSessionId, - WebUtil.readIntParam(request, AttributeNames.PARAM_USER_ID, false)); + user = getSpecifiedUser(toolSessionId, WebUtil.readIntParam(request, AttributeNames.PARAM_USER_ID, false)); } else { - user = getCurrentUser(service, toolSessionId); + user = getCurrentUser(toolSessionId); } ScratchieUser groupLeader = service.checkLeaderSelectToolForSessionLeader(user, toolSessionId); @@ -217,27 +216,21 @@ sessionMap.put(ScratchieConstants.PARAM_RUN_OFFLINE, false); } - Set initialItems = scratchie.getScratchieItems(); - // becuase in webpage will use this login name. Here is just initialize it to avoid session close error in proxy - // object. - for (ScratchieItem item : initialItems) { + // set scratched flag for display purpose + Collection items = service.getItemsWithIndicatedScratches(toolSessionId, user); + + // becuase webpage will use login name here is just initialize it to avoid session close error in proxy object. + for (ScratchieItem item : items) { if (item.getCreateBy() != null) { item.getCreateBy().getLoginName(); } } // for teacher in monitoring display the number of attempt. if (mode.isTeacher()) { - service.retrieveScratchesOrder(initialItems, user); + service.retrieveScratchesOrder(items, user); } - - // set scratched flag for display purpose - if (user != null) { - service.retrieveScratched(initialItems, user); - } - - Collection items = new TreeSet(new ScratchieItemComparator()); - items.addAll(initialItems); + sessionMap.put(ScratchieConstants.ATTR_ITEM_LIST, items); sessionMap.put(ScratchieConstants.ATTR_SCRATCHIE, scratchie); boolean isScratchingFinished = user != null && user.isScratchingFinished(); @@ -261,34 +254,25 @@ private ActionForward refreshQuestionList(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + initializeScratchieService(); String sessionMapID = request.getParameter(ScratchieConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); request.setAttribute(ScratchieConstants.ATTR_SESSION_MAP_ID, sessionMapID); - IScratchieService service = getScratchieService(); Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - ScratchieUser user = getCurrentUser(service, toolSessionId); + ScratchieUser user = getCurrentUser(toolSessionId); - // get back the scratchie and item list and display them on page - Scratchie scratchie = service.getScratchieBySessionId(toolSessionId); - - Collection items = new TreeSet(new ScratchieItemComparator()); - items.addAll(scratchie.getScratchieItems()); - // set scratched flag for display purpose - if (user != null) { - service.retrieveScratched(items, user); - } - + Set items = service.getItemsWithIndicatedScratches(toolSessionId, user); sessionMap.put(ScratchieConstants.ATTR_ITEM_LIST, items); + // refresh leadership status sessionMap.put(ScratchieConstants.ATTR_USER, user); // refresh ScratchingFinished status boolean isScratchingFinished = user != null && user.isScratchingFinished(); sessionMap.put(ScratchieConstants.ATTR_IS_SCRATCHING_FINISHED, isScratchingFinished); return mapping.findForward(ScratchieConstants.SUCCESS); - } /** @@ -305,13 +289,12 @@ private ActionForward scratchItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws JSONException, IOException { - IScratchieService service = getScratchieService(); - + initializeScratchieService(); String sessionMapID = WebUtil.readStrParam(request, ScratchieConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - ScratchieUser user = getCurrentUser(service, toolSessionId); + ScratchieUser user = getCurrentUser(toolSessionId); // only leaders are allowed to scratch answers if (!service.isUserGroupLeader(user, toolSessionId)) { return null; @@ -345,18 +328,17 @@ private ActionForward showResults(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + initializeScratchieService(); // get back SessionMap String sessionMapID = request.getParameter(ScratchieConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); request.setAttribute(ScratchieConstants.ATTR_SESSION_MAP_ID, sessionMapID); Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - IScratchieService service = getScratchieService(); - Long userId = (Long) sessionMap.get(ScratchieConstants.ATTR_USER_ID); - // only leaders should get to here to finalize scratching service.setScratchingFinished(toolSessionId); + Long userId = (Long) sessionMap.get(ScratchieConstants.ATTR_USER_ID); Set items = service.populateItemsResults(toolSessionId, userId); request.setAttribute(ScratchieConstants.ATTR_ITEM_LIST, items); @@ -375,12 +357,12 @@ private ActionForward finish(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + initializeScratchieService(); // get back SessionMap String sessionMapID = request.getParameter(ScratchieConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); Long toolSessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); ScratchieUser user = (ScratchieUser) sessionMap.get(AttributeNames.USER); - IScratchieService service = getScratchieService(); // in case of the leader we should let all other learners see Next Activity button if (service.isUserGroupLeader(user, toolSessionId)) { @@ -410,6 +392,7 @@ private ActionForward newReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + initializeScratchieService(); // get session value String sessionMapID = WebUtil.readStrParam(request, ScratchieConstants.ATTR_SESSION_MAP_ID); @@ -421,11 +404,9 @@ refForm.setSessionMapID(sessionMapID); // get the existing reflection entry - IScratchieService submitFilesService = getScratchieService(); - - SessionMap map = (SessionMap) request.getSession().getAttribute(sessionMapID); + SessionMap map = (SessionMap) request.getSession().getAttribute(sessionMapID); Long toolSessionID = (Long) map.get(AttributeNames.PARAM_TOOL_SESSION_ID); - NotebookEntry entry = submitFilesService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + NotebookEntry entry = service.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, ScratchieConstants.TOOL_SIGNATURE, user.getUserID()); if (entry != null) { @@ -446,15 +427,14 @@ */ private ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { + initializeScratchieService(); ReflectionForm refForm = (ReflectionForm) form; Integer userId = refForm.getUserID(); String sessionMapID = WebUtil.readStrParam(request, ScratchieConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - IScratchieService service = getScratchieService(); - // check for existing notebook entry NotebookEntry entry = service.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, ScratchieConstants.TOOL_SIGNATURE, userId); @@ -477,13 +457,15 @@ // Private method // ************************************************************************************* - private IScratchieService getScratchieService() { - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - return (IScratchieService) wac.getBean(ScratchieConstants.RESOURCE_SERVICE); + private void initializeScratchieService() { + if (service == null) { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + service = (IScratchieService) wac.getBean(ScratchieConstants.RESOURCE_SERVICE); + } } - private ScratchieUser getCurrentUser(IScratchieService service, Long sessionId) { + private ScratchieUser getCurrentUser(Long sessionId) { // try to get form system session HttpSession ss = SessionManager.getSession(); // get back login user DTO @@ -498,7 +480,7 @@ return scratchieUser; } - private ScratchieUser getSpecifiedUser(IScratchieService service, Long sessionId, Integer userId) { + private ScratchieUser getSpecifiedUser(Long sessionId, Integer userId) { ScratchieUser scratchieUser = service.getUserByIDAndSession(new Long(userId.intValue()), sessionId); if (scratchieUser == null) { log.error("Unable to find specified user for scratchie activity. Screens are likely to fail. SessionId=" Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/servlet/ExportServlet.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/servlet/ExportServlet.java,v diff -u -r1.3 -r1.4 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/servlet/ExportServlet.java 16 Dec 2012 08:46:41 -0000 1.3 +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/servlet/ExportServlet.java 15 Aug 2013 15:13:01 -0000 1.4 @@ -144,29 +144,21 @@ } ScratchieUser learner = service.getUserByIDAndSession(userID, toolSessionID); - if (learner == null) { String error = "The user with user id " + userID + " does not exist."; logger.error(error); throw new ScratchieApplicationException(error); } Scratchie content = service.getScratchieBySessionId(toolSessionID); - if (content == null) { String error = "The content for this activity has not been defined yet."; logger.error(error); throw new ScratchieApplicationException(error); } - Set initialItems = content.getScratchieItems(); - // set complete flag for display purpose - service.retrieveScratched(initialItems, learner); - - // randomize order if needed - Collection items = new TreeSet(new ScratchieItemComparator()); - items.addAll(initialItems); + Set items = service.getItemsWithIndicatedScratches(toolSessionID, learner); sessionMap.put(ScratchieConstants.ATTR_ITEM_LIST, items); // Add flag to indicate whether to render user notebook entries