org.unitime.timetable.gwt.server.MenuServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.unitime.timetable.gwt.server.MenuServlet.java

Source

/*
 * UniTime 3.2 (University Timetabling Application)
 * Copyright (C) 2010, UniTime LLC, and individual contributors
 * as indicated by the @authors tag.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
*/
package org.unitime.timetable.gwt.server;

import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import javax.servlet.ServletException;

import net.sf.cpsolver.ifs.util.DataProperties;

import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.unitime.commons.Debug;
import org.unitime.commons.hibernate.util.HibernateUtil;
import org.unitime.commons.web.Web;
import org.unitime.localization.impl.Localization;
import org.unitime.localization.messages.PageNames;
import org.unitime.timetable.ApplicationProperties;
import org.unitime.timetable.action.PersonalizedExamReportAction;
import org.unitime.timetable.form.ListSolutionsForm;
import org.unitime.timetable.gwt.services.MenuService;
import org.unitime.timetable.gwt.shared.MenuException;
import org.unitime.timetable.gwt.shared.MenuInterface;
import org.unitime.timetable.model.Department;
import org.unitime.timetable.model.Exam;
import org.unitime.timetable.model.Roles;
import org.unitime.timetable.model.SavedHQL;
import org.unitime.timetable.model.Session;
import org.unitime.timetable.model.SolverGroup;
import org.unitime.timetable.model.TimetableManager;
import org.unitime.timetable.model.UserData;
import org.unitime.timetable.model.dao.SessionDAO;
import org.unitime.timetable.model.dao.SolverGroupDAO;
import org.unitime.timetable.model.dao.StudentDAO;
import org.unitime.timetable.onlinesectioning.OnlineSectioningService;
import org.unitime.timetable.security.SessionContext;
import org.unitime.timetable.security.UserContext;
import org.unitime.timetable.security.rights.Right;
import org.unitime.timetable.solver.SolverProxy;
import org.unitime.timetable.solver.exam.ExamSolverProxy;
import org.unitime.timetable.solver.service.SolverService;
import org.unitime.timetable.solver.studentsct.StudentSolverProxy;
import org.unitime.timetable.util.Constants;
import org.unitime.timetable.util.RoomAvailability;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;

/**
 * @author Tomas Muller
 */
@Service("menu.gwt")
public class MenuServlet implements MenuService {
    private static Logger sLog = Logger.getLogger(MenuServlet.class);
    private static Element iRoot = null;
    private static PageNames sPageNames = Localization.create(PageNames.class);

    public MenuServlet() {
        try {
            String menu = ApplicationProperties.getProperty("unitime.menu", "menu.xml");
            Document document = null;
            URL menuUrl = ApplicationProperties.class.getClassLoader().getResource(menu);
            SAXReader sax = new SAXReader();
            sax.setEntityResolver(new EntityResolver() {
                public InputSource resolveEntity(String publicId, String systemId) {
                    if (publicId.equals("-//UniTime//UniTime Menu DTD/EN")) {
                        return new InputSource(
                                ApplicationProperties.class.getClassLoader().getResourceAsStream("menu.dtd"));
                    }
                    return null;
                }
            });
            if (menuUrl != null) {
                Debug.info("Reading menu from " + URLDecoder.decode(menuUrl.getPath(), "UTF-8") + " ...");
                document = sax.read(menuUrl.openStream());
            } else if (new File(menu).exists()) {
                Debug.info("Reading menu from " + menu + " ...");
                document = sax.read(new File(menu));
            }
            if (document == null)
                throw new ServletException("Unable to create menu, reason: resource " + menu + " not found.");

            if (!"unitime-menu".equals(document.getRootElement().getName()))
                throw new ServletException("Menu has an unknown format.");
            iRoot = document.getRootElement();

            String customMenu = ApplicationProperties.getProperty("unitime.menu.custom", "menu-custom.xml");
            Document customDocument = null;
            URL customMenuUrl = ApplicationProperties.class.getClassLoader().getResource(customMenu);
            if (customMenuUrl != null) {
                Debug.info(
                        "Reading custom menu from " + URLDecoder.decode(customMenuUrl.getPath(), "UTF-8") + " ...");
                customDocument = sax.read(customMenuUrl.openStream());
            } else if (new File(customMenu).exists()) {
                Debug.info("Reading custom menu from " + customMenu + " ...");
                customDocument = sax.read(new File(customMenu));
            }
            if (customDocument != null) {
                merge(iRoot, customDocument.getRootElement());
            }

        } catch (Exception e) {
            if (e instanceof RuntimeException)
                throw (RuntimeException) e;
            throw new RuntimeException("Unable to initialize, reason: " + e.getMessage(), e);
        }
    }

