Index: lams_build/lib/pedagogical_planner/1/1/1/LAMS_Pedagogical_Planner_Template.zip =================================================================== diff -u -r3636757b4afafb785ae0c6c8295a969c605f8e28 -r3fe05cc69b1d0cfa2cb494a4778a8ab00dec2d60 Binary files differ Index: lams_central/web/includes/javascript/pedagogicalPlanner.js =================================================================== diff -u -r05db875c7974d705f89231416ff6dfe91a5e70f1 -r3fe05cc69b1d0cfa2cb494a4778a8ab00dec2d60 --- lams_central/web/includes/javascript/pedagogicalPlanner.js (.../pedagogicalPlanner.js) (revision 05db875c7974d705f89231416ff6dfe91a5e70f1) +++ lams_central/web/includes/javascript/pedagogicalPlanner.js (.../pedagogicalPlanner.js) (revision 3fe05cc69b1d0cfa2cb494a4778a8ab00dec2d60) @@ -11,6 +11,7 @@ var ACTION_PREVIEW = 1; //After successful submit start preview var ACTION_OPEN_AUTHOR = 2; //After successful submit open full authoring var END_HEAD_REGEX_PATTERN = new RegExp(' 0){ form.ajaxSubmit({ + beforeSubmit: prepareFormData, success: onActivityResponse, dataType: "html" }); } } + function prepareFormData(formData, jqForm, options){ + for (elementIndex = 0;elementIndex0){ + $('#activity'+activityIndex).contents().find('head').html(); + } activity.contentWindow.document.body.innerHTML=responseText.substring(responseText.search(/ + + + + + + + + + + resourceList = getResourceItemList(sessionMap); - List rList = new ArrayList(resourceList); - ResourceItem item = rList.remove(itemIdx); - resourceList.clear(); - resourceList.addAll(rList); - //add to delList - List delList = getDeletedResourceItemList(sessionMap); - delList.add(item); - } - - request.setAttribute(ResourceConstants.ATTR_SESSION_MAP_ID, sessionMapID); - return mapping.findForward(ResourceConstants.SUCCESS); + /** + * Remove resource item attachment, such as single file, learning object ect. It is a ajax call and just temporarily + * remove from page, all permenant change will happen only when user sumbit this resource item again. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward removeItemAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + request.setAttribute("itemAttachment", null); + return mapping.findForward(ResourceConstants.SUCCESS); + } + + /** + * Remove resource item from HttpSession list and update page display. As authoring rule, all persist only happen + * when user submit whole page. So this remove is just impact HttpSession values. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward removeItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int itemIdx = NumberUtils.stringToInt(request.getParameter(ResourceConstants.PARAM_ITEM_INDEX), -1); + if (itemIdx != -1) { + SortedSet resourceList = getResourceItemList(sessionMap); + List rList = new ArrayList(resourceList); + ResourceItem item = rList.remove(itemIdx); + resourceList.clear(); + resourceList.addAll(rList); + // add to delList + List delList = getDeletedResourceItemList(sessionMap); + delList.add(item); } - - /** - * Display edit page for existed resource item. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward editItemInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - -// get back sessionMAP - String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(sessionMapID); - - int itemIdx = NumberUtils.stringToInt(request.getParameter(ResourceConstants.PARAM_ITEM_INDEX),-1); - ResourceItem item = null; - if(itemIdx != -1){ - SortedSet resourceList = getResourceItemList(sessionMap); - List rList = new ArrayList(resourceList); - item = rList.get(itemIdx); - if(item != null){ - populateItemToForm(itemIdx, item,(ResourceItemForm) form,request); - } - } - return findForward(item==null?-1:item.getType(),mapping); + + request.setAttribute(ResourceConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(ResourceConstants.SUCCESS); + } + + /** + * Display edit page for existed resource item. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward editItemInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + int itemIdx = NumberUtils.stringToInt(request.getParameter(ResourceConstants.PARAM_ITEM_INDEX), -1); + ResourceItem item = null; + if (itemIdx != -1) { + SortedSet resourceList = getResourceItemList(sessionMap); + List rList = new ArrayList(resourceList); + item = rList.get(itemIdx); + if (item != null) { + populateItemToForm(itemIdx, item, (ResourceItemForm) form, request); + } } - /** - * Display empty page for new resource item. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward newItemlInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); - ((ResourceItemForm)form).setSessionMapID(sessionMapID); - - short type = (short) NumberUtils.stringToInt(request.getParameter(ITEM_TYPE)); - List instructionList = new ArrayList(INIT_INSTRUCTION_COUNT); - for(int idx=0;idxHttpSession ResourceItemList. Notice, this save is not persist them into database, - * just save HttpSession temporarily. Only they will be persist when the entire authoring - * page is being persisted. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws ServletException - */ - private ActionForward saveOrUpdateItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){ - //get instructions: - List instructionList = getInstructionsFromRequest(request); - - ResourceItemForm itemForm = (ResourceItemForm)form; - ActionErrors errors = validateResourceItem(itemForm); - - if(!errors.isEmpty()){ - this.addErrors(request,errors); - request.setAttribute(ResourceConstants.ATTR_INSTRUCTION_LIST,instructionList); - return findForward(itemForm.getItemType(),mapping); - } - - try { - extractFormToResourceItem(request, instructionList, itemForm); - } catch (Exception e) { - //any upload exception will display as normal error message rather then throw exception directly - errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_UPLOAD_FAILED,e.getMessage())); - if(!errors.isEmpty()){ - this.addErrors(request,errors); - request.setAttribute(ResourceConstants.ATTR_INSTRUCTION_LIST,instructionList); - return findForward(itemForm.getItemType(),mapping); - } - } - //set session map ID so that itemlist.jsp can get sessionMAP - request.setAttribute(ResourceConstants.ATTR_SESSION_MAP_ID, itemForm.getSessionMapID()); - //return null to close this window - return mapping.findForward(ResourceConstants.SUCCESS); + request.setAttribute("instructionList", instructionList); + return findForward(type, mapping); + } + + /** + * This method will get necessary information from resource item form and save or update into + * HttpSession ResourceItemList. Notice, this save is not persist them into database, just save + * HttpSession temporarily. Only they will be persist when the entire authoring page is being + * persisted. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward saveOrUpdateItem(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + // get instructions: + List instructionList = getInstructionsFromRequest(request); + + ResourceItemForm itemForm = (ResourceItemForm) form; + ActionErrors errors = validateResourceItem(itemForm); + + if (!errors.isEmpty()) { + this.addErrors(request, errors); + request.setAttribute(ResourceConstants.ATTR_INSTRUCTION_LIST, instructionList); + return findForward(itemForm.getItemType(), mapping); } - /** - * Ajax call, will add one more input line for new resource item instruction. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward newInstruction(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - int count = NumberUtils.stringToInt(request.getParameter(INSTRUCTION_ITEM_COUNT),0); - List instructionList = new ArrayList(++count); - for(int idx=0;idx items = null; - Resource resource = null; - ResourceForm resourceForm = (ResourceForm)form; - - // Get contentFolderID and save to form. - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - resourceForm.setContentFolderID(contentFolderID); - - //initial Session Map - SessionMap sessionMap = new SessionMap(); - request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); - resourceForm.setSessionMapID(sessionMap.getSessionID()); - - try { - resource = service.getResourceByContentId(contentId); - //if resource does not exist, try to use default content instead. - if(resource == null){ - resource = service.getDefaultContent(contentId); - if(resource.getResourceItems() != null){ - items = new ArrayList(resource.getResourceItems()); - }else - items = null; - }else - items = service.getAuthoredItems(resource.getUid()); - - resourceForm.setResource(resource); + /** + * Read resource data from database and put them into HttpSession. It will redirect to init.do directly after this + * method run successfully. + * + * This method will avoid read database again and lost un-saved resouce item lost when user "refresh page", + * + * @throws ServletException + * + */ + private ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { - //initialize instruction attachment list - List attachmentList = getAttachmentList(sessionMap); - attachmentList.clear(); - attachmentList.addAll(resource.getAttachments()); - } catch (Exception e) { - log.error(e); - throw new ServletException(e); + // save toolContentID into HTTPSession + Long contentId = new Long(WebUtil.readLongParam(request, ResourceConstants.PARAM_TOOL_CONTENT_ID)); + + // get back the resource and item list and display them on page + IResourceService service = getResourceService(); + + List items = null; + Resource resource = null; + ResourceForm resourceForm = (ResourceForm) form; + + // Get contentFolderID and save to form. + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + resourceForm.setContentFolderID(contentFolderID); + + // initial Session Map + SessionMap sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + resourceForm.setSessionMapID(sessionMap.getSessionID()); + + try { + resource = service.getResourceByContentId(contentId); + // if resource does not exist, try to use default content instead. + if (resource == null) { + resource = service.getDefaultContent(contentId); + if (resource.getResourceItems() != null) { + items = new ArrayList(resource.getResourceItems()); + } else { + items = null; } - - //init it to avoid null exception in following handling - if(items == null) - items = new ArrayList(); - else{ - ResourceUser resourceUser = null; - //handle system default question: createBy is null, now set it to current user - for (ResourceItem item : items) { - if(item.getCreateBy() == null){ - if(resourceUser == null){ - //get back login user DTO - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - resourceUser = new ResourceUser(user,resource); - } - item.setCreateBy(resourceUser); - } - } + } else { + items = service.getAuthoredItems(resource.getUid()); + } + + resourceForm.setResource(resource); + + // initialize instruction attachment list + List attachmentList = getAttachmentList(sessionMap); + attachmentList.clear(); + attachmentList.addAll(resource.getAttachments()); + } catch (Exception e) { + AuthoringAction.log.error(e); + throw new ServletException(e); + } + + // init it to avoid null exception in following handling + if (items == null) { + items = new ArrayList(); + } else { + ResourceUser resourceUser = null; + // handle system default question: createBy is null, now set it to current user + for (ResourceItem item : items) { + if (item.getCreateBy() == null) { + if (resourceUser == null) { + // get back login user DTO + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + resourceUser = new ResourceUser(user, resource); + } + item.setCreateBy(resourceUser); } - //init resource item list - SortedSet resourceItemList = getResourceItemList(sessionMap); - resourceItemList.clear(); - resourceItemList.addAll(items); - - sessionMap.put(ResourceConstants.ATTR_RESOURCE_FORM, resourceForm); - return mapping.findForward(ResourceConstants.SUCCESS); + } } + // init resource item list + SortedSet resourceItemList = getResourceItemList(sessionMap); + resourceItemList.clear(); + resourceItemList.addAll(items); + sessionMap.put(ResourceConstants.ATTR_RESOURCE_FORM, resourceForm); + return mapping.findForward(ResourceConstants.SUCCESS); + } - /** - * Display same entire authoring page content from HttpSession variable. - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws ServletException - */ - private ActionForward initPage(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws ServletException { - String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(sessionMapID); - ResourceForm existForm = (ResourceForm) sessionMap.get(ResourceConstants.ATTR_RESOURCE_FORM); - - ResourceForm resourceForm = (ResourceForm )form; - try { - PropertyUtils.copyProperties(resourceForm, existForm); - } catch (Exception e) { - throw new ServletException(e); - } - - ToolAccessMode mode = getAccessMode(request); - if(mode.isAuthor()) - return mapping.findForward(ResourceConstants.SUCCESS); - else - return mapping.findForward(ResourceConstants.DEFINE_LATER); + /** + * Display same entire authoring page content from HttpSession variable. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward initPage(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { + String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + ResourceForm existForm = (ResourceForm) sessionMap.get(ResourceConstants.ATTR_RESOURCE_FORM); + + ResourceForm resourceForm = (ResourceForm) form; + try { + PropertyUtils.copyProperties(resourceForm, existForm); + } catch (Exception e) { + throw new ServletException(e); } - /** - * This method will persist all inforamtion in this authoring page, include all resource item, information etc. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws ServletException - */ - private ActionForward updateContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { - ResourceForm resourceForm = (ResourceForm)(form); - - //get back sessionMAP - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(resourceForm.getSessionMapID()); - - ToolAccessMode mode = getAccessMode(request); - - ActionMessages errors = validate(resourceForm, mapping, request); - if(!errors.isEmpty()){ - saveErrors(request, errors); - if(mode.isAuthor()) - return mapping.findForward("author"); - else - return mapping.findForward("monitor"); - } - - - Resource resource = resourceForm.getResource(); - IResourceService service = getResourceService(); - - //**********************************Get Resource PO********************* - Resource resourcePO = service.getResourceByContentId(resourceForm.getResource().getContentId()); - if(resourcePO == null){ - //new Resource, create it. - resourcePO = resource; - resourcePO.setCreated(new Timestamp(new Date().getTime())); - resourcePO.setUpdated(new Timestamp(new Date().getTime())); - }else{ - if(mode.isAuthor()){ - Long uid = resourcePO.getUid(); - PropertyUtils.copyProperties(resourcePO,resource); - //get back UID - resourcePO.setUid(uid); - }else{ //if it is Teacher, then just update basic tab content (definelater) - resourcePO.setInstructions(resource.getInstructions()); - resourcePO.setTitle(resource.getTitle()); -// change define later status - resourcePO.setDefineLater(false); - } - resourcePO.setUpdated(new Timestamp(new Date().getTime())); - } - - //*******************************Handle user******************* - //try to get form system session - HttpSession ss = SessionManager.getSession(); - //get back login user DTO - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - ResourceUser resourceUser = service.getUserByIDAndContent(new Long(user.getUserID().intValue()) - ,resourceForm.getResource().getContentId()); - if(resourceUser == null){ - resourceUser = new ResourceUser(user,resourcePO); - } - - resourcePO.setCreatedBy(resourceUser); - - //**********************************Handle Authoring Instruction Attachement ********************* - //merge attachment info - //so far, attPOSet will be empty if content is existed. because PropertyUtils.copyProperties() is executed - Set attPOSet = resourcePO.getAttachments(); - if(attPOSet == null) - attPOSet = new HashSet(); - List attachmentList = getAttachmentList(sessionMap); - List deleteAttachmentList = getDeletedAttachmentList(sessionMap); - - //current attachemnt in authoring instruction tab. - Iterator iter = attachmentList.iterator(); - while(iter.hasNext()){ - ResourceAttachment newAtt = (ResourceAttachment) iter.next(); - attPOSet.add(newAtt); - } - attachmentList.clear(); - - //deleted attachment. 2 possible types: one is persist another is non-persist before. - iter = deleteAttachmentList.iterator(); - while(iter.hasNext()){ - ResourceAttachment delAtt = (ResourceAttachment) iter.next(); - iter.remove(); - //it is an existed att, then delete it from current attachmentPO - if(delAtt.getUid() != null){ - Iterator attIter = attPOSet.iterator(); - while(attIter.hasNext()){ - ResourceAttachment att = (ResourceAttachment) attIter.next(); - if(delAtt.getUid().equals(att.getUid())){ - attIter.remove(); - break; - } - } - service.deleteResourceAttachment(delAtt.getUid()); - }//end remove from persist value - } - - //copy back - resourcePO.setAttachments(attPOSet); - //************************* Handle resource items ******************* - //Handle resource items - Set itemList = new LinkedHashSet(); - SortedSet topics = getResourceItemList(sessionMap); - iter = topics.iterator(); - while(iter.hasNext()){ - ResourceItem item = (ResourceItem) iter.next(); - if(item != null){ - //This flushs user UID info to message if this user is a new user. - item.setCreateBy(resourceUser); - itemList.add(item); - } - } - resourcePO.setResourceItems(itemList); - //delete instructino file from database. - List delResourceItemList = getDeletedResourceItemList(sessionMap); - iter = delResourceItemList.iterator(); - while(iter.hasNext()){ - ResourceItem item = (ResourceItem) iter.next(); - iter.remove(); - if(item.getUid() != null) - service.deleteResourceItem(item.getUid()); - } - //handle resource item attachment file: - List delItemAttList = getDeletedItemAttachmentList(sessionMap); - iter = delItemAttList.iterator(); - while(iter.hasNext()){ - ResourceItem delAtt = (ResourceItem) iter.next(); - iter.remove(); - } - - //if miniview number is bigger than available items, then set it topics size - if(resourcePO.getMiniViewResourceNumber() > topics.size()) - resourcePO.setMiniViewResourceNumber((topics.size())); - //********************************************** - //finally persist resourcePO again - service.saveOrUpdateResource(resourcePO); - - //initialize attachmentList again - attachmentList = getAttachmentList(sessionMap); - attachmentList.addAll(resource.getAttachments()); - resourceForm.setResource(resourcePO); - - request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG,Boolean.TRUE); - if(mode.isAuthor()) - return mapping.findForward("author"); - else - return mapping.findForward("monitor"); + + ToolAccessMode mode = getAccessMode(request); + if (mode.isAuthor()) { + return mapping.findForward(ResourceConstants.SUCCESS); + } else { + return mapping.findForward(ResourceConstants.DEFINE_LATER); } + } - /** - * Handle upload online instruction files request. - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws UploadResourceFileException - */ - public ActionForward uploadOnline(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) throws UploadResourceFileException { - return uploadFile(mapping, form, IToolContentHandler.TYPE_ONLINE,request); + /** + * This method will persist all inforamtion in this authoring page, include all resource item, information etc. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws ServletException + */ + private ActionForward updateContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + ResourceForm resourceForm = (ResourceForm) form; + + // get back sessionMAP + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(resourceForm.getSessionMapID()); + + ToolAccessMode mode = getAccessMode(request); + + ActionMessages errors = validate(resourceForm, mapping, request); + if (!errors.isEmpty()) { + saveErrors(request, errors); + if (mode.isAuthor()) { + return mapping.findForward("author"); + } else { + return mapping.findForward("monitor"); + } } - /** - * Handle upload offline instruction files request. - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws UploadResourceFileException - */ - public ActionForward uploadOffline(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) throws UploadResourceFileException { - return uploadFile(mapping, form, IToolContentHandler.TYPE_OFFLINE,request); + + Resource resource = resourceForm.getResource(); + IResourceService service = getResourceService(); + + // **********************************Get Resource PO********************* + Resource resourcePO = service.getResourceByContentId(resourceForm.getResource().getContentId()); + if (resourcePO == null) { + // new Resource, create it. + resourcePO = resource; + resourcePO.setCreated(new Timestamp(new Date().getTime())); + resourcePO.setUpdated(new Timestamp(new Date().getTime())); + } else { + if (mode.isAuthor()) { + Long uid = resourcePO.getUid(); + PropertyUtils.copyProperties(resourcePO, resource); + // get back UID + resourcePO.setUid(uid); + } else { // if it is Teacher, then just update basic tab content (definelater) + resourcePO.setInstructions(resource.getInstructions()); + resourcePO.setTitle(resource.getTitle()); + // change define later status + resourcePO.setDefineLater(false); + } + resourcePO.setUpdated(new Timestamp(new Date().getTime())); } - /** - * Common method to upload online or offline instruction files request. - * @param mapping - * @param form - * @param type - * @param request - * @return - * @throws UploadResourceFileException - */ - private ActionForward uploadFile(ActionMapping mapping, ActionForm form, - String type,HttpServletRequest request) throws UploadResourceFileException { - ResourceForm resourceForm = (ResourceForm) form; - //get back sessionMAP - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(resourceForm.getSessionMapID()); + // *******************************Handle user******************* + // try to get form system session + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + ResourceUser resourceUser = service.getUserByIDAndContent(new Long(user.getUserID().intValue()), resourceForm + .getResource().getContentId()); + if (resourceUser == null) { + resourceUser = new ResourceUser(user, resourcePO); + } - FormFile file; - if(StringUtils.equals(IToolContentHandler.TYPE_OFFLINE,type)) - file = (FormFile) resourceForm.getOfflineFile(); - else - file = (FormFile) resourceForm.getOnlineFile(); - - if(file == null || StringUtils.isBlank(file.getFileName())) - return mapping.findForward(ResourceConstants.SUCCESS); - - //validate file size - ActionMessages errors = new ActionMessages(); - FileValidatorUtil.validateFileSize(file, true, errors ); - if(!errors.isEmpty()){ - this.saveErrors(request, errors); - return mapping.findForward(ResourceConstants.SUCCESS); + resourcePO.setCreatedBy(resourceUser); + + // **********************************Handle Authoring Instruction Attachement ********************* + // merge attachment info + // so far, attPOSet will be empty if content is existed. because PropertyUtils.copyProperties() is executed + Set attPOSet = resourcePO.getAttachments(); + if (attPOSet == null) { + attPOSet = new HashSet(); + } + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + + // current attachemnt in authoring instruction tab. + Iterator iter = attachmentList.iterator(); + while (iter.hasNext()) { + ResourceAttachment newAtt = (ResourceAttachment) iter.next(); + attPOSet.add(newAtt); + } + attachmentList.clear(); + + // deleted attachment. 2 possible types: one is persist another is non-persist before. + iter = deleteAttachmentList.iterator(); + while (iter.hasNext()) { + ResourceAttachment delAtt = (ResourceAttachment) iter.next(); + iter.remove(); + // it is an existed att, then delete it from current attachmentPO + if (delAtt.getUid() != null) { + Iterator attIter = attPOSet.iterator(); + while (attIter.hasNext()) { + ResourceAttachment att = (ResourceAttachment) attIter.next(); + if (delAtt.getUid().equals(att.getUid())) { + attIter.remove(); + break; + } } - - IResourceService service = getResourceService(); - //upload to repository - ResourceAttachment att = service.uploadInstructionFile(file, type); - //handle session value - List attachmentList = getAttachmentList(sessionMap); - List deleteAttachmentList = getDeletedAttachmentList(sessionMap); - //first check exist attachment and delete old one (if exist) to deletedAttachmentList - Iterator iter = attachmentList.iterator(); - ResourceAttachment existAtt; - while(iter.hasNext()){ - existAtt = (ResourceAttachment) iter.next(); - if (StringUtils.equals(existAtt.getFileName(), att.getFileName()) - && StringUtils.equals(existAtt.getFileType(), att.getFileType())) { - //if there is same name attachment, delete old one - deleteAttachmentList.add(existAtt); - iter.remove(); - break; - } - } - //add to attachmentList - attachmentList.add(att); + service.deleteResourceAttachment(delAtt.getUid()); + }// end remove from persist value + } - return mapping.findForward(ResourceConstants.SUCCESS); + // copy back + resourcePO.setAttachments(attPOSet); + // ************************* Handle resource items ******************* + // Handle resource items + Set itemList = new LinkedHashSet(); + SortedSet topics = getResourceItemList(sessionMap); + iter = topics.iterator(); + while (iter.hasNext()) { + ResourceItem item = (ResourceItem) iter.next(); + if (item != null) { + // This flushs user UID info to message if this user is a new user. + item.setCreateBy(resourceUser); + itemList.add(item); + } + } + resourcePO.setResourceItems(itemList); + // delete instructino file from database. + List delResourceItemList = getDeletedResourceItemList(sessionMap); + iter = delResourceItemList.iterator(); + while (iter.hasNext()) { + ResourceItem item = (ResourceItem) iter.next(); + iter.remove(); + if (item.getUid() != null) { + service.deleteResourceItem(item.getUid()); + } + } + // handle resource item attachment file: + List delItemAttList = getDeletedItemAttachmentList(sessionMap); + iter = delItemAttList.iterator(); + while (iter.hasNext()) { + ResourceItem delAtt = (ResourceItem) iter.next(); + iter.remove(); + } + // if miniview number is bigger than available items, then set it topics size + if (resourcePO.getMiniViewResourceNumber() > topics.size()) { + resourcePO.setMiniViewResourceNumber(topics.size()); } - /** - * Delete offline instruction file from current Resource authoring page. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - public ActionForward deleteOfflineFile(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { - return deleteFile(mapping,request, response,form, IToolContentHandler.TYPE_OFFLINE); + // ********************************************** + // finally persist resourcePO again + service.saveOrUpdateResource(resourcePO); + + // initialize attachmentList again + attachmentList = getAttachmentList(sessionMap); + attachmentList.addAll(resource.getAttachments()); + resourceForm.setResource(resourcePO); + + request.setAttribute(AuthoringConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + if (mode.isAuthor()) { + return mapping.findForward("author"); + } else { + return mapping.findForward("monitor"); } - /** - * Delete online instruction file from current Resource authoring page. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - public ActionForward deleteOnlineFile(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { - return deleteFile(mapping, request, response,form, IToolContentHandler.TYPE_ONLINE); + } + + /** + * Handle upload online instruction files request. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws UploadResourceFileException + */ + public ActionForward uploadOnline(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws UploadResourceFileException { + return uploadFile(mapping, form, IToolContentHandler.TYPE_ONLINE, request); + } + + /** + * Handle upload offline instruction files request. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws UploadResourceFileException + */ + public ActionForward uploadOffline(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws UploadResourceFileException { + return uploadFile(mapping, form, IToolContentHandler.TYPE_OFFLINE, request); + } + + /** + * Common method to upload online or offline instruction files request. + * + * @param mapping + * @param form + * @param type + * @param request + * @return + * @throws UploadResourceFileException + */ + private ActionForward uploadFile(ActionMapping mapping, ActionForm form, String type, HttpServletRequest request) + throws UploadResourceFileException { + + ResourceForm resourceForm = (ResourceForm) form; + // get back sessionMAP + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(resourceForm.getSessionMapID()); + + FormFile file; + if (StringUtils.equals(IToolContentHandler.TYPE_OFFLINE, type)) { + file = resourceForm.getOfflineFile(); + } else { + file = resourceForm.getOnlineFile(); } - /** - * General method to delete file (online or offline) - * @param mapping - * @param request - * @param response - * @param form - * @param type - * @return - */ - private ActionForward deleteFile(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response, ActionForm form, String type) { - Long versionID = new Long(WebUtil.readLongParam(request,ResourceConstants.PARAM_FILE_VERSION_ID)); - Long uuID = new Long(WebUtil.readLongParam(request,ResourceConstants.PARAM_FILE_UUID)); - - //get back sessionMAP - String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(sessionMapID); - - //handle session value - List attachmentList = getAttachmentList(sessionMap); - List deleteAttachmentList = getDeletedAttachmentList(sessionMap); - //first check exist attachment and delete old one (if exist) to deletedAttachmentList - Iterator iter = attachmentList.iterator(); - ResourceAttachment existAtt; - while(iter.hasNext()){ - existAtt = (ResourceAttachment) iter.next(); - if(existAtt.getFileUuid().equals(uuID) && existAtt.getFileVersionId().equals(versionID)){ - //if there is same name attachment, delete old one - deleteAttachmentList.add(existAtt); - iter.remove(); - } - } + if (file == null || StringUtils.isBlank(file.getFileName())) { + return mapping.findForward(ResourceConstants.SUCCESS); + } - request.setAttribute(ResourceConstants.ATTR_FILE_TYPE_FLAG, type); - request.setAttribute(ResourceConstants.ATTR_SESSION_MAP_ID, sessionMapID); - return mapping.findForward(ResourceConstants.SUCCESS); + // validate file size + ActionMessages errors = new ActionMessages(); + FileValidatorUtil.validateFileSize(file, true, errors); + if (!errors.isEmpty()) { + this.saveErrors(request, errors); + return mapping.findForward(ResourceConstants.SUCCESS); + } + IResourceService service = getResourceService(); + // upload to repository + ResourceAttachment att = service.uploadInstructionFile(file, type); + // handle session value + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + // first check exist attachment and delete old one (if exist) to deletedAttachmentList + Iterator iter = attachmentList.iterator(); + ResourceAttachment existAtt; + while (iter.hasNext()) { + existAtt = (ResourceAttachment) iter.next(); + if (StringUtils.equals(existAtt.getFileName(), att.getFileName()) + && StringUtils.equals(existAtt.getFileType(), att.getFileType())) { + // if there is same name attachment, delete old one + deleteAttachmentList.add(existAtt); + iter.remove(); + break; + } } - //************************************************************************************* - // Private method - //************************************************************************************* - /** - * Return ResourceService bean. - */ - private IResourceService getResourceService() { - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet().getServletContext()); - return (IResourceService) wac.getBean(ResourceConstants.RESOURCE_SERVICE); + // add to attachmentList + attachmentList.add(att); + + return mapping.findForward(ResourceConstants.SUCCESS); + + } + + /** + * Delete offline instruction file from current Resource authoring page. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + public ActionForward deleteOfflineFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return deleteFile(mapping, request, response, form, IToolContentHandler.TYPE_OFFLINE); + } + + /** + * Delete online instruction file from current Resource authoring page. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + public ActionForward deleteOnlineFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return deleteFile(mapping, request, response, form, IToolContentHandler.TYPE_ONLINE); + } + + /** + * General method to delete file (online or offline) + * + * @param mapping + * @param request + * @param response + * @param form + * @param type + * @return + */ + private ActionForward deleteFile(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response, + ActionForm form, String type) { + Long versionID = new Long(WebUtil.readLongParam(request, ResourceConstants.PARAM_FILE_VERSION_ID)); + Long uuID = new Long(WebUtil.readLongParam(request, ResourceConstants.PARAM_FILE_UUID)); + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, ResourceConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + // handle session value + List attachmentList = getAttachmentList(sessionMap); + List deleteAttachmentList = getDeletedAttachmentList(sessionMap); + // first check exist attachment and delete old one (if exist) to deletedAttachmentList + Iterator iter = attachmentList.iterator(); + ResourceAttachment existAtt; + while (iter.hasNext()) { + existAtt = (ResourceAttachment) iter.next(); + if (existAtt.getFileUuid().equals(uuID) && existAtt.getFileVersionId().equals(versionID)) { + // if there is same name attachment, delete old one + deleteAttachmentList.add(existAtt); + iter.remove(); + } } - /** - * @param request - * @return - */ - private List getAttachmentList(SessionMap sessionMap) { - return getListFromSession(sessionMap,ResourceConstants.ATT_ATTACHMENT_LIST); + + request.setAttribute(ResourceConstants.ATTR_FILE_TYPE_FLAG, type); + request.setAttribute(ResourceConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(ResourceConstants.SUCCESS); + + } + + // ************************************************************************************* + // Private method + // ************************************************************************************* + /** + * Return ResourceService bean. + */ + private IResourceService getResourceService() { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + return (IResourceService) wac.getBean(ResourceConstants.RESOURCE_SERVICE); + } + + /** + * @param request + * @return + */ + private List getAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, ResourceConstants.ATT_ATTACHMENT_LIST); + } + + /** + * @param request + * @return + */ + private List getDeletedAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, ResourceConstants.ATTR_DELETED_ATTACHMENT_LIST); + } + + /** + * List save current resource items. + * + * @param request + * @return + */ + private SortedSet getResourceItemList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(ResourceConstants.ATTR_RESOURCE_ITEM_LIST); + if (list == null) { + list = new TreeSet(new ResourceItemComparator()); + sessionMap.put(ResourceConstants.ATTR_RESOURCE_ITEM_LIST, list); } - /** - * @param request - * @return - */ - private List getDeletedAttachmentList(SessionMap sessionMap) { - return getListFromSession(sessionMap,ResourceConstants.ATTR_DELETED_ATTACHMENT_LIST); + return list; + } + + /** + * List save deleted resource items, which could be persisted or non-persisted items. + * + * @param request + * @return + */ + private List getDeletedResourceItemList(SessionMap sessionMap) { + return getListFromSession(sessionMap, ResourceConstants.ATTR_DELETED_RESOURCE_ITEM_LIST); + } + + /** + * If a resource item has attahment file, and the user edit this item and change the attachment to new file, then + * the old file need be deleted when submitting the whole authoring page. Save the file uuid and version id into + * ResourceItem object for temporarily use. + * + * @param request + * @return + */ + private List getDeletedItemAttachmentList(SessionMap sessionMap) { + return getListFromSession(sessionMap, ResourceConstants.ATTR_DELETED_RESOURCE_ITEM_ATTACHMENT_LIST); + } + + /** + * Get java.util.List from HttpSession by given name. + * + * @param request + * @param name + * @return + */ + private List getListFromSession(SessionMap sessionMap, String name) { + List list = (List) sessionMap.get(name); + if (list == null) { + list = new ArrayList(); + sessionMap.put(name, list); } - /** - * List save current resource items. - * @param request - * @return - */ - private SortedSet getResourceItemList(SessionMap sessionMap) { - SortedSet list = (SortedSet) sessionMap.get(ResourceConstants.ATTR_RESOURCE_ITEM_LIST); - if(list == null){ - list = new TreeSet(new ResourceItemComparator()); - sessionMap.put(ResourceConstants.ATTR_RESOURCE_ITEM_LIST,list); - } - return list; - } - /** - * List save deleted resource items, which could be persisted or non-persisted items. - * @param request - * @return - */ - private List getDeletedResourceItemList(SessionMap sessionMap) { - return getListFromSession(sessionMap,ResourceConstants.ATTR_DELETED_RESOURCE_ITEM_LIST); + return list; + } + + /** + * Get resource items instruction from HttpRequest + * + * @param request + */ + private List getInstructionsFromRequest(HttpServletRequest request) { + String list = request.getParameter("instructionList"); + String[] params = list.split("&"); + Map paramMap = new HashMap(); + String[] pair; + for (String item : params) { + pair = item.split("="); + if (pair == null || pair.length != 2) { + continue; + } + try { + paramMap.put(pair[0], URLDecoder.decode(pair[1], "UTF-8")); + } catch (UnsupportedEncodingException e) { + AuthoringAction.log.error("Error occurs when decode instruction string:" + e.toString()); + } } - /** - * If a resource item has attahment file, and the user edit this item and change the attachment - * to new file, then the old file need be deleted when submitting the whole authoring page. - * Save the file uuid and version id into ResourceItem object for temporarily use. - * @param request - * @return - */ - private List getDeletedItemAttachmentList(SessionMap sessionMap) { - return getListFromSession(sessionMap,ResourceConstants.ATTR_DELETED_RESOURCE_ITEM_ATTACHMENT_LIST); + + int count = NumberUtils.stringToInt(paramMap.get(AuthoringAction.INSTRUCTION_ITEM_COUNT)); + List instructionList = new ArrayList(); + for (int idx = 0; idx < count; idx++) { + String item = paramMap.get(AuthoringAction.INSTRUCTION_ITEM_DESC_PREFIX + idx); + if (item == null) { + continue; + } + instructionList.add(item); } + return instructionList; + } + /** + * Get back relative ActionForward from request. + * + * @param type + * @param mapping + * @return + */ + private ActionForward findForward(short type, ActionMapping mapping) { + ActionForward forward; + switch (type) { + case ResourceConstants.RESOURCE_TYPE_URL: + forward = mapping.findForward("url"); + break; + case ResourceConstants.RESOURCE_TYPE_FILE: + forward = mapping.findForward("file"); + break; + case ResourceConstants.RESOURCE_TYPE_WEBSITE: + forward = mapping.findForward("website"); + break; + case ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT: + forward = mapping.findForward("learningobject"); + break; + default: + forward = null; + break; + } + return forward; + } - /** - * Get java.util.List from HttpSession by given name. - * - * @param request - * @param name - * @return - */ - private List getListFromSession(SessionMap sessionMap,String name) { - List list = (List) sessionMap.get(name); - if(list == null){ - list = new ArrayList(); - sessionMap.put(name,list); - } - return list; + /** + * This method will populate resource item information to its form for edit use. + * + * @param itemIdx + * @param item + * @param form + * @param request + */ + private void populateItemToForm(int itemIdx, ResourceItem item, ResourceItemForm form, HttpServletRequest request) { + form.setDescription(item.getDescription()); + form.setTitle(item.getTitle()); + form.setUrl(item.getUrl()); + form.setOpenUrlNewWindow(item.isOpenUrlNewWindow()); + if (itemIdx >= 0) { + form.setItemIndex(new Integer(itemIdx).toString()); } - - - /** - * Get resource items instruction from HttpRequest - * @param request - */ - private List getInstructionsFromRequest(HttpServletRequest request) { - String list = request.getParameter("instructionList"); - String[] params = list.split("&"); - Map paramMap = new HashMap(); - String[] pair; - for (String item: params) { - pair = item.split("="); - if(pair == null || pair.length != 2) - continue; - try { - paramMap.put(pair[0],URLDecoder.decode(pair[1],"UTF-8")); - } catch (UnsupportedEncodingException e) { - log.error("Error occurs when decode instruction string:" + e.toString()); - } - } - - int count = NumberUtils.stringToInt(paramMap.get(INSTRUCTION_ITEM_COUNT)); - List instructionList = new ArrayList(); - for(int idx=0;idx instructionList = item.getItemInstructions(); + List instructions = new ArrayList(); + for (ResourceItemInstruction in : instructionList) { + instructions.add(in.getDescription()); } - /** - * Get back relative ActionForward from request. - * @param type - * @param mapping - * @return - */ - private ActionForward findForward(short type, ActionMapping mapping) { - ActionForward forward; - switch (type) { - case ResourceConstants.RESOURCE_TYPE_URL: - forward = mapping.findForward("url"); - break; - case ResourceConstants.RESOURCE_TYPE_FILE: - forward = mapping.findForward("file"); - break; - case ResourceConstants.RESOURCE_TYPE_WEBSITE: - forward = mapping.findForward("website"); - break; - case ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT: - forward = mapping.findForward("learningobject"); - break; - default: - forward = null; - break; - } - return forward; + // FOR requirment from LDEV-754 + // add extra blank line for instructions + // for(int idx=0;idx instructionList, + ResourceItemForm itemForm) throws Exception { + /* + * BE CAREFUL: This method will copy nessary info from request form to a old or new ResourceItem instance. It + * gets all info EXCEPT ResourceItem.createDate and ResourceItem.createBy, which need be set when persisting + * this resource item. */ - private void populateItemToForm(int itemIdx, ResourceItem item, ResourceItemForm form, HttpServletRequest request) { - form.setDescription(item.getDescription()); - form.setTitle(item.getTitle()); - form.setUrl(item.getUrl()); - form.setOpenUrlNewWindow(item.isOpenUrlNewWindow()); - if(itemIdx >=0) - form.setItemIndex(new Integer(itemIdx).toString()); - - Set instructionList = item.getItemInstructions(); - List instructions = new ArrayList(); - for(ResourceItemInstruction in : instructionList){ - instructions.add(in.getDescription()); - } - //FOR requirment from LDEV-754 - //add extra blank line for instructions -// for(int idx=0;idx resourceList = getResourceItemList(sessionMap); + int itemIdx = NumberUtils.stringToInt(itemForm.getItemIndex(), -1); + ResourceItem item = null; + + if (itemIdx == -1) { // add + item = new ResourceItem(); + item.setCreateDate(new Timestamp(new Date().getTime())); + resourceList.add(item); + } else { // edit + List rList = new ArrayList(resourceList); + item = rList.get(itemIdx); } - /** - * Extract web from content to resource item. - * @param request - * @param instructionList - * @param itemForm - * @throws ResourceApplicationException + short type = itemForm.getItemType(); + item.setType(itemForm.getItemType()); + /* + * Set following fields regards to the type: item.setFileUuid(); item.setFileVersionId(); item.setFileType(); + * item.setFileName(); + * + * item.getInitialItem() item.setImsSchema() item.setOrganizationXml() */ - private void extractFormToResourceItem(HttpServletRequest request, List instructionList, ResourceItemForm itemForm) - throws Exception { - /* BE CAREFUL: This method will copy nessary info from request form to a old or new ResourceItem instance. - * It gets all info EXCEPT ResourceItem.createDate and ResourceItem.createBy, which need be set when persisting - * this resource item. - */ - - SessionMap sessionMap = (SessionMap)request.getSession().getAttribute(itemForm.getSessionMapID()); - //check whether it is "edit(old item)" or "add(new item)" - SortedSet resourceList = getResourceItemList(sessionMap); - int itemIdx = NumberUtils.stringToInt(itemForm.getItemIndex(),-1); - ResourceItem item = null; - - if(itemIdx == -1){ //add - item = new ResourceItem(); - item.setCreateDate(new Timestamp(new Date().getTime())); - resourceList.add(item); - }else{ //edit - List rList = new ArrayList(resourceList); - item = rList.get(itemIdx); + // if the item is edit (not new add) then the getFile may return null + // it may throw exception, so put it as first, to avoid other invlidate update: + if (itemForm.getFile() != null) { + if (type == ResourceConstants.RESOURCE_TYPE_WEBSITE + || type == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT + || type == ResourceConstants.RESOURCE_TYPE_FILE) { + // if it has old file, and upload a new, then save old to deleteList + ResourceItem delAttItem = new ResourceItem(); + boolean hasOld = false; + if (item.getFileUuid() != null) { + hasOld = true; + // be careful, This new ResourceItem object never be save into database + // just temporarily use for saving fileUuid and versionID use: + delAttItem.setFileUuid(item.getFileUuid()); + delAttItem.setFileVersionId(item.getFileVersionId()); } - short type = itemForm.getItemType(); - item.setType(itemForm.getItemType()); - /* Set following fields regards to the type: - item.setFileUuid(); - item.setFileVersionId(); - item.setFileType(); - item.setFileName(); - - item.getInitialItem() - item.setImsSchema() - item.setOrganizationXml() - */ - //if the item is edit (not new add) then the getFile may return null - //it may throw exception, so put it as first, to avoid other invlidate update: - if(itemForm.getFile() != null){ - if(type == ResourceConstants.RESOURCE_TYPE_WEBSITE - ||type == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT - ||type == ResourceConstants.RESOURCE_TYPE_FILE){ - //if it has old file, and upload a new, then save old to deleteList - ResourceItem delAttItem = new ResourceItem(); - boolean hasOld = false; - if(item.getFileUuid() != null){ - hasOld = true; - //be careful, This new ResourceItem object never be save into database - //just temporarily use for saving fileUuid and versionID use: - delAttItem.setFileUuid(item.getFileUuid()); - delAttItem.setFileVersionId(item.getFileVersionId()); - } - IResourceService service = getResourceService(); - try { - service.uploadResourceItemFile(item, itemForm.getFile()); - } catch (UploadResourceFileException e) { - //if it is new add , then remove it! - if(itemIdx == -1){ - resourceList.remove(item); - } - throw e; - } - //put it after "upload" to ensure deleted file added into list only no exception happens during upload - if(hasOld){ - List delAtt = getDeletedItemAttachmentList(sessionMap); - delAtt.add(delAttItem); - } - } + IResourceService service = getResourceService(); + try { + service.uploadResourceItemFile(item, itemForm.getFile()); + } catch (UploadResourceFileException e) { + // if it is new add , then remove it! + if (itemIdx == -1) { + resourceList.remove(item); + } + throw e; } - item.setTitle(itemForm.getTitle()); - item.setCreateByAuthor(true); - item.setHide(false); - //set instrcutions - Set instructions = new LinkedHashSet(); - int idx=0; - for (String ins : instructionList) { - ResourceItemInstruction rii = new ResourceItemInstruction(); - rii.setDescription(ins); - rii.setSequenceId(idx++); - instructions.add(rii); + // put it after "upload" to ensure deleted file added into list only no exception happens during upload + if (hasOld) { + List delAtt = getDeletedItemAttachmentList(sessionMap); + delAtt.add(delAttItem); } - item.setItemInstructions(instructions); + } + } + item.setTitle(itemForm.getTitle()); + item.setCreateByAuthor(true); + item.setHide(false); + // set instrcutions + Set instructions = new LinkedHashSet(); + int idx = 0; + for (String ins : instructionList) { + ResourceItemInstruction rii = new ResourceItemInstruction(); + rii.setDescription(ins); + rii.setSequenceId(idx++); + instructions.add(rii); + } + item.setItemInstructions(instructions); - if(type == ResourceConstants.RESOURCE_TYPE_URL){ - item.setUrl(itemForm.getUrl()); - item.setOpenUrlNewWindow(itemForm.isOpenUrlNewWindow()); - } -// if(type == ResourceConstants.RESOURCE_TYPE_WEBSITE -// ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT){ - item.setDescription(itemForm.getDescription()); -// } - + if (type == ResourceConstants.RESOURCE_TYPE_URL) { + item.setUrl(itemForm.getUrl()); + item.setOpenUrlNewWindow(itemForm.isOpenUrlNewWindow()); } + // if(type == ResourceConstants.RESOURCE_TYPE_WEBSITE + // ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT){ + item.setDescription(itemForm.getDescription()); + // } - /** - * Vaidate resource item regards to their type (url/file/learning object/website zip file) - * @param itemForm - * @return - */ - private ActionErrors validateResourceItem(ResourceItemForm itemForm) { - ActionErrors errors = new ActionErrors(); - if(StringUtils.isBlank(itemForm.getTitle())) - errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_TITLE_BLANK)); - - if(itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_URL){ - if(StringUtils.isBlank(itemForm.getUrl())) - errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_URL_BLANK)); - //URL validation: Commom URL validate(1.3.0) work not very well: it can not support http://address:port format!!! -// UrlValidator validator = new UrlValidator(); -// if(!validator.isValid(itemForm.getUrl())) -// errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_INVALID_URL)); - } -// if(itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_WEBSITE -// ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT){ -// if(StringUtils.isBlank(itemForm.getDescription())) -// errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_DESC_BLANK)); -// } - if(itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_WEBSITE - ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT - ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_FILE){ - //validate item size - FileValidatorUtil.validateFileSize(itemForm.getFile(), true, errors ); - //for edit validate: file already exist - if(!itemForm.isHasFile() && - (itemForm.getFile() == null || StringUtils.isEmpty(itemForm.getFile().getFileName()))) - errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_FILE_BLANK)); - } - return errors; + } + + /** + * Vaidate resource item regards to their type (url/file/learning object/website zip file) + * + * @param itemForm + * @return + */ + private ActionErrors validateResourceItem(ResourceItemForm itemForm) { + ActionErrors errors = new ActionErrors(); + if (StringUtils.isBlank(itemForm.getTitle())) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(ResourceConstants.ERROR_MSG_TITLE_BLANK)); } - /** - * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. - * @param request - * @return - */ - private ToolAccessMode getAccessMode(HttpServletRequest request) { - ToolAccessMode mode; - String modeStr = request.getParameter(AttributeNames.ATTR_MODE); - if(StringUtils.equalsIgnoreCase(modeStr,ToolAccessMode.TEACHER.toString())) - mode = ToolAccessMode.TEACHER; - else - mode = ToolAccessMode.AUTHOR; - return mode; + if (itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_URL) { + if (StringUtils.isBlank(itemForm.getUrl())) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(ResourceConstants.ERROR_MSG_URL_BLANK)); + // URL validation: Commom URL validate(1.3.0) work not very well: it can not support http:// + // address:port format!!! + // UrlValidator validator = new UrlValidator(); + // if(!validator.isValid(itemForm.getUrl())) + // errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_INVALID_URL)); + } } - - - private ActionMessages validate(ResourceForm resourceForm, ActionMapping mapping, HttpServletRequest request) { - ActionMessages errors = new ActionMessages(); -// if (StringUtils.isBlank(resourceForm.getResource().getTitle())) { -// ActionMessage error = new ActionMessage("error.resource.item.title.blank"); -// errors.add(ActionMessages.GLOBAL_MESSAGE, error); -// } - - //define it later mode(TEACHER) skip below validation. - String modeStr = request.getParameter(AttributeNames.ATTR_MODE); - if(StringUtils.equals(modeStr, ToolAccessMode.TEACHER.toString())){ - return errors; - } + // if(itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_WEBSITE + // ||itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT){ + // if(StringUtils.isBlank(itemForm.getDescription())) + // errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ResourceConstants.ERROR_MSG_DESC_BLANK)); + // } + if (itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_WEBSITE + || itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_LEARNING_OBJECT + || itemForm.getItemType() == ResourceConstants.RESOURCE_TYPE_FILE) { + // validate item size + FileValidatorUtil.validateFileSize(itemForm.getFile(), true, errors); + // for edit validate: file already exist + if (!itemForm.isHasFile() + && (itemForm.getFile() == null || StringUtils.isEmpty(itemForm.getFile().getFileName()))) { + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(ResourceConstants.ERROR_MSG_FILE_BLANK)); + } + } + return errors; + } - //Some other validation outside basic Tab. - - return errors; + /** + * Get ToolAccessMode from HttpRequest parameters. Default value is AUTHOR mode. + * + * @param request + * @return + */ + private ToolAccessMode getAccessMode(HttpServletRequest request) { + ToolAccessMode mode; + String modeStr = request.getParameter(AttributeNames.ATTR_MODE); + if (StringUtils.equalsIgnoreCase(modeStr, ToolAccessMode.TEACHER.toString())) { + mode = ToolAccessMode.TEACHER; + } else { + mode = ToolAccessMode.AUTHOR; } + return mode; + } + private ActionMessages validate(ResourceForm resourceForm, ActionMapping mapping, HttpServletRequest request) { + ActionMessages errors = new ActionMessages(); + // if (StringUtils.isBlank(resourceForm.getResource().getTitle())) { + // ActionMessage error = new ActionMessage("error.resource.item.title.blank"); + // errors.add(ActionMessages.GLOBAL_MESSAGE, error); + // } + // define it later mode(TEACHER) skip below validation. + String modeStr = request.getParameter(AttributeNames.ATTR_MODE); + if (StringUtils.equals(modeStr, ToolAccessMode.TEACHER.toString())) { + return errors; + } + + // Some other validation outside basic Tab. + + return errors; + } + + public ActionForward initPedagogicalPlannerForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + ResourcePedagogicalPlannerForm plannerForm = (ResourcePedagogicalPlannerForm) form; + Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID); + Resource taskList = getResourceService().getResourceByContentId(toolContentID); + plannerForm.fillForm(taskList); + + return mapping.findForward(ResourceConstants.SUCCESS); + } + + public ActionForward saveOrUpdatePedagogicalPlannerForm(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) throws IOException { + ResourcePedagogicalPlannerForm plannerForm = (ResourcePedagogicalPlannerForm) form; + ActionMessages errors = plannerForm.validate(); + if (errors.isEmpty()) { + Resource taskList = getResourceService().getResourceByContentId(plannerForm.getToolContentID()); + + int itemIndex = 0; + String title = null; + ResourceItem resourceItem = null; + List newItems = new LinkedList(); + Set resourceItems = taskList.getResourceItems(); + Iterator taskListItemIterator = resourceItems.iterator(); + // We need to reverse the order, since the items are delivered newest-first + LinkedList reversedResourceItems = new LinkedList(); + while (taskListItemIterator.hasNext()) { + reversedResourceItems.addFirst(taskListItemIterator.next()); + } + taskListItemIterator = reversedResourceItems.iterator(); + do { + title = plannerForm.getTitle(itemIndex); + if (StringUtils.isEmpty(title)) { + plannerForm.removeItem(itemIndex); + } else { + if (taskListItemIterator.hasNext()) { + resourceItem = taskListItemIterator.next(); + } else { + resourceItem = new ResourceItem(); + resourceItem.setCreateByAuthor(true); + Date currentDate = new Date(); + resourceItem.setCreateDate(currentDate); + + HttpSession session = SessionManager.getSession(); + UserDTO user = (UserDTO) session.getAttribute(AttributeNames.USER); + ResourceUser taskListUser = getResourceService().getUserByIDAndContent( + new Long(user.getUserID().intValue()), plannerForm.getToolContentID()); + resourceItem.setCreateBy(taskListUser); + + newItems.add(resourceItem); + } + resourceItem.setTitle(title); + Short type = plannerForm.getType(itemIndex); + resourceItem.setType(type); + boolean hasFile = resourceItem.getFileUuid() != null; + if (type.equals(ResourceConstants.RESOURCE_TYPE_URL)) { + resourceItem.setUrl(plannerForm.getUrl(itemIndex)); + if (hasFile) { + resourceItem.setFileName(null); + resourceItem.setFileUuid(null); + resourceItem.setFileVersionId(null); + resourceItem.setFileType(null); + } + } else if (type.equals(ResourceConstants.RESOURCE_TYPE_FILE)) { + FormFile file = plannerForm.getFile(itemIndex); + resourceItem.setUrl(null); + IResourceService service = getResourceService(); + if (file != null) { + try { + if (hasFile) { + // delete the old file + service.deleteFromRepository(resourceItem.getFileUuid(), resourceItem + .getFileVersionId()); + } + service.uploadResourceItemFile(resourceItem, file); + } catch (Exception e) { + AuthoringAction.log.error(e); + ActionMessage error = new ActionMessage("error.msg.io.exception"); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + saveErrors(request, errors); + plannerForm.setValid(false); + return mapping.findForward(ResourceConstants.SUCCESS); + } + } + plannerForm.setFileName(itemIndex, resourceItem.getFileName()); + plannerForm.setFileUuid(itemIndex, resourceItem.getFileUuid()); + plannerForm.setFileVersion(itemIndex, resourceItem.getFileVersionId()); + plannerForm.setFile(itemIndex, null); + } + itemIndex++; + } + + } while (title != null); + // we need to clear it now, otherwise we get Hibernate error (item re-saved by cascade) + taskList.getResourceItems().clear(); + while (taskListItemIterator.hasNext()) { + resourceItem = taskListItemIterator.next(); + taskListItemIterator.remove(); + getResourceService().deleteResourceItem(resourceItem.getUid()); + } + reversedResourceItems.addAll(newItems); + + taskList.getResourceItems().addAll(reversedResourceItems); + getResourceService().saveOrUpdateResource(taskList); + } else { + saveErrors(request, errors); + } + return mapping.findForward(ResourceConstants.SUCCESS); + } + + public ActionForward createPedagogicalPlannerItem(ActionMapping mapping, ActionForm form, + HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + ResourcePedagogicalPlannerForm plannerForm = (ResourcePedagogicalPlannerForm) form; + int insertIndex = plannerForm.getItemCount(); + plannerForm.setTitle(insertIndex, ""); + plannerForm.setType(insertIndex, new Short(request.getParameter(ResourceConstants.ATTR_ADD_RESOURCE_TYPE))); + plannerForm.setUrl(insertIndex, null); + plannerForm.setFileName(insertIndex, null); + plannerForm.setFile(insertIndex, null); + plannerForm.setFileUuid(insertIndex, null); + plannerForm.setFileVersion(insertIndex, null); + return mapping.findForward(ResourceConstants.SUCCESS); + } } \ No newline at end of file Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourcePedagogicalPlannerForm.java =================================================================== diff -u --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourcePedagogicalPlannerForm.java (revision 0) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/web/form/ResourcePedagogicalPlannerForm.java (revision 3fe05cc69b1d0cfa2cb494a4778a8ab00dec2d60) @@ -0,0 +1,292 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.tool.rsrc.web.form; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.struts.action.ActionMessage; +import org.apache.struts.action.ActionMessages; +import org.apache.struts.upload.FormFile; +import org.lamsfoundation.lams.tool.rsrc.ResourceConstants; +import org.lamsfoundation.lams.tool.rsrc.model.Resource; +import org.lamsfoundation.lams.tool.rsrc.model.ResourceItem; +import org.lamsfoundation.lams.util.FileValidatorUtil; +import org.lamsfoundation.lams.web.planner.PedagogicalPlannerForm; + +/** + * @struts.form name="pedagogicalPlannerForm" + */ +public class ResourcePedagogicalPlannerForm extends PedagogicalPlannerForm { + private List title; + private List url; + private List file; + private List fileName; + private List fileUuid; + private List fileVersion; + private List type; + + @Override + public ActionMessages validate() { + ActionMessages errors = new ActionMessages(); + boolean allEmpty = true; + if (title != null && !title.isEmpty()) { + for (int index = 0; index < title.size(); index++) { + if (!StringUtils.isEmpty(title.get(index))) { + // at least one item exists and it has non-blank title + allEmpty = false; + Short itemType = type.get(index); + // URL should not be blank + if (itemType.equals(ResourceConstants.RESOURCE_TYPE_URL) && StringUtils.isEmpty(url.get(index))) { + ActionMessage error = new ActionMessage("error.planner.url.blank", index + 1); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + + } else if (itemType.equals(ResourceConstants.RESOURCE_TYPE_FILE)) { + /* + * File should be saved already or it should be provided. This functionality required some + * changes in pedagogicalPlanner.js in lams_central (see prepareFormData() there) + */ + FileValidatorUtil.validateFileSize(file.get(index), true, errors); + if (fileUuid.get(index) == null && file.get(index) == null) { + ActionMessage error = new ActionMessage("error.planner.file.blank", index + 1); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + } + } + } + } + } + if (allEmpty) { + ActionMessage error = new ActionMessage("error.planner.no.resource.save"); + errors.add(ActionMessages.GLOBAL_MESSAGE, error); + title = null; + url = null; + fileName = null; + fileUuid = null; + fileVersion = null; + type = null; + } + + setValid(errors.isEmpty()); + return errors; + } + + public void fillForm(Resource resource) { + if (resource != null) { + setToolContentID(resource.getContentId()); + + title = new ArrayList(); + url = new ArrayList(); + fileName = new ArrayList(); + file = new ArrayList(); + type = new ArrayList(); + Set items = resource.getResourceItems(); + if (items != null) { + int topicIndex = 0; + for (ResourceItem item : items) { + short itemType = item.getType(); + setTitle(topicIndex, item.getTitle()); + setType(topicIndex, itemType); + setUrl(topicIndex, itemType == ResourceConstants.RESOURCE_TYPE_URL ? item.getUrl() : null); + setFileName(topicIndex, itemType == ResourceConstants.RESOURCE_TYPE_FILE ? item.getFileName() + : null); + setFileUuid(topicIndex, itemType == ResourceConstants.RESOURCE_TYPE_FILE ? item.getFileUuid() + : null); + setFileVersion(topicIndex, itemType == ResourceConstants.RESOURCE_TYPE_FILE ? item + .getFileVersionId() : null); + topicIndex++; + } + } + } + } + + public void setTitle(int number, String formTitle) { + if (title == null) { + title = new ArrayList(); + } + while (number >= title.size()) { + title.add(null); + } + title.set(number, formTitle); + // URL items do not declare the file field, but addition is required for consistency + if (file == null || file.size() <= number) { + setFile(number, null); + } + } + + public String getTitle(int number) { + if (title == null || number >= title.size()) { + return null; + } + return title.get(number); + } + + public void setUrl(int number, String formUrl) { + if (url == null) { + url = new ArrayList(); + } + while (number >= url.size()) { + url.add(null); + } + url.set(number, formUrl); + } + + public String getUrl(int number) { + if (url == null || number >= url.size()) { + return null; + } + return url.get(number); + } + + public void setType(int number, Short formType) { + if (type == null) { + type = new ArrayList(); + } + while (number >= type.size()) { + type.add(null); + } + type.set(number, formType); + } + + public Short getType(int number) { + if (type == null || number >= type.size()) { + return null; + } + return type.get(number); + } + + public void setFile(int number, FormFile formFile) { + if (file == null) { + file = new ArrayList(); + } + while (number >= file.size()) { + file.add(null); + } + file.set(number, formFile); + } + + public FormFile getFile(int number) { + if (file == null || number >= file.size()) { + return null; + } + return file.get(number); + } + + public void setFileName(int number, String formFileName) { + if (fileName == null) { + fileName = new ArrayList(); + } + while (number >= fileName.size()) { + fileName.add(null); + } + fileName.set(number, formFileName); + } + + public String getFileName(int number) { + if (fileName == null || number >= fileName.size()) { + return null; + } + return fileName.get(number); + } + + public void setFileVersion(int number, Long formFileVersion) { + if (fileVersion == null) { + fileVersion = new ArrayList(); + } + while (number >= fileVersion.size()) { + fileVersion.add(null); + } + fileVersion.set(number, formFileVersion); + } + + public Long getFileVersion(int number) { + if (fileVersion == null || number >= fileVersion.size()) { + return null; + } + return fileVersion.get(number); + } + + public void setFileUuid(int number, Long formFileUuid) { + if (fileUuid == null) { + fileUuid = new ArrayList(); + } + while (number >= fileUuid.size()) { + fileUuid.add(null); + } + if (new Long(0).equals(formFileUuid)) { + fileUuid.set(number, null); + } else { + fileUuid.set(number, formFileUuid); + } + } + + public Long getFileUuid(int number) { + if (fileUuid == null || number >= fileUuid.size()) { + return null; + } + return fileUuid.get(number); + } + + public Integer getItemCount() { + return title == null ? 0 : title.size(); + } + + public boolean removeItem(int number) { + if (title == null || number >= title.size()) { + return false; + } + title.remove(number); + url.remove(number); + type.remove(number); + file.remove(number); + fileName.remove(number); + fileUuid.remove(number); + fileVersion.remove(number); + return true; + } + + public List getTypeList() { + return type; + } + + public List getFileNameList() { + return fileName; + } + + /** + * Special method that is used to fool the browser. If there was no file provided, there was an argument type + * mismatch excpetion since browser tried to fill an empty string to file field. Now in pedagogicalPlanner.js in + * lams_central it is detected and the field name is changed to fileDummy, which sets the file to NULLM + * here in Java form file. + * + * @param number + * where to set the empty file + * @param emptyString + * never used; the file is set to NULL anyway + */ + public void setFileDummy(int number, String emptyString) { + setFile(number, null); + } +} \ No newline at end of file Index: lams_tool_larsrc/web/pages/authoring/pedagogicalPlannerForm.jsp =================================================================== diff -u --- lams_tool_larsrc/web/pages/authoring/pedagogicalPlannerForm.jsp (revision 0) +++ lams_tool_larsrc/web/pages/authoring/pedagogicalPlannerForm.jsp (revision 3fe05cc69b1d0cfa2cb494a4778a8ab00dec2d60) @@ -0,0 +1,82 @@ + + +<%@ include file="/common/taglibs.jsp"%> + + + + + + + + + + + + + <%@ include file="/common/messages.jsp"%> + + + + + + + + + + + + + +

+ + + +

+ +
+ + +

+ : ${itemFileName} +

+ +
+
+
+
+
+ + + +
\ No newline at end of file