/**
   * Make sure that we have a proper page selected in the site pageid is generally the last page
   * used in the site. pageId must be in the site and the user must have permission for the page as
   * well.
   *
   * @see org.sakaiproject.portal.api.PortalSiteHelper#lookupSitePage(java.lang.String,
   *     org.sakaiproject.site.api.Site)
   */
  public SitePage lookupSitePage(String pageId, Site site) {
    // Make sure we have some permitted pages
    List pages = getPermittedPagesInOrder(site);
    if (pages.isEmpty()) return null;
    SitePage page = site.getPage(pageId);
    if (page == null) {
      page = lookupAliasToPage(pageId, site);
      if (page == null) {
        page = (SitePage) pages.get(0);
        return page;
      }
    }

    // Make sure that they user has permission for the page.
    // If the page is not in the permitted list go to the first
    // page.
    boolean found = false;
    for (Iterator i = pages.iterator(); i.hasNext(); ) {
      SitePage p = (SitePage) i.next();
      if (p.getId().equals(page.getId())) return page;
    }

    return (SitePage) pages.get(0);
  }
 public String lookupPageToAlias(String siteId, SitePage page) {
   // Shortcut if we aren't using page aliases.
   if (!lookForPageAliases) {
     return null;
   }
   String alias = null;
   List<Alias> aliases = AliasService.getAliases(page.getReference());
   if (aliases.size() > 0) {
     if (aliases.size() > 1 && log.isWarnEnabled()) {
       log.warn("More than one alias for: " + siteId + ":" + page.getId());
       // Sort on ID so it is consistent in the alias it uses.
       Collections.sort(aliases, getAliasComparator());
     }
     alias = aliases.get(0).getId();
     alias = parseAlias(alias, siteId);
   }
   return alias;
 }
  /**
   * Produce a page and/or a tool list doPage = true is best for the tabs-based portal and for RSS -
   * these think in terms of pages doPage = false is best for the portlet-style - it unrolls all of
   * the tools unless a page is marked as a popup. If the page is a popup - it is left a page and
   * marked as such. restTools = true - generate resetting tool URLs.
   *
   * @see
   *     org.sakaiproject.portal.api.PortalSiteHelper#pageListToMap(javax.servlet.http.HttpServletRequest,
   *     boolean, org.sakaiproject.site.api.Site, org.sakaiproject.site.api.SitePage,
   *     java.lang.String, java.lang.String, boolean, boolean, boolean)
   */
  public Map pageListToMap(
      HttpServletRequest req,
      boolean loggedIn,
      Site site,
      SitePage page,
      String toolContextPath,
      String portalPrefix,
      boolean doPages,
      boolean resetTools,
      boolean includeSummary) {

    Map<String, Object> theMap = new HashMap<String, Object>();

    String pageUrl =
        Web.returnUrl(
            req, "/" + portalPrefix + "/" + Web.escapeUrl(getSiteEffectiveId(site)) + "/page/");
    String toolUrl =
        Web.returnUrl(req, "/" + portalPrefix + "/" + Web.escapeUrl(getSiteEffectiveId(site)));
    if (resetTools) {
      toolUrl = toolUrl + "/tool-reset/";
    } else {
      toolUrl = toolUrl + "/tool/";
    }

    String pagePopupUrl = Web.returnUrl(req, "/page/");
    boolean showHelp = ServerConfigurationService.getBoolean("display.help.menu", true);
    String iconUrl = "";
    try {
      if (site.getIconUrlFull() != null) iconUrl = new URI(site.getIconUrlFull()).toString();
    } catch (URISyntaxException uex) {
      log.debug("Icon URL is invalid: " + site.getIconUrlFull());
    }

    boolean published = site.isPublished();
    String type = site.getType();

    theMap.put("siteId", site.getId());
    theMap.put("pageNavPublished", Boolean.valueOf(published));
    theMap.put("pageNavType", type);
    theMap.put("pageNavIconUrl", iconUrl);
    String htmlInclude = site.getProperties().getProperty(PROP_HTML_INCLUDE);
    if (htmlInclude != null) theMap.put("siteHTMLInclude", htmlInclude);

    // theMap.put("pageNavSitToolsHead",
    // Web.escapeHtml(rb.getString("sit_toolshead")));

    // order the pages based on their tools and the tool order for the
    // site type
    // List pages = site.getOrderedPages();
    List pages = getPermittedPagesInOrder(site);

    List<Map> l = new ArrayList<Map>();

    String addMoreToolsUrl = null;
    for (Iterator i = pages.iterator(); i.hasNext(); ) {

      SitePage p = (SitePage) i.next();
      // check if current user has permission to see page
      // we will draw page button if it have permission to see at least
      // one tool on the page
      List<ToolConfiguration> pTools = p.getTools();
      ToolConfiguration firstTool = null;
      String toolsOnPage = null;

      boolean current = (page != null && p.getId().equals(page.getId()) && !p.isPopUp());
      String alias = lookupPageToAlias(site.getId(), p);
      String pagerefUrl = pageUrl + Web.escapeUrl((alias != null) ? alias : p.getId());

      if (doPages || p.isPopUp()) {
        Map<String, Object> m = new HashMap<String, Object>();
        StringBuffer desc = new StringBuffer();

        boolean hidden = false;
        if (pTools != null && pTools.size() > 0) {
          firstTool = pTools.get(0);
          hidden = true; // Only set the page to hidden when we have tools that might un-hide it.
          Iterator<ToolConfiguration> tools = pTools.iterator();
          // get the tool descriptions for this page, typically only one per page, execpt for the
          // Home page
          int tCount = 0;
          while (tools.hasNext()) {
            ToolConfiguration t = tools.next();
            if (hidden && !isHidden(t)) {
              hidden = false;
            }
            if (tCount > 0) {
              desc.append(" | ");
            }
            if (t.getTool() == null) continue;
            desc.append(t.getTool().getDescription());
            tCount++;
            if ("sakai.siteinfo".equals(t.getToolId())) {
              addMoreToolsUrl =
                  Web.returnUrl(
                      req,
                      "/site/"
                          + Web.escapeUrl(site.getId())
                          + "/page/"
                          + Web.escapeUrl(p.getId())
                          + "?sakai_action=doMenu_edit_site_tools&panel=Shortcut");
            }
          }
          // Won't work with mutliple tools per page
          if (tCount > 1) addMoreToolsUrl = null;
        }

        boolean siteUpdate = SecurityService.unlock("site.upd", site.getReference());
        if (!siteUpdate) addMoreToolsUrl = null;

        if (!ServerConfigurationService.getBoolean("portal.experimental.addmoretools", false))
          addMoreToolsUrl = null;

        m.put("isPage", Boolean.valueOf(true));
        m.put("current", Boolean.valueOf(current));
        m.put("ispopup", Boolean.valueOf(p.isPopUp()));
        m.put("pagePopupUrl", pagePopupUrl);
        m.put("pageTitle", Web.escapeHtml(p.getTitle()));
        m.put("jsPageTitle", Web.escapeJavascript(p.getTitle()));
        m.put("pageId", Web.escapeUrl(p.getId()));
        m.put("jsPageId", Web.escapeJavascript(p.getId()));
        m.put("pageRefUrl", pagerefUrl);

        // TODO: Should have Web.escapeHtmlAttribute()
        String description = desc.toString().replace("\"", "&quot;");
        m.put("description", description);
        m.put("hidden", Boolean.valueOf(hidden));
        // toolsOnPage is always null
        // if (toolsOnPage != null) m.put("toolsOnPage", toolsOnPage);
        if (includeSummary) summarizePage(m, site, p);
        if (firstTool != null) {
          String menuClass = firstTool.getToolId();
          menuClass = "icon-" + menuClass.replace('.', '-');
          m.put("menuClass", menuClass);
          Properties tmp = firstTool.getConfig();
          if (tmp != null) {
            String mc = tmp.getProperty(PROP_MENU_CLASS);
            if (mc != null && mc.length() > 0) m.put("menuClassOverride", mc);
          }
        } else {
          m.put("menuClass", "icon-default-tool");
        }
        m.put("pageProps", createPageProps(p));
        // this is here to allow the tool reorder to work
        m.put("_sitePage", p);
        l.add(m);
        continue;
      }

      // Loop through the tools again and Unroll the tools
      Iterator iPt = pTools.iterator();

      while (iPt.hasNext()) {
        ToolConfiguration placement = (ToolConfiguration) iPt.next();

        Tool tool = placement.getTool();
        if (tool != null) {
          String toolrefUrl = toolUrl + Web.escapeUrl(placement.getId());

          Map<String, Object> m = new HashMap<String, Object>();
          m.put("isPage", Boolean.valueOf(false));
          m.put("toolId", Web.escapeUrl(placement.getId()));
          m.put("jsToolId", Web.escapeJavascript(placement.getId()));
          m.put("toolRegistryId", placement.getToolId());
          m.put("toolTitle", Web.escapeHtml(placement.getTitle()));
          m.put("jsToolTitle", Web.escapeJavascript(placement.getTitle()));
          m.put("toolrefUrl", toolrefUrl);
          String menuClass = placement.getToolId();
          menuClass = "icon-" + menuClass.replace('.', '-');
          m.put("menuClass", menuClass);
          Properties tmp = placement.getConfig();
          if (tmp != null) {
            String mc = tmp.getProperty(PROP_MENU_CLASS);
            if (mc != null && mc.length() > 0) m.put("menuClassOverride", mc);
          }
          // this is here to allow the tool reorder to work if requried.
          m.put("_placement", placement);
          l.add(m);
        }
      }
    }
    PageFilter pageFilter = portal.getPageFilter();
    if (pageFilter != null) {
      l = pageFilter.filterPlacements(l, site);
    }

    if (addMoreToolsUrl != null) {
      theMap.put("pageNavAddMoreToolsUrl", addMoreToolsUrl);
      theMap.put("pageNavCanAddMoreTools", true);
    } else {
      theMap.put("pageNavCanAddMoreTools", false);
    }

    theMap.put("pageNavTools", l);
    theMap.put(
        "pageMaxIfSingle",
        ServerConfigurationService.getBoolean("portal.experimental.maximizesinglepage", false));
    theMap.put("pageNavToolsCount", Integer.valueOf(l.size()));

    String helpUrl = ServerConfigurationService.getHelpUrl(null);
    theMap.put("pageNavShowHelp", Boolean.valueOf(showHelp));
    theMap.put("pageNavHelpUrl", helpUrl);
    theMap.put("helpMenuClass", "icon-sakai-help");
    theMap.put("subsiteClass", "icon-sakai-subsite");

    // theMap.put("pageNavSitContentshead",
    // Web.escapeHtml(rb.getString("sit_contentshead")));

    // Display presence? Global property display.users.present may be always / never / true / false
    // If true or false, the value may be overriden by the site property display-users-present
    // which may be true or false.

    boolean showPresence;
    String globalShowPresence =
        ServerConfigurationService.getString("display.users.present", "true");

    if ("never".equals(globalShowPresence)) {
      showPresence = false;
    } else if ("always".equals(globalShowPresence)) {
      showPresence = true;
    } else {
      String showPresenceSite = site.getProperties().getProperty("display-users-present");

      if (showPresenceSite == null) {
        showPresence = Boolean.valueOf(globalShowPresence).booleanValue();
      } else {
        showPresence = Boolean.valueOf(showPresenceSite).booleanValue();
      }
    }

    // Check to see if this is a my workspace site, and if so, whether presence is disabled
    if (showPresence
        && SiteService.isUserSite(site.getId())
        && !ServerConfigurationService.getBoolean("display.users.present.myworkspace", false))
      showPresence = false;

    String presenceUrl = Web.returnUrl(req, "/presence/" + Web.escapeUrl(site.getId()));

    // theMap.put("pageNavSitPresenceTitle",
    // Web.escapeHtml(rb.getString("sit_presencetitle")));
    // theMap.put("pageNavSitPresenceFrameTitle",
    // Web.escapeHtml(rb.getString("sit_presenceiframetit")));
    theMap.put("pageNavShowPresenceLoggedIn", Boolean.valueOf(showPresence && loggedIn));
    theMap.put("pageNavPresenceUrl", presenceUrl);

    // Retrieve whether or not we are to put presence in a frame
    theMap.put(
        "pageNavPresenceIframe",
        Boolean.valueOf(
            ServerConfigurationService.getBoolean("display.users.present.iframe", false)));
    theMap.put(
        "sakaiPresenceTimeDelay",
        Integer.valueOf(
            ServerConfigurationService.getInt("display.users.present.time.delay", 3000)));

    return theMap;
  }