package org.sakaiproject.delegatedaccess.tool.pages; import java.util.ArrayList; import java.util.List; import javax.swing.tree.DefaultMutableTreeNode; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.tree.AbstractTree; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.StringResourceModel; import org.sakaiproject.delegatedaccess.model.ListOptionSerialized; import org.sakaiproject.delegatedaccess.model.NodeModel; /** * BaseTreePage is a base page for all pages that want to use AbstractTree. It extends BasePage as well. * * @author Bryan Holladay (holladay@longsight.com) */ public abstract class BaseTreePage extends BasePage { /** * Returns the tree on this pages. This is used to collapse, expand, ect * * @return Tree instance on this page */ protected abstract AbstractTree getTree(); /** * This saves the state of the tree. It goes through the entire structure and saves the access and role information * for each node. It will remove and add all information. * * @param userId * @param defaultRole pass this in if there is a default Role, if null, it will be ignored */ protected void updateNodeAccess(String userId, String[] defaultRole){ if(getTree() != null){ DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) getTree().getModelObject().getRoot(); if(rootNode != null){ updateNodeAccessHelper(rootNode, userId, defaultRole); } projectLogic.syncMyworkspaceToolForUser(userId); } } /** * This is a helper function for updateNodeAccess * * @param node * @param userId * @param defaultRole */ private void updateNodeAccessHelper(DefaultMutableTreeNode node, String userId, String[] defaultRole){ if(node.getUserObject() != null){ NodeModel nodeModel = (NodeModel) node.getUserObject(); if(defaultRole != null && defaultRole.length == 2){ nodeModel.setRealm(defaultRole[0]); nodeModel.setRole(defaultRole[1]); } if(nodeModel.isModified()){ //since this is the DA UI, we need to set instructorEdit to false ((NodeModel) node.getUserObject()).setInstructorEdited(false); projectLogic.updateNodePermissionsForUser(node, userId); //now reset the node's "original" values to ensure the next save will check against //the newly saved settings nodeModel.setOriginals(); } //check the rest of the children: for(int i = 0; i < node.getChildCount(); i++){ updateNodeAccessHelper((DefaultMutableTreeNode)node.getChildAt(i), userId, defaultRole); } } } /** * This collapses all empty folders in the tree. This helps the user know that they need to click on the folder * in order to populate the children nodes. (used when the structure is being populated on the fly w/ajax and the * folders haven't been populated yet) */ protected void collapseEmptyFolders(){ collapseEmptyFoldersHelper((DefaultMutableTreeNode) getTree().getModelObject().getRoot()); } /** * Helper function for collapseEmptyFoldersHelper * @param node */ protected void collapseEmptyFoldersHelper(DefaultMutableTreeNode node){ if(node != null){ if(!node.isLeaf() && node.getChildCount() == 0){ //this is a node that isn't a leaf but hasn't had the children updated, make it collapse getTree().getTreeState().collapseNode(node); } for(int i = 0; i < node.getChildCount(); i++){ collapseEmptyFoldersHelper((DefaultMutableTreeNode)node.getChildAt(i)); } } } protected AjaxLink getExpandCollapseLink(){ //Expand Collapse Link: final Label expandCollapse = new Label("expandCollapse", new StringResourceModel("exapndNodes", null)); expandCollapse.setOutputMarkupId(true); AjaxLink expandLink = new AjaxLink("expandAll") { boolean expand = true; @Override public void onClick(AjaxRequestTarget target) { if(expand){ getTree().getTreeState().expandAll(); expandCollapse.setDefaultModel(new StringResourceModel("collapseNodes", null)); collapseEmptyFolders(); }else{ getTree().getTreeState().collapseAll(); expandCollapse.setDefaultModel(new StringResourceModel("exapndNodes", null)); } target.addComponent(expandCollapse); getTree().updateTree(target); expand = !expand; } @Override public boolean isVisible() { return getTree().getDefaultModelObject() != null; } }; expandLink.add(expandCollapse); return expandLink; } private void createInheritedSpan(){ WebMarkupContainer inheritedSpan = new WebMarkupContainer("inheritedSpan"); inheritedSpan.setOutputMarkupId(true); final String inheritedSpanId = inheritedSpan.getMarkupId(); add(inheritedSpan); AbstractReadOnlyModel<List<? extends ListOptionSerialized>> inheritedRestrictedToolsModel = new AbstractReadOnlyModel<List<? extends ListOptionSerialized>>(){ private static final long serialVersionUID = 1L; @Override public List<? extends ListOptionSerialized> getObject() { return new ArrayList<ListOptionSerialized>(); } }; final ListView<ListOptionSerialized> inheritedListView = new ListView<ListOptionSerialized>("inheritedRestrictedTools",inheritedRestrictedToolsModel){ private static final long serialVersionUID = 1L; @Override protected void populateItem(ListItem<ListOptionSerialized> item) { ListOptionSerialized tool = (ListOptionSerialized) item.getModelObject(); Label name = new Label("name", tool.getName()); item.add(name); } }; inheritedListView.setOutputMarkupId(true); inheritedSpan.add(inheritedListView); AjaxLink<Void> closeInheritedSpanLink = new AjaxLink("closeInheritedSpanLink"){ @Override public void onClick(AjaxRequestTarget arg0) { } }; inheritedSpan.add(closeInheritedSpanLink); Label inheritedNodeTitle = new Label("inheritedNodeTitle", ""); inheritedSpan.add(inheritedNodeTitle); Label noInheritedToolsLabel = new Label("noToolsInherited", new StringResourceModel("inheritedNothing", null)); inheritedSpan.add(noInheritedToolsLabel); } }