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

Java tutorial

Introduction

Here is the source code for org.sakaiproject.delegatedaccess.tool.pages.SearchAccessPage.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.Set;

import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
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.FormComponentLabel;
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.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.DefaultItemReuseStrategy;
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.AccessSearchResult;
import org.sakaiproject.delegatedaccess.model.HierarchyNodeSerialized;
import org.sakaiproject.delegatedaccess.model.ListOptionSerialized;
import org.sakaiproject.delegatedaccess.model.SelectOption;
import org.sakaiproject.delegatedaccess.util.AccessSearchResultComparator;
import org.sakaiproject.delegatedaccess.util.DelegatedAccessConstants;
import org.sakaiproject.user.api.User;

public class SearchAccessPage extends BasePage implements Serializable {

    public String selectedSearchType = "hierarchy";
    public static final String searchTypeHierarchy = "hierarchy";
    public static final String searchTypeEid = "eid";
    public String eid = "";
    public Map<String, List<SelectOption>> hierarchySelectOptions;
    public Map<String, SelectOption> nodeSelects;
    public List<String> nodeSelectOrder;
    private int orderBy = DelegatedAccessConstants.SEARCH_COMPARE_DEFAULT;
    private boolean orderAsc = true;
    private AccessSearchResultDataProvider provider;
    private DataView<AccessSearchResult> dataView;
    private int rowIndex = 0;
    private boolean firstLoad = true;
    private boolean includeLowerPerms = true;

    public SearchAccessPage() {
        main();
    }

    public SearchAccessPage(boolean searchHierarchy, String userEid) {
        selectedSearchType = searchHierarchy ? searchTypeHierarchy : searchTypeEid;
        this.eid = userEid;
        firstLoad = false;
        main();
    }