    private @Autowired SessionContext sessionContext;

    private SessionContext getSessionContext() {
        return sessionContext;
    }

    private void merge(Element menu, Element custom) {
        if ("remove".equals(custom.getName())) {
            menu.getParent().remove(menu);
            return;
        }
        for (Iterator<Attribute> i = custom.attributeIterator(); i.hasNext();) {
            Attribute a = i.next();
            menu.addAttribute(a.getName(), a.getValue());
        }
        for (Iterator<Element> i = custom.elementIterator(); i.hasNext();) {
            Element e = i.next();
            if ("parameter".equals(e.getName())) {
                for (Iterator<Element> j = menu.elementIterator("parameter"); j.hasNext();) {
                    menu.remove(j.next());
                }
                menu.add(e.createCopy());
                continue;
            }
            if ("condition".equals(e.getName())) {
                menu.add(e.createCopy());
                continue;
            }
            if ("new-condition".equals(e.getName())) {
                for (Iterator<Element> j = menu.elementIterator("condition"); j.hasNext();) {
                    menu.remove(j.next());
                }
                Element f = e.createCopy();
                f.setName("condition");
                menu.add(f);
                continue;
            }
            String name = e.attributeValue("name");
            Element x = null;
            if (name != null) {
                for (Iterator<Element> j = menu.elementIterator(); j.hasNext();) {
                    Element f = j.next();
                    if (name.equals(f.attributeValue("name"))) {
                        x = f;
                        break;
                    }
                }
            }
            if (x != null) {
                merge(x, e);
            } else {
                int pos = Integer.parseInt(e.attributeValue("position", "-1"));
                if (pos >= 0) {
                    List<Element> after = new ArrayList<Element>();
                    for (Iterator<Element> j = menu.elementIterator(); j.hasNext();) {
                        Element f = j.next();
                        if ("condition".equals(f.getName()))
                            continue;
                        if (pos > 0) {
                            pos--;
                        } else {
                            after.add(f);
                            menu.remove(f);
                        }
                    }
                    menu.add(e.createCopy());
                    for (Element f : after)
                        menu.add(f);
                } else
                    menu.add(e.createCopy());
            }
        }
    }

