Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaController.java =================================================================== diff -u -re0dcf97659b72435ef0f29c69a4999847ae11d5b -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaController.java (.../QaController.java) (revision e0dcf97659b72435ef0f29c69a4999847ae11d5b) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaController.java (.../QaController.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -88,7 +88,7 @@ @Qualifier("qaMessageService") private MessageService messageService; - @RequestMapping("/") + @RequestMapping("") public String unspecified() { return "authoring/AuthoringTabsHolder"; } Index: lams_tool_laqa/web/authoring/newQuestionBox.jsp =================================================================== diff -u -r5f5d164117e56516c294f276bbaa4a33e2108372 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_laqa/web/authoring/newQuestionBox.jsp (.../newQuestionBox.jsp) (revision 5f5d164117e56516c294f276bbaa4a33e2108372) +++ lams_tool_laqa/web/authoring/newQuestionBox.jsp (.../newQuestionBox.jsp) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -5,7 +5,7 @@
- + @@ -17,7 +17,7 @@
Index: lams_tool_pixlr/.classpath =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/.classpath (.../.classpath) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/.classpath (.../.classpath) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -3,10 +3,9 @@ - - + @@ -18,11 +17,12 @@ - + + Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/LearningController.java =================================================================== diff -u -r2d2c869032858b474398c651f8c45371410ba0d2 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/LearningController.java (.../LearningController.java) (revision 2d2c869032858b474398c651f8c45371410ba0d2) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/LearningController.java (.../LearningController.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -101,7 +101,7 @@ @Autowired private WebApplicationContext applicationContext; - @RequestMapping("/") + @RequestMapping("") public String unspecified(@ModelAttribute("learningForm") LearningForm learningForm, HttpServletRequest request, HttpServletResponse response) throws Exception { Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/MonitoringController.java =================================================================== diff -u -r2d2c869032858b474398c651f8c45371410ba0d2 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 2d2c869032858b474398c651f8c45371410ba0d2) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/controller/MonitoringController.java (.../MonitoringController.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -62,8 +62,8 @@ @Autowired private IPixlrService pixlrService; - @RequestMapping("/") - public String unspecified(HttpServletRequest request) { + @RequestMapping("") + public String unspecified(@ModelAttribute("monitoringForm")MonitoringForm monitoringForm,HttpServletRequest request) { Long toolContentID = new Long(WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID)); @@ -104,7 +104,7 @@ } @RequestMapping("/showPixlr") - public String showPixlr(HttpServletRequest request) { + public String showPixlr(@ModelAttribute("monitoringForm")MonitoringForm monitoringForm,HttpServletRequest request) { Long uid = new Long(WebUtil.readLongParam(request, "userUID")); @@ -171,6 +171,6 @@ pixlrUser.setImageHidden(true); } pixlrService.saveOrUpdatePixlrUser(pixlrUser); - return unspecified(request); + return unspecified(monitoringForm,request); } } Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/AdminForm.java =================================================================== diff -u -r46e01bf046d755f571ba59957ac869c086bad58c -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/AdminForm.java (.../AdminForm.java) (revision 46e01bf046d755f571ba59957ac869c086bad58c) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/AdminForm.java (.../AdminForm.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -20,21 +20,12 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.pixlr.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; - /** * */ -public class AdminForm{ +public class AdminForm { private static final long serialVersionUID = 378528935723874238L; Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/LearningForm.java =================================================================== diff -u -r46e01bf046d755f571ba59957ac869c086bad58c -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/LearningForm.java (.../LearningForm.java) (revision 46e01bf046d755f571ba59957ac869c086bad58c) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/LearningForm.java (.../LearningForm.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -21,19 +21,15 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.pixlr.web.forms; -import org.apache.struts.action.ActionForm; - /** * * @author lfoxton * * */ -public class LearningForm{ +public class LearningForm { private static final long serialVersionUID = -4728946254882237144L; Index: lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/MonitoringForm.java =================================================================== diff -u -r46e01bf046d755f571ba59957ac869c086bad58c -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/MonitoringForm.java (.../MonitoringForm.java) (revision 46e01bf046d755f571ba59957ac869c086bad58c) +++ lams_tool_pixlr/src/java/org/lamsfoundation/lams/tool/pixlr/web/forms/MonitoringForm.java (.../MonitoringForm.java) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -21,16 +21,12 @@ * **************************************************************** */ - - package org.lamsfoundation.lams.tool.pixlr.web.forms; -import org.apache.struts.action.ActionForm; - /** * */ -public class MonitoringForm{ +public class MonitoringForm { private static final long serialVersionUID = 9096908688391850595L; Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/struts-config.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_pixlr/web/WEB-INF/tags/AuthoringButton.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/AuthoringButton.tag (.../AuthoringButton.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -32,7 +32,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"%> <%@ attribute name="formID" required="true" rtexprvalue="true" %> @@ -123,11 +122,11 @@ } \ No newline at end of file Index: lams_tool_pixlr/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/AuthoringRatingAllStyleCriteria.tag (.../AuthoringRatingAllStyleCriteria.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -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_pixlr/web/WEB-INF/tags/AuthoringRatingCriteria.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/AuthoringRatingCriteria.tag (.../AuthoringRatingCriteria.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -8,9 +8,9 @@ <%@ 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" %> +<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ attribute name="criterias" required="true" rtexprvalue="true" type="java.util.Collection" %> @@ -284,42 +284,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_pixlr/web/WEB-INF/tags/CommentsAuthor.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/CommentsAuthor.tag (.../CommentsAuthor.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -1,5 +1,4 @@ <%@ taglib uri="tags-core" prefix="c"%> -<%@ taglib uri="tags-html" prefix="html"%> <%@ taglib uri="tags-fmt" prefix="fmt"%> <%@ taglib uri="tags-lams" prefix="lams"%> @@ -42,23 +41,23 @@
-     -   +     +  
Index: lams_tool_pixlr/web/WEB-INF/tags/Rating.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/Rating.tag (.../Rating.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -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_pixlr/web/WEB-INF/tags/StyledRating.tag =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_pixlr/web/WEB-INF/tags/StyledRating.tag (.../StyledRating.tag) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -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" %> Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tiles-defs.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-bean-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-bean.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-html-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-html.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-logic-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-logic.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-nested.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-tiles-el.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/tlds/struts/struts-tiles.tld'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/validation.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_pixlr/web/WEB-INF/validator-rules.xml'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_pixlr/web/WEB-INF/web.xml =================================================================== diff -u -r46e01bf046d755f571ba59957ac869c086bad58c -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/WEB-INF/web.xml (.../web.xml) (revision 46e01bf046d755f571ba59957ac869c086bad58c) +++ lams_tool_pixlr/web/WEB-INF/web.xml (.../web.xml) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -133,41 +133,6 @@ - - - - tags-bean - /WEB-INF/tlds/struts/struts-bean.tld - - - tags-html - /WEB-INF/tlds/struts/struts-html.tld - - - tags-logic - /WEB-INF/tlds/struts/struts-logic.tld - - - tags-tiles - /WEB-INF/tlds/struts/struts-tiles.tld - - - tags-bean-el - /WEB-INF/tlds/struts/struts-bean-el.tld - - - tags-html-el - /WEB-INF/tlds/struts/struts-html-el.tld - - - tags-logic-el - /WEB-INF/tlds/struts/struts-logic-el.tld - - - tags-tiles-el - /WEB-INF/tlds/struts/struts-tiles-el.tld - - Index: lams_tool_pixlr/web/pages/admin/config.jsp =================================================================== diff -u -r46e01bf046d755f571ba59957ac869c086bad58c -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/pages/admin/config.jsp (.../config.jsp) (revision 46e01bf046d755f571ba59957ac869c086bad58c) +++ lams_tool_pixlr/web/pages/admin/config.jsp (.../config.jsp) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -28,15 +28,14 @@ - + - - + - + Index: lams_tool_pixlr/web/pages/authoring/authoring.jsp =================================================================== diff -u -r2d2c869032858b474398c651f8c45371410ba0d2 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/pages/authoring/authoring.jsp (.../authoring.jsp) (revision 2d2c869032858b474398c651f8c45371410ba0d2) +++ lams_tool_pixlr/web/pages/authoring/authoring.jsp (.../authoring.jsp) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -55,7 +55,7 @@ } - + Index: lams_tool_pixlr/web/pages/monitoring/monitoring.jsp =================================================================== diff -u -r14949f3bb9736ad6386b56eca018dc1257cb36a1 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_pixlr/web/pages/monitoring/monitoring.jsp (.../monitoring.jsp) (revision 14949f3bb9736ad6386b56eca018dc1257cb36a1) +++ lams_tool_pixlr/web/pages/monitoring/monitoring.jsp (.../monitoring.jsp) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -23,7 +23,7 @@ - " type="navbar"> + Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/AuthoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/ClearSessionAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/MonitoringAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag b7b682644cd1d20e061092b1411eeb679a1f9fb2 refers to a dead (removed) revision in file `lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/PedagogicalPlannerAction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/AuthoringAction.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/AuthoringAction.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/AuthoringAction.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,414 @@ +/**************************************************************** + * 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.scribe.web.controller; + +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.scribe.model.Scribe; +import org.lamsfoundation.lams.tool.scribe.model.ScribeHeading; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.util.ScribeConstants; +import org.lamsfoundation.lams.tool.scribe.web.forms.AuthoringForm; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.action.LamsDispatchAction; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * + * + * + * + * + * + * + * + * + * + */ +@Controller +@RequestMapping("") +public class AuthoringAction extends LamsDispatchAction { + + private static Logger logger = Logger.getLogger(AuthoringAction.class); + + public IScribeService scribeService; + + // 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"; + + private static final String KEY_HEADINGS = "headings"; + + /** + * 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. + * + */ + @Override + protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // 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); + + // set up scribeService + if (scribeService == null) { + scribeService = ScribeServiceProxy.getScribeService(this.getServlet().getServletContext()); + } + + // retrieving Scribe with given toolContentID + Scribe scribe = scribeService.getScribeByContentId(toolContentID); + if (scribe == null) { + scribe = scribeService.copyDefaultContent(toolContentID); + scribe.setCreateDate(new Date()); + scribeService.saveOrUpdateScribe(scribe); + // TODO NOTE: this causes DB orphans when LD not saved. + } + + // check if content in use is set + if (scribe.isContentInUse()) { + // Cannot edit, send to message page. + request.setAttribute(ScribeConstants.ATTR_MESSAGE, + getResources(request).getMessage("error.content.locked")); + return mapping.findForward("message_page"); + } + + 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. + scribe.setDefineLater(true); + scribeService.saveOrUpdateScribe(scribe); + + //audit log the teacher has started editing activity in monitor + scribeService.auditLogStartEditingActivityInMonitor(toolContentID); + } + + // Set up the authForm. + AuthoringForm authForm = (AuthoringForm) form; + updateAuthForm(authForm, scribe); + + // Set up sessionMap + SessionMap map = createSessionMap(scribe, mode, contentFolderID, + toolContentID); + authForm.setSessionMapID(map.getSessionID()); + + // add the sessionMap to HTTPSession. + request.getSession().setAttribute(map.getSessionID(), map); + request.setAttribute(ScribeConstants.ATTR_SESSION_MAP, map); + + return mapping.findForward("success"); + } + + public ActionForward updateContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + // TODO need error checking. + + // get authForm and session map. + AuthoringForm authForm = (AuthoringForm) form; + SessionMap map = getSessionMap(request, authForm); + + // get scribe content. + Scribe scribe = scribeService.getScribeByContentId((Long) map.get(KEY_TOOL_CONTENT_ID)); + + // update scribe content using form inputs + updateScribe(scribe, authForm); + + // update headings. + List updatedHeadings = getHeadingList(map); + Set currentHeadings = scribe.getScribeHeadings(); + for (ScribeHeading heading : updatedHeadings) { + // it is update + if (heading.getUid() != null) { + Iterator iter = currentHeadings.iterator(); + while (iter.hasNext()) { + ScribeHeading currHeading = (ScribeHeading) iter.next(); + if (heading.getUid().equals(currHeading.getUid())) { + // update fields + currHeading.setHeadingText(heading.getHeadingText()); + currHeading.setDisplayOrder(heading.getDisplayOrder()); + break; + } + } // go to next heading from page + } else { + currentHeadings.add(heading); + } + } + // remove deleted heading. + Iterator iter = currentHeadings.iterator(); + while (iter.hasNext()) { + ScribeHeading currHeading = (ScribeHeading) iter.next(); + // skip new added heading + if (currHeading.getUid() == null) { + continue; + } + boolean find = false; + for (ScribeHeading heading : updatedHeadings) { + if (currHeading.getUid().equals(heading.getUid())) { + find = true; + break; + } + } + if (!find) { + // delete current heading's report first + scribeService.deleteHeadingReport(currHeading.getUid()); + iter.remove(); + } + } + + // set the update date + scribe.setUpdateDate(new Date()); + + // releasing defineLater flag so that learner can start using the tool. + scribe.setDefineLater(false); + + scribeService.saveOrUpdateScribe(scribe); + + request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + + // add the sessionMapID to form + authForm.setSessionMapID(map.getSessionID()); + + request.setAttribute(ScribeConstants.ATTR_SESSION_MAP, map); + + return mapping.findForward("success"); + } + + public ActionForward loadHeadingForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + String sessionMapID = WebUtil.readStrParam(request, "sessionMapID"); + Integer headingIndex = WebUtil.readIntParam(request, "headingIndex", true); + + AuthoringForm authForm = ((AuthoringForm) form); + + if (headingIndex == null) { + headingIndex = -1; + } + + authForm.setHeadingIndex(headingIndex); + authForm.setSessionMapID(sessionMapID); + + return mapping.findForward("heading_form"); + } + + public ActionForward addOrUpdateHeading(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + AuthoringForm authForm = (AuthoringForm) form; + SessionMap map = getSessionMap(request, authForm); + + String headingText = authForm.getHeading(); + Integer headingIndex = authForm.getHeadingIndex(); + Long toolContentID = getToolContentID(map); + + Scribe scribe = scribeService.getScribeByContentId(toolContentID); + + if (headingIndex == -1) { + // create a new heading + List headings = getHeadingList(map); + + ScribeHeading scribeHeading = new ScribeHeading(headings.size()); + scribeHeading.setScribe(scribe); + scribeHeading.setHeadingText(headingText); + + headings.add(scribeHeading); + } else { + // update the existing heading + ScribeHeading heading = getHeadingList(map).get(headingIndex); + heading.setHeadingText(headingText); + } + + request.setAttribute("sessionMapID", map.getSessionID()); + return mapping.findForward("heading_response"); + } + + public ActionForward moveHeading(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + AuthoringForm authForm = (AuthoringForm) form; + SessionMap map = getSessionMap(request, authForm); + + int headingIndex = WebUtil.readIntParam(request, "headingIndex"); + String direction = WebUtil.readStrParam(request, "direction"); + + ListIterator iter = getHeadingList(map).listIterator(headingIndex); + + ScribeHeading heading = iter.next(); + iter.remove(); + + // move to correct location + if (direction.equals("up")) { + if (iter.hasPrevious()) { + iter.previous(); + } + } else if (direction.equals("down")) { + if (iter.hasNext()) { + iter.next(); + } + } else { + // invalid direction, don't move anywhere. + log.error("moveHeading: received invalid direction : " + direction); + } + + // adding heading back into list + iter.add(heading); + + // update the displayOrder + int i = 0; + for (ScribeHeading elem : getHeadingList(map)) { + elem.setDisplayOrder(i); + i++; + } + + request.setAttribute("sessionMapID", map.getSessionID()); + return mapping.findForward("heading_response"); + } + + public ActionForward deleteHeading(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + AuthoringForm authForm = (AuthoringForm) form; + SessionMap map = getSessionMap(request, authForm); + + Integer headingIndex = authForm.getHeadingIndex(); + + getHeadingList(map).remove(headingIndex.intValue()); + + request.setAttribute("sessionMapID", map.getSessionID()); + return mapping.findForward("heading_response"); + + } + + /* ========== Private Methods ********** */ + + /** + * Updates Scribe content using AuthoringForm inputs. + * + * @param authForm + * @param mode + * @return + */ + private void updateScribe(Scribe scribe, AuthoringForm authForm) { + scribe.setTitle(authForm.getTitle()); + scribe.setInstructions(authForm.getInstructions()); + scribe.setReflectOnActivity(authForm.isReflectOnActivity()); + scribe.setReflectInstructions(authForm.getReflectInstructions()); + scribe.setAutoSelectScribe(authForm.isAutoSelectScribe()); + scribe.setShowAggregatedReports(authForm.isShowAggregatedReports()); + } + + /** + * Updates AuthoringForm using Scribe content. + * + * @param scribe + * @param authForm + * @return + */ + private void updateAuthForm(AuthoringForm authForm, Scribe scribe) { + authForm.setTitle(scribe.getTitle()); + authForm.setInstructions(scribe.getInstructions()); + authForm.setReflectOnActivity(scribe.isReflectOnActivity()); + authForm.setReflectInstructions(scribe.getReflectInstructions()); + authForm.setAutoSelectScribe(scribe.isAutoSelectScribe()); + authForm.setShowAggregatedReports(scribe.isShowAggregatedReports()); + } + + /** + * Updates SessionMap using Scribe content. + * + * @param scribe + * @param mode + */ + private SessionMap createSessionMap(Scribe scribe, ToolAccessMode mode, String contentFolderID, + Long toolContentID) { + + SessionMap map = new SessionMap(); + + map.put(KEY_MODE, mode); + map.put(KEY_CONTENT_FOLDER_ID, contentFolderID); + map.put(KEY_TOOL_CONTENT_ID, toolContentID); + map.put(KEY_HEADINGS, new LinkedList()); + + // adding headings + Iterator iter = scribe.getScribeHeadings().iterator(); + while (iter.hasNext()) { + ScribeHeading element = (ScribeHeading) iter.next(); + getHeadingList(map).add(element); + } + + // sorting headings according to displayOrder. + Collections.sort(getHeadingList(map)); + + return map; + } + + private List getHeadingList(SessionMap map) { + return (List) map.get(KEY_HEADINGS); + } + + /** + * Retrieve the SessionMap from the HttpSession. + * + * @param request + * @param authForm + * @return + */ + private SessionMap getSessionMap(HttpServletRequest request, AuthoringForm authForm) { + return (SessionMap) request.getSession().getAttribute(authForm.getSessionMapID()); + } + + private Long getToolContentID(SessionMap map) { + return (Long) map.get(KEY_TOOL_CONTENT_ID); + } +} \ No newline at end of file Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/ClearSessionAction.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/ClearSessionAction.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/ClearSessionAction.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,51 @@ +/**************************************************************** + * 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.scribe.web.controller; + +import javax.servlet.http.HttpSession; + +import org.lamsfoundation.lams.authoring.web.LamsAuthoringFinishAction; +import org.lamsfoundation.lams.tool.ToolAccessMode; + +/** + * This class give a chance to clear HttpSession when user save/close authoring page. + * + * @author Steve.Ni + * + * + * + * + * @version $Revision$ + */ +public class ClearSessionAction extends LamsAuthoringFinishAction { + + @Override + public void clearSession(String customiseSessionID, HttpSession session, ToolAccessMode mode) { + if (mode.isAuthor()) { + session.removeAttribute(customiseSessionID); + } + } + +} Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningAction.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningAction.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningAction.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,337 @@ +/**************************************************************** + * 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.scribe.web.controller; + +import java.io.IOException; +import java.util.TreeMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +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.exception.DataMissingException; +import org.lamsfoundation.lams.tool.exception.ToolException; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeDTO; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeSessionDTO; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeUserDTO; +import org.lamsfoundation.lams.tool.scribe.model.Scribe; +import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; +import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.util.ScribeConstants; +import org.lamsfoundation.lams.tool.scribe.util.ScribeException; +import org.lamsfoundation.lams.tool.scribe.util.ScribeUtils; +import org.lamsfoundation.lams.tool.scribe.web.forms.LearningForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.action.LamsDispatchAction; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +public class LearningAction extends LamsDispatchAction { + + private static Logger log = Logger.getLogger(LearningAction.class); + + private static final boolean MODE_OPTIONAL = false; + + private IScribeService scribeService; + + @Override + public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + // 'toolSessionID' and 'mode' paramters are expected to be present. + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, + LearningAction.MODE_OPTIONAL); + + Long toolSessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + + // set up scribeService + if (scribeService == null) { + scribeService = ScribeServiceProxy.getScribeService(this.getServlet().getServletContext()); + } + scribeService.createReportEntry(toolSessionID); + + // Retrieve the session and content. + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + if (scribeSession == null) { + throw new ScribeException("Cannot retrieve session with toolSessionID" + toolSessionID); + } + Scribe scribe = scribeSession.getScribe(); + + // check defineLater + if (scribe.isDefineLater()) { + return mapping.findForward("defineLater"); + } + + // Ensure that the content in use flag is set. + if (!scribe.isContentInUse()) { + scribe.setContentInUse(new Boolean(true)); + scribeService.saveOrUpdateScribe(scribe); + } + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(toolSessionID, request, + getServlet().getServletContext()); + + // Retrieve the current user + ScribeUser scribeUser = getCurrentUser(toolSessionID); + + // check whether scribe has been appointed + while (scribeSession.getAppointedScribe() == null) { + // check autoSelectScribe + if (scribe.isAutoSelectScribe() == false) { + // learner needs to wait until a scribe has been appointed by + // teacher. + return mapping.findForward("waitForScribe"); + + } else { + // appoint the currentUser as the scribe + scribeSession.setAppointedScribe(scribeUser); + scribeService.saveOrUpdateScribeSession(scribeSession); + } + } + + // setup dto's forms and attributes. + ((LearningForm) form).setToolSessionID(scribeSession.getSessionId()); + request.setAttribute("MODE", mode.toString()); + setupDTOs(request, scribeSession, scribeUser); + + // check force complete + if (scribeSession.isForceComplete()) { + // go to report page + if (scribeSession.getScribe().isShowAggregatedReports()) { + setupOtherGroupReportDTO(request, scribeSession, scribeUser); + } + return mapping.findForward("report"); + } + + // check if user has started activity + if (!scribeUser.isStartedActivity()) { + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + request.setAttribute("role", "scribe"); + } else { + request.setAttribute("role", "learner"); + } + return mapping.findForward("instructions"); + } + + // check if current user is the scribe. + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + return mapping.findForward("scribe"); + } else { + return mapping.findForward("learning"); + } + + } + + private ScribeUser getCurrentUser(Long toolSessionID) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + // attempt to retrieve user using userId and toolSessionID + ScribeUser scribeUser = scribeService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionID); + + if (scribeUser == null) { + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + scribeUser = scribeService.createScribeUser(user, scribeSession); + } + + return scribeUser; + } + + public ActionForward startActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + LearningForm lrnForm = (LearningForm) form; + Long toolSessionID = lrnForm.getToolSessionID(); + + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + ScribeUser scribeUser = getCurrentUser(toolSessionID); + + // setup dto's, forms and attributes. + lrnForm.setToolSessionID(scribeSession.getSessionId()); + request.setAttribute("MODE", lrnForm.getMode()); + setupDTOs(request, scribeSession, scribeUser); + + // update scribe user and go to instructions page + scribeUser.setStartedActivity(true); + scribeService.saveOrUpdateScribeUser(scribeUser); + + // check if current user is the scribe. + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + return mapping.findForward("scribe"); + } + + return mapping.findForward("learning"); + } + + public ActionForward finishActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + LearningForm lrnForm = (LearningForm) form; + + // set the finished flag + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + if (scribeUser != null) { + scribeUser.setFinishedActivity(true); + scribeService.saveOrUpdateScribeUser(scribeUser); + } else { + LearningAction.log + .error("finishActivity(): couldn't find ScribeUser with uid: " + lrnForm.getScribeUserUID()); + } + + ToolSessionManager sessionMgrService = ScribeServiceProxy + .getScribeSessionManager(getServlet().getServletContext()); + + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + Long toolSessionID = scribeUser.getScribeSession().getSessionId(); + + String nextActivityUrl; + try { + nextActivityUrl = sessionMgrService.leaveToolSession(toolSessionID, userID); + response.sendRedirect(nextActivityUrl); + } catch (DataMissingException e) { + throw new ScribeException(e); + } catch (ToolException e) { + throw new ScribeException(e); + } catch (IOException e) { + throw new ScribeException(e); + } + + return null; // TODO need to return proper page. + } + + public ActionForward openNotebook(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + LearningForm lrnForm = (LearningForm) form; + + // set the finished flag + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + ScribeDTO scribeDTO = new ScribeDTO(scribeUser.getScribeSession().getScribe()); + + request.setAttribute("scribeDTO", scribeDTO); + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(scribeUser.getScribeSession().getSessionId(), + request, getServlet().getServletContext()); + + return mapping.findForward("notebook"); + } + + public ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // save the reflection entry and call the notebook. + + LearningForm lrnForm = (LearningForm) form; + + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + + scribeService.createNotebookEntry(scribeUser.getScribeSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, scribeUser.getUserId().intValue(), + lrnForm.getEntryText()); + + return finishActivity(mapping, form, request, response); + } + + public ActionForward forceCompleteActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException { + LearningForm lrnForm = (LearningForm) form; + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + ScribeSession session = scribeUser.getScribeSession(); + + if (session.getAppointedScribe().getUid() == scribeUser.getUid()) { + session.setForceComplete(true); + } else { + // TODO need to implement this. + LearningAction.log + .error("ScribeUserUID: " + scribeUser.getUid() + " is not allowed to forceComplete this session"); + } + + request.setAttribute("MODE", lrnForm.getMode()); + setupDTOs(request, session, scribeUser); + scribeService.saveOrUpdateScribeUser(scribeUser); + + if (session.getScribe().isShowAggregatedReports()) { + setupOtherGroupReportDTO(request, session, scribeUser); + } + + LearningWebUtil.putActivityPositionInRequestByToolSessionId(session.getSessionId(), request, + getServlet().getServletContext()); + + return mapping.findForward("report"); + } + + // Private methods. + + /** + * Set up all the DTO relating to this session. Doesn't set up the DTO containing the reports of the other groups. + */ + private void setupDTOs(HttpServletRequest request, ScribeSession scribeSession, ScribeUser scribeUser) { + + ScribeDTO scribeDTO = new ScribeDTO(scribeSession.getScribe()); + request.setAttribute("scribeDTO", scribeDTO); + + ScribeSessionDTO sessionDTO = new ScribeSessionDTO(scribeSession); + request.setAttribute("scribeSessionDTO", sessionDTO); + + ScribeUserDTO scribeUserDTO = new ScribeUserDTO(scribeUser); + if (scribeUser.isFinishedActivity()) { + // get the notebook entry. + NotebookEntry notebookEntry = scribeService.getEntry(scribeSession.getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, + scribeUser.getUserId().intValue()); + if (notebookEntry != null) { + scribeUserDTO.notebookEntry = notebookEntry.getEntry(); + } + } + request.setAttribute("scribeUserDTO", scribeUserDTO); + } + + /** + * Create a map of the reports (in ScribeSessionDTO format) for all the other groups/sessions, where the key is the + * group/session name. The code ensures that the session name is unique, adding the session id if necessary. It will + * only include the finalized reports. + */ + private void setupOtherGroupReportDTO(HttpServletRequest request, ScribeSession scribeSession, + ScribeUser scribeUser) { + TreeMap otherScribeSessions = ScribeUtils.getReportDTOs(scribeSession); + if (otherScribeSessions.size() > 0) { + request.setAttribute("otherScribeSessions", otherScribeSessions.values()); + } + } + +} Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningWebsocketServer.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningWebsocketServer.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/LearningWebsocketServer.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,342 @@ +package org.lamsfoundation.lams.tool.scribe.web.controller; + +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +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.scribe.model.ScribeReportEntry; +import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; +import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.util.ScribeUtils; +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.util.HtmlUtils; + +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 Scribe reports and votes to Learners. + * + * @author Marcin Cieslak + */ +@ServerEndpoint("/learningWebsocket") +public class LearningWebsocketServer { + + // caches what was sent to users already so it can be compared with DB + private static class ScribeSessionCache { + private int numberOfVotes = 0; + private int numberOfLearners = 0; + private final Map reports = new TreeMap<>(); + } + + /** + * A singleton which updates Learners with reports and votes. + */ + private static class SendWorker extends Thread { + private boolean stopFlag = false; + // how ofter the thread runs + private static final long CHECK_INTERVAL = 3000; + + @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 through activities and update registered learners with reports and vote count + while (entryIterator.hasNext()) { + Entry> entry = entryIterator.next(); + Long toolSessionId = entry.getKey(); + // if all learners left the activity, remove the obsolete mapping + Set sessionWebsockets = entry.getValue(); + if (sessionWebsockets.isEmpty()) { + entryIterator.remove(); + LearningWebsocketServer.cache.remove(toolSessionId); + continue; + } + + ScribeSession scribeSession = LearningWebsocketServer.getScribeService() + .getSessionBySessionId(toolSessionId); + if (scribeSession.isForceComplete()) { + LearningWebsocketServer.sendCloseRequest(toolSessionId); + continue; + } + + SendWorker.send(toolSessionId, null); + } + } catch (Exception e) { + // error caught, but carry on + LearningWebsocketServer.log.error("Error in Scribe worker thread", e); + } finally { + HibernateSessionManager.closeSession(); + try { + Thread.sleep(SendWorker.CHECK_INTERVAL); + } catch (InterruptedException e) { + LearningWebsocketServer.log.warn("Stopping Scribe worker thread"); + stopFlag = true; + } + } + } + } + + /** + * Feeds websockets with reports and votes. + */ + @SuppressWarnings("unchecked") + private static void send(Long toolSessionId, Session newWebsocket) throws IOException { + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + ScribeSessionCache sessionCache = LearningWebsocketServer.cache.get(toolSessionId); + if (sessionCache == null) { + // first time run, create the cache + sessionCache = new ScribeSessionCache(); + LearningWebsocketServer.cache.put(toolSessionId, sessionCache); + } + + boolean send = false; + ScribeSession scribeSession = LearningWebsocketServer.getScribeService() + .getSessionBySessionId(toolSessionId); + Set learners = scribeSession.getScribeUsers(); + if (sessionCache.numberOfLearners != learners.size()) { + // new users have arrived + sessionCache.numberOfLearners = learners.size(); + send = true; + } + + // collect users who agreed on the report + Set learnersApproved = new TreeSet<>(); + for (ScribeUser user : learners) { + if (user.isReportApproved()) { + learnersApproved.add(user.getLoginName()); + } + } + if (sessionCache.numberOfVotes != learnersApproved.size()) { + sessionCache.numberOfVotes = learnersApproved.size(); + send = true; + } + + ArrayNode reportsJSON = JsonNodeFactory.instance.arrayNode(); + synchronized (sessionCache) { + for (ScribeReportEntry storedReport : (Set) scribeSession.getScribeReportEntries()) { + Long uid = storedReport.getUid(); + String cachedReportText = sessionCache.reports.get(uid); + String storedReportText = HtmlUtils.htmlEscape(storedReport.getEntryText()); + storedReportText = storedReportText != null ? storedReportText.replaceAll("\n", "
") : null; + if (cachedReportText == null ? storedReportText != null + : (storedReportText == null) || (cachedReportText.length() != storedReportText.length()) + || !cachedReportText.equals(storedReportText)) { + // we could be storing hash instead of full report + // but to build hash each report char needs to be processed anyway + sessionCache.reports.put(uid, storedReportText); + + ObjectNode reportJSON = JsonNodeFactory.instance.objectNode(); + reportJSON.put("uid", uid); + reportJSON.put("text", storedReportText); + reportsJSON.add(reportJSON); + } + } + } + if (reportsJSON.size() > 0) { + responseJSON.set("reports", reportsJSON); + send = true; + } + + // always send to an user who just entered, otherwise only if there is new data + if (!send && (newWebsocket == null)) { + return; + } + + responseJSON.put("numberOfLearners", sessionCache.numberOfLearners); + responseJSON.put("numberOfVotes", sessionCache.numberOfVotes); + int votePercentage = ScribeUtils.calculateVotePercentage(sessionCache.numberOfVotes, + sessionCache.numberOfLearners); + responseJSON.put("votePercentage", votePercentage); + + // either send only to the new user or to everyone + if (newWebsocket == null) { + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + for (Session websocket : sessionWebsockets) { + String userName = websocket.getUserPrincipal().getName(); + responseJSON.put("approved", learnersApproved.contains(userName)); + websocket.getBasicRemote().sendText(responseJSON.toString()); + } + } else { + String userName = newWebsocket.getUserPrincipal().getName(); + responseJSON.put("approved", learnersApproved.contains(userName)); + newWebsocket.getBasicRemote().sendText(responseJSON.toString()); + } + } + } + + private static Logger log = Logger.getLogger(LearningWebsocketServer.class); + + private static IScribeService scribeService; + + private static final SendWorker sendWorker = new SendWorker(); + // maps toolSessionId -> cached session data + private static final Map cache = 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 websocket) throws IOException { + Long toolSessionId = Long + .valueOf(websocket.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); + } + sessionWebsockets.add(websocket); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + + " entered Scribe with toolSessionId: " + toolSessionId); + } + + new Thread(() -> { + try { + HibernateSessionManager.openSession(); + SendWorker.send(toolSessionId, websocket); + } catch (Exception e) { + log.error("Error while sending messages", e); + } finally { + HibernateSessionManager.closeSession(); + } + }).start(); + } + + /** + * When user leaves the activity. + */ + @OnClose + public void unregisterUser(Session websocket, CloseReason reason) { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + LearningWebsocketServer.websockets.get(toolSessionId).remove(websocket); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + // If there was something wrong with the connection, put it into logs. + LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + + " left Scribe with Tool Session ID: " + toolSessionId + + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) + || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) + ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + + reason.getReasonPhrase() + : "")); + } + } + + /** + * Receives a message sent by Learner via a websocket. + * + * @throws IOException + * @throws JsonProcessingException + */ + @OnMessage + public void receiveRequest(String input, Session websocket) throws JsonProcessingException, IOException { + if (StringUtils.isBlank(input)) { + return; + } + if (input.equalsIgnoreCase("ping")) { + // just a ping every few minutes + return; + } + + ObjectNode requestJSON = JsonUtil.readObject(input); + switch (JsonUtil.optString(requestJSON, "type")) { + case "vote": + LearningWebsocketServer.vote(websocket); + break; + case "submitReport": + LearningWebsocketServer.submitReport(requestJSON, websocket); + break; + } + } + + /** + * User has approved a report. + */ + private static void vote(Session websocket) { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + String userName = websocket.getUserPrincipal().getName(); + ScribeUser learner = LearningWebsocketServer.getScribeService().getUserByLoginNameAndSessionId(userName, + toolSessionId); + if (learner != null) { + learner.setReportApproved(true); + LearningWebsocketServer.getScribeService().saveOrUpdateScribeUser(learner); + } + } + + /** + * The scribe has submitted a report. + */ + private static void submitReport(ObjectNode requestJSON, Session websocket) { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + String userName = websocket.getUserPrincipal().getName(); + LearningWebsocketServer.getScribeService().submitReport(toolSessionId, userName, requestJSON); + } + + /** + * The scribe or a Monitor has force completed the activity. Browsers will refresh and display report summary. + */ + static void sendCloseRequest(Long toolSessionId) throws IOException { + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + if (sessionWebsockets == null) { + return; + } + + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.put("close", true); + String response = responseJSON.toString(); + + for (Session websocket : sessionWebsockets) { + if (websocket.isOpen()) { + websocket.getBasicRemote().sendText(response); + } + } + } + + private static IScribeService getScribeService() { + if (LearningWebsocketServer.scribeService == null) { + LearningWebsocketServer.scribeService = ScribeServiceProxy + .getScribeService(SessionManager.getServletContext()); + } + return LearningWebsocketServer.scribeService; + } +} \ No newline at end of file Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/MonitoringAction.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/MonitoringAction.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/MonitoringAction.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,214 @@ +/**************************************************************** + * 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.scribe.web.controller; + +import java.io.IOException; +import java.util.Iterator; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; + +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeDTO; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeSessionDTO; +import org.lamsfoundation.lams.tool.scribe.dto.ScribeUserDTO; +import org.lamsfoundation.lams.tool.scribe.model.Scribe; +import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; +import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.util.ScribeConstants; +import org.lamsfoundation.lams.tool.scribe.util.ScribeUtils; +import org.lamsfoundation.lams.tool.scribe.web.forms.MonitoringForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.action.LamsDispatchAction; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** + * @author + * @version + * + * + * + * + * + * + * + */ +public class MonitoringAction extends LamsDispatchAction { + + private static Logger log = Logger.getLogger(MonitoringAction.class); + + public IScribeService scribeService; + + @Override + public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + 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); + MonitoringForm monForm = (MonitoringForm) form; + monForm.setContentFolderID(contentFolderID); + + monForm.setCurrentTab(WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); + + // set up scribeService + if (scribeService == null) { + scribeService = ScribeServiceProxy.getScribeService(this.getServlet().getServletContext()); + } + Scribe scribe = scribeService.getScribeByContentId(toolContentID); + + ScribeDTO scribeDTO = setupScribeDTO(scribe); + boolean isGroupedActivity = scribeService.isGroupedActivity(toolContentID); + request.setAttribute("isGroupedActivity", isGroupedActivity); + request.setAttribute("monitoringDTO", scribeDTO); + request.setAttribute("contentFolderID", contentFolderID); + + return mapping.findForward("success"); + } + + public ActionForward openNotebook(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + Long uid = WebUtil.readLongParam(request, "uid", false); + + ScribeUser scribeUser = scribeService.getUserByUID(uid); + NotebookEntry notebookEntry = scribeService.getEntry(scribeUser.getScribeSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, scribeUser.getUserId().intValue()); + + ScribeUserDTO scribeUserDTO = new ScribeUserDTO(scribeUser); + scribeUserDTO.setNotebookEntry(notebookEntry.getEntry()); + + request.setAttribute("scribeUserDTO", scribeUserDTO); + + return mapping.findForward("notebook"); + } + + public ActionForward appointScribe(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + MonitoringForm monForm = (MonitoringForm) form; + + ScribeSession session = scribeService.getSessionBySessionId(monForm.getToolSessionID()); + ScribeUser user = scribeService.getUserByUID(monForm.getAppointedScribeUID()); + + session.setAppointedScribe(user); + scribeService.saveOrUpdateScribeSession(session); + + ScribeDTO scribeDTO = setupScribeDTO(session.getScribe()); + boolean isGroupedActivity = scribeService.isGroupedActivity(session.getScribe().getToolContentId()); + request.setAttribute("isGroupedActivity", isGroupedActivity); + request.setAttribute("monitoringDTO", scribeDTO); + request.setAttribute("contentFolderID", monForm.getContentFolderID()); + + monForm.setCurrentTab(WebUtil.readLongParam(request, AttributeNames.PARAM_CURRENT_TAB, true)); + + return mapping.findForward("success"); + } + + public ActionForward forceCompleteActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException { + + MonitoringForm monForm = (MonitoringForm) form; + + ScribeSession session = scribeService.getSessionBySessionId(monForm.getToolSessionID()); + session.setForceComplete(true); + scribeService.saveOrUpdateScribeSession(session); + + ScribeDTO scribeDTO = setupScribeDTO(session.getScribe()); + request.setAttribute("monitoringDTO", scribeDTO); + request.setAttribute("contentFolderID", monForm.getContentFolderID()); + + return mapping.findForward("success"); + } + + /* Private Methods */ + + private ScribeDTO setupScribeDTO(Scribe scribe) { + ScribeDTO scribeDTO = new ScribeDTO(scribe); + + for (Iterator sessIter = scribe.getScribeSessions().iterator(); sessIter.hasNext();) { + ScribeSession session = (ScribeSession) sessIter.next(); + + ScribeSessionDTO sessionDTO = new ScribeSessionDTO(session); + int numberOfVotes = 0; + + for (Iterator userIter = session.getScribeUsers().iterator(); userIter.hasNext();) { + ScribeUser user = (ScribeUser) userIter.next(); + ScribeUserDTO userDTO = new ScribeUserDTO(user); + + // get the notebook entry. + NotebookEntry notebookEntry = scribeService.getEntry(session.getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, + user.getUserId().intValue()); + if (notebookEntry != null) { + userDTO.finishedReflection = true; + } else { + userDTO.finishedReflection = false; + } + + if (user.isReportApproved()) { + numberOfVotes++; + } + + sessionDTO.getUserDTOs().add(userDTO); + } + int numberOfLearners = session.getScribeUsers().size(); + + sessionDTO.setNumberOfVotes(numberOfVotes); + sessionDTO.setNumberOfLearners(numberOfLearners); + sessionDTO.setVotePercentage(ScribeUtils.calculateVotePercentage(numberOfVotes, numberOfLearners)); + scribeDTO.getSessionDTOs().add(sessionDTO); + } + + return scribeDTO; + + } + + private ScribeUser getCurrentUser(Long toolSessionID) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + // attempt to retrieve user using userId and toolSessionID + ScribeUser scribeUser = scribeService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionID); + + if (scribeUser == null) { + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + scribeUser = scribeService.createScribeUser(user, scribeSession); + } + + return scribeUser; + } +} Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/PedagogicalPlannerAction.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/PedagogicalPlannerAction.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/controller/PedagogicalPlannerAction.java (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -0,0 +1,139 @@ +/**************************************************************** + * 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.scribe.web.controller; + +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionMessages; +import org.lamsfoundation.lams.tool.scribe.model.Scribe; +import org.lamsfoundation.lams.tool.scribe.model.ScribeHeading; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.web.forms.ScribePedagogicalPlannerForm; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.action.LamsDispatchAction; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** + * @author + * @version + * + * + * + * + * + */ +public class PedagogicalPlannerAction extends LamsDispatchAction { + + private static Logger logger = Logger.getLogger(PedagogicalPlannerAction.class); + public IScribeService scribeService; + + @Override + protected ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return initPedagogicalPlannerForm(mapping, form, request, response); + } + + public ActionForward initPedagogicalPlannerForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + ScribePedagogicalPlannerForm plannerForm = (ScribePedagogicalPlannerForm) form; + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Scribe scribe = getScribeService().getScribeByContentId(toolContentID); + plannerForm.fillForm(scribe); + String contentFolderId = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + plannerForm.setContentFolderID(contentFolderId); + return mapping.findForward("success"); + } + + public ActionForward saveOrUpdatePedagogicalPlannerForm(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) throws IOException { + ScribePedagogicalPlannerForm plannerForm = (ScribePedagogicalPlannerForm) form; + ActionMessages errors = plannerForm.validate(); + if (errors.isEmpty()) { + Scribe scribe = getScribeService().getScribeByContentId(plannerForm.getToolContentID()); + + int headingIndex = 0; + String heading = null; + ScribeHeading scribeHeading = null; + List newHeadings = new LinkedList(); + Iterator scribeHeadingIterator = scribe.getScribeHeadings().iterator(); + do { + heading = plannerForm.getHeading(headingIndex); + if (StringUtils.isEmpty(heading)) { + plannerForm.removeHeading(headingIndex); + } else { + if (scribeHeadingIterator.hasNext()) { + scribeHeading = scribeHeadingIterator.next(); + scribeHeading.setDisplayOrder(headingIndex); + } else { + scribeHeading = new ScribeHeading(); + scribeHeading.setHeadingText(heading); + scribeHeading.setDisplayOrder(headingIndex); + + newHeadings.add(scribeHeading); + scribeHeading.setScribe(scribe); + } + headingIndex++; + } + + } while (heading != null); + while (scribeHeadingIterator.hasNext()) { + scribeHeading = scribeHeadingIterator.next(); + scribeHeadingIterator.remove(); + getScribeService().deleteHeading(scribeHeading.getUid()); + } + scribe.getScribeHeadings().addAll(newHeadings); + getScribeService().saveOrUpdateScribe(scribe); + } else { + saveErrors(request, errors); + } + return mapping.findForward("success"); + } + + public ActionForward createPedagogicalPlannerHeading(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) { + ScribePedagogicalPlannerForm plannerForm = (ScribePedagogicalPlannerForm) form; + plannerForm.setHeading(plannerForm.getHeadingCount().intValue(), ""); + return mapping.findForward("success"); + } + + private IScribeService getScribeService() { + if (scribeService == null) { + scribeService = ScribeServiceProxy.getScribeService(this.getServlet().getServletContext()); + } + return scribeService; + } +} \ No newline at end of file Index: lams_tool_scribe/web/WEB-INF/spring-servlet.xml =================================================================== diff -u -r2d2c869032858b474398c651f8c45371410ba0d2 -rb7b682644cd1d20e061092b1411eeb679a1f9fb2 --- lams_tool_scribe/web/WEB-INF/spring-servlet.xml (.../spring-servlet.xml) (revision 2d2c869032858b474398c651f8c45371410ba0d2) +++ lams_tool_scribe/web/WEB-INF/spring-servlet.xml (.../spring-servlet.xml) (revision b7b682644cd1d20e061092b1411eeb679a1f9fb2) @@ -8,7 +8,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> - +