Index: lams_build/build.xml =================================================================== diff -u -r2a14741090c7e0f8cc12158171de8f9af40a17cc -rc697b5c30ab742ab453859355b35cd518856334f --- lams_build/build.xml (.../build.xml) (revision 2a14741090c7e0f8cc12158171de8f9af40a17cc) +++ lams_build/build.xml (.../build.xml) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -413,11 +413,6 @@ - - - - - Index: lams_build/lib/pedagogical_planner/1/1/1/LAMS_Pedagogical_Planner_Template.zip =================================================================== diff -u -rc938db99e80a21d9099839105f58e9c7537fe0d5 -rc697b5c30ab742ab453859355b35cd518856334f Binary files differ Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r8a8f2f8f903adda7b9cd3096a747d01bf5923008 -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8a8f2f8f903adda7b9cd3096a747d01bf5923008) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -262,14 +262,26 @@ button.planner.save.node=Save node label.planner.create.subnode=Create subnode label.planner.edit.node=Edit node -label.planner.root.node=Root -msg.planner.open.template=This node opens planner template. +label.planner.root.node=Planner +msg.planner.open.template=This node opens a planner template. msg.planner.remove.node=Remove node label.planner.empty.subnode=There are no subnodes defined. label.planner.description.brief=Brief description (for parent node) label.planner.description.full=Full description (for self) label.planner.root.choose=Choose a planner from one of the following activity categories: msg.planner.remove.warning=Are you sure you want to remove this node and all of its subnodes? - -#======= End labels: Exported 223 labels for en AU ===== +label.planner.node.type=This node: +label.planner.node.type.subnodes=has subnodes +label.planner.node.type.template=opens a template +label.planner.remove.file=Remove file +label.planner.change.file=Change file: +label.planner.uploaded.template=Uploaded template file: +msg.planner.move.node.up=Move node up +msg.planner.move.node.down=Move node down +label.planner.choose.file=Choose a template file: +error.planner.node.title.blank=Node title must not be blank. +error.planner.repository=There was a file respository error. Template file was not saved. +error.planner.file.empty=For a node opening a template you must upload a file. +error.planner.file.bad.extension=Template file must have a ZIP or LAS extension. +#======= End labels: Exported 222 labels for en AU ===== Index: lams_central/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r8a8f2f8f903adda7b9cd3096a747d01bf5923008 -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 8a8f2f8f903adda7b9cd3096a747d01bf5923008) +++ lams_central/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -262,14 +262,26 @@ button.planner.save.node=Save node label.planner.create.subnode=Create subnode label.planner.edit.node=Edit node -label.planner.root.node=Root -msg.planner.open.template=This node opens planner template. +label.planner.root.node=Planner +msg.planner.open.template=This node opens a planner template. msg.planner.remove.node=Remove node label.planner.empty.subnode=There are no subnodes defined. label.planner.description.brief=Brief description (for parent node) label.planner.description.full=Full description (for self) label.planner.root.choose=Choose a planner from one of the following activity categories: msg.planner.remove.warning=Are you sure you want to remove this node and all of its subnodes? - -#======= End labels: Exported 223 labels for en AU ===== +label.planner.node.type=This node: +label.planner.node.type.subnodes=has subnodes +label.planner.node.type.template=opens a template +label.planner.remove.file=Remove file +label.planner.change.file=Change file: +label.planner.uploaded.template=Uploaded template file: +msg.planner.move.node.up=Move node up +msg.planner.move.node.down=Move node down +label.planner.choose.file=Choose a template file: +error.planner.node.title.blank=Node title must not be blank. +error.planner.repository=There was a file respository error. Template file was not saved. +error.planner.file.empty=For a node opening a template you must upload a file. +error.planner.file.bad.extension=Template file must have a ZIP or LAS extension. +#======= End labels: Exported 222 labels for en AU ===== Index: lams_central/conf/xdoclet/taglibs.xml =================================================================== diff -u -rccd319d5814f7182b441e35cd615aa162fef83fb -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/conf/xdoclet/taglibs.xml (.../taglibs.xml) (revision ccd319d5814f7182b441e35cd615aa162fef83fb) +++ lams_central/conf/xdoclet/taglibs.xml (.../taglibs.xml) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -65,7 +65,7 @@ fck-editor - /WEB-INF/fckeditor/tlds/FCKeditor.tld + /WEB-INF/jstl/tlds/FCKeditor.tld Index: lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml (.../authoringApplicationContext.xml) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml (.../authoringApplicationContext.xml) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -51,7 +51,6 @@ - Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -164,10 +164,6 @@ } - public PedagogicalPlannerDAO getPedagogicalPlannerDAO() { - return pedagogicalPlannerDAO; - } - public void setPedagogicalPlannerDAO(PedagogicalPlannerDAO pedagogicalPlannerDAO) { this.pedagogicalPlannerDAO = pedagogicalPlannerDAO; } @@ -538,8 +534,8 @@ } if (design != null) { /* - * only the user who is editing the design may unlock it - */ + * only the user who is editing the design may unlock it + */ if (design.getEditOverrideUser().equals(user)) { design.setEditOverrideLock(false); design.setEditOverrideUser(null); Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java (.../IAuthoringService.java) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java (.../IAuthoringService.java) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -34,7 +34,6 @@ import org.lamsfoundation.lams.learningdesign.dto.AuthoringActivityDTO; import org.lamsfoundation.lams.learningdesign.dto.ValidationErrorDTO; import org.lamsfoundation.lams.learningdesign.exception.LearningDesignException; -import org.lamsfoundation.lams.planner.dao.PedagogicalPlannerDAO; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; import org.lamsfoundation.lams.usermanagement.exception.UserException; @@ -390,6 +389,4 @@ public Grouping getGroupingById(Long groupingID); - public PedagogicalPlannerDAO getPedagogicalPlannerDAO(); - -} +} \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/util/CentralConstants.java (.../CentralConstants.java) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -139,19 +139,27 @@ public static final String ERROR_PLANNER_TITLE_BLANK = "error.planner.title.blank"; - public static final String PATH_ACTIVITY_NO_PLANNER_SUPPORT = "/pedagogical_planner/defaultActivityForm.jsp"; - - public static final String TEMPLATE_FILE_NAME = "LAMS_Pedagogical_Planner_Template.zip"; - - public static final String IMAGE_PATH_GATE = "images/stop.gif"; - public static final String RESOURCE_KEY_BRANCH_EMPTY = "label.planner.branch.empty"; - public static final String IMAGE_PATH_GROUPING = "images/grouping.gif"; - public static final String FORWARD_GROUPING = "grouping"; public static final int PLANNER_MAX_BRANCHES = 4; public static final int PLANNER_MAX_OPTIONS = 4; + + public static final String MONITORING_SERVICE_BEAN_NAME = "monitoringService"; + + public static final String CENTRAL_MESSAGE_SERVICE_BEAN_NAME = "centralMessageService"; + + public static final String ATTR_NODE = "node"; + + public static final String PARAM_CREATE_SUBNODE = "createSubnode"; + + public static final String PARAM_UID = "uid"; + + public static final String CENTRAL_TOOL_CONTENT_HANDLER_BEAN_NAME = "centralToolContentHandler"; + + public static final String PARAM_EDIT = "edit"; + + public static final String USER_MANAGEMENT_SERVICE_BEAN_NAME = "userManagementService"; } \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerAction.java =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerAction.java (.../PedagogicalPlannerAction.java) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerAction.java (.../PedagogicalPlannerAction.java) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -24,7 +24,9 @@ package org.lamsfoundation.lams.web.planner; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -39,8 +41,15 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; +import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; +import org.apache.struts.upload.FormFile; import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.authoring.web.AuthoringConstants; +import org.lamsfoundation.lams.contentrepository.NodeKey; +import org.lamsfoundation.lams.contentrepository.RepositoryCheckedException; +import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; +import org.lamsfoundation.lams.contentrepository.client.ToolContentHandler; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.Grouping; @@ -61,11 +70,14 @@ import org.lamsfoundation.lams.planner.dto.PedagogicalPlannerActivityDTO; import org.lamsfoundation.lams.planner.dto.PedagogicalPlannerSequenceNodeDTO; import org.lamsfoundation.lams.planner.dto.PedagogicalPlannerTemplateDTO; +import org.lamsfoundation.lams.usermanagement.Role; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.CentralConstants; -import org.lamsfoundation.lams.util.Configuration; +import org.lamsfoundation.lams.util.CentralToolContentHandler; +import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.FileUtilException; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; @@ -82,15 +94,22 @@ * @struts:action path="/pedagogicalPlanner" scope="request" parameter="method" * name="PedagogicalPlannerSequenceNodeForm" * @struts:action-forward name="template" path="/pedagogical_planner/templateBase.jsp" + * @struts:action-forward name="preview" path="/home.do?method=learner" + * @struts:action-forward name="sequenceChooser" path="/pedagogical_planner/sequenceChooser.jsp" * * @struts:action path="/pedagogicalPlanner/grouping" scope="request" name="PedagogicalPlannerGroupingForm" * validate="false" parameter="method" * @struts:action-forward name="grouping" path="/pedagogical_planner/grouping.jsp" - * @struts:action-forward name="preview" path="/home.do?method=learner" - * @struts:action-forward name="sequenceChooser" path="/pedagogical_planner/sequenceChooser.jsp" */ public class PedagogicalPlannerAction extends LamsDispatchAction { + private static final String FILE_EXTENSION_ZIP = ".zip"; + private static final String FILE_EXTENSION_LAS = ".las"; + + private static final String FORWARD_TEMPLATE = "template"; + private static final String FORWARD_PREVIEW = "preview"; + private static final String FORWARD_SEQUENCE_CHOOSER = "sequenceChooser"; + // Several chars and strings used for building HTML requests private static final String CHAR_QUESTION_MARK = "?"; private static final String CHAR_AMPERSAND = "&"; @@ -104,6 +123,7 @@ private static IMonitoringService monitoringService; private static MessageService messageService; private static PedagogicalPlannerDAO pedagogicalPlannerDAO; + private static ToolContentHandler contentHandler; // Error messages used in class private static final String ERROR_TOOL_ERRORS = "There were tool errors."; @@ -117,8 +137,17 @@ private static final String ERROR_NESTED_BRANCHING = "Nested branching activities are not allowed in Pedagogical Planner."; private static final String ERROR_TOO_MANY_BRANCHES = "Number of branches in branching activity is limited to " + CentralConstants.PLANNER_MAX_BRANCHES + " in Pedagogical Planner."; + private static final String ERROR_PLANNER_NODE_TITLE_BLANK = "error.planner.node.title.blank"; + private static final String ERROR_PLANNER_REPOSITORY = "error.planner.repository"; + private static final String ERROR_PLANNER_FILE_BAD_EXTENSION = "error.planner.file.bad.extension"; + private static final String ERROR_PLANNER_FILE_EMPTY = "error.planner.file.empty"; private static Logger log = Logger.getLogger(PedagogicalPlannerAction.class); + private static final String PEDAGOGICAL_PLANNER_DAO_BEAN_NAME = "pedagogicalPlannerDAO"; + private static final String IMAGE_PATH_GATE = "images/stop.gif"; + private static final String PATH_ACTIVITY_NO_PLANNER_SUPPORT = "/pedagogical_planner/defaultActivityForm.jsp"; + private static final String IMAGE_PATH_GROUPING = "images/grouping.gif"; + @Override /** * Go straight to start(). @@ -139,14 +168,29 @@ * @throws IOException * @throws ServletException */ - private ActionForward openTemplate(ActionMapping mapping, HttpServletRequest request, String filePath) + private ActionForward openTemplate(ActionMapping mapping, HttpServletRequest request, Long fileUuid, String fileName) throws IOException, ServletException { // Get the learning design template zip file - String designFilePath = "pedagogical_planner" + File.separator + "1" + File.separator + "1" + File.separator - + "1"; - String contentRepositoryPath = Configuration.get("ContentRepositoryPath"); - File templateDirectory = new File(contentRepositoryPath, designFilePath); - File designFile = new File(templateDirectory, CentralConstants.TEMPLATE_FILE_NAME); + + File designFile = null; + + try { + InputStream inputStream = getContentHandler().getFileNode(fileUuid).getFile(); + designFile = new File(FileUtil.TEMP_DIR, fileName); + FileOutputStream fileOutputStream = new FileOutputStream(designFile); + byte[] data = new byte[1024]; + int read = 0; + do { + read = inputStream.read(data); + if (read > 0) { + fileOutputStream.write(data, 0, read); + } + } while (read > 0); + fileOutputStream.close(); + inputStream.close(); + } catch (Exception e) { + throw new ServletException(e); + } if (!designFile.exists() || designFile.isDirectory()) { throw new IOException(PedagogicalPlannerAction.ERROR_NOT_PROPER_FILE); } @@ -163,6 +207,7 @@ // Extract the template try { Object[] ldResults = getExportService().importLearningDesign(designFile, user, null, toolsErrorMsgs, ""); + designFile.delete(); learningDesignID = (Long) ldResults[0]; learningDesignErrorMsgs = (List) ldResults[1]; toolsErrorMsgs = (List) ldResults[2]; @@ -221,56 +266,9 @@ planner.setActivitiesInPortion(2); request.setAttribute(CentralConstants.ATTR_PLANNER, planner); - return mapping.findForward("template"); + return mapping.findForward(PedagogicalPlannerAction.FORWARD_TEMPLATE); } - private IExportToolContentService getExportService() { - if (PedagogicalPlannerAction.exportService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - PedagogicalPlannerAction.exportService = (IExportToolContentService) ctx - .getBean("exportToolContentService"); - } - return PedagogicalPlannerAction.exportService; - } - - private IAuthoringService getAuthoringService() { - if (PedagogicalPlannerAction.authoringService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - PedagogicalPlannerAction.authoringService = (IAuthoringService) ctx.getBean("authoringService"); - } - return PedagogicalPlannerAction.authoringService; - } - - private IMonitoringService getMonitoringService() { - if (PedagogicalPlannerAction.monitoringService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - PedagogicalPlannerAction.monitoringService = (IMonitoringService) ctx.getBean("monitoringService"); - } - return PedagogicalPlannerAction.monitoringService; - } - - private IUserManagementService getUserManagementService() { - if (PedagogicalPlannerAction.userManagementService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - PedagogicalPlannerAction.userManagementService = (IUserManagementService) ctx - .getBean("userManagementService"); - } - return PedagogicalPlannerAction.userManagementService; - } - - private MessageService getMessageService() { - if (PedagogicalPlannerAction.messageService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - PedagogicalPlannerAction.messageService = (MessageService) ctx.getBean("centralMessageService"); - } - return PedagogicalPlannerAction.messageService; - } - /** * Saves additional, non tool bound template details - currently only the title. * @@ -358,7 +356,7 @@ getMonitoringService().createPreviewClassForLesson(userDto.getUserID(), lesson.getLessonId()); getMonitoringService().startLesson(lesson.getLessonId(), userDto.getUserID()); - String newPath = mapping.findForward("preview").getPath(); + String newPath = mapping.findForward(PedagogicalPlannerAction.FORWARD_PREVIEW).getPath(); newPath = newPath + PedagogicalPlannerAction.CHAR_AMPERSAND + AttributeNames.PARAM_LESSON_ID + PedagogicalPlannerAction.CHAR_EQUALS + lesson.getLessonId(); return new ActionForward(newPath, true); @@ -392,7 +390,7 @@ if (pedagogicalPlannerUrl == null) { // if there is no URL, the tool does not support the planner addedDTO = new PedagogicalPlannerActivityDTO(toolActivity.getTool().getToolDisplayName(), activity - .getTitle(), false, CentralConstants.PATH_ACTIVITY_NO_PLANNER_SUPPORT, activity + .getTitle(), false, PedagogicalPlannerAction.PATH_ACTIVITY_NO_PLANNER_SUPPORT, activity .getLibraryActivityUiImage(), null, null); } else { // add some required parameters @@ -421,12 +419,13 @@ + PedagogicalPlannerAction.CHAR_AMPERSAND + AttributeNames.PARAM_TOOL_CONTENT_ID + PedagogicalPlannerAction.CHAR_EQUALS + groupingActivity.getCreateGrouping().getGroupingId(), - CentralConstants.IMAGE_PATH_GROUPING, null, null); + PedagogicalPlannerAction.IMAGE_PATH_GROUPING, null, null); activities.add(addedDTO); } else if (activity.isGateActivity()) { // gate is not supported, but takes its image from a differen spot addedDTO = new PedagogicalPlannerActivityDTO(null, activity.getTitle(), false, - CentralConstants.PATH_ACTIVITY_NO_PLANNER_SUPPORT, CentralConstants.IMAGE_PATH_GATE, null, null); + PedagogicalPlannerAction.PATH_ACTIVITY_NO_PLANNER_SUPPORT, + PedagogicalPlannerAction.IMAGE_PATH_GATE, null, null); activities.add(addedDTO); } else if (activity.isBranchingActivity()) { // Planner does not support branching inside branching/options @@ -448,7 +447,7 @@ if (nestedActivity == null) { // Empty sequence - String path = CentralConstants.PATH_ACTIVITY_NO_PLANNER_SUPPORT + String path = PedagogicalPlannerAction.PATH_ACTIVITY_NO_PLANNER_SUPPORT + PedagogicalPlannerAction.CHAR_QUESTION_MARK + CentralConstants.PARAM_FORM_MESSAGE + PedagogicalPlannerAction.CHAR_EQUALS + getMessageService().getMessage(CentralConstants.RESOURCE_KEY_BRANCH_EMPTY); @@ -519,82 +518,295 @@ addedDTO.setLastNestedActivity(true); } else { addedDTO = new PedagogicalPlannerActivityDTO(null, activity.getTitle(), false, - CentralConstants.PATH_ACTIVITY_NO_PLANNER_SUPPORT, activity.getLibraryActivityUiImage(), null, null); + PedagogicalPlannerAction.PATH_ACTIVITY_NO_PLANNER_SUPPORT, activity.getLibraryActivityUiImage(), + null, null); activities.add(addedDTO); } return addedDTO; } public ActionForward openSequenceNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - Long nodeUid = WebUtil.readLongParam(request, "uid", true); - return openSequenceNode(mapping, request, nodeUid); + Long nodeUid = WebUtil.readLongParam(request, CentralConstants.PARAM_UID, true); + return openSequenceNode(mapping, form, request, nodeUid); } - public ActionForward openSequenceNode(ActionMapping mapping, HttpServletRequest request, Long nodeUid) - throws IOException, ServletException { + public ActionForward openSequenceNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, + Long nodeUid) throws IOException, ServletException { + Boolean isSysAdmin = request.isUserInRole(Role.SYSADMIN); + Boolean edit = WebUtil.readBooleanParam(request, CentralConstants.PARAM_EDIT, false); + edit &= isSysAdmin; PedagogicalPlannerSequenceNode node = null; if (nodeUid == null) { node = getPedagogicalPlannerDAO().getRootNode(); } else { node = getPedagogicalPlannerDAO().getByUid(nodeUid); - if (node.getFileName() != null) { - String filePath = getPedagogicalPlannerDAO().getFilePath(node); - return openTemplate(mapping, request, filePath); + if (!edit && node.getFileUuid() != null) { + return openTemplate(mapping, request, node.getFileUuid(), node.getFileName()); } } List titlePath = getPedagogicalPlannerDAO().getTitlePath(node); PedagogicalPlannerSequenceNodeDTO dto = new PedagogicalPlannerSequenceNodeDTO(node, titlePath); - Boolean edit = WebUtil.readBooleanParam(request, "edit", false); + Boolean createSubnode = WebUtil.readBooleanParam(request, CentralConstants.PARAM_CREATE_SUBNODE, false); + dto.setCreateSubnode(createSubnode); dto.setEdit(edit); + dto.setIsSysAdmin(isSysAdmin); - Boolean createSubnode = WebUtil.readBooleanParam(request, "createSubnode", false); - dto.setCreateSubnode(createSubnode); + request.setAttribute(CentralConstants.ATTR_NODE, dto); - request.setAttribute("node", dto); - return mapping.findForward("sequenceChooser"); + if (edit) { + PedagogicalPlannerSequenceNodeForm nodeForm = (PedagogicalPlannerSequenceNodeForm) form; + nodeForm.setNodeType(node.getFileName() == null ? PedagogicalPlannerSequenceNodeForm.NODE_TYPE_SUBNODES + : PedagogicalPlannerSequenceNodeForm.NODE_TYPE_TEMPLATE); + nodeForm.setRemoveFile(false); + nodeForm.setTitle(dto.getTitle()); + nodeForm.setBriefDescription(dto.getBriefDescription()); + nodeForm.setFullDescription(dto.getFullDescription()); + nodeForm.setFileUuid(node.getFileUuid()); + + if (createSubnode) { + if (node.getParent() == null) { + try { + String contentFolderId = getAuthoringService().generateUniqueContentFolder(); + nodeForm.setContentFolderId(contentFolderId); + } catch (FileUtilException e) { + PedagogicalPlannerAction.log.error(e); + } + } else { + nodeForm.setContentFolderId(node.getParent().getContentFolderId()); + } + } + } + return mapping.findForward(PedagogicalPlannerAction.FORWARD_SEQUENCE_CHOOSER); } public ActionForward saveSequenceNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - Long nodeUid = WebUtil.readLongParam(request, "uid", true); + Long nodeUid = WebUtil.readLongParam(request, CentralConstants.PARAM_UID, true); PedagogicalPlannerSequenceNode node = null; PedagogicalPlannerSequenceNodeForm nodeForm = (PedagogicalPlannerSequenceNodeForm) form; + if (nodeUid == null) { node = new PedagogicalPlannerSequenceNode(); - if (nodeForm.getParentUid() != null) { - PedagogicalPlannerSequenceNode parent = getPedagogicalPlannerDAO().getByUid(nodeForm.getParentUid()); + Long parentUid = nodeForm.getParentUid() == 0 ? null : nodeForm.getParentUid(); + if (parentUid != null) { + PedagogicalPlannerSequenceNode parent = getPedagogicalPlannerDAO().getByUid(parentUid); node.setParent(parent); } - node.setSubdir(getPedagogicalPlannerDAO().getNextSubdir(nodeForm.getParentUid())); + node.setOrder(getPedagogicalPlannerDAO().getNextOrderId(parentUid)); } else { node = getPedagogicalPlannerDAO().getByUid(nodeUid); + nodeUid = node.getUid(); } - node.setTitle(nodeForm.getTitle()); - node.setBriefDescription(nodeForm.getBriefDescription()); - node.setFullDescription(nodeForm.getFullDescription()); - getPedagogicalPlannerDAO().saveOrUpdateNode(node); + String title = nodeForm.getTitle(); + String briefDescription = nodeForm.getBriefDescription(); + String fullDescription = nodeForm.getFullDescription(); + String nodeType = nodeForm.getNodeType(); - nodeUid = node.getUid(); - return openSequenceNode(mapping, request, nodeUid); + ActionMessages errors = validateNodeForm(node, nodeForm); + if (errors.isEmpty()) { + try { + node.setTitle(title); + node.setBriefDescription(briefDescription); + node.setContentFolderId(nodeForm.getContentFolderId()); + + if (PedagogicalPlannerSequenceNodeForm.NODE_TYPE_SUBNODES.equals(nodeForm.getNodeType())) { + if (node.getFileUuid() != null) { + getContentHandler().deleteFile(node.getFileUuid()); + node.setFileName(null); + node.setFileUuid(null); + } + node.setFullDescription(fullDescription); + } else if (Boolean.TRUE.equals(nodeForm.getRemoveFile())) { + getContentHandler().deleteFile(node.getFileUuid()); + node.setFileName(null); + node.setFileUuid(null); + node.setFullDescription(null); + } else if (nodeForm.getFile() != null) { + FormFile file = nodeForm.getFile(); + InputStream inputStream = file.getInputStream(); + String fileName = file.getFileName(); + String type = file.getContentType(); + NodeKey nodeKey = getContentHandler().uploadFile(inputStream, fileName, type, + IToolContentHandler.TYPE_OFFLINE); + if (node.getFileUuid() != null) { + getContentHandler().deleteFile(node.getFileUuid()); + } + node.setFileUuid(nodeKey.getUuid()); + node.setFileName(fileName); + node.setFullDescription(null); + } + + getPedagogicalPlannerDAO().saveOrUpdateNode(node); + nodeUid = node.getUid(); + + } catch (RepositoryCheckedException e) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + PedagogicalPlannerAction.ERROR_PLANNER_REPOSITORY)); + PedagogicalPlannerAction.log.error(e); + } + } + boolean createSubnode = false; + if (nodeUid == null) { + nodeUid = node.getParent() == null ? null : node.getParent().getUid(); + createSubnode = true; + } + openSequenceNode(mapping, form, request, nodeUid); + + if (!errors.isEmpty()) { + saveErrors(request, errors); + nodeForm.setTitle(title); + nodeForm.setBriefDescription(briefDescription); + nodeForm.setFullDescription(fullDescription); + nodeForm.setNodeType(nodeType); + if (createSubnode) { + PedagogicalPlannerSequenceNodeDTO dto = (PedagogicalPlannerSequenceNodeDTO) request + .getAttribute(CentralConstants.ATTR_NODE); + dto.setCreateSubnode(true); + } + } + return mapping.findForward(PedagogicalPlannerAction.FORWARD_SEQUENCE_CHOOSER); } + private ActionMessages validateNodeForm(PedagogicalPlannerSequenceNode node, PedagogicalPlannerSequenceNodeForm form) { + ActionMessages errors = new ActionMessages(); + if (StringUtils.isEmpty(form.getTitle())) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + PedagogicalPlannerAction.ERROR_PLANNER_NODE_TITLE_BLANK)); + } + if (PedagogicalPlannerSequenceNodeForm.NODE_TYPE_TEMPLATE.equals(form.getNodeType()) + && node.getFileName() == null) { + if (form.getFile() == null || form.getFile().getFileSize() == 0) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + PedagogicalPlannerAction.ERROR_PLANNER_FILE_EMPTY)); + } else { + String fileName = form.getFile().getFileName(); + boolean badExtension = false; + if (fileName.length() >= 4) { + String extension = fileName.substring(fileName.length() - 4); + if (!(extension.equalsIgnoreCase(PedagogicalPlannerAction.FILE_EXTENSION_LAS) || extension + .equalsIgnoreCase(PedagogicalPlannerAction.FILE_EXTENSION_ZIP))) { + badExtension = true; + } + } else { + badExtension = true; + } + if (badExtension) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( + PedagogicalPlannerAction.ERROR_PLANNER_FILE_BAD_EXTENSION)); + } + + } + } + return errors; + } + public ActionForward removeSequenceNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - Long nodeUid = WebUtil.readLongParam(request, "uid"); + Long nodeUid = WebUtil.readLongParam(request, CentralConstants.PARAM_UID); PedagogicalPlannerSequenceNode node = getPedagogicalPlannerDAO().getByUid(nodeUid); Long parentUid = node.getParent() == null ? null : node.getParent().getUid(); getPedagogicalPlannerDAO().removeNode(node); - return openSequenceNode(mapping, request, parentUid); + return openSequenceNode(mapping, form, request, parentUid); } - public PedagogicalPlannerDAO getPedagogicalPlannerDAO() { + public ActionForward moveNodeUp(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + return moveNode(mapping, form, request, -1); + } + + public ActionForward moveNodeDown(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + return moveNode(mapping, form, request, 1); + } + + private ActionForward moveNode(ActionMapping mapping, ActionForm form, HttpServletRequest request, + Integer orderDelta) throws IOException, ServletException { + Long nodeUid = WebUtil.readLongParam(request, CentralConstants.PARAM_UID); + PedagogicalPlannerSequenceNode node = getPedagogicalPlannerDAO().getByUid(nodeUid); + Long parentUid = node.getParent() == null ? null : node.getParent().getUid(); + PedagogicalPlannerSequenceNode neighbourNode = getPedagogicalPlannerDAO().getNeighbourNode(node, orderDelta); + + neighbourNode.setOrder(0); + getPedagogicalPlannerDAO().saveOrUpdateNode(neighbourNode); + node.setOrder(node.getOrder() + orderDelta); + getPedagogicalPlannerDAO().saveOrUpdateNode(node); + neighbourNode.setOrder(node.getOrder() - orderDelta); + getPedagogicalPlannerDAO().saveOrUpdateNode(neighbourNode); + + return openSequenceNode(mapping, form, request, parentUid); + } + + private IExportToolContentService getExportService() { + if (PedagogicalPlannerAction.exportService == null) { + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.exportService = (IExportToolContentService) ctx + .getBean(CentralConstants.EXPORT_TOOLCONTENT_SERVICE_BEAN_NAME); + } + return PedagogicalPlannerAction.exportService; + } + + private IAuthoringService getAuthoringService() { + if (PedagogicalPlannerAction.authoringService == null) { + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.authoringService = (IAuthoringService) ctx + .getBean(AuthoringConstants.AUTHORING_SERVICE_BEAN_NAME); + } + return PedagogicalPlannerAction.authoringService; + } + + private IMonitoringService getMonitoringService() { + if (PedagogicalPlannerAction.monitoringService == null) { + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.monitoringService = (IMonitoringService) ctx + .getBean(CentralConstants.MONITORING_SERVICE_BEAN_NAME); + } + return PedagogicalPlannerAction.monitoringService; + } + + private IUserManagementService getUserManagementService() { + if (PedagogicalPlannerAction.userManagementService == null) { + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.userManagementService = (IUserManagementService) ctx + .getBean(CentralConstants.USER_MANAGEMENT_SERVICE_BEAN_NAME); + } + return PedagogicalPlannerAction.userManagementService; + } + + private MessageService getMessageService() { + if (PedagogicalPlannerAction.messageService == null) { + WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.messageService = (MessageService) ctx + .getBean(CentralConstants.CENTRAL_MESSAGE_SERVICE_BEAN_NAME); + } + return PedagogicalPlannerAction.messageService; + } + + private PedagogicalPlannerDAO getPedagogicalPlannerDAO() { if (PedagogicalPlannerAction.pedagogicalPlannerDAO == null) { - PedagogicalPlannerAction.pedagogicalPlannerDAO = getAuthoringService().getPedagogicalPlannerDAO(); + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.pedagogicalPlannerDAO = (PedagogicalPlannerDAO) wac + .getBean(PedagogicalPlannerAction.PEDAGOGICAL_PLANNER_DAO_BEAN_NAME); } return PedagogicalPlannerAction.pedagogicalPlannerDAO; } + + private ToolContentHandler getContentHandler() { + if (PedagogicalPlannerAction.contentHandler == null) { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + PedagogicalPlannerAction.contentHandler = (CentralToolContentHandler) wac + .getBean(CentralConstants.CENTRAL_TOOL_CONTENT_HANDLER_BEAN_NAME); + } + return PedagogicalPlannerAction.contentHandler; + } } \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerSequenceNodeForm.java =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerSequenceNodeForm.java (.../PedagogicalPlannerSequenceNodeForm.java) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/src/java/org/lamsfoundation/lams/web/planner/PedagogicalPlannerSequenceNodeForm.java (.../PedagogicalPlannerSequenceNodeForm.java) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -24,14 +24,23 @@ package org.lamsfoundation.lams.web.planner; import org.apache.struts.action.ActionForm; +import org.apache.struts.upload.FormFile; public class PedagogicalPlannerSequenceNodeForm extends ActionForm { private Long uid; private Long parentUid; + private String contentFolderId; private String title; private String briefDescription; private String fullDescription; + private FormFile file; + private Boolean removeFile; + private String nodeType; + private Long fileUuid; + public final static String NODE_TYPE_SUBNODES = "subnodes"; + public final static String NODE_TYPE_TEMPLATE = "template"; + public Long getUid() { return uid; } @@ -71,4 +80,44 @@ public void setParentUid(Long parentUid) { this.parentUid = parentUid; } + + public FormFile getFile() { + return file; + } + + public void setFile(FormFile file) { + this.file = file; + } + + public Boolean getRemoveFile() { + return removeFile; + } + + public void setRemoveFile(Boolean removeFile) { + this.removeFile = removeFile; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getContentFolderId() { + return contentFolderId; + } + + public void setContentFolderId(String contentFolderId) { + this.contentFolderId = contentFolderId; + } + + public Long getFileUuid() { + return fileUuid; + } + + public void setFileUuid(Long fileUuid) { + this.fileUuid = fileUuid; + } } \ No newline at end of file Index: lams_central/web/WEB-INF/jstl/tlds/FCKeditor.tld =================================================================== diff -u --- lams_central/web/WEB-INF/jstl/tlds/FCKeditor.tld (revision 0) +++ lams_central/web/WEB-INF/jstl/tlds/FCKeditor.tld (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -0,0 +1,129 @@ + + + + The FCKeditor Tag Library offers a very convenient way to create + several FCKeditor instances with different configurations. + Additionally, you can check for user-based capabilities. + + FCKeditor Tag Library + 2.4 + FCK + http://java.fckeditor.net + + + Creates a FCKeditor instance with the given parameters. Any + parameter except instanceName which is empty or contains + whitespaces only will be ignored. + + editor + editor + net.fckeditor.tags.EditorTag + JSP + + + The unique instance name under which the editor can be + retrieved through the API. + + instanceName + true + true + java.lang.String + + + + Width of the FCKeditor instance in the browser window. + + width + true + java.lang.String + + + + Height of the FCKeditor instance in the browser window. + + height + true + java.lang.String + + + + The toolbar set which shall be displayed to the user. + + toolbarSet + true + java.lang.String + + + + The path/folder in which the editor is deployed under + the given context. The context path will be attached + automatically. (e.g. '/fckeditor') + + basePath + true + java.lang.String + + + + Passes any content to the FCKeditor document. Use the + jsp:attribute tag for large inline content. \r, \n, and + \t will be truncated. + + value + true + java.lang.String + + ]]> + + + + + Sets a config property of the editor to the supplied value. + You may provide any attribute you want for the editor. Set + at least one attribute per tag or several attributes with + one tag. This tag can only be nested within an editor tag. + For all configuration options click + here]]>. + + config + config + net.fckeditor.tags.ConfigTag + empty + true + + ]]> + + + + + Displays session-dependent and compatibility-related + information. This tag is intended for developers only. + Response messages cannot be localized, they are English + only. + + check + check + net.fckeditor.tags.CheckTag + empty + + + Provide the feature name you want to check. Valid + features are [FileUpload, FileBrowsing, + CompatibleBrowser] + + command + true + java.lang.String + + +]]> + + + \ No newline at end of file Index: lams_central/web/WEB-INF/struts/struts-config.xml =================================================================== diff -u -r38eea63d76357e11cad168548c1332b9297f0828 -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/web/WEB-INF/struts/struts-config.xml (.../struts-config.xml) (revision 38eea63d76357e11cad168548c1332b9297f0828) +++ lams_central/web/WEB-INF/struts/struts-config.xml (.../struts-config.xml) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -31,9 +31,13 @@ /> + + + \ No newline at end of file Index: lams_central/web/pedagogical_planner/sequenceChooser.jsp =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/web/pedagogical_planner/sequenceChooser.jsp (.../sequenceChooser.jsp) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/web/pedagogical_planner/sequenceChooser.jsp (.../sequenceChooser.jsp) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -7,18 +7,11 @@ <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-function" prefix="fn" %> <%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="tags-logic" prefix="logic" %> <fmt:message key="title.lams"/> :: <fmt:message key="planner.title" /> - - - - - + @@ -54,47 +47,71 @@ -
+
-

