org.sakaiproject.delegatedaccess.tool.pages.UserPage.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.delegatedaccess.tool.pages.UserPage.java

Source

/*
* The Trustees of Columbia University in the City of New York
* licenses this file to you under the Educational Community License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.sakaiproject.delegatedaccess.tool.pages;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.tree.AbstractTree;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.markup.html.tree.LinkTree;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.sakaiproject.delegatedaccess.model.HierarchyNodeSerialized;
import org.sakaiproject.delegatedaccess.model.ListOptionSerialized;
import org.sakaiproject.delegatedaccess.model.NodeModel;
import org.sakaiproject.delegatedaccess.model.SelectOption;
import org.sakaiproject.delegatedaccess.util.DelegatedAccessConstants;
import org.sakaiproject.site.api.Site;

/**
 * Creates the landing page for a user to show them all their access and links to go to the sites
 * 
 * @author Bryan Holladay (holladay@longsight.com)
 *
 */
public class UserPage extends BaseTreePage {

    private BaseTree tree;
    boolean expand = true;
    private String search = "";
    private String instructorField = "";
    private SelectOption termField;
    private TreeModel treeModel = null;
    private String userId;
    private String selectedInstructorOption = DelegatedAccessConstants.ADVANCED_SEARCH_INSTRUCTOR_TYPE_INSTRUCTOR;
    public Map<String, List<SelectOption>> hierarchySelectOptions;
    public Map<String, SelectOption> hierarchySearchMap;
    public List<String> nodeSelectOrder;
    public Map<String, String> hierarchyLabels = new HashMap<String, String>();

    protected AbstractTree getTree() {
        return tree;
    }

    public UserPage() {
        disableLink(accessPageLink);

        //this is the home page so set user as current user
        if (isShoppingPeriodTool()) {
            userId = DelegatedAccessConstants.SHOPPING_PERIOD_USER;
        } else {
            //check if they should even have acces to this page:
            if (!hasDelegatedAccess) {
                if (hasShoppingAdmin) {
                    setResponsePage(new ShoppingEditPage());
                } else if (hasAccessAdmin) {
                    setResponsePage(new SearchUsersPage());
                }
            }

            userId = sakaiProxy.getCurrentUserId();
        }

        //Title
        Label title = new Label("title");
        if (isShoppingPeriodTool()) {
            title.setDefaultModel(new StringResourceModel("shoppingTitle", null));
        } else {
            title.setDefaultModel(new StringResourceModel("delegatedAccessTitle", null));
        }
        add(title);

        //Description
        Label description = new Label("description");
        if (isShoppingPeriodTool()) {
            description.setDefaultModel(new StringResourceModel("shoppingInstruction", null));
        } else {
            description.setDefaultModel(new StringResourceModel("delegatedAccessInstructions", null));
        }
        add(description);

        setTreeModel(userId, false);

        final List<ListOptionSerialized> blankRestrictedTools = projectLogic.getEntireToolsList();
        if (treeModel != null) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getRoot();
            if (((NodeModel) node.getUserObject()).isDirectAccess()) {
                projectLogic.addChildrenNodes(node, userId, blankRestrictedTools, true, null, false,
                        isShoppingPeriodTool());
            }
        }
        //a null model means the user doesn't have any associations
        tree = new LinkTree("tree", treeModel) {
            @Override
            public boolean isVisible() {
                return treeModel != null && ((!sakaiProxy.getDisableUserTreeView() && !isShoppingPeriodTool())
                        || (!sakaiProxy.getDisableShoppingTreeView() && isShoppingPeriodTool()));
            }

            protected void onNodeLinkClicked(Object node, BaseTree tree, AjaxRequestTarget target) {
                if (tree.isLeaf(node)) {
                    //The user has clicked a leaf and chances are its a site.
                    //all sites are leafs, but there may be non sites as leafs
                    NodeModel nodeModel = (NodeModel) ((DefaultMutableTreeNode) node).getUserObject();
                    if (nodeModel.isSiteNode()) {
                        Site site = sakaiProxy.getSiteByRef(nodeModel.getNode().title);
                        if (site != null) {
                            //redirect the user to the site
                            target.appendJavascript("popupWindow('" + site.getUrl() + "', '"
                                    + new StringResourceModel("popupBlockWarning", null).getObject() + "')");
                        }
                    }
                } else {
                    boolean anyAdded = false;
                    if (!tree.getTreeState().isNodeExpanded(node)
                            && !((NodeModel) ((DefaultMutableTreeNode) node).getUserObject())
                                    .isAddedDirectChildrenFlag()) {
                        anyAdded = projectLogic.addChildrenNodes(node, userId, blankRestrictedTools, true, null,
                                false, isShoppingPeriodTool());
                        ((NodeModel) ((DefaultMutableTreeNode) node).getUserObject())
                                .setAddedDirectChildrenFlag(true);
                    }
                    if (anyAdded) {
                        collapseEmptyFoldersHelper((DefaultMutableTreeNode) node);
                    }

                    if (!tree.getTreeState().isNodeExpanded(node) || anyAdded) {
                        tree.getTreeState().expandNode(node);
                    } else {
                        tree.getTreeState().collapseNode(node);
                    }
                }
            };

            protected void onJunctionLinkClicked(AjaxRequestTarget target, Object node) {
                //the nodes are generated on the fly with ajax.  This will add any child nodes that 
                //are missing in the tree.  Expanding and collapsing will refresh the tree node
                if (tree.getTreeState().isNodeExpanded(node)
                        && !((NodeModel) ((DefaultMutableTreeNode) node).getUserObject())
                                .isAddedDirectChildrenFlag()) {
                    boolean anyAdded = projectLogic.addChildrenNodes(node, userId, blankRestrictedTools, true, null,
                            false, isShoppingPeriodTool());
                    ((NodeModel) ((DefaultMutableTreeNode) node).getUserObject()).setAddedDirectChildrenFlag(true);
                    if (anyAdded) {
                        collapseEmptyFoldersHelper((DefaultMutableTreeNode) node);
                    }
                }
            }

            @Override
            protected boolean isForceRebuildOnSelectionChange() {
                return false;
            };
        };
        tree.setRootLess(true);
        add(tree);
        tree.getTreeState().collapseAll();