    public List<MenuInterface> getMenu() throws MenuException {
        try {
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {
                List<MenuInterface> menu = new ArrayList<MenuInterface>();
                if (iRoot == null)
                    throw new MenuException("menu is not configured properly");

                UserInfo user = new UserInfo(getSessionContext());

                for (Iterator<Element> i = iRoot.elementIterator(); i.hasNext();) {
                    Element element = i.next();
                    MenuInterface m = getMenu(user, element);
                    if (m != null)
                        menu.add(m);
                }

                if (menu.isEmpty())
                    throw new MenuException("no menu");

                return menu;
            } finally {
                hibSession.close();
            }
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    private MenuInterface getMenu(UserInfo user, Element menuElement) {
        try {
            MenuInterface menu = new MenuInterface();
            String name = menuElement.attributeValue("name");
            String localizedName = (name == null ? null
                    : sPageNames.translateMessage(
                            name.trim().replace(' ', '_').replace("(", "").replace(")", "").replace(':', '_'),
                            null));
            menu.setName(localizedName == null ? name : localizedName);
            menu.setTitle(menuElement.attributeValue("title"));
            menu.setTarget(menuElement.attributeValue("target"));
            menu.setPage(menuElement.attributeValue("page"));
            menu.setHash(menuElement.attributeValue("hash"));
            String type = menuElement.attributeValue("type");
            if ("gwt".equals(type))
                menu.setGWT(true);
            if ("property".equals(type) && menu.getPage() != null) {
                menu.setPage(ApplicationProperties.getProperty(menu.getPage()));
                if (menu.getPage() == null)
                    return null;
            }

            for (Iterator<Element> i = menuElement.elementIterator(); i.hasNext();) {
                Element element = i.next();
                if ("condition".equals(element.getName())) {
                    if (!check(user, element))
                        return null;
                } else if ("parameter".equals(element.getName())) {
                    menu.addParameter(element.attributeValue("name"),
                            element.attributeValue("value", element.getText()));
                } else {
                    MenuInterface m = getMenu(user, element);
                    if (m != null)
                        menu.addSubMenu(m);
                }
            }
            return menu;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private boolean check(UserInfo userInfo, Element conditionElement) {
        String cond = conditionElement.getName();
        if ("and".equals(cond) || "condition".equals(cond)) {
            for (Iterator<Element> i = conditionElement.elementIterator(); i.hasNext();) {
                Element element = i.next();
                if (!check(userInfo, element))
                    return false;
            }
            return true;
        } else if ("or".equals(cond)) {
            for (Iterator<Element> i = conditionElement.elementIterator(); i.hasNext();) {
                Element element = i.next();
                if (check(userInfo, element))
                    return true;
            }
            return false;
        } else if ("not".equals(cond)) {
            for (Iterator<Element> i = conditionElement.elementIterator(); i.hasNext();) {
                Element element = i.next();
                if (check(userInfo, element))
                    return false;
            }
            return true;
        } else if ("isAuthenticated".equals(cond)) {
            return userInfo.getUser() != null;
        } else if ("hasRole".equals(cond)) {
            UserContext user = userInfo.getUser();
            if (user == null)
                return false;
            String role = conditionElement.attributeValue("name");
            if (role == null)
                return user.getCurrentRole() != null; // has any role
            return role.equalsIgnoreCase(user.getCurrentRole());
        } else if ("propertyEquals".equals(cond)) {
            return conditionElement.attributeValue("value", "true").equalsIgnoreCase(
                    ApplicationProperties.getProperty(conditionElement.attributeValue("name", "dummy"),
                            conditionElement.attributeValue("defaultValue", "false")));
        } else if ("hasProperty".equals(cond)) {
            return ApplicationProperties.getProperty(conditionElement.attributeValue("name", "dummy")) != null;
        } else if ("hasPermission".equals(cond)) {
            Right right = Right.valueOf(conditionElement.attributeValue("name"));
            return (right == null ? false
                    : sessionContext.hasPermission(null, conditionElement.attributeValue("target"), right));
        } else if ("hasRight".equals(cond)) {
            String right = conditionElement.attributeValue("name", "unknown");
            if ("canSeeEvents".equals(right)) {
                return userInfo.getUser() != null && TimetableManager.canSeeEvents(userInfo.getUser());
            } else if ("hasRoomAvailability".equals(right)) {
                return RoomAvailability.getInstance() != null;
            } else if ("hasPersonalReport".equals(right)) {
                return userInfo.getUser() != null
                        && PersonalizedExamReportAction.hasPersonalReport(userInfo.getUser().getExternalUserId());
            } else if ("isChameleon".equals(right)) {
                return getSessionContext().isAuthenticated() && (getSessionContext().hasPermission(Right.Chameleon)
                        || getSessionContext().getUser() instanceof UserContext.Chameleon);
            } else if ("isSectioningEnabled".equals(right)) {
                return OnlineSectioningService.isEnabled();
            } else if ("isStudent".equals(right)) {
                return userInfo != null && userInfo.isStudent();
            } else if ("isInstructor".equals(right)) {
                return userInfo != null && userInfo.isInstructor();
            } else if ("isRegistrationEnabled".equals(right)) {
                return OnlineSectioningService.isRegistrationEnabled();
            } else {
                UserContext user = userInfo.getUser();
                if (user == null)
                    return false;
                TimetableManager manager = userInfo.getManager();
                if (manager == null)
                    return false;
                Session session = userInfo.getSession();
                if (session == null)
                    return false;
                if ("canSeeCourses".equals(right)) {
                    return manager.canSeeCourses(session, user);
                } else if ("canSeeTimetable".equals(right)) {
                    return sessionContext.hasPermission(Right.ClassAssignments);
                } else if ("canDoTimetable".equals(right)) {
                    return sessionContext.hasPermission(Right.CourseTimetabling);
                } else if ("hasASolverGroup".equals(right)) {
                    return manager.hasASolverGroup(session, user);
                } else if ("canSectionStudents".equals(right)) {
                    return manager.canSectionStudents(session, user);
                } else if ("canSeeExams".equals(right)) {
                    return sessionContext.hasPermission(Right.Examinations);
                } else if ("canTimetableExams".equals(right)) {
                    return manager.canTimetableExams(session, user);
                } else if ("canAudit".equals(right)) {
                    return manager.canAudit(session, user);
                } else if ("hasCourseReports".equals(right)) {
                    return SavedHQL.hasQueries(SavedHQL.Flag.APPEARANCE_COURSES,
                            Roles.ADMIN_ROLE.equals(user.getCurrentRole()));
                } else if ("hasExamReports".equals(right)) {
                    return SavedHQL.hasQueries(SavedHQL.Flag.APPEARANCE_EXAMS,
                            Roles.ADMIN_ROLE.equals(user.getCurrentRole()));
                } else if ("hasEventReports".equals(right)) {
                    return SavedHQL.hasQueries(SavedHQL.Flag.APPEARANCE_EVENTS,
                            Roles.ADMIN_ROLE.equals(user.getCurrentRole()));
                } else if ("hasStudentReports".equals(right)) {
                    return SavedHQL.hasQueries(SavedHQL.Flag.APPEARANCE_SECTIONING,
                            Roles.ADMIN_ROLE.equals(user.getCurrentRole()));
                }
            }
            sLog.warn("Unknown right " + right + ".");
            return true;
        }
        sLog.warn("Unknown condition " + cond + ".");
        return true;
    }

    public static class UserInfo {
        UserContext iUser = null;
        Session iSession = null;
        TimetableManager iManager = null;

        public UserInfo(SessionContext context) {
            iUser = context.getUser();
            if (iUser != null) {
                Long sessionId = iUser.getCurrentAcademicSessionId();
                if (sessionId != null)
                    iSession = SessionDAO.getInstance().get(sessionId);
                iManager = TimetableManager.findByExternalId(iUser.getExternalUserId());
            }
        }

        public UserContext getUser() {
            return iUser;
        }

        public Session getSession() {
            return iSession;
        }

        public TimetableManager getManager() {
            return iManager;
        }

        public boolean isStudent() {
            if (getUser() == null)
                return false;
            return ((Number) StudentDAO.getInstance().getSession()
                    .createQuery("select count(s) from Student s where " + "s.externalUniqueId = :uid")
                    .setString("uid", getUser().getExternalUserId()).setCacheable(true).uniqueResult())
                            .intValue() > 0;
        }

        public boolean isInstructor() {
            if (getUser() == null)
                return false;
            return ((Number) StudentDAO.getInstance().getSession()
                    .createQuery(
                            "select count(s) from DepartmentalInstructor s where " + "s.externalUniqueId = :uid")
                    .setString("uid", getUser().getExternalUserId()).setCacheable(true).uniqueResult())
                            .intValue() > 0;
        }

    }

    public HashMap<String, String> getUserInfo() throws MenuException {
        try {
            HashMap<String, String> ret = new HashMap<String, String>();
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {

                UserInfo user = new UserInfo(getSessionContext());
                if (user.getUser() == null)
                    return null;

                String userName = Constants.toInitialCase(user.getUser().getName(), "-".toCharArray());

                ret.put("0Name", userName);

                String dept = "";
                TimetableManager manager = user.getManager();
                if (manager != null) {
                    for (Iterator i = manager.getDepartments().iterator(); i.hasNext();) {
                        Department d = (Department) i.next();
                        if (d.getSessionId().equals(user.getSession().getUniqueId())) {
                            if (dept.length() > 0)
                                dept += ",";
                            dept += "<span title='" + d.getHtmlTitle() + "'>" + d.getShortLabel() + "</span>";
                        }
                    }
                } else {
                    if (user.getManager() != null)
                        for (Department department : user.getManager().getDepartments())
                            if (department.getSession().equals(user.getSession()))
                                dept += (dept.isEmpty() ? "" : ",") + department.getDeptCode();
                }
                ret.put("1Dept", dept);

                String role = user.getUser().getCurrentRole();
                if (role == null)
                    role = "No Role";
                ret.put("2Role", role);

                if (user.getUser() != null && (Roles.ADMIN_ROLE.equals(user.getUser().getCurrentRole())
                        || user.getUser() instanceof UserContext.Chameleon))
                    ret.put("Chameleon", "");

            } finally {
                hibSession.close();
            }
            return ret;
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public HashMap<String, String> getSessionInfo() throws MenuException {
        try {
            HashMap<String, String> ret = new HashMap<String, String>();
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {

                UserInfo user = new UserInfo(getSessionContext());
                if (user.getSession() == null)
                    return null;

                ret.put("0Session", user.getSession().getLabel());
                ret.put("1Status", user.getSession().getStatusType().getLabel());

                ret.put("2Database", HibernateUtil.getDatabaseName());

            } finally {
                hibSession.close();
            }
            return ret;
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public String getVersion() throws MenuException {
        return "Version " + Constants.getVersion() + " built on " + Constants.getReleaseDate();
    }

    private String getName(String puid) {
        return getName(TimetableManager.findByExternalId(puid));
    }

    private String getName(TimetableManager mgr) {
        if (mgr == null)
            return null;
        return mgr.getShortName();
    }

    private String getName(SolverGroup gr) {
        if (gr == null)
            return null;
        return gr.getAbbv();
    }

    @Autowired
    SolverService<SolverProxy> courseTimetablingSolverService;
    @Autowired
    SolverService<ExamSolverProxy> examinationSolverService;
    @Autowired
    SolverService<StudentSolverProxy> studentSectioningSolverService;

    public HashMap<String, String> getSolverInfo(boolean includeSolutionInfo) throws MenuException {
        try {
            HashMap<String, String> ret = new HashMap<String, String>();
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {

                SolverProxy solver = courseTimetablingSolverService.getSolver();
                ExamSolverProxy examSolver = examinationSolverService.getSolver();
                StudentSolverProxy studentSolver = studentSectioningSolverService.getSolver();

                Map progress = (studentSolver != null ? studentSolver.getProgress()
                        : examSolver != null ? examSolver.getProgress()
                                : solver != null ? solver.getProgress() : null);
                if (progress == null)
                    return null;

                DataProperties properties = (studentSolver != null ? studentSolver.getProperties()
                        : examSolver != null ? examSolver.getProperties() : solver.getProperties());
                String progressStatus = (String) progress.get("STATUS");
                String progressPhase = (String) progress.get("PHASE");
                long progressCur = ((Long) progress.get("PROGRESS")).longValue();
                long progressMax = ((Long) progress.get("MAX_PROGRESS")).longValue();
                String version = (String) progress.get("VERSION");
                if (version == null || "-1".equals(version))
                    version = "N/A";
                double progressPercent = 100.0 * ((double) (progressCur < progressMax ? progressCur : progressMax))
                        / ((double) progressMax);
                String runnerName = getName(properties.getProperty("General.OwnerPuid", "N/A"));
                Long[] solverGroupId = properties.getPropertyLongArry("General.SolverGroupId", null);
                String ownerName = "";
                if (solverGroupId != null) {
                    for (int i = 0; i < solverGroupId.length; i++) {
                        if (i > 0)
                            ownerName += " & ";
                        ownerName += getName((new SolverGroupDAO()).get(solverGroupId[i]));
                    }
                }
                if (examSolver != null)
                    ownerName = Exam.sExamTypes[examSolver.getExamType()];
                if (ownerName == null || ownerName.length() == 0)
                    ownerName = "N/A";
                if (ownerName.equals("N/A"))
                    ownerName = runnerName;
                if (runnerName.equals("N/A"))
                    runnerName = ownerName;
                if (!ownerName.equals(runnerName))
                    ownerName = runnerName + " as " + ownerName;
                if (ownerName.length() > 50)
                    ownerName = ownerName.substring(0, 47) + "...";

                ret.put("0Type", (studentSolver != null ? "Student Sectioning Solver"
                        : examSolver != null ? "Examinations Solver" : "Course Timetabling Solver"));
                ret.put("4Owner", ownerName);
                ret.put("5Host", (studentSolver != null ? studentSolver.getHostLabel()
                        : examSolver != null ? examSolver.getHostLabel() : solver.getHostLabel()));
                ret.put("1Solver", progressStatus);
                ret.put("2Phase", progressPhase);
                if (progressMax > 0)
                    ret.put("3Progress", (progressCur < progressMax ? progressCur : progressMax) + " of "
                            + progressMax + " (" + Web.format(progressPercent) + "%)");
                ret.put("7Version", version);
                ret.put("6Session", SessionDAO.getInstance()
                        .get(properties.getPropertyLong("General.SessionId", null)).getLabel());

                if (includeSolutionInfo) {
                    Map<String, String> info = null;
                    if (solver != null) {
                        info = solver.statusSolutionInfo();
                    } else if (examSolver != null) {
                        info = examSolver.statusSolutionInfo();
                    } else if (studentSolver != null) {
                        info = studentSolver.statusSolutionInfo();
                    }

                    if (info != null) {
                        TreeSet<String> keys = new TreeSet<String>(new ListSolutionsForm.InfoComparator());
                        keys.addAll(info.keySet());
                        int idx = 0;
                        for (String key : keys) {
                            ret.put((char) ('A' + idx) + key, (String) info.get(key));
                            idx++;
                        }
                    }
                }

            } finally {
                hibSession.close();
            }
            return ret;
        } catch (Exception e) {
            sLog.warn("Unable to get solver info: " + e.getMessage());
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public String[] getHelpPageAndLocalizedTitle(String title) throws MenuException {
        String name = title.trim().replace(' ', '_').replace("(", "").replace(")", "").replace(':', '_');
        String help = null;
        if ("true".equals(ApplicationProperties.getProperty("tmtbl.wiki.help", "true"))
                && ApplicationProperties.getProperty("tmtbl.wiki.url") != null) {
            help = ApplicationProperties.getProperty("tmtbl.wiki.url") + name;
        }
        return new String[] { help, sPageNames.translateMessage(name, title) };
    }

    public String getUserData(String property) throws MenuException {
        try {
            UserContext user = getSessionContext().getUser();
            if (user == null)
                return null;
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {
                return UserData.getProperty(user.getExternalUserId(), property);
            } finally {
                hibSession.close();
            }
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public Boolean setUserData(String property, String value) throws MenuException {
        try {
            UserContext user = getSessionContext().getUser();
            if (user == null)
                return null;
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {
                UserData.setProperty(user.getExternalUserId(), property, value);
                return null;
            } finally {
                hibSession.close();
            }
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public HashMap<String, String> getUserData(Collection<String> property) throws MenuException {
        try {
            UserContext user = getSessionContext().getUser();
            if (user == null)
                return null;
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {
                return UserData.getProperties(user.getExternalUserId(), property);
            } finally {
                hibSession.close();
            }
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

    public Boolean setUserData(List<String[]> property2value) throws MenuException {
        try {
            UserContext user = getSessionContext().getUser();
            if (user == null)
                return null;
            org.hibernate.Session hibSession = SessionDAO.getInstance().getSession();
            try {
                for (String[] p : property2value)
                    UserData.setProperty(user.getExternalUserId(), p[0], p[1]);
                return null;
            } finally {
                hibSession.close();
            }
        } catch (Exception e) {
            if (e instanceof MenuException)
                throw (MenuException) e;
            throw new MenuException(e.getMessage());
        }
    }

}