-
+

+
${node.fullDescription}
- - +

<%-- Iterate through subnodes --%> - + - + <%-- Cell with icons (info or actions like remove node) --%> - - - - - - - " - onclick="javascript:removeNode('','${removeNodeUrl}')" /> - - - - <fmt:message key=" /> - - + + + + + + + + + + + + " + onclick="javascript:leaveNodeEditor('','${removeNodeUrl}')" /> + + + + + + + " + onclick="javascript:leaveNodeEditor(null,'${upNodeUrl}')" /> + + + + + + + + " + onclick="javascript:leaveNodeEditor(null,'${downNodeUrl}')" /> + + + + + " /> + + @@ -109,7 +126,7 @@ (locked) - - ${subnode.briefDescription} +
${subnode.briefDescription}
@@ -120,91 +137,137 @@ <%-- Form for editing the node --%>
+ +

+ +
+
+

+
<%-- Do we edit the current node or create a subnode? --%> -

+

-

- - - - - - - - -

- + + + +

+

- - value="" - - /> + - - - - -
- + + - - - +


+
+ + + +
+ style="display: none;" - -
- + > +
+ + +
+
+ style="display: none;" + + > + + + + + + ${node.fileName} +

+ +
+
+ + + + + + + + +
+ +
+
-
+ - - - - -
- + + + + + + + +
Index: lams_central/web/pedagogical_planner/templateBase.jsp =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_central/web/pedagogical_planner/templateBase.jsp (.../templateBase.jsp) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_central/web/pedagogical_planner/templateBase.jsp (.../templateBase.jsp) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -155,7 +155,7 @@ - ${complexActivityType} group${activity.group} + ${complexActivityType} group${activity.group} ${complexActivityType}LastActivity Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/planner/PedagogicalPlannerSequenceNode.hbm.xml =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -rc697b5c30ab742ab453859355b35cd518856334f --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/planner/PedagogicalPlannerSequenceNode.hbm.xml (.../PedagogicalPlannerSequenceNode.hbm.xml) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/planner/PedagogicalPlannerSequenceNode.hbm.xml (.../PedagogicalPlannerSequenceNode.hbm.xml) (revision c697b5c30ab742ab453859355b35cd518856334f) @@ -37,11 +37,11 @@ /> + +