        //Access Warning:
        Label noAccessLabel = new Label("noAccess") {
            @Override
            public boolean isVisible() {
                return treeModel == null && (!isShoppingPeriodTool() && !sakaiProxy.getDisableUserTreeView());
            }
        };
        if (isShoppingPeriodTool()) {
            noAccessLabel.setDefaultModel(new StringResourceModel("noShoppingSites", null));

        } else {
            noAccessLabel.setDefaultModel(new StringResourceModel("noDelegatedAccess", null));
        }
        add(noAccessLabel);

        //no hierarchy setup:
        add(new Label("noHierarchy", new StringResourceModel("noHierarchy", null)) {
            public boolean isVisible() {
                return treeModel == null && sakaiProxy.isSuperUser() && "".equals(projectLogic.getRootNodeId().id);
            }
        });

        //Create Search Form:
        final PropertyModel<String> messageModel = new PropertyModel<String>(this, "search");
        final PropertyModel<String> instructorFieldModel = new PropertyModel<String>(this, "instructorField");
        final PropertyModel<SelectOption> termFieldModel = new PropertyModel<SelectOption>(this, "termField");
        final Form<?> form = new Form("form") {
            @Override
            protected void onSubmit() {
                Map<String, Object> advancedOptions = new HashMap<String, Object>();
                if (termField != null && !"".equals(termField.getValue())) {
                    advancedOptions.put(DelegatedAccessConstants.ADVANCED_SEARCH_TERM, termField.getValue());
                }
                if (instructorField != null && !"".equals(instructorField)) {
                    advancedOptions.put(DelegatedAccessConstants.ADVANCED_SEARCH_INSTRUCTOR, instructorField);
                    advancedOptions.put(DelegatedAccessConstants.ADVANCED_SEARCH_INSTRUCTOR_TYPE,
                            selectedInstructorOption);
                }
                Map<String, String> hierarchySearchFields = new HashMap<String, String>();
                for (Entry<String, SelectOption> entry : hierarchySearchMap.entrySet()) {
                    if (entry.getValue() != null && !"".equals(entry.getValue().getValue().trim())) {
                        hierarchySearchFields.put(entry.getKey(), entry.getValue().getValue().trim());
                    }
                }
                if (hierarchySearchFields.size() > 0) {
                    advancedOptions.put(DelegatedAccessConstants.ADVANCED_SEARCH_HIERARCHY_FIELDS,
                            hierarchySearchFields);
                }
                //need to set the tree model so that is is the full model
                setResponsePage(new UserPageSiteSearch(search, advancedOptions, false, false));
            }

            @Override
            public boolean isVisible() {
                return treeModel != null || isShoppingPeriodTool()
                        || (!isShoppingPeriodTool() && sakaiProxy.getDisableUserTreeView());
            }
        };
        AbstractReadOnlyModel<String> instructorFieldLabelModel = new AbstractReadOnlyModel<String>() {

            @Override
            public String getObject() {
                if (isShoppingPeriodTool()) {
                    return new StringResourceModel("instructor", null).getObject() + ":";
                } else {
                    return new StringResourceModel("user", null).getObject() + ":";
                }
            }
        };
        form.add(new Label("instructorFieldLabel", instructorFieldLabelModel));
        form.add(new TextField<String>("search", messageModel));
        form.add(new TextField<String>("instructorField", instructorFieldModel));
        //Instructor Options:
        RadioGroup group = new RadioGroup("instructorOptionsGroup",
                new PropertyModel<String>(this, "selectedInstructorOption")) {
            @Override
            public boolean isVisible() {
                //only show if its not shopping period
                return !isShoppingPeriodTool();
            }
        };
        group.add(new Radio("instructorOption",
                Model.of(DelegatedAccessConstants.ADVANCED_SEARCH_INSTRUCTOR_TYPE_INSTRUCTOR)));
        group.add(new Radio("memberOption",
                Model.of(DelegatedAccessConstants.ADVANCED_SEARCH_INSTRUCTOR_TYPE_MEMBER)));
        form.add(group);
        List<SelectOption> termOptions = new ArrayList<SelectOption>();
        for (String[] entry : sakaiProxy.getTerms()) {
            termOptions.add(new SelectOption(entry[1], entry[0]));
        }
        final ChoiceRenderer choiceRenderer = new ChoiceRenderer("label", "value");
        DropDownChoice termFieldDropDown = new DropDownChoice("termField", termFieldModel, termOptions,
                choiceRenderer) {
            @Override
            public boolean isVisible() {
                return !sakaiProxy.isSearchHideTerm();
            }
        };
        //keeps the null option (choose one) after a user selects an option
        termFieldDropDown.setNullValid(true);
        form.add(termFieldDropDown);