    private void main() {
        disableLink(searchAccessLink);

        final AbstractReadOnlyModel resultModel = new AbstractReadOnlyModel<String>() {

            @Override
            public String getObject() {
                if (firstLoad) {
                    return "";
                } else {
                    if (provider.getData().size() == 0) {
                        if (searchTypeEid.equals(selectedSearchType)) {
                            if (eid == null || "".equals(eid.trim())) {
                                return new StringResourceModel("noEidEntered", null).getObject();
                            } else {
                                User u = getUser();
                                if (u == null) {
                                    return new StringResourceModel("eidDoesNotExist", null).getObject();
                                } else {
                                    return new StringResourceModel("noResultsUser", null).getObject();
                                }
                            }
                        } else {
                            return new StringResourceModel("noResultsHierarchy", null).getObject();
                        }
                    } else {
                        return "";
                    }
                }
            }

        };
        add(new Label("resultInfo", resultModel) {
            @Override
            public boolean isVisible() {
                return !"".equals(resultModel.getObject());
            }
        });

        //create form
        final Form<?> form = new Form("form") {
            protected void onSubmit() {
                super.onSubmit();
                firstLoad = false;
                if (provider != null) {
                    provider.detachManually();
                }
            }
        };
        form.setOutputMarkupId(true);

        //search by label:
        form.add(new Label("searchByLabel", new StringResourceModel("searchByLabel", null)));

        //setup radio buttons for search type:
        final RadioGroup group = new RadioGroup("searchGroup",
                new PropertyModel<String>(this, "selectedSearchType"));

        final Radio hierarchyRadio = new Radio("searchByHierarchy", new Model<String>(searchTypeHierarchy));
        FormComponentLabel hierarchyLabel = new FormComponentLabel("searchByHierarchyLabel", hierarchyRadio);
        hierarchyLabel.add(
                new Label("searchByHierarchyLabelText", new StringResourceModel("searchByHierarchyLabel", null)));
        group.add(hierarchyRadio);
        group.add(hierarchyLabel);
        group.add(hierarchyRadio.add(new AjaxEventBehavior("onchange") {
            @Override
            protected void onEvent(AjaxRequestTarget arg0) {
                selectedSearchType = searchTypeHierarchy;
            }
        }));

        Radio eidRadio = new Radio("searchByEid", new Model<String>(searchTypeEid));
        FormComponentLabel eidRadioLabel = new FormComponentLabel("searchByEidLabel", eidRadio);
        eidRadioLabel.add(new Label("searchByEidLabelText", new StringResourceModel("searchByEidLabel", null)));
        group.add(eidRadio);
        group.add(eidRadioLabel);
        group.add(eidRadio.add(new AjaxEventBehavior("onchange") {
            @Override
            protected void onEvent(AjaxRequestTarget arg0) {
                selectedSearchType = searchTypeEid;
            }
        }));

        form.add(group);

        //input for hierarchy fields:
        WebMarkupContainer hierarchyDiv = new WebMarkupContainer("hierarchyFields") {
            @Override
            protected void onComponentTag(ComponentTag tag) {
                if (!selectedSearchType.equals(searchTypeHierarchy)) {
                    //set to hidden
                    tag.put("style", "display:none");
                }
            }
        };
        final Comparator<SelectOption> optionComparator = new SelectOptionComparator();
        if (hierarchySelectOptions == null || hierarchySelectOptions.size() == 0) {
            hierarchySelectOptions = new HashMap<String, List<SelectOption>>();
            HierarchyNodeSerialized rootNode = projectLogic.getRootNodeId();
            nodeSelects = new HashMap<String, SelectOption>();
            nodeSelectOrder = new ArrayList<String>();
            if (rootNode != null && rootNode.id != null && !"".equals(rootNode.id)) {
                Set<HierarchyNodeSerialized> nodes = projectLogic.getDirectNodes(rootNode.id);
                List<SelectOption> options = new ArrayList<SelectOption>();
                if (nodes != null) {
                    for (HierarchyNodeSerialized node : nodes) {
                        options.add(new SelectOption(node.description, node.id));
                    }
                }
                Collections.sort(options, optionComparator);
                hierarchySelectOptions.put(rootNode.id, options);

                //since nothing is selected, set the node selection to null
                nodeSelects.put(rootNode.id, null);
                //add the root node as the first selection            
                nodeSelectOrder.add(rootNode.id);
            }
        }
        final ChoiceRenderer choiceRenderer = new ChoiceRenderer("label", "value");
        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 itemNodeId = item.getModelObject().toString();
                final DropDownChoice choice = new DropDownChoice("hierarchyLevel", new NodeSelectModel(itemNodeId),
                        hierarchySelectOptions.get(itemNodeId), 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) {
                        List<String> newOrder = new ArrayList<String>();
                        for (String nodeId : nodeSelectOrder) {
                            newOrder.add(nodeId);
                            if (nodeId.equals(itemNodeId)) {
                                break;
                            }
                        }
                        if (choice.getModelObject() != null
                                && !"".equals(((SelectOption) choice.getModelObject()).getValue())) {
                            String value = ((SelectOption) choice.getModelObject()).getValue();
                            //check if options list exist for newly selected node
                            if (!hierarchySelectOptions.containsKey(value)) {
                                Set<HierarchyNodeSerialized> nodes = projectLogic.getDirectNodes(value);
                                List<SelectOption> options = new ArrayList<SelectOption>();
                                if (nodes != null) {
                                    for (HierarchyNodeSerialized node : nodes) {
                                        options.add(new SelectOption(node.description, node.id));
                                    }
                                    Collections.sort(options, optionComparator);
                                }
                                hierarchySelectOptions.put(value, options);
                            }
                            //check to see if there are any additional direct children, or if
                            //this is the last node
                            if (hierarchySelectOptions.containsKey(value)
                                    && hierarchySelectOptions.get(value).size() > 0) {
                                //update node select order
                                newOrder.add(value);
                            }
                        }
                        nodeSelectOrder = newOrder;
                        //refresh everything:
                        target.addComponent(form);
                    }
                });
                item.add(choice);
            }

        };
        hierarchyDiv.add(dropdowns);

        //include lower perms checkbox:
        CheckBox checkbox = new CheckBox("includeLowerPerms", new PropertyModel(this, "includeLowerPerms"));
        FormComponentLabel checkboxLabel = new FormComponentLabel("includeLowerPermsLabel", checkbox);
        checkboxLabel.add(
                new Label("includeLowerPermsLabelText", new StringResourceModel("includeLowerPermsLabel", null)));
        hierarchyDiv.add(checkboxLabel);
        hierarchyDiv.add(checkbox);

        form.add(hierarchyDiv);

        //input for eid fields:
        WebMarkupContainer eidDiv = new WebMarkupContainer("eidFields") {
            @Override
            protected void onComponentTag(ComponentTag tag) {
                if (!selectedSearchType.equals(searchTypeEid)) {
                    //set to hidden
                    tag.put("style", "display:none");
                }
            }
        };
        final PropertyModel<String> eidModel = new PropertyModel<String>(this, "eid");
        TextField<String> eidText = new TextField<String>("eid", eidModel);
        eidDiv.add(eidText);

        form.add(eidDiv);

        add(form);

        //Display Results:

        //Headers:
        Link<Void> userIdSort = new Link<Void>("userIdSortLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                changeOrder(DelegatedAccessConstants.SEARCH_COMPARE_EID);
            }

            @Override
            public boolean isVisible() {
                return provider.size() > 0 && searchTypeHierarchy.equals(selectedSearchType);
            }
        };
        add(userIdSort);
        Link<Void> nameSort = new Link<Void>("nameSortLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                changeOrder(DelegatedAccessConstants.SEARCH_COMPARE_SORT_NAME);
            }

            @Override
            public boolean isVisible() {
                return provider.size() > 0 && searchTypeHierarchy.equals(selectedSearchType);
            }
        };
        add(nameSort);
        Link<Void> typeSort = new Link<Void>("typeSortLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                changeOrder(DelegatedAccessConstants.SEARCH_COMPARE_TYPE);
            }

            @Override
            public boolean isVisible() {
                return provider.size() > 0;
            }
        };
        add(typeSort);
        Link<Void> levelSort = new Link<Void>("levelSortLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                changeOrder(DelegatedAccessConstants.SEARCH_COMPARE_LEVEL);
            }

            @Override
            public boolean isVisible() {
                return provider.size() > 0;
            }
        };
        add(levelSort);
        Link<Void> accessSort = new Link<Void>("accessSortLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                changeOrder(DelegatedAccessConstants.SEARCH_COMPARE_ACCESS);
            }
        };
        add(accessSort);
        Label restrictedToolsHeader = new Label("restrictedToolsHeader",
                new StringResourceModel("restrictedToolsHeader", null)) {
            @Override
            public boolean isVisible() {
                return provider.size() > 0;
            }
        };
        add(restrictedToolsHeader);
        Label hierarchyHeader = new Label("hierarchyHeader", new StringResourceModel("hierarchyHeader", null)) {
            @Override
            public boolean isVisible() {
                return provider.size() > 0;
            }
        };
        add(hierarchyHeader);

        //Display user (if available)
        final AbstractReadOnlyModel userModel = new AbstractReadOnlyModel() {
            @Override
            public Object getObject() {
                if (searchTypeEid.equals(selectedSearchType) && eid != null && !"".equals(eid.trim())) {
                    User u = getUser();
                    if (u != null) {
                        return u.getDisplayName();
                    }
                }
                return "";
            }
        };
        Label userName = new Label("userName", userModel) {
            @Override
            public boolean isVisible() {
                return searchTypeEid.equals(selectedSearchType) && eid != null && !"".equals(eid)
                        && !"".equals(userModel.getObject());
            }
        };
        add(userName);

        add(new Link("editUserLink") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                User u = getUser();
                if (u != null) {
                    setResponsePage(new UserEditPage(u.getId(), u.getDisplayName()));
                }
            }
        });

        Link removeAllPermsLink = new Link("removeAllPerms") {
            private static final long serialVersionUID = 1L;

            public void onClick() {
                User u = getUser();
                if (u != null) {
                    projectLogic.removeAllPermsForUser(u.getId());
                    provider.detachManually();
                }
            }

            @Override
            public boolean isVisible() {
                return sakaiProxy.isSuperUser();
            }
        };
        String confirm = new StringResourceModel("confirmRemoveAll", null).getObject();
        removeAllPermsLink.add(new SimpleAttributeModifier("onclick", "return confirm('" + confirm + "');"));
        add(removeAllPermsLink);

        //tool id=>title map:
        final Map<String, String> toolTitleMap = new HashMap<String, String>();
        final List<ListOptionSerialized> blankRestrictedTools = projectLogic.getEntireToolsList();
        for (ListOptionSerialized opt : blankRestrictedTools) {
            toolTitleMap.put(opt.getId(), opt.getName());
        }

        //Data
        String[] tmpHierarchy = sakaiProxy
                .getServerConfigurationStrings(DelegatedAccessConstants.HIERARCHY_SITE_PROPERTIES);
        if (tmpHierarchy == null || tmpHierarchy.length == 0) {
            tmpHierarchy = DelegatedAccessConstants.DEFAULT_HIERARCHY;
        }
        final String[] hierarchy = new String[tmpHierarchy.length + 1];
        //include the root as part of the hierarchy:
        hierarchy[0] = sakaiProxy.getRootName();
        for (int i = 1; i < hierarchy.length; i++) {
            hierarchy[i] = tmpHierarchy[i - 1];
        }
        provider = new AccessSearchResultDataProvider();
        dataView = new DataView<AccessSearchResult>("searchResult", provider) {
            @Override
            public void populateItem(final Item item) {
                final AccessSearchResult searchResult = (AccessSearchResult) item.getModelObject();
                item.add(new Label("userId", searchResult.getEid()) {
                    @Override
                    public boolean isVisible() {
                        return searchTypeHierarchy.equals(selectedSearchType);
                    }
                });
                item.add(new Label("name", searchResult.getSortName()));
                item.add(new Label("type", new StringResourceModel("accessType" + searchResult.getType(), null)));
                String level = "";
                if (hierarchy != null && searchResult.getLevel() < hierarchy.length) {
                    level = hierarchy[searchResult.getLevel()];
                } else {
                    level = new StringResourceModel("site", null).getObject();
                }
                item.add(new Label("level", level));
                AbstractReadOnlyModel<String> accessModel = new AbstractReadOnlyModel<String>() {
                    @Override
                    public String getObject() {
                        String returnVal = "";
                        if (searchResult.getAccess() != null && searchResult.getAccess().length == 2) {
                            returnVal = searchResult.getAccess()[0] + ":" + searchResult.getAccess()[1];
                            if (":".equals(returnVal)) {
                                returnVal = "";
                            }
                        }
                        return returnVal;
                    }
                };
                item.add(new Label("access", accessModel));
                item.add(new ListView<String>("restrictedTools", searchResult.getRestrictedTools()) {

                    @Override
                    protected void populateItem(ListItem<String> arg0) {
                        String toolTitle = arg0.getDefaultModelObject().toString();
                        if (toolTitleMap.containsKey(toolTitle)) {
                            toolTitle = toolTitleMap.get(toolTitle);
                        }
                        arg0.add(new Label("restrictedTool", toolTitle));
                    }
                });
                item.add(new ListView<String>("hierarchy", searchResult.getHierarchyNodes()) {

                    @Override
                    protected void populateItem(ListItem<String> arg0) {
                        String hierarchyStr = "|-";
                        for (String hierarchyLevel : searchResult.getHierarchyNodes()) {
                            if (hierarchyLevel.equals(arg0.getDefaultModelObject())) {
                                break;
                            }
                            hierarchyStr += "-";
                        }
                        hierarchyStr += arg0.getDefaultModelObject();
                        arg0.add(new Label("hierarchyTitle", hierarchyStr));
                    }

                });
                Link<Void> viewLink = new Link("view") {
                    private static final long serialVersionUID = 1L;

                    public void onClick() {
                        setResponsePage(new SearchAccessPage(false, searchResult.getEid()));
                    }

                    @Override
                    public boolean isVisible() {
                        return searchTypeHierarchy.equals(selectedSearchType);
                    }
                };
                item.add(viewLink);
                Link<Void> userIdLink = new Link("edit") {
                    private static final long serialVersionUID = 1L;

                    public void onClick() {
                        setResponsePage(new UserEditPage(searchResult.getId(), searchResult.getDisplayName()));
                    }

                    @Override
                    public boolean isVisible() {
                        return searchTypeHierarchy.equals(selectedSearchType);
                    }
                };
                item.add(userIdLink);
                Link<Void> removeLink = new Link("remove") {
                    @Override
                    public void onClick() {
                        projectLogic.removeAccess(searchResult.getNodeId(), searchResult.getId(),
                                searchResult.getType());
                        provider.detachManually();
                    }

                    @Override
                    public boolean isVisible() {
                        return searchResult.isCanEdit();
                    }
                };
                String confirm = new StringResourceModel("confirmRemove", null).getObject();
                removeLink.add(new SimpleAttributeModifier("onclick", "return confirm('" + confirm + "');"));
                item.add(removeLink);

                //add css class
                if (rowIndex == 100) {
                    rowIndex = 0;
                }
                item.add(new AttributeAppender("class", true, new Model<String>(rowIndex % 2 == 0 ? "even" : "odd"),
                        ";"));
                rowIndex++;
            }

            @Override
            public boolean isVisible() {
                return provider.size() > 0;
            }

            @Override
            protected void onComponentTag(ComponentTag arg0) {

            }

        };
        dataView.setOutputMarkupId(true);
        dataView.setItemReuseStrategy(new DefaultItemReuseStrategy());
        dataView.setItemsPerPage(DelegatedAccessConstants.SEARCH_RESULTS_PAGE_SIZE);
        add(dataView);
        //Navigation
        //add a pager to our table, only visible if we have more than SEARCH_RESULTS_PAGE_SIZE items
        add(new PagingNavigator("navigatorTop", dataView) {

            @Override
            public boolean isVisible() {
                if (provider.size() > DelegatedAccessConstants.SEARCH_RESULTS_PAGE_SIZE) {
                    return true;
                }
                return false;
            }

            @Override
            public void onBeforeRender() {
                super.onBeforeRender();

                //clear the feedback panel messages
                clearFeedback(feedbackPanel);
            }
        });
        add(new PagingNavigator("navigatorBottom", dataView) {

            @Override
            public boolean isVisible() {
                if (provider.size() > DelegatedAccessConstants.SEARCH_RESULTS_PAGE_SIZE) {
                    return true;
                }
                return false;
            }

            @Override
            public void onBeforeRender() {
                super.onBeforeRender();

                //clear the feedback panel messages
                clearFeedback(feedbackPanel);
            }
        });

    }

    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 nodeSelects.get(nodeId);
        }

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

    private class SelectOptionComparator implements Comparator<SelectOption>, Serializable {

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

    /**
     * changes order by desc or asc
     * 
     * @param sortByColumn
     */
    private void changeOrder(int sortByColumn) {
        if (sortByColumn == orderBy) {
            orderAsc = !orderAsc;
        } else {
            orderBy = sortByColumn;
        }
    }

    private class AccessSearchResultDataProvider implements IDataProvider<AccessSearchResult> {

        private boolean lastOrderAsc = true;
        private int lastOrderBy = DelegatedAccessConstants.SEARCH_COMPARE_DEFAULT;

        private List<AccessSearchResult> list;

        public void detach() {

        }

        public void detachManually() {
            this.list = null;
        }

        public Iterator<? extends AccessSearchResult> iterator(int first, int count) {
            return getData().subList(first, first + count).iterator();
        }

        public IModel<AccessSearchResult> model(final AccessSearchResult object) {
            return new AbstractReadOnlyModel<AccessSearchResult>() {
                private static final long serialVersionUID = 1L;

                @Override
                public AccessSearchResult getObject() {
                    return object;
                }
            };
        }

        public int size() {
            return getData().size();
        }

        private List<AccessSearchResult> getData() {
            if (firstLoad) {
                return new ArrayList<AccessSearchResult>();
            }
            if (list == null) {
                list = new ArrayList<AccessSearchResult>();
                if (eid != null && !"".equals(eid.trim()) && selectedSearchType.equals(searchTypeEid)) {
                    User u = getUser();
                    if (u != null) {
                        list = projectLogic.getAccessForUser(u);
                    }
                } else if (selectedSearchType.equals(searchTypeHierarchy) && nodeSelectOrder != null
                        && nodeSelectOrder.size() > 0) {
                    list = projectLogic.getAccessAtLevel(nodeSelectOrder, includeLowerPerms);
                }
            } else if (lastOrderAsc != orderAsc || lastOrderBy != orderBy) {
                sortList();
            }

            return list;
        }

        private void sortList() {
            Collections.sort(list, new AccessSearchResultComparator(orderBy));
            if (!orderAsc) {
                Collections.reverse(list);
            }
            this.lastOrderAsc = orderAsc;
            this.lastOrderBy = orderBy;
        }

    }

    public User getUser() {
        User u = sakaiProxy.getUserByEid(eid);
        if (u == null) {
            //couldn't find the user by eid, try internal id
            u = sakaiProxy.getUser(eid);
        }
        return u;
    }
}