private UIStyleDecorator getImageSourceDecoratorFromMimeType(SimplePageItem pageItem) { String mimeType = pageItem.getHtml(); if (SimplePageItem.TEXT == pageItem.getType()) { mimeType = "text/html"; } else if ("application/octet-stream".equals(mimeType)) { // OS X reports octet stream for things like MS Excel documents. // Force a mimeType lookup so we get a decent icon. mimeType = null; } if (mimeType == null || mimeType.equals("")) { String s = pageItem.getSakaiId(); int j = s.lastIndexOf("."); if (j >= 0) s = s.substring(j + 1); mimeType = ContentTypeImageService.getContentType(s); } String src = null; src = imageToMimeMap.get(mimeType); if (src == null) { src = "fa-file-o"; } return new UIStyleDecorator(src); }
public boolean hasSubPages(Long pageId) { // now recursively do subpages List<SimplePageItem> items = simplePageToolDao.findItemsOnPage(pageId); // subpages done in place for (SimplePageItem item : items) { if (item.getType() == SimplePageItem.PAGE) { return true; } } return false; }
private UIStyleDecorator getImageSourceDecorator(SimplePageItem pageItem) { switch (pageItem.getType()) { case SimplePageItem.FORUM: return new UIStyleDecorator("fa-comments"); case SimplePageItem.ASSIGNMENT: return new UIStyleDecorator("fa-tasks"); case SimplePageItem.ASSESSMENT: return new UIStyleDecorator("fa-puzzle-piece"); case SimplePageItem.QUESTION: return new UIStyleDecorator("fa-question"); case SimplePageItem.COMMENTS: return new UIStyleDecorator("fa-commenting"); case SimplePageItem.BLTI: return new UIStyleDecorator("fa-globe"); case SimplePageItem.PAGE: return new UIStyleDecorator("fa-folder-open-o"); case SimplePageItem.RESOURCE: return getImageSourceDecoratorFromMimeType(pageItem); case SimplePageItem.MULTIMEDIA: return getImageSourceDecoratorFromMimeType(pageItem); case SimplePageItem.TEXT: return getImageSourceDecoratorFromMimeType(pageItem); default: return new UIStyleDecorator(""); } }
private UIFreeAttributeDecorator getImageSourceDecorator(SimplePageItem pageItem) { switch (pageItem.getType()) { case SimplePageItem.FORUM: return new UIFreeAttributeDecorator("src", "/library/image/silk/comments.png"); case SimplePageItem.ASSIGNMENT: return new UIFreeAttributeDecorator("src", "/library/image/silk/page_edit.png"); case SimplePageItem.ASSESSMENT: return new UIFreeAttributeDecorator("src", "/library/image/silk/pencil.png"); case SimplePageItem.QUESTION: return new UIFreeAttributeDecorator("src", "/library/image/silk/pencil.png"); case SimplePageItem.COMMENTS: return new UIFreeAttributeDecorator("src", "/library/image/silk/comments.png"); case SimplePageItem.BLTI: return new UIFreeAttributeDecorator("src", "/library/image/silk/application_go.png"); case SimplePageItem.PAGE: return new UIFreeAttributeDecorator("src", "/library/image/silk/book_open.png"); case SimplePageItem.RESOURCE: return getImageSourceDecoratorFromMimeType(pageItem); case SimplePageItem.MULTIMEDIA: return getImageSourceDecoratorFromMimeType(pageItem); case SimplePageItem.TEXT: return getImageSourceDecoratorFromMimeType(pageItem); default: return new UIFreeAttributeDecorator("src", ""); } }
public void fillComponents( UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { CommentsViewParameters params = (CommentsViewParameters) viewparams; filter = params.filter; // set up locale String langLoc[] = localeGetter.get().toString().split("_"); if (langLoc.length >= 2) { if ("en".equals(langLoc[0]) && "ZA".equals(langLoc[1])) { M_locale = new Locale("en", "GB"); } else { M_locale = new Locale(langLoc[0], langLoc[1]); } } else { M_locale = new Locale(langLoc[0]); } df = DateFormat.getDateTimeInstance( DateFormat.DEFAULT, DateFormat.DEFAULT, new ResourceLoader().getLocale()); df.setTimeZone(TimeService.getLocalTimeZone()); dfTime = DateFormat.getTimeInstance(DateFormat.SHORT, M_locale); dfTime.setTimeZone(TimeService.getLocalTimeZone()); dfDate = DateFormat.getDateInstance(DateFormat.MEDIUM, M_locale); dfDate.setTimeZone(TimeService.getLocalTimeZone()); // errors redirect back to ShowPage. But if this is embedded in the page, ShowPage // will call us again. This is very hard for the user to recover from. So trap // all possible errors. It may result in an incomplete page or something invalid, // but better that than an infinite recursion. try { SimplePage currentPage = simplePageToolDao.getPage(params.pageId); simplePageBean.setCurrentSiteId(params.siteId); simplePageBean.setCurrentPage(currentPage); simplePageBean.setCurrentPageId(params.pageId); UIOutput.make(tofill, "mainlist") .decorate( new UIFreeAttributeDecorator( "aria-label", messageLocator.getMessage("simplepage.comments-section"))); SimplePageItem commentsItem = simplePageToolDao.findItem(params.itemId); if (commentsItem != null && commentsItem.getSakaiId() != null && !commentsItem.getSakaiId().equals("")) { SimpleStudentPage studentPage = simplePageToolDao.findStudentPage(Long.valueOf(commentsItem.getSakaiId())); if (studentPage != null) { owner = studentPage.getOwner(); } } if (params.deleteComment != null) { simplePageBean.deleteComment(params.deleteComment); } List<SimplePageComment> comments; if (!filter && !params.studentContentItem) { comments = (List<SimplePageComment>) simplePageToolDao.findComments(params.itemId); } else if (filter && !params.studentContentItem) { comments = (List<SimplePageComment>) simplePageToolDao.findCommentsOnItemByAuthor(params.itemId, params.author); } else if (filter && params.studentContentItem) { List<SimpleStudentPage> studentPages = simplePageToolDao.findStudentPages(params.itemId); Site site = SiteService.getSite(currentPage.getSiteId()); itemToPageowner = new HashMap<Long, String>(); List<Long> commentsItemIds = new ArrayList<Long>(); for (SimpleStudentPage p : studentPages) { // If the page is deleted, don't show the comments if (!p.isDeleted()) { commentsItemIds.add(p.getCommentsSection()); String pageOwner = p.getOwner(); String pageGroup = p.getGroup(); if (pageGroup != null) pageOwner = pageGroup; try { String o = null; if (pageGroup != null) o = site.getGroup(pageGroup).getTitle(); else o = UserDirectoryService.getUser(pageOwner).getDisplayName(); if (o != null) pageOwner = o; } catch (Exception ignore) { } ; itemToPageowner.put(p.getCommentsSection(), pageOwner); } } comments = simplePageToolDao.findCommentsOnItemsByAuthor(commentsItemIds, params.author); } else { List<SimpleStudentPage> studentPages = simplePageToolDao.findStudentPages(params.itemId); List<Long> commentsItemIds = new ArrayList<Long>(); for (SimpleStudentPage p : studentPages) { commentsItemIds.add(p.getCommentsSection()); } comments = simplePageToolDao.findCommentsOnItems(commentsItemIds); } // Make sure everything is chronological Collections.sort( comments, new Comparator<SimplePageComment>() { public int compare(SimplePageComment c1, SimplePageComment c2) { if (itemToPageowner != null) { String o1 = itemToPageowner.get(c1.getItemId()); String o2 = itemToPageowner.get(c2.getItemId()); if (o1 != o2) { if (o1 == null) return 1; return o1.compareTo(o2); } } return c1.getTimePosted().compareTo(c2.getTimePosted()); } }); currentUserId = UserDirectoryService.getCurrentUser().getId(); boolean anonymous = simplePageBean.findItem(params.itemId).isAnonymous(); if (anonymous) { int i = 1; for (SimplePageComment comment : comments) { if (!anonymousLookup.containsKey(comment.getAuthor())) { anonymousLookup.put( comment.getAuthor(), messageLocator.getMessage("simplepage.anonymous") + " " + i); i++; } } } boolean highlighted = false; // We don't want page owners to edit or grade comments on their page // at the moment. Perhaps add option? canEditPage = simplePageBean.getEditPrivs() == 0; boolean showGradingMessage = canEditPage && commentsItem.getGradebookId() != null && !params.filter; Date lastViewed = null; // remains null if never viewed before SimplePageLogEntry log = simplePageBean.getLogEntry(params.itemId); if (log != null) lastViewed = log.getLastViewed(); int newItems = 0; // Remove any "phantom" comments. So that the anonymous order stays the same, // comments are deleted by removing all content. Also check to see if any comments // have been graded yet. Finally, if we're filtering, it takes out comments not by // this author. for (int i = comments.size() - 1; i >= 0; i--) { if (comments.get(i).getComment() == null || comments.get(i).getComment().equals("")) { comments.remove(i); } else if (params.filter && !comments.get(i).getAuthor().equals(params.author)) { comments.remove(i); } else { if (showGradingMessage && comments.get(i).getPoints() != null) showGradingMessage = false; if (lastViewed == null) newItems++; // all items are new if never viewed else if (comments.get(i).getTimePosted().after(lastViewed)) newItems++; } } // update date only if we actually are going to see all the comments, and it's // not a weird view (i.e. filter is on) // The situation with items <= 5 is actually dubious. The user has them on the // screen, but there's no way to know whether he's actually seen them. Some users // are going to be surprised either way we do it. if (params.showAllComments || params.showNewComments || (!params.filter && newItems <= 5)) { if (log != null) { simplePageBean.update(log); } else { log = simplePageToolDao.makeLogEntry(currentUserId, params.itemId, null); simplePageBean.saveItem(log); } } // Make sure we don't show the grading message if there's nothing to grade. if (comments.size() == 0) { showGradingMessage = false; } boolean editable = false; if (comments.size() <= 5 || params.showAllComments || params.filter) { for (int i = 0; i < comments.size(); i++) { // We don't want them editing on the grading screen, which is why we also check filter. boolean canEdit = simplePageBean.canModifyComment(comments.get(i), canEditPage) && !params.filter; printComment( comments.get(i), tofill, (params.postedComment == comments.get(i).getId()), anonymous, canEdit, params, commentsItem, currentPage); if (!highlighted) { highlighted = (params.postedComment == comments.get(i).getId()); } if (!editable) editable = canEdit; } } else { UIBranchContainer container = UIBranchContainer.make(tofill, "commentList:"); UIOutput.make(container, "commentDiv"); // UIBranchContainer container = UIBranchContainer.make(tofill, "commentDiv:"); CommentsViewParameters eParams = new CommentsViewParameters(VIEW_ID); eParams.placementId = params.placementId; eParams.itemId = params.itemId; eParams.showAllComments = true; eParams.showNewComments = false; eParams.pageId = params.pageId; eParams.siteId = params.siteId; UIInternalLink.make(container, "to-load", eParams); UIOutput.make( container, "load-more-link", messageLocator .getMessage("simplepage.see_all_comments") .replace("{}", Integer.toString(comments.size()))); if (!params.showNewComments && newItems > 5) { container = UIBranchContainer.make(tofill, "commentList:"); UIOutput.make(container, "commentDiv"); // UIBranchContainer container = UIBranchContainer.make(tofill, "commentDiv:"); eParams = new CommentsViewParameters(VIEW_ID); eParams.placementId = params.placementId; eParams.itemId = params.itemId; eParams.showAllComments = false; eParams.showNewComments = true; eParams.pageId = params.pageId; eParams.siteId = params.siteId; UIInternalLink.make(container, "to-load", eParams); UIOutput.make( container, "load-more-link", messageLocator .getMessage("simplepage.see_new_comments") .replace("{}", Integer.toString(newItems))); } int start = comments.size() - 5; if (params.showNewComments) start = 0; // Show 5 most recent comments for (int i = start; i < comments.size(); i++) { if (!params.showNewComments || lastViewed == null || comments.get(i).getTimePosted().after(lastViewed)) { boolean canEdit = simplePageBean.canModifyComment(comments.get(i), canEditPage); printComment( comments.get(i), tofill, (params.postedComment == comments.get(i).getId()), anonymous, canEdit, params, commentsItem, currentPage); if (!highlighted) { highlighted = (params.postedComment == comments.get(i).getId()); } if (!editable) editable = canEdit; } } } if (highlighted) { // We have something to highlight UIOutput.make(tofill, "highlightScript"); } if (showGradingMessage) { UIOutput.make(tofill, "gradingAlert"); } if (anonymous && canEditPage && comments.size() > 0 && lastViewed == null) { // Tells the admin that they can see the names, but everyone else can't UIOutput.make(tofill, "anonymousAlert"); } else if (editable && simplePageBean.getEditPrivs() != 0) { // Warns user that they only have 30 mins to edit. UIOutput.make(tofill, "editAlert"); } } catch (Exception e) { e.printStackTrace(); System.out.println("comments error " + e); } ; }
public void printComment( SimplePageComment comment, UIContainer tofill, boolean highlight, boolean anonymous, boolean showModifiers, CommentsViewParameters params, SimplePageItem commentsItem, SimplePage currentPage) { if (canEditPage && itemToPageowner != null && comment.getItemId() != lastTitle) { UIBranchContainer commentContainer = UIBranchContainer.make(tofill, "commentList:"); UIOutput.make( commentContainer, "commentTitle", messageLocator .getMessage("simplepage.comments-grading") .replace("{}", itemToPageowner.get(comment.getItemId()))); lastTitle = comment.getItemId(); } // print title if this is a comment on a different page. Normally this // shold only happen for subpages of student pages String pageTitle = null; if (currentPage.getPageId() != comment.getPageId()) { SimplePage commentPage = simplePageBean.getPage(comment.getPageId()); pageTitle = commentPage.getTitle(); } UIBranchContainer commentContainer = UIBranchContainer.make(tofill, "commentList:"); UIOutput.make(commentContainer, "commentDiv"); if (highlight) commentContainer.decorate(new UIStyleDecorator("highlight-comment")); if (!filter && params.author != null && params.author.equals(comment.getAuthor())) { commentContainer.decorate(new UIStyleDecorator("backgroundHighlight")); } String author; if (!anonymous) { try { User user = UserDirectoryService.getUser(comment.getAuthor()); author = user.getDisplayName(); } catch (Exception ex) { author = messageLocator.getMessage("simplepage.comment-unknown-user"); ex.printStackTrace(); } } else { author = anonymousLookup.get(comment.getAuthor()); if (comment.getAuthor().equals(owner)) { author = messageLocator.getMessage("simplepage.comment-author-owner"); } if (author == null) author = "Anonymous User"; // Shouldn't ever occur if (simplePageBean.getEditPrivs() == 0) { try { User user = UserDirectoryService.getUser(comment.getAuthor()); author += " (" + user.getDisplayName() + ")"; } catch (Exception ex) { author += " (" + messageLocator.getMessage("simplepage.comment-unknown-user") + ")"; } } else if (comment.getAuthor().equals(currentUserId)) { author += " (" + messageLocator.getMessage("simplepage.comment-you") + ")"; } } UIOutput authorOutput = UIOutput.make(commentContainer, "userId", author); if (comment.getAuthor().equals(currentUserId)) { authorOutput.decorate(new UIStyleDecorator("specialCommenter")); authorOutput.decorate(new UIStyleDecorator("personalComment")); } else if (comment.getAuthor().equals(owner)) { authorOutput.decorate(new UIStyleDecorator("specialCommenter")); authorOutput.decorate(new UIStyleDecorator("ownerComment")); } if (pageTitle != null) UIOutput.make(commentContainer, "pageTitle", pageTitle); String timeDifference = getTimeDifference(comment.getTimePosted().getTime()); UIOutput.make(commentContainer, "timePosted", timeDifference); if (showModifiers) { UIOutput.make(commentContainer, "deleteSpan"); CommentsViewParameters eParams = (CommentsViewParameters) params.copy(); eParams.placementId = params.placementId; eParams.deleteComment = comment.getUUID(); eParams.pageId = params.pageId; eParams.siteId = params.siteId; UIInternalLink.make(commentContainer, "deleteCommentURL", eParams); UIOutput.make(commentContainer, "deleteComment") .decorate( new UIFreeAttributeDecorator( "title", messageLocator.getMessage("simplepage.comment-delete").replace("{}", author))); UIOutput.make(commentContainer, "editComment") .decorate( new UIFreeAttributeDecorator("onclick", "edit($(this), " + comment.getId() + ");")) .decorate( new UIFreeAttributeDecorator( "title", messageLocator.getMessage("simplepage.comment-edit").replace("{}", author))); if (!filter && simplePageBean.getEditPrivs() == 0 && commentsItem.getGradebookId() != null) { UIOutput.make(commentContainer, "gradingSpan"); UIOutput.make(commentContainer, "commentsUUID", comment.getUUID()); UIOutput.make( commentContainer, "commentPoints", (comment.getPoints() == null ? "" : String.valueOf(comment.getPoints()))); UIOutput.make(commentContainer, "pointsBox") .decorate( new UIFreeAttributeDecorator( "title", messageLocator .getMessage("simplepage.grade-for-student") .replace("{}", author))); UIOutput.make(commentContainer, "maxpoints", " / " + commentsItem.getGradebookPoints()); UIOutput.make(commentContainer, "authorUUID", comment.getAuthor()); } } if (filter && simplePageBean.getEditPrivs() == 0) { UIOutput.make(commentContainer, "contextSpan"); // because this is called via /faces, the full Sakai context is not set up. // in particular, UIInternalLink will generate the wrong thing. Thus we // make up a full URL ourselves. String pars = "/portal/tool/" + URLEncoder.encode(params.placementId) + "/ShowPage?path=none" + "&author=" + URLEncoder.encode(comment.getAuthor()); // Need to provide the item ID if (!params.studentContentItem && params.pageItemId != -1L) { pars += "&itemId=" + URLEncoder.encode(Long.toString(params.pageItemId)); } UILink contextLink = UILink.make( commentContainer, "contextLink", messageLocator.getMessage("simplepage.show-context"), pars); if (itemToPageowner == null) contextLink.decorate( new UIFreeAttributeDecorator( "title", messageLocator .getMessage("simplepage.context-link-title-1") .replace("{}", author))); else contextLink.decorate( new UIFreeAttributeDecorator( "title", messageLocator .getMessage("simplepage.context-link-title-2") .replace("{1}", author) .replace("{2}", itemToPageowner.get(comment.getItemId())))); } String dateString = df.format(comment.getTimePosted()); if (!filter) UIOutput.make(commentContainer, "replyTo") .decorate( new UIFreeAttributeDecorator( "onclick", "replyToComment($(this),'" + messageLocator .getMessage("simplepage.in-reply-to") .replace("{1}", author) .replace("{2}", dateString) + "')")) .decorate( new UIFreeAttributeDecorator( "title", messageLocator.getMessage("simplepage.comment-reply").replace("{}", author))); if (!comment.getHtml()) { UIOutput.make(commentContainer, "comment", comment.getComment()); } else { UIVerbatim.make(commentContainer, "comment", comment.getComment()); } }
public void fillComponents( UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { CommentsGradingPaneViewParameters params = (CommentsGradingPaneViewParameters) viewparams; SimplePage currentPage = simplePageToolDao.getPage(params.pageId); simplePageBean.setCurrentSiteId(params.siteId); simplePageBean.setCurrentPage(currentPage); simplePageBean.setCurrentPageId(params.pageId); GeneralViewParameters backParams = new GeneralViewParameters(ShowPageProducer.VIEW_ID, params.pageId); backParams.setItemId(params.pageItemId); backParams.setPath("log"); UIOutput.make(tofill, "html") .decorate(new UIFreeAttributeDecorator("lang", localeGetter.get().getLanguage())) .decorate(new UIFreeAttributeDecorator("xml:lang", localeGetter.get().getLanguage())); UIInternalLink.make( tofill, "back-link", messageLocator.getMessage("simplepage.go-back"), backParams); if (simplePageBean.getEditPrivs() != 0) { UIOutput.make(tofill, "permissionsError"); return; } String heading = null; if (params.studentContentItem) { heading = messageLocator.getMessage("simplepage.student-comments-grading"); } else { heading = messageLocator.getMessage("simplepage.comments-grading"); } SimplePageItem commentItem = simplePageToolDao.findItem(params.commentsItemId); SimplePage containingPage = simplePageToolDao.getPage(commentItem.getPageId()); heading = heading.replace("{}", containingPage.getTitle()); UIOutput.make(tofill, "page-header", heading); List<SimplePageComment> comments; if (!params.studentContentItem) { comments = simplePageToolDao.findComments(params.commentsItemId); } else { List<SimpleStudentPage> studentPages = simplePageToolDao.findStudentPages(params.commentsItemId); List<Long> commentsItemIds = new ArrayList<Long>(); for (SimpleStudentPage p : studentPages) { // If the page is deleted, don't show the comments if (!p.isDeleted()) { commentsItemIds.add(p.getCommentsSection()); } } comments = simplePageToolDao.findCommentsOnItems(commentsItemIds); } ArrayList<String> userIds = new ArrayList<String>(); HashMap<String, SimpleUser> users = new HashMap<String, SimpleUser>(); for (SimplePageComment comment : comments) { if (comment.getComment() == null || comment.getComment().equals("")) { continue; } if (!userIds.contains(comment.getAuthor())) { userIds.add(comment.getAuthor()); try { SimpleUser user = new SimpleUser(); user.displayName = UserDirectoryService.getUser(comment.getAuthor()).getDisplayName(); user.postCount++; user.userId = comment.getAuthor(); user.grade = comment.getPoints(); user.uuid = comment.getUUID(); if (params.studentContentItem) { user.pages.add(comment.getPageId()); } users.put(comment.getAuthor(), user); } catch (Exception ex) { } } else { SimpleUser user = users.get(comment.getAuthor()); if (user != null) { user.postCount++; if (params.studentContentItem && !user.pages.contains(comment.getPageId())) { user.pages.add(comment.getPageId()); } } } } ArrayList<SimpleUser> simpleUsers = new ArrayList<SimpleUser>(users.values()); Collections.sort(simpleUsers); if (params.studentContentItem) { UIOutput.make( tofill, "unique-header", messageLocator.getMessage("simplepage.grading-unique")); } if (simpleUsers.size() > 0) { UIOutput.make(tofill, "gradingTable"); } else { UIOutput.make(tofill, "noEntriesWarning"); } if (params.studentContentItem) UIOutput.make(tofill, "clickfiller"); UIOutput.make(tofill, "clickToSubmit", messageLocator.getMessage("simplepage.update-points")) .decorate( new UIFreeAttributeDecorator( "title", messageLocator.getMessage("simplepage.update-points"))); for (SimpleUser user : simpleUsers) { UIBranchContainer branch = UIBranchContainer.make(tofill, "student-row:"); UIOutput.make(branch, "first-row"); UIOutput.make(branch, "details-row"); UIOutput detailsCell = UIOutput.make(branch, "details-cell"); // Set the column span based on which type of item it is. Student content // items have an extra column, so we have to accommodate. if (params.studentContentItem) { detailsCell.decorate(new UIFreeAttributeDecorator("colspan", "5")); } else { detailsCell.decorate(new UIFreeAttributeDecorator("colspan", "4")); } UIOutput.make(branch, "student-name", user.displayName); UIOutput.make(branch, "student-total", String.valueOf(user.postCount)); if (params.studentContentItem) { UIOutput.make(branch, "student-unique", String.valueOf(user.pages.size())); } // Add the link that will be fetched using Ajax CommentsViewParameters eParams = new CommentsViewParameters(CommentsProducer.VIEW_ID); eParams.placementId = ToolManager.getCurrentPlacement().getId(); eParams.itemId = params.commentsItemId; eParams.author = user.userId; eParams.filter = true; eParams.pageItemId = params.pageItemId; eParams.studentContentItem = params.studentContentItem; eParams.siteId = simplePageBean.getCurrentSiteId(); eParams.pageId = containingPage.getPageId(); UIInternalLink.make(branch, "commentsLink", eParams); // The grading stuff UIOutput.make(branch, "student-grade"); UIOutput.make(branch, "gradingSpan"); UIOutput.make(branch, "commentsUUID", user.uuid); UIOutput.make( branch, "commentPoints", (user.grade == null ? "" : String.valueOf(user.grade))); UIOutput.make(branch, "pointsBox") .decorate( new UIFreeAttributeDecorator( "title", messageLocator .getMessage("simplepage.grade-for-student") .replace("{}", user.displayName))); UIOutput.make( branch, "maxpoints", " / " + (params.studentContentItem ? commentItem.getAltPoints() : commentItem.getGradebookPoints())); UIOutput.make( branch, "clickToExpand", messageLocator.getMessage("simplepage.click-to-expand")) .decorate( new UIFreeAttributeDecorator( "title", messageLocator .getMessage("simplepage.expand-for-student") .replace("{}", user.displayName))); UIOutput.make(branch, "authorUUID", user.userId); } UIForm gradingForm = UIForm.make(tofill, "gradingForm"); gradingForm.viewparams = new SimpleViewParameters(UVBProducer.VIEW_ID); UIInput idInput = UIInput.make(gradingForm, "gradingForm-id", "gradingBean.id"); UIInput jsIdInput = UIInput.make(gradingForm, "gradingForm-jsId", "gradingBean.jsId"); UIInput pointsInput = UIInput.make(gradingForm, "gradingForm-points", "gradingBean.points"); UIInput typeInput = UIInput.make(gradingForm, "gradingForm-type", "gradingBean.type"); Object sessionToken = SessionManager.getCurrentSession().getAttribute("sakai.csrf.token"); UIInput csrfInput = UIInput.make( gradingForm, "csrf", "gradingBean.csrfToken", (sessionToken == null ? "" : sessionToken.toString())); UIInitBlock.make( tofill, "gradingForm-init", "initGradingForm", new Object[] { idInput, pointsInput, jsIdInput, typeInput, csrfInput, "gradingBean.results" }); }
public void fillComponents( UIContainer tofill, ViewParameters viewparams, ComponentChecker checker) { if (((GeneralViewParameters) viewparams).getSendingPage() != -1) { // will fail if page not in this site // security then depends upon making sure that we only deal with this page try { simplePageBean.updatePageObject(((GeneralViewParameters) viewparams).getSendingPage()); } catch (Exception e) { System.out.println("PagePicker permission exception " + e); return; } } UIOutput.make(tofill, "html") .decorate(new UIFreeAttributeDecorator("lang", localeGetter.get().getLanguage())) .decorate(new UIFreeAttributeDecorator("xml:lang", localeGetter.get().getLanguage())); boolean canEditPage = (simplePageBean.getEditPrivs() == 0); String source = ((GeneralViewParameters) viewparams).getSource(); // summaryPage is the "index of pages". It has status icons and links, but isn't a chooser // otherwise we have the chooser page for the "add subpage" command boolean summaryPage = "summary".equals(source); if (summaryPage) { GeneralViewParameters view = new GeneralViewParameters(ShowPageProducer.VIEW_ID); // path defaults to null, which is next UIOutput.make(tofill, "return-div"); UIInternalLink.make(tofill, "return", messageLocator.getMessage("simplepage.return"), view); UIOutput.make(tofill, "title", messageLocator.getMessage("simplepage.page.index")); } else { UIOutput.make(tofill, "title", messageLocator.getMessage("simplepage.page.chooser")); } // Explain which pages may be deleted if (summaryPage && canEditPage) { UIOutput.make(tofill, "deleteAlert"); } // this looks at pages in the site, which should be safe // but need to make sure the item we update is legal Long itemId = ((GeneralViewParameters) viewparams).getItemId(); simplePageBean.setItemId(itemId); SimplePage page = simplePageBean.getCurrentPage(); currentPageId = page.getPageId(); if (itemId != null && itemId != -1) { SimplePageItem currentItem = simplePageToolDao.findItem(itemId); if (currentItem == null) return; // trying to hack on item not on this page if (currentItem.getPageId() != page.getPageId()) return; } // list we're going to display List<PageEntry> entries = new ArrayList<PageEntry>(); // build map of all pages, so we can see if any are left over Map<Long, SimplePage> pageMap = new HashMap<Long, SimplePage>(); Set<Long> sharedPages = new HashSet<Long>(); // all pages List<SimplePage> pages = simplePageToolDao.getSitePages(simplePageBean.getCurrentSiteId()); for (SimplePage p : pages) pageMap.put(p.getPageId(), p); // set of all top level pages, actually the items pointing to them List<SimplePageItem> sitePages = simplePageToolDao.findItemsInSite(toolManager.getCurrentPlacement().getContext()); Set<Long> topLevelPages = new HashSet<Long>(); for (SimplePageItem i : sitePages) topLevelPages.add(Long.valueOf(i.getSakaiId())); // this adds everything you can find from top level pages to entries. But make sure user can see // the tool for (SimplePageItem sitePageItem : sitePages) { // System.out.println("findallpages " + sitePageItem.getName() + " " + true); findAllPages( sitePageItem, entries, pageMap, topLevelPages, sharedPages, 0, true, canEditPage); } // warn students if we aren't showing all the pages if (!canEditPage && somePagesHavePrerequisites) UIOutput.make(tofill, "onlyseen"); // now add everything we didn't find that way if (canEditPage && pageMap.size() > 0) { // marker PageEntry marker = new PageEntry(); marker.level = -1; entries.add(marker); for (SimplePage p : pageMap.values()) { if (p.getOwner() == null) { PageEntry entry = new PageEntry(); entry.pageId = p.getPageId(); entry.itemId = null; entry.title = p.getTitle(); entry.level = 0; // TopLevel determines if we can select the page. // Since this means that the page is detached, it isn't // a conflict to be able to select it. entry.toplevel = false; entries.add(entry); } } } if (canEditPage && sharedPages.size() > 0) UIOutput.make(tofill, "sharedpageexplanation"); UIForm form = UIForm.make(tofill, "page-picker"); Object sessionToken = SessionManager.getCurrentSession().getAttribute("sakai.csrf.token"); if (sessionToken != null) UIInput.make(form, "csrf", "simplePageBean.csrfToken", sessionToken.toString()); ArrayList<String> values = new ArrayList<String>(); ArrayList<String> initValues = new ArrayList<String>(); for (PageEntry entry : entries) { if (entry.level >= 0) { values.add(entry.pageId.toString()); initValues.add(""); } } UISelect select = null; if (summaryPage) select = UISelect.makeMultiple( form, "page-span", values.toArray(new String[1]), "#{simplePageBean.selectedEntities}", initValues.toArray(new String[1])); else select = UISelect.make( form, "page-span", values.toArray(new String[1]), "#{simplePageBean.selectedEntity}", null); int index = 0; boolean showDeleteButton = false; for (PageEntry entry : entries) { UIBranchContainer row = UIBranchContainer.make(form, "page:"); if (entry.toplevel) row.decorate( new UIFreeAttributeDecorator("style", "list-style-type:none; margin-top:0.5em")); if (entry.level < 0) { UIOutput.make(row, "heading", messageLocator.getMessage("simplepage.chooser.unused")); if (summaryPage) UIOutput.make(row, "chooseall"); } // if no itemid, it's unused. Only canedit people will see it else if (summaryPage && entry.itemId != null) { int level = entry.level; if (level > 5) level = 5; String imagePath = "/lessonbuilder-tool/images/"; SimplePageItem item = simplePageBean.findItem(entry.itemId); SimplePageLogEntry logEntry = simplePageBean.getLogEntry(entry.itemId); String note = null; if (logEntry != null && logEntry.isComplete()) { imagePath += "checkmark.png"; note = messageLocator.getMessage("simplepage.status.completed"); } else if (logEntry != null && !logEntry.getDummy()) { imagePath += "hourglass.png"; note = messageLocator.getMessage("simplepage.status.inprogress"); } else if (!canEditPage && somePagesHavePrerequisites) { // it's too complex to compute prerequisites for all pages, and // I'm concerned that faculty may not be careful in setting them // for pages that would normally not be accessible. So if there are // any prerequisites in the site, only show pages that are // in progress or done. continue; } else { imagePath += "not-required.png"; } UIOutput.make(row, "status-image").decorate(new UIFreeAttributeDecorator("src", imagePath)); GeneralViewParameters p = new GeneralViewParameters(ShowPageProducer.VIEW_ID); p.setSendingPage(entry.pageId); p.setItemId(entry.itemId); // reset the path to the saved one p.setPath("log"); UIInternalLink.make(row, "link", p) .decorate(new UIFreeAttributeDecorator("style", "padding-left: " + (2 * level) + "em")); String levelstr = null; if (level > 0) levelstr = messageLocator .getMessage("simplepage.status.level") .replace("{}", Integer.toString(level)); if (levelstr != null) { if (note != null) note = levelstr + " " + note; else note = levelstr; } if (note != null) UIOutput.make(row, "link-note", note + " "); UIOutput.make(row, "link-text", entry.title); if (enableShowItems) { UIOutput.make(row, "item-list-toggle"); UIOutput.make(row, "itemListContainer") .decorate( new UIFreeAttributeDecorator("style", "margin-left: " + (3 * level) + "em")); UIOutput.make(row, "itemList"); Set<String> myGroups = simplePageBean.getMyGroups(); for (SimplePageItem pageItem : simplePageToolDao.findItemsOnPage(entry.pageId)) { // if item is group controlled, skip if user isn't in one of the groups Collection<String> itemGroups = null; try { itemGroups = simplePageBean.getItemGroups(pageItem, null, false); } catch (IdUnusedException e) { // underlying assignment, etc, doesn't exist. skip the item continue; } if (itemGroups != null) { boolean groupsOk = false; for (String group : itemGroups) { if (myGroups.contains(group)) { groupsOk = true; break; } } if (!groupsOk) continue; } UIBranchContainer itemListItem = UIBranchContainer.make(row, "item:"); if (pageItem.isRequired()) { UIOutput.make(itemListItem, "required-image"); } else { UIOutput.make(itemListItem, "not-required-image"); } UIOutput.make(itemListItem, "item-icon").decorate(getImageSourceDecorator(pageItem)); if (pageItem.isPrerequisite()) { itemListItem.decorate(new UIFreeAttributeDecorator("class", "disabled-text-item")); } if (SimplePageItem.TEXT == pageItem.getType()) { UIOutput.make( itemListItem, "name", messageLocator.getMessage("simplepage.chooser.textitemplaceholder")) .decorate(new UIFreeAttributeDecorator("class", "text-item-placeholder")); } else if (SimplePageItem.BREAK == pageItem.getType()) { String text = null; if ("section".equals(pageItem.getFormat())) text = messageLocator.getMessage("simplepage.break-here"); else text = messageLocator.getMessage("simplepage.break-column-here"); UIOutput.make(itemListItem, "name", text) .decorate(new UIFreeAttributeDecorator("class", "text-item-placeholder")); } else { UIOutput.make(itemListItem, "name", pageItem.getName()); } // UIOutput.make(itemListItem, "page1", // Boolean.toString(lessonsAccess.isItemAccessible(pageItem.getId(),simplePageBean.getCurrentSiteId(),"c08d3ac9-c717-472a-ad91-7ce0b434f42f", simplePageBean))); } } index++; // for pagepicker or summary if canEdit and page doesn't have an item } else { int level = entry.level; if (level > 5) level = 5; if (!summaryPage /*&& !entry.toplevel*/) { // i.e. pagepicker; for the moment to edit // something you need to attach it to something UISelectChoice.make(row, "select", select.getFullID(), index) .decorate( new UIFreeAttributeDecorator( "title", entry.title + " " + messageLocator.getMessage("simplepage.select"))); } else if (summaryPage) { // i.e. summary if canEdit and page doesn't have an item UISelectChoice.make(row, "select-for-deletion", select.getFullID(), index) .decorate( new UIFreeAttributeDecorator( "title", entry.title + " " + messageLocator.getMessage("simplepage.select-for-deletion"))); showDeleteButton = true; // at least one item to delete } GeneralViewParameters params = new GeneralViewParameters(); params.viewID = PreviewProducer.VIEW_ID; params.setSendingPage(entry.pageId); UIInternalLink.make(row, "link", params) .decorate(new UIFreeAttributeDecorator("style", "padding-left: " + (2 * level) + "em")) .decorate(new UIFreeAttributeDecorator("target", "_blank")); String levelstr = messageLocator .getMessage("simplepage.status.level") .replace("{}", Integer.toString(level)) + " "; if (level > 0) UIOutput.make(row, "link-note", levelstr); UIOutput.make(row, "link-text", entry.title); index++; } if (canEditPage && entry != null && entry.pageId != null && sharedPages.contains(entry.pageId)) { UIOutput.make(row, "shared"); } // debug code for development. this will be removed at some point // UIOutput.make(row, "page2", // lessonsAccess.printPath(lessonsAccess.getPagePaths(entry.pageId))); // UIOutput.make(row, "page1", Boolean.toString(lessonsAccess.isPageAccessible(entry.pageId, // simplePageBean.getCurrentSiteId(), "c08d3ac9-c717-472a-ad91-7ce0b434f42f", // simplePageBean))); if (ServerConfigurationService.getBoolean("lessonbuilder.accessibilitydebug", false)) { if (entry != null && entry.pageId != null && lessonsAccess.isPageAccessible( entry.pageId, simplePageBean.getCurrentSiteId(), "c08d3ac9-c717-472a-ad91-7ce0b434f42f", null)) { UIOutput.make(row, "page1"); } if (entry != null && entry.pageId != null && lessonsAccess.isPageAccessible( entry.pageId, simplePageBean.getCurrentSiteId(), "c08d3ac9-c717-472a-ad91-7ce0b434f42f", simplePageBean)) { UIOutput.make(row, "page2"); } if (entry != null && entry.pageId != null && lessonsAccess.isItemAccessible( entry.itemId, simplePageBean.getCurrentSiteId(), "c08d3ac9-c717-472a-ad91-7ce0b434f42f", null)) { UIOutput.make(row, "item1"); } if (entry != null && entry.pageId != null && lessonsAccess.isItemAccessible( entry.itemId, simplePageBean.getCurrentSiteId(), "c08d3ac9-c717-472a-ad91-7ce0b434f42f", simplePageBean)) { UIOutput.make(row, "item2"); } } } if (!summaryPage) { UIInput.make(form, "item-id", "#{simplePageBean.itemId}"); if (itemId == -1 && !((GeneralViewParameters) viewparams).newTopLevel) { UIOutput.make(form, "hr"); UIOutput.make(form, "options"); UIBoundBoolean.make(form, "subpage-next", "#{simplePageBean.subpageNext}", false); UIBoundBoolean.make(form, "subpage-button", "#{simplePageBean.subpageButton}", false); } String returnView = ((GeneralViewParameters) viewparams).getReturnView(); if (returnView != null && returnView.equals("reorder")) { // return to Reorder, to add items from this page UICommand.make( form, "submit", messageLocator.getMessage("simplepage.chooser.select"), "#{simplePageBean.selectPage}"); } else if (((GeneralViewParameters) viewparams).newTopLevel) { UIInput.make( form, "addBefore", "#{simplePageBean.addBefore}", ((GeneralViewParameters) viewparams).getAddBefore()); UICommand.make( form, "submit", messageLocator.getMessage("simplepage.chooser.select"), "#{simplePageBean.addOldPage}"); } else { UIInput.make( form, "addBefore", "#{simplePageBean.addBefore}", ((GeneralViewParameters) viewparams).getAddBefore()); UICommand.make( form, "submit", messageLocator.getMessage("simplepage.chooser.select"), "#{simplePageBean.createSubpage}"); } UICommand.make( form, "cancel", messageLocator.getMessage("simplepage.cancel"), "#{simplePageBean.cancel}"); } else if (showDeleteButton) { UICommand.make( form, "submit", messageLocator.getMessage("simplepage.delete-selected"), "#{simplePageBean.deletePages}"); } }
public void findAllPages( SimplePageItem pageItem, List<PageEntry> entries, Map<Long, SimplePage> pageMap, Set<Long> topLevelPages, Set<Long> sharedPages, int level, boolean toplevel, boolean canEditPage) { // System.out.println("in findallpages " + pageItem.getName() + " " + toplevel); Long pageId = Long.valueOf(pageItem.getSakaiId()); if (pageId == 0L) return; try { if (pageItem.isPrerequisite() || simplePageBean.getItemGroups(pageItem, null, false) != null) somePagesHavePrerequisites = true; } catch (IdUnusedException exe) { // underlying item missing. should be impossible for a page return; } // implement hidden. if (!canEditPage) { SimplePage page = simplePageToolDao.getPage(pageId); if (page.isHidden()) return; if (page.getReleaseDate() != null && page.getReleaseDate().after(new Date())) return; if (toplevel) { if (page.getToolId() != null) { // getCurrentSite is cached, so it's reasonable to get it at this level Site site = simplePageBean.getCurrentSite(); SitePage sitePage = site.getPage(page.getToolId()); List<ToolConfiguration> tools = sitePage.getTools(); // If all the tools on a page require site.upd then only users with site.upd will see // the page in the site nav of Charon... not sure about the other Sakai portals floating // about boolean visible = false; for (ToolConfiguration placement : tools) { Properties roleConfig = placement.getPlacementConfig(); String roleList = roleConfig.getProperty("functions.require"); String visibility = roleConfig.getProperty("sakai-portal:visible"); // System.out.println("roles " + roleList + " visi " + visibility); // doesn't require site update, so visible if ((visibility == null || !visibility.equals("false")) && (roleList == null || roleList.indexOf(SITE_UPD) < 0)) { // only need one tool on the page to be visible visible = true; break; } } // not visible, ignore it if (!visible) return; } } } PageEntry entry = new PageEntry(); entry.pageId = pageId; entry.itemId = pageItem.getId(); entry.title = pageItem.getName(); entry.level = level; entry.toplevel = toplevel; // add entry entries.add(entry); // if page has already been done, don't do the subpages. Otherwise we can // get into infinite loops // already done if removed from map. // however for top level pages, expand them for their primary entry, // i.e. when toplevel is set. if (pageMap.get(pageId) == null || (topLevelPages.contains(pageId) && !toplevel)) { sharedPages.add(pageId); return; } // say done pageMap.remove(pageId); // now recursively do subpages List<SimplePageItem> items = simplePageToolDao.findItemsOnPage(pageId); List<SimplePageItem> nexts = new ArrayList<SimplePageItem>(); // subpages done in place for (SimplePageItem item : items) { if (item.getType() == SimplePageItem.PAGE) { Long pageNum = Long.valueOf(item.getSakaiId()); // ignore top-level pages. // show next pages (including top level pages) after all the subpages // so stick it on the delayed display list. if (item.getNextPage()) nexts.add(item); else { // System.out.println("call for subpage " + item.getName() + " " + false); findAllPages( item, entries, pageMap, topLevelPages, sharedPages, level + 1, false, canEditPage); } } } // nexts done afterwards for (SimplePageItem item : nexts) { if (item.getType() == SimplePageItem.PAGE) { // System.out.println("calling findallpage " + item.getName() + " " + false); findAllPages(item, entries, pageMap, topLevelPages, sharedPages, level, false, canEditPage); } } }