        //hierarchy dropdown:
        String[] hierarchyTmp = sakaiProxy
                .getServerConfigurationStrings(DelegatedAccessConstants.HIERARCHY_SITE_PROPERTIES);
        if (hierarchyTmp == null || hierarchyTmp.length == 0) {
            hierarchyTmp = DelegatedAccessConstants.DEFAULT_HIERARCHY;
        }
        final String[] hierarchy = hierarchyTmp;
        WebMarkupContainer hierarchyDiv = new WebMarkupContainer("hierarchyFields");
        final Comparator<SelectOption> optionComparator = new SelectOptionComparator();
        if (hierarchySelectOptions == null || hierarchySelectOptions.size() == 0) {
            nodeSelectOrder = new ArrayList<String>();
            hierarchySearchMap = new HashMap<String, SelectOption>();
            for (String s : hierarchy) {
                hierarchySearchMap.put(s, null);
                nodeSelectOrder.add(s);
                hierarchyLabels.put(s, sakaiProxy.getHierarchySearchLabel(s));
            }
            Map<String, String> searchParams = new HashMap<String, String>();
            for (Entry<String, SelectOption> entry : hierarchySearchMap.entrySet()) {
                searchParams.put(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().getValue());
            }
            Map<String, Set<String>> hierarchyOptions = projectLogic.getHierarchySearchOptions(searchParams);
            hierarchySelectOptions = new HashMap<String, List<SelectOption>>();
            for (Entry<String, Set<String>> entry : hierarchyOptions.entrySet()) {
                List<SelectOption> options = new ArrayList<SelectOption>();
                for (String s : entry.getValue()) {
                    options.add(new SelectOption(s, s));
                }
                Collections.sort(options, optionComparator);
                hierarchySelectOptions.put(entry.getKey(), options);
            }
        }
        DataView dropdowns = new DataView("hierarchyDropdowns", new IDataProvider<String>() {

            @Override
            public void detach() {

            }

            @Override
            public Iterator<? extends String> iterator(int first, int count) {
                return nodeSelectOrder.subList(first, first + count).iterator();
            }

            @Override
            public IModel<String> model(final String arg0) {
                return new AbstractReadOnlyModel<String>() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public String getObject() {
                        return arg0;
                    }
                };
            }

            @Override
            public int size() {
                return nodeSelectOrder.size();
            }

        }) {

            @Override
            protected void populateItem(Item item) {
                final String hierarchyLevel = item.getModelObject().toString();
                item.add(new Label("hierarchyLabel",
                        hierarchyLabels.containsKey(hierarchyLevel) ? hierarchyLabels.get(hierarchyLevel)
                                : hierarchyLevel));
                final DropDownChoice choice = new DropDownChoice("hierarchyLevel",
                        new NodeSelectModel(hierarchyLevel), hierarchySelectOptions.get(hierarchyLevel),
                        choiceRenderer);
                //keeps the null option (choose one) after a user selects an option
                choice.setNullValid(true);
                choice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
                    protected void onUpdate(AjaxRequestTarget target) {
                        Map<String, String> searchParams = new HashMap<String, String>();
                        for (Entry<String, SelectOption> entry : hierarchySearchMap.entrySet()) {
                            searchParams.put(entry.getKey(),
                                    entry.getValue() == null ? "" : entry.getValue().getValue());
                        }
                        Map<String, Set<String>> hierarchyOptions = projectLogic
                                .getHierarchySearchOptions(searchParams);
                        hierarchySelectOptions = new HashMap<String, List<SelectOption>>();
                        for (Entry<String, Set<String>> entry : hierarchyOptions.entrySet()) {
                            List<SelectOption> options = new ArrayList<SelectOption>();
                            for (String s : entry.getValue()) {
                                options.add(new SelectOption(s, s));
                            }
                            Collections.sort(options, optionComparator);
                            hierarchySelectOptions.put(entry.getKey(), options);
                        }

                        //refresh everything:
                        target.addComponent(form);
                    }
                });
                item.add(choice);
            }

        };
        hierarchyDiv.add(dropdowns);
        form.add(hierarchyDiv);

        form.add(new WebMarkupContainer("searchHeader"));
        form.add(new Button("submitButton"));

        add(form);

    }

    private void setTreeModel(String userId, boolean cascade) {
        if (isShoppingPeriodTool()) {
            if (sakaiProxy.getDisableShoppingTreeView()) {
                treeModel = null;
            } else {
                treeModel = projectLogic.createAccessTreeModelForUser(DelegatedAccessConstants.SHOPPING_PERIOD_USER,
                        false, cascade);
                if (treeModel != null && ((DefaultMutableTreeNode) treeModel.getRoot()).getChildCount() == 0) {
                    treeModel = null;
                }
            }
        } else {
            if (sakaiProxy.getDisableUserTreeView()) {
                treeModel = null;
            } else {
                treeModel = projectLogic.createAccessTreeModelForUser(userId, false, cascade);
            }
        }
    }

    private class SelectOptionComparator implements Comparator<SelectOption>, Serializable {

        @Override
        public int compare(SelectOption o1, SelectOption o2) {
            return o1.getLabel().compareTo(o2.getLabel());
        }
    }

    private class NodeSelectModel implements IModel<SelectOption>, Serializable {

        private String nodeId;

        public NodeSelectModel(String nodeId) {
            this.nodeId = nodeId;
        }

        @Override
        public void detach() {

        }

        @Override
        public SelectOption getObject() {
            return hierarchySearchMap.get(nodeId);
        }

        @Override
        public void setObject(SelectOption arg0) {
            hierarchySearchMap.put(nodeId, arg0);
        }
    }
}