Index: lams_tool_chat/.classpath =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/.classpath (.../.classpath) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/.classpath (.../.classpath) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -3,7 +3,7 @@ - + Index: lams_tool_chat/.externalToolBuilders/SASS_lams_tool_chat.launch =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/.externalToolBuilders/SASS_lams_tool_chat.launch (.../SASS_lams_tool_chat.launch) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/.externalToolBuilders/SASS_lams_tool_chat.launch (.../SASS_lams_tool_chat.launch) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,16 +1,22 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + Index: lams_tool_chat/build.xml =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/build.xml (.../build.xml) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/build.xml (.../build.xml) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -18,7 +18,7 @@ ${ant.project.name}: Copying additional Java classes to WAR Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20180801.sql =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20180801.sql (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20180801.sql (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,23 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +----------------------Put all sql statements below here------------------------- + +-- LDEV-4440 Change tool access URLs after migration to Spring MVC +UPDATE lams_tool SET + author_url = 'tool/lachat11/authoring/authoring.do', + learner_url = 'tool/lachat11/learning/learning.do?mode=learner', + learner_preview_url = 'tool/lachat11/learning/learning.do?mode=author', + learner_progress_url = 'tool/lachat11/learning/learning.do?mode=teacher', + monitor_url = 'tool/lachat11/monitoring/monitoring.do', + pedagogical_planner_url = 'tool/lachat11/pedagogicalPlanner/initPedagogicalPlannerForm.do' +WHERE tool_signature = 'lachat11'; + +UPDATE lams_tool SET tool_version='20180801' WHERE tool_signature='lachat11'; + +----------------------Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; \ No newline at end of file Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/AuthoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/AuthoringChatConditionAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/ClearSessionAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/MonitoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/PedagogicalPlannerAction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringChatConditionController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringChatConditionController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringChatConditionController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,324 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.util.ArrayList; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.lamsfoundation.lams.learningdesign.TextSearchConditionComparator; +import org.lamsfoundation.lams.tool.chat.model.ChatCondition; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.util.ChatConstants; +import org.lamsfoundation.lams.tool.chat.web.forms.ChatConditionForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Auxiliary action in author mode. It contains operations with ChatCondition. The rest of operations are located in + * AuthoringAction action. + * + * @author Marcin Cieslak + * @see org.lamsfoundation.lams.tool.notebook.web.action.AuthoringAction + * + */ +@Controller +@RequestMapping("/authoringCondition") +public class AuthoringChatConditionController { + + @Autowired + @Qualifier("chatService") + private IChatService chatService; + + @Autowired + @Qualifier("chatMessageService") + private MessageService messageService; + + /** + * Display empty page for new taskList item. + */ + @RequestMapping("/newConditionInit") + public String newConditionInit(@ModelAttribute ChatConditionForm chatConditionForm, HttpServletRequest request) { + + String sessionMapID = request.getParameter(ChatConstants.ATTR_SESSION_MAP_ID); + chatConditionForm.setSessionMapID(sessionMapID); + chatConditionForm.setOrderId(-1); + return "pages/authoring/addCondition"; + } + + /** + * Display edit page for existed taskList item. + */ + @RequestMapping("/editCondition") + public String editCondition(@ModelAttribute ChatConditionForm chatConditionForm, HttpServletRequest request) { + + String sessionMapID = chatConditionForm.getSessionMapID(); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int orderId = NumberUtils.stringToInt(request.getParameter(ChatConstants.PARAM_ORDER_ID), -1); + ChatCondition condition = null; + if (orderId != -1) { + SortedSet conditionSet = getChatConditionSet(sessionMap); + List conditionList = new ArrayList<>(conditionSet); + condition = conditionList.get(orderId); + if (condition != null) { + populateConditionToForm(orderId, condition, chatConditionForm, request); + } + } + return condition == null ? null : "pages/authoring/addCondition"; + } + + /** + * This method will get necessary information from taskList item form and save or update into + * HttpSession ChatItemList. Notice, this save is not persist them into database, just save + * HttpSession temporarily. Only they will be persist when the entire authoring page is being + * persisted. + */ + @RequestMapping("/saveOrUpdateCondition") + public String saveOrUpdateCondition(@ModelAttribute ChatConditionForm chatConditionForm, + HttpServletRequest request) { + + MultiValueMap errorMap = validateChatCondition(chatConditionForm, request); + + if (!errorMap.isEmpty()) { + request.setAttribute("errorMap", errorMap); + return "pages/authoring/addCondition"; + } + + try { + extractFormToChatCondition(request, chatConditionForm); + } catch (Exception e) { + // any upload exception will display as normal error message rather then throw exception directly + errorMap.add("GLOBAL", messageService.getMessage("error.condition")); + if (!errorMap.isEmpty()) { + request.setAttribute("errorMap", errorMap); + return "pages/authoring/addCondition"; + } + } + // set session map ID so that itemlist.jsp can get sessionMAP + request.setAttribute(ChatConstants.ATTR_SESSION_MAP_ID, chatConditionForm.getSessionMapID()); + // return null to close this window + return "pages/authoring/conditionList"; + } + + /** + * Remove taskList item from HttpSession list and update page display. As authoring rule, all persist only happen + * when user submit whole page. So this remove is just impact HttpSession values. + */ + @RequestMapping("/removeCondition") + public String removeCondition(HttpServletRequest request) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, ChatConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int orderId = NumberUtils.stringToInt(request.getParameter(ChatConstants.PARAM_ORDER_ID), -1); + if (orderId != -1) { + SortedSet conditionSet = getChatConditionSet(sessionMap); + List conditionList = new ArrayList<>(conditionSet); + ChatCondition condition = conditionList.remove(orderId); + for (ChatCondition otherCondition : conditionSet) { + if (otherCondition.getOrderId() > orderId) { + otherCondition.setOrderId(otherCondition.getOrderId() - 1); + } + } + conditionSet.clear(); + conditionSet.addAll(conditionList); + // add to delList + List delList = getDeletedChatConditionList(sessionMap); + delList.add(condition); + } + + request.setAttribute(ChatConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return "pages/authoring/conditionList"; + } + + /** + * Move up current item. + */ + @RequestMapping("/upCondition") + public String upCondition(@ModelAttribute ChatConditionForm chatConditionForm, HttpServletRequest request, + HttpServletResponse response) { + return switchItem(request, true); + } + + /** + * Move down current item. + */ + @RequestMapping("/downCondition") + public String downCondition(@ModelAttribute ChatConditionForm chatConditionForm, HttpServletRequest request, + HttpServletResponse response) { + return switchItem(request, false); + } + + @RequestMapping("/switchItem") + public String switchItem(HttpServletRequest request, boolean up) { + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, ChatConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int orderId = NumberUtils.stringToInt(request.getParameter(ChatConstants.PARAM_ORDER_ID), -1); + if (orderId != -1) { + SortedSet conditionSet = getChatConditionSet(sessionMap); + List conditionList = new ArrayList<>(conditionSet); + // get current and the target item, and switch their sequnece + ChatCondition condition = conditionList.get(orderId); + ChatCondition repCondition; + if (up) { + repCondition = conditionList.get(--orderId); + } else { + repCondition = conditionList.get(++orderId); + } + int upSeqId = repCondition.getOrderId(); + repCondition.setOrderId(condition.getOrderId()); + condition.setOrderId(upSeqId); + + // put back list, it will be sorted again + conditionSet.clear(); + conditionSet.addAll(conditionList); + } + + request.setAttribute(ChatConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return "pages/authoring/conditionList"; + } + + // ************************************************************************************* + // Private methods for internal needs + // ************************************************************************************* + + /** + * List save current taskList items. + */ + private SortedSet getChatConditionSet(SessionMap sessionMap) { + SortedSet set = (SortedSet) sessionMap.get(ChatConstants.ATTR_CONDITION_SET); + if (set == null) { + set = new TreeSet<>(new TextSearchConditionComparator()); + sessionMap.put(ChatConstants.ATTR_CONDITION_SET, set); + } + return set; + } + + /** + * List save deleted taskList items, which could be persisted or non-persisted items. + */ + private List getDeletedChatConditionList(SessionMap sessionMap) { + return getListFromSession(sessionMap, ChatConstants.ATTR_DELETED_CONDITION_LIST); + } + + /** + * Get java.util.List from HttpSession by given name. + */ + private List getListFromSession(SessionMap sessionMap, String name) { + List list = (List) sessionMap.get(name); + if (list == null) { + list = new ArrayList(); + sessionMap.put(name, list); + } + return list; + } + + /** + * This method will populate taskList item information to its form for edit use. + */ + private void populateConditionToForm(int orderId, ChatCondition condition, ChatConditionForm chatConditionForm, + HttpServletRequest request) { + chatConditionForm.populateForm(condition); + if (orderId >= 0) { + chatConditionForm.setOrderId(orderId + 1); + } + } + + /** + * Extract form content to taskListContent. + */ + private void extractFormToChatCondition(HttpServletRequest request, ChatConditionForm chatConditionForm) + throws Exception { + + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(chatConditionForm.getSessionMapID()); + // check whether it is "edit(old item)" or "add(new item)" + SortedSet conditionSet = getChatConditionSet(sessionMap); + int orderId = chatConditionForm.getOrderId(); + ChatCondition condition = null; + + if (orderId == -1) { // add + String properConditionName = chatService.createConditionName(conditionSet); + condition = chatConditionForm.extractCondition(); + condition.setName(properConditionName); + int maxSeq = 1; + if (conditionSet != null && conditionSet.size() > 0) { + ChatCondition last = conditionSet.last(); + maxSeq = last.getOrderId() + 1; + } + condition.setOrderId(maxSeq); + conditionSet.add(condition); + } else { // edit + List conditionList = new ArrayList<>(conditionSet); + condition = conditionList.get(orderId - 1); + chatConditionForm.extractCondition(condition); + } + } + + /** + * Validate taskListCondition + */ + private MultiValueMap validateChatCondition(ChatConditionForm chatConditionForm, + HttpServletRequest request) { + + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + + String formConditionName = chatConditionForm.getDisplayName(); + if (StringUtils.isBlank(formConditionName)) { + errorMap.add("GLOBAL", messageService.getMessage("error.condition.name.blank")); + } else { + + Integer formConditionSequenceId = chatConditionForm.getOrderId(); + + String sessionMapID = chatConditionForm.getSessionMapID(); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + SortedSet conditionList = getChatConditionSet(sessionMap); + for (ChatCondition condition : conditionList) { + if (formConditionName.equals(condition.getName()) + && !formConditionSequenceId.equals(new Integer(condition.getOrderId() - 1).toString())) { + errorMap.add("GLOBAL", messageService.getMessage("error.condition.duplicated.name")); + break; + } + } + } + return errorMap; + } + +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/AuthoringController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,230 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.learningdesign.TextSearchConditionComparator; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.chat.model.Chat; +import org.lamsfoundation.lams.tool.chat.model.ChatCondition; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.util.ChatConstants; +import org.lamsfoundation.lams.tool.chat.web.forms.AuthoringForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + */ +@Controller +@RequestMapping("/authoring") +public class AuthoringController { + + private static Logger logger = Logger.getLogger(AuthoringController.class); + + @Autowired + @Qualifier("chatService") + private IChatService chatService; + + @Autowired + @Qualifier("chatMessageService") + private MessageService messageService; + + // Authoring SessionMap key names + private static final String KEY_TOOL_CONTENT_ID = "toolContentID"; + + private static final String KEY_CONTENT_FOLDER_ID = "contentFolderID"; + + private static final String KEY_MODE = "mode"; + + /** + * Default method when no dispatch parameter is specified. It is expected that the parameter + * toolContentID will be passed in. This will be used to retrieve content for this tool. + */ + @RequestMapping("/authoring") + public String unspecified(@ModelAttribute AuthoringForm authoringForm, HttpServletRequest request) { + + // Extract toolContentID from parameters. + Long toolContentID = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID)); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); + + // retrieving Chat with given toolContentID + Chat chat = chatService.getChatByContentId(toolContentID); + if (chat == null) { + chat = chatService.copyDefaultContent(toolContentID); + chat.setCreateDate(new Date()); + chatService.saveOrUpdateChat(chat); + // TODO NOTE: this causes DB orphans when LD not saved. + } + + if (mode.isTeacher()) { + // Set the defineLater flag so that learners cannot use content + // while we + // are editing. This flag is released when updateContent is called. + chat.setDefineLater(true); + chatService.saveOrUpdateChat(chat); + + //audit log the teacher has started editing activity in monitor + chatService.auditLogStartEditingActivityInMonitor(toolContentID); + } + + // Set up the authForm. + updateAuthForm(authoringForm, chat); + + // Set up sessionMap + SessionMap map = createSessionMap(chat, mode, contentFolderID, toolContentID); + authoringForm.setSessionMapID(map.getSessionID()); + + // add the sessionMap to HTTPSession. + request.getSession().setAttribute(map.getSessionID(), map); + request.setAttribute(ChatConstants.ATTR_SESSION_MAP, map); + + return "pages/authoring/authoring"; + } + + @RequestMapping("/updateContent") + public String updateContent(@ModelAttribute AuthoringForm authoringForm, HttpServletRequest request) { + // TODO need error checking. + + // get session map. + SessionMap map = getSessionMap(request, authoringForm); + + // get chat content. + Chat chat = chatService.getChatByContentId((Long) map.get(AuthoringController.KEY_TOOL_CONTENT_ID)); + + // update chat content using form inputs + updateChat(chat, authoringForm); + + chatService.releaseConditionsFromCache(chat); + + Set conditions = chat.getConditions(); + if (conditions == null) { + conditions = new TreeSet<>(new TextSearchConditionComparator()); + } + SortedSet conditionSet = (SortedSet) map.get(ChatConstants.ATTR_CONDITION_SET); + conditions.addAll(conditionSet); + + List deletedConditionList = (List) map + .get(ChatConstants.ATTR_DELETED_CONDITION_LIST); + if (deletedConditionList != null) { + for (ChatCondition condition : deletedConditionList) { + // remove from db, leave in repository + conditions.remove(condition); + chatService.deleteCondition(condition); + } + } + + // set conditions in case it didn't exist + chat.setConditions(conditionSet); + // set the update date + chat.setUpdateDate(new Date()); + + // releasing defineLater flag so that learners can start using the tool + chat.setDefineLater(false); + + chatService.saveOrUpdateChat(chat); + + request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + + // add the sessionMapID to form + authoringForm.setSessionMapID(map.getSessionID()); + + request.setAttribute(ChatConstants.ATTR_SESSION_MAP, map); + + return "pages/authoring/authoring"; + } + + /* ========== Private Methods ********** */ + + /** + * Updates Chat content using AuthoringForm inputs. + */ + private void updateChat(Chat chat, AuthoringForm authoringForm) { + chat.setTitle(authoringForm.getTitle()); + chat.setInstructions(authoringForm.getInstructions()); + chat.setLockOnFinished(authoringForm.isLockOnFinished()); + chat.setReflectOnActivity(authoringForm.isReflectOnActivity()); + chat.setReflectInstructions(authoringForm.getReflectInstructions()); + chat.setFilteringEnabled(authoringForm.isFilteringEnabled()); + chat.setFilterKeywords(authoringForm.getFilterKeywords()); + } + + /** + * Updates AuthoringForm using Chat content. + */ + private void updateAuthForm(AuthoringForm authoringForm, Chat chat) { + authoringForm.setTitle(chat.getTitle()); + authoringForm.setInstructions(chat.getInstructions()); + authoringForm.setLockOnFinished(chat.isLockOnFinished()); + authoringForm.setReflectOnActivity(chat.isReflectOnActivity()); + authoringForm.setReflectInstructions(chat.getReflectInstructions()); + authoringForm.setFilteringEnabled(chat.isFilteringEnabled()); + authoringForm.setFilterKeywords(chat.getFilterKeywords()); + } + + /** + * Updates SessionMap using Chat content. + */ + private SessionMap createSessionMap(Chat chat, ToolAccessMode mode, String contentFolderID, + Long toolContentID) { + + SessionMap sessionMap = new SessionMap<>(); + + sessionMap.put(AuthoringController.KEY_MODE, mode); + sessionMap.put(AuthoringController.KEY_CONTENT_FOLDER_ID, contentFolderID); + sessionMap.put(AuthoringController.KEY_TOOL_CONTENT_ID, toolContentID); + + SortedSet set = new TreeSet<>(new TextSearchConditionComparator()); + if (chat.getConditions() != null) { + set.addAll(chat.getConditions()); + } + sessionMap.put(ChatConstants.ATTR_CONDITION_SET, set); + return sessionMap; + } + + /** + * Retrieve the SessionMap from the HttpSession. + */ + private SessionMap getSessionMap(HttpServletRequest request, AuthoringForm authoringForm) { + return (SessionMap) request.getSession().getAttribute(authoringForm.getSessionMapID()); + } +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/ClearSessionController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/ClearSessionController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/ClearSessionController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,71 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.authoring.web.LamsAuthoringFinishController; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.WebApplicationContext; + +/** + * This class give a chance to clear HttpSession when user save/close authoring page. + * + * @author Steve.Ni + * + * + * + * + * @version $Revision$ + */ +@Controller +public class ClearSessionController extends LamsAuthoringFinishController { + private static Logger logger = Logger.getLogger(ClearSessionController.class.getName()); + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/clearsession") + public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException { + super.execute(request, response, applicationContext); + } + + @Override + public void clearSession(String customiseSessionID, HttpSession session, ToolAccessMode mode) { + session.removeAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG); + if (mode.isAuthor()) { + ClearSessionController.logger.debug("In Author mode"); + session.removeAttribute(customiseSessionID); + } + } +} Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,268 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.io.IOException; +import java.util.Date; +import java.util.TimeZone; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.ToolSessionManager; +import org.lamsfoundation.lams.tool.chat.dto.ChatDTO; +import org.lamsfoundation.lams.tool.chat.dto.ChatUserDTO; +import org.lamsfoundation.lams.tool.chat.model.Chat; +import org.lamsfoundation.lams.tool.chat.model.ChatSession; +import org.lamsfoundation.lams.tool.chat.model.ChatUser; +import org.lamsfoundation.lams.tool.chat.service.ChatServiceProxy; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.util.ChatConstants; +import org.lamsfoundation.lams.tool.chat.util.ChatException; +import org.lamsfoundation.lams.tool.chat.web.forms.LearningForm; +import org.lamsfoundation.lams.tool.exception.DataMissingException; +import org.lamsfoundation.lams.tool.exception.ToolException; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.WebApplicationContext; + +/** + * @author + * @version + * + * + * + * + * + * + */ +@Controller +@RequestMapping("/learning") +public class LearningController { + + private static Logger log = Logger.getLogger(LearningController.class); + + @Autowired + @Qualifier("chatService") + private IChatService chatService; + + @Autowired + @Qualifier("chatMessageService") + private MessageService messageService; + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/learning") + public String unspecified(@ModelAttribute LearningForm learningForm, HttpServletRequest request) throws Exception { + + // 'toolSessionID' and 'mode' paramters are expected to be present. + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, false); + + Long toolSessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + + // Retrieve the session and content. + ChatSession chatSession = chatService.getSessionBySessionId(toolSessionID); + if (chatSession == null) { + throw new ChatException("Cannot retrieve session with toolSessionID" + toolSessionID); + } + + Chat chat = chatSession.getChat(); + + // Retrieve the current user + ChatUser chatUser = getCurrentUser(toolSessionID); + + // check defineLater + if (chat.isDefineLater()) { + return "pages/learning/defineLater"; + } + + request.setAttribute("MODE", mode.toString()); + + ChatDTO chatDTO = new ChatDTO(chat); + request.setAttribute("chatDTO", chatDTO); + + ChatUserDTO chatUserDTO = new ChatUserDTO(chatUser); + if (chatUser.isFinishedActivity()) { + // get the notebook entry. + NotebookEntry notebookEntry = chatService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + ChatConstants.TOOL_SIGNATURE, chatUser.getUserId().intValue()); + if (notebookEntry != null) { + chatUserDTO.notebookEntry = notebookEntry.getEntry(); + } + } + request.setAttribute("chatUserDTO", chatUserDTO); + + // Ensure that the content is use flag is set. + if (!chat.isContentInUse()) { + chat.setContentInUse(new Boolean(true)); + chatService.saveOrUpdateChat(chat); + } + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(toolSessionID, request, + applicationContext.getServletContext()); + + /* Check if submission deadline is null */ + + Date submissionDeadline = chatDTO.getSubmissionDeadline(); + request.setAttribute("chatDTO", chatDTO); + + if (submissionDeadline != null) { + + HttpSession ss = SessionManager.getSession(); + UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone learnerTimeZone = learnerDto.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); + Date currentLearnerDate = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, new Date()); + request.setAttribute("submissionDeadline", submissionDeadline); + + // calculate whether submission deadline has passed, and if so forward to "submissionDeadline" + if (currentLearnerDate.after(tzSubmissionDeadline)) { + return "pages/learning/submissionDeadline"; + } + + } + + return "pages/learning/learning"; + } + + @RequestMapping("/finishActivity") + public String finishActivity(@ModelAttribute LearningForm learningForm, HttpServletRequest request, + HttpServletResponse response) { + + // set the finished flag + ChatUser chatUser = chatService.getUserByUID(learningForm.getChatUserUID()); + if (chatUser != null) { + chatUser.setFinishedActivity(true); + chatService.saveOrUpdateChatUser(chatUser); + } else { + LearningController.log + .error("finishActivity(): couldn't find ChatUser with uid: " + learningForm.getChatUserUID()); + } + + ToolSessionManager sessionMgrService = ChatServiceProxy + .getChatSessionManager(applicationContext.getServletContext()); + + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + Long toolSessionID = chatUser.getChatSession().getSessionId(); + + String nextActivityUrl; + try { + nextActivityUrl = sessionMgrService.leaveToolSession(toolSessionID, userID); + response.sendRedirect(nextActivityUrl); + } catch (DataMissingException e) { + throw new ChatException(e); + } catch (ToolException e) { + throw new ChatException(e); + } catch (IOException e) { + throw new ChatException(e); + } + + return null; // TODO need to return proper page. + } + + @RequestMapping("/openNotebook") + public String openNotebook(@ModelAttribute LearningForm learningForm, HttpServletRequest request, + HttpServletResponse response) { + + // set the finished flag + ChatUser chatUser = chatService.getUserByUID(learningForm.getChatUserUID()); + ChatDTO chatDTO = new ChatDTO(chatUser.getChatSession().getChat()); + + request.setAttribute("chatDTO", chatDTO); + + NotebookEntry notebookEntry = chatService.getEntry(chatUser.getChatSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ChatConstants.TOOL_SIGNATURE, chatUser.getUserId().intValue()); + + if (notebookEntry != null) { + learningForm.setEntryText(notebookEntry.getEntry()); + } + + request.setAttribute(AttributeNames.PARAM_TOOL_SESSION_ID, chatUser.getChatSession().getSessionId()); + LearningWebUtil.putActivityPositionInRequestByToolSessionId(chatUser.getChatSession().getSessionId(), request, + applicationContext.getServletContext()); + + return "pages/learning/notebook"; + } + + @RequestMapping("/submitReflection") + public String submitReflection(@ModelAttribute LearningForm learningForm, HttpServletRequest request, + HttpServletResponse response) { + + // save the reflection entry and call the notebook. + + ChatUser chatUser = chatService.getUserByUID(learningForm.getChatUserUID()); + Long toolSessionID = chatUser.getChatSession().getSessionId(); + Integer userID = chatUser.getUserId().intValue(); + + // check for existing notebook entry + NotebookEntry entry = chatService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + ChatConstants.TOOL_SIGNATURE, userID); + + if (entry == null) { + // create new entry + chatService.createNotebookEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + ChatConstants.TOOL_SIGNATURE, userID, learningForm.getEntryText()); + } else { + // update existing entry + entry.setEntry(learningForm.getEntryText()); + entry.setLastModified(new Date()); + chatService.updateEntry(entry); + } + + return finishActivity(learningForm, request, response); + } + + private ChatUser getCurrentUser(Long toolSessionId) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + // attempt to retrieve user using userId and toolSessionId + ChatUser chatUser = chatService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionId); + + if (chatUser == null) { + ChatSession chatSession = chatService.getSessionBySessionId(toolSessionId); + chatUser = chatService.createChatUser(user, chatSession); + } + + return chatUser; + } +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/LearningWebsocketServer.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,436 @@ +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.io.IOException; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; + +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.tool.chat.model.ChatMessage; +import org.lamsfoundation.lams.tool.chat.model.ChatSession; +import org.lamsfoundation.lams.tool.chat.model.ChatUser; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.util.ChatConstants; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.util.HashUtil; +import org.lamsfoundation.lams.util.JsonUtil; +import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Receives, processes and sends Chat messages to Learners. + * + * @author Marcin Cieslak + */ +@ServerEndpoint("/learningWebsocket") +public class LearningWebsocketServer { + + /** + * Identifies a single connection. There can be more than one connection for the same user: multiple windows open or + * the same user in an another role. + */ + private static class Websocket { + private Session session; + private String userName; + private String nickName; + private Long lamsUserId; + private Long portraitId; + private String hash; + + private Websocket(Session session, String nickName, Long lamsUserId, Long portraitId) { + this.session = session; + this.userName = session.getUserPrincipal().getName(); + this.nickName = nickName; + this.lamsUserId = lamsUserId; + this.portraitId = portraitId; + } + } + + /** + * A singleton which updates Learners with messages and presence. + */ + private static class SendWorker extends Thread { + private boolean stopFlag = false; + // how ofter the thread runs + private static final long CHECK_INTERVAL = 2000; + // mapping toolSessionId -> timestamp when the check was last performed, so the thread does not run too often + private static final Map lastSendTimes = new TreeMap<>(); + + @Override + public void run() { + while (!stopFlag) { + try { + // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually + HibernateSessionManager.openSession(); + Iterator>> entryIterator = LearningWebsocketServer.websockets.entrySet() + .iterator(); + // go throus Tool Session and update registered users with messages and roster + while (entryIterator.hasNext()) { + Entry> entry = entryIterator.next(); + Long toolSessionId = entry.getKey(); + Long lastSendTime = lastSendTimes.get(toolSessionId); + if ((lastSendTime == null) + || ((System.currentTimeMillis() - lastSendTime) >= SendWorker.CHECK_INTERVAL)) { + SendWorker.send(toolSessionId); + } + // if all users left the chat, remove the obsolete mapping + Set sessionWebsockets = entry.getValue(); + if (sessionWebsockets.isEmpty()) { + entryIterator.remove(); + LearningWebsocketServer.rosters.remove(toolSessionId); + lastSendTimes.remove(toolSessionId); + } + } + } catch (Exception e) { + // error caught, but carry on + LearningWebsocketServer.log.error("Error in Chat worker thread", e); + } finally { + HibernateSessionManager.closeSession(); + try { + Thread.sleep(SendWorker.CHECK_INTERVAL); + } catch (InterruptedException e) { + LearningWebsocketServer.log.warn("Stopping Chat worker thread"); + stopFlag = true; + } + } + } + } + + /** + * Feeds opened websockets with messages and roster. + */ + private static void send(Long toolSessionId) { + // update the timestamp + lastSendTimes.put(toolSessionId, System.currentTimeMillis()); + + ChatSession chatSession = LearningWebsocketServer.getChatService().getSessionBySessionId(toolSessionId); + List messages = LearningWebsocketServer.getChatService().getLastestMessages(chatSession, null, + true); + + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + Roster roster = null; + ArrayNode rosterJSON = null; + String rosterString = null; + for (Websocket websocket : sessionWebsockets) { + // the connection is valid, carry on + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + // fetch roster only once, but messages are personalised + try { + if (rosterJSON == null) { + roster = LearningWebsocketServer.rosters.get(toolSessionId); + if (roster == null) { + // build a new roster object + roster = new Roster(toolSessionId); + LearningWebsocketServer.rosters.put(toolSessionId, roster); + } + + rosterJSON = roster.getRosterJSON(); + rosterString = rosterJSON.toString(); + } + + String userName = websocket.userName; + ArrayNode messagesJSON = LearningWebsocketServer.getMessages(chatSession, messages, userName); + // if hash of roster and messages is the same as before, do not send the message, save the bandwidth + String hash = HashUtil.sha1(rosterString + messagesJSON.toString()); + if ((websocket.hash == null) || !websocket.hash.equals(hash)) { + websocket.hash = hash; + + responseJSON.set("messages", messagesJSON); + responseJSON.set("roster", rosterJSON); + + // send the payload to the Learner's browser + if (websocket.session.isOpen()) { + websocket.session.getBasicRemote().sendText(responseJSON.toString()); + } + } + } catch (Exception e) { + LearningWebsocketServer.log.error("Error while building message JSON", e); + } + } + } + } + + /** + * Keeps information of users present in a Chat session. Needs to work with DB so presence is visible in clustered + * environment. + */ + private static class Roster { + private Long toolSessionId = null; + // timestamp when DB was last hit + private long lastDBCheckTime = 0; + + // Learners who are currently active + private final TreeMap activeUsers = new TreeMap(); + + private Roster(Long toolSessionId) { + this.toolSessionId = toolSessionId; + } + + /** + * Checks which Learners + * + * @throws IOException + * @throws JsonProcessingException + */ + private ArrayNode getRosterJSON() throws JsonProcessingException, IOException { + TreeMap localActiveUsers = new TreeMap(); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + // find out who is active locally + for (Websocket websocket : sessionWebsockets) { + localActiveUsers.put(websocket.nickName, new Long[] { websocket.lamsUserId, websocket.portraitId }); + } + + // is it time to sync with the DB yet? + long currentTime = System.currentTimeMillis(); + if ((currentTime - lastDBCheckTime) > ChatConstants.PRESENCE_IDLE_TIMEOUT) { + // store Learners active on this node + LearningWebsocketServer.getChatService().updateUserPresence(toolSessionId, localActiveUsers.keySet()); + + // read active Learners from all nodes + List storedActiveUsers = LearningWebsocketServer.getChatService() + .getUsersActiveBySessionId(toolSessionId); + // refresh current collection + activeUsers.clear(); + for (ChatUser activeUser : storedActiveUsers) { + activeUsers.put(activeUser.getNickname(), new Long[] { activeUser.getUserId(), + LearningWebsocketServer.getPortraitId(activeUser.getUserId()) }); + } + + lastDBCheckTime = currentTime; + } else { + // add users active on this node; no duplicates - it is a set, not a list + activeUsers.putAll(localActiveUsers); + } + + ArrayNode rosterJSON = JsonNodeFactory.instance.arrayNode(); + for (Map.Entry entry : activeUsers.entrySet()) { + Long[] ids = entry.getValue(); + ObjectNode userJSON = JsonNodeFactory.instance.objectNode().put("nickName", entry.getKey()) + .put("lamsUserId", ids[0]).put("portraitId", ids[1]); + rosterJSON.add(userJSON); + } + return rosterJSON; + } + } + + private static Logger log = Logger.getLogger(LearningWebsocketServer.class); + + private static IChatService chatService; + private static IUserManagementService userManagmentService; + + private static final SendWorker sendWorker = new SendWorker(); + private static final Map rosters = new ConcurrentHashMap<>(); + private static final Map> websockets = new ConcurrentHashMap<>(); + + static { + // run the singleton thread + LearningWebsocketServer.sendWorker.start(); + } + + /** + * Registeres the Learner for processing by SendWorker. + */ + @OnOpen + public void registerUser(Session session) throws IOException { + Long toolSessionId = Long + .valueOf(session.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + if (sessionWebsockets == null) { + sessionWebsockets = ConcurrentHashMap.newKeySet(); + LearningWebsocketServer.websockets.put(toolSessionId, sessionWebsockets); + } + final Set finalSessionWebsockets = sessionWebsockets; + + String userName = session.getUserPrincipal().getName(); + new Thread(() -> { + try { + // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually + HibernateSessionManager.openSession(); + ChatUser chatUser = LearningWebsocketServer.getChatService().getUserByLoginNameAndSessionId(userName, + toolSessionId); + Websocket websocket = new Websocket(session, chatUser.getNickname(), chatUser.getUserId(), + LearningWebsocketServer.getPortraitId(chatUser.getUserId())); + finalSessionWebsockets.add(websocket); + + // update the chat window immediatelly + SendWorker.send(toolSessionId); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + LearningWebsocketServer.log + .debug("User " + userName + " entered Chat with toolSessionId: " + toolSessionId); + } + } finally { + HibernateSessionManager.closeSession(); + } + }).start(); + } + + /** + * When user leaves the activity. + */ + @OnClose + public void unregisterUser(Session session, CloseReason reason) { + Long toolSessionId = Long + .valueOf(session.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + Iterator websocketIterator = sessionWebsockets.iterator(); + while (websocketIterator.hasNext()) { + Websocket websocket = websocketIterator.next(); + if (websocket.session.equals(session)) { + websocketIterator.remove(); + break; + } + } + + if (LearningWebsocketServer.log.isDebugEnabled()) { + LearningWebsocketServer.log.debug( + "User " + session.getUserPrincipal().getName() + " left Chat with toolSessionId: " + toolSessionId + + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) + || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) + ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + + reason.getReasonPhrase() + : "")); + } + } + + /** + * Stores a message sent by a Learner. + * + * @throws IOException + * @throws JsonProcessingException + */ + @OnMessage + public void receiveMessage(String input, Session session) throws JsonProcessingException, IOException { + if (StringUtils.isBlank(input)) { + return; + } + if (input.equalsIgnoreCase("ping")) { + // just a ping every few minutes + return; + } + ObjectNode messageJSON = JsonUtil.readObject(input); + String message = JsonUtil.optString(messageJSON, "message"); + if (StringUtils.isBlank(message)) { + return; + } + + Long toolSessionId = JsonUtil.optLong(messageJSON, "toolSessionID"); + String toUser = JsonUtil.optString(messageJSON, "toUser"); + new Thread(() -> { + try { + // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually + HibernateSessionManager.openSession(); + + ChatUser toChatUser = null; + if (!StringUtils.isBlank(toUser)) { + toChatUser = LearningWebsocketServer.getChatService().getUserByNicknameAndSessionID(toUser, + toolSessionId); + if (toChatUser == null) { + // there should be an user, but he could not be found, so don't send the message to everyone + LearningWebsocketServer.log + .error("Could not find nick: " + toUser + " in session: " + toolSessionId); + return; + } + } + + ChatUser chatUser = LearningWebsocketServer.getChatService() + .getUserByLoginNameAndSessionId(session.getUserPrincipal().getName(), toolSessionId); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setFromUser(chatUser); + chatMessage.setChatSession(chatUser.getChatSession()); + chatMessage.setToUser(toChatUser); + chatMessage.setType( + toChatUser == null ? ChatMessage.MESSAGE_TYPE_PUBLIC : ChatMessage.MESSAGE_TYPE_PRIVATE); + chatMessage.setBody(message); + chatMessage.setSendDate(new Date()); + chatMessage.setHidden(Boolean.FALSE); + LearningWebsocketServer.getChatService().saveOrUpdateChatMessage(chatMessage); + } catch (Exception e) { + log.error("Error in thread", e); + } finally { + HibernateSessionManager.closeSession(); + } + }).start(); + } + + /** + * Filteres messages meant for the given user (group or personal). + */ + private static ArrayNode getMessages(ChatSession chatSession, List messages, String userName) { + ArrayNode messagesJSON = JsonNodeFactory.instance.arrayNode(); + + for (ChatMessage message : messages) { + // all messasges need to be written out, not only new ones, + // as old ones could have been edited or hidden by Monitor + if (!message.isHidden() && (message.getType().equals(ChatMessage.MESSAGE_TYPE_PUBLIC) + || message.getFromUser().getLoginName().equals(userName) + || message.getToUser().getLoginName().equals(userName))) { + String filteredMessage = LearningWebsocketServer.getChatService().filterMessage(message.getBody(), + chatSession.getChat()); + ObjectNode messageJSON = JsonNodeFactory.instance.objectNode(); + messageJSON.put("body", filteredMessage); + messageJSON.put("from", message.getFromUser().getNickname()); + messageJSON.put("lamsUserId", message.getFromUser().getUserId()); + messageJSON.put("type", message.getType()); + messagesJSON.add(messageJSON); + } + } + + return messagesJSON; + } + + private static Long getPortraitId(Long userId) { + if (userId != null) { + User user = (User) LearningWebsocketServer.getUserManagementService().findById(User.class, + userId.intValue()); + if (user != null) { + return user.getPortraitUuid(); + } + } + return null; + } + + private static IChatService getChatService() { + if (LearningWebsocketServer.chatService == null) { + WebApplicationContext wac = WebApplicationContextUtils + .getRequiredWebApplicationContext(SessionManager.getServletContext()); + LearningWebsocketServer.chatService = (IChatService) wac.getBean("chatService"); + } + return LearningWebsocketServer.chatService; + } + + private static IUserManagementService getUserManagementService() { + if (LearningWebsocketServer.userManagmentService == null) { + WebApplicationContext wac = WebApplicationContextUtils + .getRequiredWebApplicationContext(SessionManager.getServletContext()); + LearningWebsocketServer.userManagmentService = (IUserManagementService) wac + .getBean("userManagementService"); + } + return LearningWebsocketServer.userManagmentService; + } + +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/MonitoringController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/MonitoringController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/MonitoringController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,275 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.io.IOException; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.chat.dto.ChatDTO; +import org.lamsfoundation.lams.tool.chat.dto.ChatSessionDTO; +import org.lamsfoundation.lams.tool.chat.dto.ChatUserDTO; +import org.lamsfoundation.lams.tool.chat.model.Chat; +import org.lamsfoundation.lams.tool.chat.model.ChatMessage; +import org.lamsfoundation.lams.tool.chat.model.ChatSession; +import org.lamsfoundation.lams.tool.chat.model.ChatUser; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.util.ChatConstants; +import org.lamsfoundation.lams.tool.chat.web.forms.MonitoringForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.WebApplicationContext; + +/** + * @author + * @version + * + * + * + * + * + * + * + * + * + */ +@Controller +@RequestMapping("/monitoring") +public class MonitoringController { + + private static Logger log = Logger.getLogger(MonitoringController.class); + + @Autowired + @Qualifier("chatService") + private IChatService chatService; + + @Autowired + @Qualifier("chatMessageService") + private MessageService messageService; + + @Autowired + private WebApplicationContext applicationContext; + + @RequestMapping("/monitoring") + public String unspecified(HttpServletRequest request) { + + MonitoringController.log.info("excuting monitoring action"); + + Long toolContentID = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID)); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + Chat chat = chatService.getChatByContentId(toolContentID); + ChatDTO chatDTO = new ChatDTO(chat); + + Long currentTab = WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true); + chatDTO.setCurrentTab(currentTab); + + /* Check if submission deadline is null */ + + Date submissionDeadline = chatDTO.getSubmissionDeadline(); + + if (submissionDeadline != null) { + + HttpSession ss = SessionManager.getSession(); + UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone learnerTimeZone = learnerDto.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); + request.setAttribute("submissionDeadline", tzSubmissionDeadline.getTime()); + // use the unconverted time, as convertToStringForJSON() does the timezone conversion if needed + request.setAttribute("submissionDateString", + DateUtil.convertToStringForJSON(submissionDeadline, request.getLocale())); + + } + + Map sessCountMap = chatService.getMessageCountBySession(chat.getUid()); + + for (Iterator sessIter = chat.getChatSessions().iterator(); sessIter.hasNext();) { + ChatSession session = (ChatSession) sessIter.next(); + + List latestMessages = chatService.getLastestMessages(session, ChatConstants.MONITORING_SUMMARY_MAX_MESSAGES, + false); + ChatSessionDTO sessionDTO = new ChatSessionDTO(session, latestMessages); + + Integer count = sessCountMap.get(session.getUid()); + if (count == null) { + count = 0; + } + sessionDTO.setNumberOfPosts(count); + + // constructing userDTOs + Map userCountMap = chatService.getMessageCountByFromUser(session.getUid()); + + sessionDTO.setNumberOfLearners(userCountMap.size()); + + for (Iterator userIter = session.getChatUsers().iterator(); userIter.hasNext();) { + ChatUser user = (ChatUser) userIter.next(); + ChatUserDTO userDTO = new ChatUserDTO(user); + count = userCountMap.get(user.getUid()); + if (count == null) { + count = 0; + } + userDTO.setPostCount(count); + + // get the notebook entry. + NotebookEntry notebookEntry = chatService.getEntry(session.getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ChatConstants.TOOL_SIGNATURE, user.getUserId().intValue()); + if (notebookEntry != null) { + userDTO.finishedReflection = true; + } else { + userDTO.finishedReflection = false; + } + + sessionDTO.getUserDTOs().add(userDTO); + } + + chatDTO.getSessionDTOs().add(sessionDTO); + } + + boolean isGroupedActivity = chatService.isGroupedActivity(toolContentID); + request.setAttribute("isGroupedActivity", isGroupedActivity); + request.setAttribute("monitoringDTO", chatDTO); + request.setAttribute("contentFolderID", contentFolderID); + + return "pages/monitoring/monitoring"; + } + + @RequestMapping("/openChatHistory") + public String openChatHistory(@ModelAttribute MonitoringForm monitoringForm, HttpServletRequest request, + HttpServletResponse response) { + + // TODO check for null from chatService. forward to appropriate page. + ChatSession chatSession = chatService.getSessionBySessionId(monitoringForm.getToolSessionID()); + ChatSessionDTO sessionDTO = new ChatSessionDTO(chatSession); + request.setAttribute("sessionDTO", sessionDTO); + return "pages/monitoring/chatHistory"; + } + + @RequestMapping("/openNotebook") + public String openNotebook(HttpServletRequest request) { + + Long uid = WebUtil.readLongParam(request, "uid", false); + + ChatUser chatUser = chatService.getUserByUID(uid); + NotebookEntry notebookEntry = chatService.getEntry(chatUser.getChatSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ChatConstants.TOOL_SIGNATURE, chatUser.getUserId().intValue()); + + ChatUserDTO chatUserDTO = new ChatUserDTO(chatUser); + chatUserDTO.setNotebookEntry(notebookEntry.getEntry()); + + request.setAttribute("chatUserDTO", chatUserDTO); + + return "pages/monitoring/notebook"; + } + + @RequestMapping("/editMessage") + public String editMessage(@ModelAttribute MonitoringForm monitoringForm, HttpServletRequest request, + HttpServletResponse response) { + + ChatMessage chatMessage = chatService.getMessageByUID(monitoringForm.getMessageUID()); + + boolean hasChanged = false; + if (chatMessage.isHidden() != monitoringForm.isMessageHidden()) { + hasChanged = true; + chatService.auditHideShowMessage(chatMessage, monitoringForm.isMessageHidden()); + } + + if (!chatMessage.getBody().equals(monitoringForm.getMessageBody())) { + hasChanged = true; + chatService.auditEditMessage(chatMessage, monitoringForm.getMessageBody()); + } + + if (hasChanged) { + chatMessage.setBody(monitoringForm.getMessageBody()); + chatMessage.setHidden(monitoringForm.isMessageHidden()); + chatService.saveOrUpdateChatMessage(chatMessage); + } + return openChatHistory(monitoringForm, request, response); + } + + /** + * Set Submission Deadline + */ + @RequestMapping(path = "setSubmissionDeadline", produces = MediaType.TEXT_PLAIN_VALUE) + @ResponseBody + public String setSubmissionDeadline(HttpServletRequest request, HttpServletResponse response) throws IOException { + + Long contentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Chat chat = chatService.getChatByContentId(contentID); + + Long dateParameter = WebUtil.readLongParam(request, ChatConstants.ATTR_SUBMISSION_DEADLINE, true); + Date tzSubmissionDeadline = null; + String formattedDate = ""; + if (dateParameter != null) { + Date submissionDeadline = new Date(dateParameter); + HttpSession ss = SessionManager.getSession(); + UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone teacherTimeZone = teacher.getTimeZone(); + tzSubmissionDeadline = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, submissionDeadline); + formattedDate = DateUtil.convertToStringForJSON(tzSubmissionDeadline, request.getLocale()); + } + chat.setSubmissionDeadline(tzSubmissionDeadline); + chatService.saveOrUpdateChat(chat); + + return formattedDate; + } + + /* Private Methods */ + + private ChatUser getCurrentUser(Long toolSessionId) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + // attempt to retrieve user using userId and toolSessionId + ChatUser chatUser = chatService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionId); + + if (chatUser == null) { + ChatSession chatSession = chatService.getSessionBySessionId(toolSessionId); + chatUser = chatService.createChatUser(user, chatSession); + } + + return chatUser; + } +} Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/PedagogicalPlannerController.java =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/PedagogicalPlannerController.java (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/controller/PedagogicalPlannerController.java (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,98 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.chat.web.controller; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.tool.chat.model.Chat; +import org.lamsfoundation.lams.tool.chat.service.IChatService; +import org.lamsfoundation.lams.tool.chat.web.forms.ChatPedagogicalPlannerForm; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author + * @version + * + * + * + * + * + */ +@Controller +@RequestMapping("/pedagogicalPlanner") +public class PedagogicalPlannerController { + + private static Logger logger = Logger.getLogger(PedagogicalPlannerController.class); + + @Autowired + @Qualifier("chatService") + private IChatService chatService; + + @Autowired + @Qualifier("chatMessageService") + private MessageService messageService; + + @RequestMapping("/initPedagogicalPlannerForm") + public String initPedagogicalPlannerForm(@ModelAttribute ChatPedagogicalPlannerForm plannerForm, + HttpServletRequest request, HttpServletResponse response) { + + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Chat chat = chatService.getChatByContentId(toolContentID); + plannerForm.fillForm(chat); + String contentFolderId = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + plannerForm.setContentFolderID(contentFolderId); + return "pages/authoring/pedagogicalPlannerForm"; + } + + @RequestMapping("/saveOrUpdatePedagogicalPlannerForm") + public String saveOrUpdatePedagogicalPlannerForm(@ModelAttribute ChatPedagogicalPlannerForm plannerForm, + HttpServletRequest request, HttpServletResponse response) throws IOException { + + MultiValueMap errorMap = plannerForm.validate(messageService); + if (errorMap.isEmpty()) { + String instructions = plannerForm.getInstructions(); + Long toolContentID = plannerForm.getToolContentID(); + Chat chat = chatService.getChatByContentId(toolContentID); + chat.setInstructions(instructions); + chatService.saveOrUpdateChat(chat); + } else { + request.setAttribute("errorMap", errorMap); + ; + } + return "pages/authoring/pedagogicalPlannerForm"; + } + +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/AuthoringForm.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/AuthoringForm.java (.../AuthoringForm.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/AuthoringForm.java (.../AuthoringForm.java) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -21,23 +21,19 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.chat.web.forms; import javax.servlet.http.HttpServletRequest; -import org.apache.struts.action.ActionErrors; -import org.apache.struts.action.ActionForm; -import org.apache.struts.action.ActionMapping; -import org.apache.struts.action.ActionMessage; -import org.apache.struts.action.ActionMessages; +import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; /** * */ -public class AuthoringForm extends ActionForm { +public class AuthoringForm { private static final long serialVersionUID = 3950453134542135495L; @@ -67,12 +63,12 @@ SessionMap sessionMap; - @Override - public ActionErrors validate(ActionMapping arg0, HttpServletRequest arg1) { - ActionErrors ac = new ActionErrors(); - ac.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("this is an error")); + public MultiValueMap validate(MessageService messageService, HttpServletRequest arg1) { - return ac; + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + errorMap.add("GLOBAL", messageService.getMessage("this is an error")); + + return errorMap; } public String getSessionMapID() { Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatConditionForm.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatConditionForm.java (.../ChatConditionForm.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatConditionForm.java (.../ChatConditionForm.java) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,15 +1,15 @@ package org.lamsfoundation.lams.tool.chat.web.forms; import org.lamsfoundation.lams.tool.chat.model.ChatCondition; -import org.lamsfoundation.lams.web.TextSearchActionForm; +import org.lamsfoundation.lams.web.TextSearchForm; /** * A text search form with additional parameters for Chat needs. * * @author Marcin Cieslak * */ -public class ChatConditionForm extends TextSearchActionForm { +public class ChatConditionForm extends TextSearchForm { private Integer orderId; private String displayName; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatPedagogicalPlannerForm.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatPedagogicalPlannerForm.java (.../ChatPedagogicalPlannerForm.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/ChatPedagogicalPlannerForm.java (.../ChatPedagogicalPlannerForm.java) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -20,16 +20,15 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.chat.web.forms; import org.lamsfoundation.lams.tool.chat.model.Chat; -import org.lamsfoundation.lams.web.planner.PedagogicalPlannerActivityForm; +import org.lamsfoundation.lams.web.planner.PedagogicalPlannerActivitySpringForm; /** * */ -public class ChatPedagogicalPlannerForm extends PedagogicalPlannerActivityForm { +public class ChatPedagogicalPlannerForm extends PedagogicalPlannerActivitySpringForm { private String instructions; private String contentFolderID; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/LearningForm.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/LearningForm.java (.../LearningForm.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/LearningForm.java (.../LearningForm.java) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -21,19 +21,15 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.chat.web.forms; -import org.apache.struts.action.ActionForm; - /** * * @author Anthony Sukkar * * */ -public class LearningForm extends ActionForm { +public class LearningForm { private static final long serialVersionUID = -4728946254882237144L; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/MonitoringForm.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/MonitoringForm.java (.../MonitoringForm.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/forms/MonitoringForm.java (.../MonitoringForm.java) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -21,16 +21,12 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.chat.web.forms; -import org.apache.struts.action.ActionForm; - /** * */ -public class MonitoringForm extends ActionForm { +public class MonitoringForm { private static final long serialVersionUID = 9096908688391850595L; Index: lams_tool_chat/web/WEB-INF/spring-servlet.xml =================================================================== diff -u --- lams_tool_chat/web/WEB-INF/spring-servlet.xml (revision 0) +++ lams_tool_chat/web/WEB-INF/spring-servlet.xml (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -0,0 +1,17 @@ + + + + + + + + + + + \ No newline at end of file Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/struts-config.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_chat/web/WEB-INF/tags/AuthoringButton.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -32,8 +32,8 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ attribute name="formID" required="true" rtexprvalue="true" %> <%@ attribute name="toolSignature" required="true" rtexprvalue="true" %> @@ -123,11 +123,11 @@ } \ No newline at end of file Index: lams_tool_chat/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_chat/web/WEB-INF/tags/AuthoringRatingCriteria.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> @@ -284,42 +283,42 @@ - - + + - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + - - + + - - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - + + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + Index: lams_tool_chat/web/WEB-INF/tags/CommentsAuthor.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,7 +1,7 @@ <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-html" prefix="html"%> <%@ taglib uri="tags-fmt" prefix="fmt"%> <%@ taglib uri="tags-lams" prefix="lams"%> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ attribute name="allowCommentsVariableName" required="false" rtexprvalue="true"%> <%@ attribute name="allowCommentLabelKey" required="false" rtexprvalue="true"%> @@ -42,23 +42,21 @@
-     -   +     +  
Index: lams_tool_chat/web/WEB-INF/tags/Page.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/Page.tag (.../Page.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/Page.tag (.../Page.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -4,6 +4,7 @@ <%@ taglib uri="tags-lams" prefix="lams"%> <%@ attribute name="type" required="true" rtexprvalue="true"%> +<%@ attribute name="formID" required="false" rtexprvalue="true"%> <%@ attribute name="style" required="false" rtexprvalue="true"%> <%@ attribute name="title" required="false" rtexprvalue="true"%> <%@ attribute name="titleHelpURL" required="false" rtexprvalue="true"%> @@ -88,8 +89,8 @@ - - + + ${toolForm.toolSessionID} @@ -434,4 +435,4 @@
- + \ No newline at end of file Index: lams_tool_chat/web/WEB-INF/tags/Rating.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_chat/web/WEB-INF/tags/StyledRating.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -8,7 +8,6 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> <%@ taglib uri="tags-lams" prefix="lams"%> <%@ taglib uri="tags-function" prefix="fn" %> Index: lams_tool_chat/web/WEB-INF/tags/TabBody.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/TabBody.tag (.../TabBody.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/TabBody.tag (.../TabBody.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -34,7 +34,6 @@ <%@ attribute name="titleKey" required="false" rtexprvalue="true"%> <%@ attribute name="page" required="false" rtexprvalue="true"%> <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-bean" prefix="bean"%> Index: lams_tool_chat/web/WEB-INF/tags/TabBodyArea.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/TabBodyArea.tag (.../TabBodyArea.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/TabBodyArea.tag (.../TabBodyArea.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -30,7 +30,6 @@ %> <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-bean" prefix="bean"%>
Index: lams_tool_chat/web/WEB-INF/tags/TextSearch.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/tags/TextSearch.tag (.../TextSearch.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/tags/TextSearch.tag (.../TextSearch.tag) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -32,12 +32,11 @@ <%@ tag body-content="scriptless" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-fmt" prefix="fmt" %> -<%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ taglib uri="tags-lams" prefix="lams" %> <%-- Required attributes --%> <%@ attribute name="sessionMapID" required="true" rtexprvalue="true" %> -<%@ attribute name="wrapInFormTag" required="true" rtexprvalue="true" %> <%-- Optional attributes --%> <%@ attribute name="action" required="false" rtexprvalue="true" %> @@ -53,10 +52,10 @@ <%-- Default value for message key --%> - + - + @@ -85,52 +84,40 @@ - -
- - -

- - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - - - - - - - + +

+ + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
\ No newline at end of file Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tiles-defs.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-bean-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-bean.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-html-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-html.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-logic-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-logic.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-nested.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-tiles-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/tlds/struts/struts-tiles.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/validation.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 903574fa3e87a5a85057a975acfe6ccfba0b9de0 refers to a dead (removed) revision in file `lams_tool_chat/web/WEB-INF/validator-rules.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_chat/web/WEB-INF/web.xml =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/WEB-INF/web.xml (.../web.xml) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/WEB-INF/web.xml (.../web.xml) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -62,29 +62,16 @@ org.springframework.web.context.ContextLoaderListener - - - action - org.apache.struts.action.ActionServlet - - config - /WEB-INF/struts-config.xml - - - debug - 999 - - - detail - 2 - - - validate - true - + + + spring + + org.springframework.web.servlet.DispatcherServlet + 1 + @@ -116,7 +103,7 @@ - action + spring *.do Index: lams_tool_chat/web/common/taglibs.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/common/taglibs.jsp (.../taglibs.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/common/taglibs.jsp (.../taglibs.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -8,4 +8,5 @@ <%@ taglib uri="tags-function" prefix="fn" %> <%@ taglib uri="tags-fmt" prefix="fmt"%> <%@ taglib uri="tags-lams" prefix="lams"%> + <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> \ No newline at end of file Index: lams_tool_chat/web/layouts/defaultLayout.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/layouts/defaultLayout.jsp (.../defaultLayout.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/layouts/defaultLayout.jsp (.../defaultLayout.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,9 +1,118 @@ + <%@ include file="/common/taglibs.jsp"%> - + + + + + + + <fmt:message key="activity.title" /> + + + + + + + + + + - + + + + + + + + + + + +
+ + + + + + + + + + +
+
+ ${message.from} +
+ + +
+ +
+ + + + + + + + + + + + + + +
+ +
- +
Index: lams_tool_chat/web/pages/authoring/authoring.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/authoring/authoring.jsp (.../authoring.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/authoring/authoring.jsp (.../authoring.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,54 +1,71 @@ + <%@ include file="/common/taglibs.jsp"%> <%@ page import="org.lamsfoundation.lams.tool.chat.util.ChatConstants"%> - + - - + + - - - + + + <fmt:message key="activity.title" /> + + + + + + + + + - - - - - - - - - - + + + + + + + -
- - -
-
-
-
+ + + + + - <%-- Page tabs --%> - - - - - - - + - +
+ + +
+
+
+
+ + <%-- Page tabs --%> + + + + + + + + +
+ + + +
- +
+ +
- - -
- Index: lams_tool_chat/web/pages/authoring/basic.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/authoring/basic.jsp (.../basic.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/authoring/basic.jsp (.../basic.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,16 +1,14 @@ <%@ include file="/common/taglibs.jsp"%> - - - + +
- +
- +
Index: lams_tool_chat/web/pages/authoring/conditions.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/authoring/conditions.jsp (.../conditions.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/authoring/conditions.jsp (.../conditions.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,6 +1,4 @@ <%@ include file="/common/taglibs.jsp"%> - - - - + + + + + + + + <fmt:message key="activity.title" /> + + + + + + - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- -
-
- -
-
-
- -   -
+ + + + + + + + + +
+
-
- - - -
-
-
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
-
-
-
- +
+
-
- + +
+
+
+ +   +
+
+
+
+ + +
+
+
+ +
+
+
+
+ +
+
+
+
+ + + <%@ include file="parts/finishButton.jsp"%> + + - - <%@ include file="parts/finishButton.jsp"%> - - + + + Index: lams_tool_chat/web/pages/learning/notebook.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/learning/notebook.jsp (.../notebook.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/learning/notebook.jsp (.../notebook.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,46 +1,69 @@ + + <%@ include file="/common/taglibs.jsp"%> - + + + + + + + + <fmt:message key="activity.title" /> + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + +
+
+ + + - - -
- -
- - - - - - - - - - - - - - - -
-
- - - - - + + +
Index: lams_tool_chat/web/pages/learning/parts/finishButton.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/learning/parts/finishButton.jsp (.../finishButton.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/learning/parts/finishButton.jsp (.../finishButton.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,8 +1,7 @@ <%@ include file="/common/taglibs.jsp"%> - - - + + @@ -24,12 +23,10 @@

- - - + ">
- + - - + + - - - - + " class="btn btn-responsive btn-primary pull-right voffset10"/> - - + @@ -70,8 +63,8 @@ - +
- + Index: lams_tool_chat/web/pages/learning/submissionDeadline.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/learning/submissionDeadline.jsp (.../submissionDeadline.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/learning/submissionDeadline.jsp (.../submissionDeadline.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,18 +1,36 @@ + + <%@ include file="/common/taglibs.jsp"%> - - - + + + + + + + + <fmt:message key="activity.title" /> + + + + - - - - - - - - - <%@ include file="parts/finishButton.jsp"%> - - + + + + + + + + + + + + + + <%@ include file="parts/finishButton.jsp"%> + + + + Index: lams_tool_chat/web/pages/monitoring/chatHistory.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/monitoring/chatHistory.jsp (.../chatHistory.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/monitoring/chatHistory.jsp (.../chatHistory.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -4,100 +4,121 @@ - + + + + + + + + - + - - - - - - - - - - -
- - - - - - - - - - -
-
- ${message.from} -
- - -
- -
- - - - - + + + + + + + +
+ - - - - - - + + + + + + - - + +
+
+ ${message.from} +
+ + +
+ +
+ + + + + + + + + + + + + + +
+ + +
+
+
+
+ +
+
+
+ + + + <%@ include file="parts/finishButton.jsp"%> + + + + + + Index: lams_tool_chat/web/pages/monitoring/notebook.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/monitoring/notebook.jsp (.../notebook.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/monitoring/notebook.jsp (.../notebook.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -1,23 +1,46 @@ + <%@ include file="/common/taglibs.jsp"%> +<%@ page import="org.lamsfoundation.lams.tool.chat.util.ChatConstants"%> + - - + + + + + + - - - - - - - -
-

- -

-
-

- -

-
+ + + <fmt:message key="activity.title" /> + + + + -
\ No newline at end of file + + + + + + + + + + + + +
+

+ +

+
+

+ +

+
+ +
+ +
Index: lams_tool_chat/web/pages/monitoring/summary.jsp =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_chat/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_chat/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -13,7 +13,7 @@ lams: '${lams}', submissionDeadline: '${submissionDeadline}', submissionDateString: '${submissionDateString}', - setSubmissionDeadlineUrl: '', + setSubmissionDeadlineUrl: '', toolContentID: '${param.toolContentID}', messageNotification: '', messageRestrictionSet: '', @@ -69,9 +69,9 @@ @@ -135,8 +135,7 @@ - - + Index: lams_tool_lamc/web/monitoring/Edit.jsp =================================================================== diff -u -r9e395fca5d7eb4a5ac4c9768642a336723a950f7 -r903574fa3e87a5a85057a975acfe6ccfba0b9de0 --- lams_tool_lamc/web/monitoring/Edit.jsp (.../Edit.jsp) (revision 9e395fca5d7eb4a5ac4c9768642a336723a950f7) +++ lams_tool_lamc/web/monitoring/Edit.jsp (.../Edit.jsp) (revision 903574fa3e87a5a85057a975acfe6ccfba0b9de0) @@ -16,7 +16,7 @@ - +