/**
   * Respond to navigation / access requests.
   *
   * @param req The servlet request.
   * @param res The servlet response.
   * @throws ServletException.
   * @throws IOException.
   */
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    try {
      // this is either going to be editor.js or editor-launch.js
      String path = URLUtils.getSafePathInfo(req);
      if ((path == null) || (path.length() <= 1)) throw new Exception("no path");

      // get the requested file, ignoring the first "/"
      String[] parts = StringUtil.splitFirst(path.substring(1), "/");
      String name = parts[0];

      String placementId = req.getParameter("placement");
      ToolConfiguration tool = SiteService.findTool(placementId);

      Editor editor = portalService.getActiveEditor(tool);

      if (EDITOR_JS.equals(name)) {
        res.sendRedirect(editor.getEditorUrl());
        // res.sendRedirect("/library/editor/FCKeditor/fckeditor.js");
        // res.sendRedirect("/library/editor/ckeditor/ckeditor.js");
      } else if (EDITOR_LAUNCH_JS.equals(name)) {
        res.sendRedirect(editor.getLaunchUrl());
        // res.sendRedirect("/library/editor/launchfck.js");
        // res.sendRedirect("/library/editor/ckeditor.launch.js");
      } else if (EDITOR_BOOTSTRAP_JS.equals(name)) {
        res.addHeader("Pragma", "no-cache");
        res.addHeader("Cache-Control", "no-cache");
        res.addHeader("Content-Type", "text/javascript");

        // Note that this is the same stuff as in SkinnableCharonPortal. We should probably do a bit
        // of refactoring.
        PrintWriter out = res.getWriter();
        out.print("var sakai = sakai || {}; sakai.editor = sakai.editor || {}; \n");
        out.print(
            "sakai.editor.collectionId = '" + portalService.getBrowserCollectionId(tool) + "';\n");
        out.print(
            "sakai.editor.enableResourceSearch = '"
                + EditorConfiguration.enableResourceSearch()
                + "';\n");
        out.print(editor.getPreloadScript());
      } else {
        throw new Exception("unrecognized request");
      }

    } catch (Throwable t) {
      doError(req, res, t);
    }
  }
  /**
   * Respond to navigation / access requests.
   *
   * @param req The servlet request.
   * @param res The servlet response.
   * @throws ServletException.
   * @throws IOException.
   */
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    try {
      // get the Sakai session
      Session session = SessionManager.getCurrentSession();

      // our path is /placement-id/tool-destination, but we want to
      // include anchors and parameters in the destination...
      String path = URLUtils.getSafePathInfo(req);
      if ((path == null) || (path.length() <= 1)) {
        res.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      // get the placement id, ignoring the first "/"
      String[] parts = StringUtil.splitFirst(path.substring(1), "/");
      String placementId = parts[0];

      // get the toolPath if specified
      String toolPath = null;
      if (parts.length == 2) toolPath = "/" + parts[1];

      boolean success =
          doTool(
              req,
              res,
              session,
              placementId,
              req.getContextPath() + req.getServletPath() + "/" + placementId,
              toolPath);

    } catch (Exception t) {
      doError(req, res, t);
    }
  }
  public void doTool(
      HttpServletRequest req,
      HttpServletResponse res,
      Session session,
      String placementId,
      String toolContextPath,
      String toolPathInfo)
      throws ToolException, IOException {

    if (portal.redirectIfLoggedOut(res)) return;

    // find the tool from some site
    ToolConfiguration siteTool = SiteService.findTool(placementId);
    if (siteTool == null) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    // Reset the tool state if requested
    if (portalService.isResetRequested(req)) {
      Session s = SessionManager.getCurrentSession();
      ToolSession ts = s.getToolSession(placementId);
      ts.clearAttributes();
      portalService.setResetState(null);
      M_log.debug("Tool state reset");
    }

    // find the tool registered for this

    ActiveTool tool = ActiveToolManager.getActiveTool(siteTool.getToolId());
    if (tool == null) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    // permission check - visit the site (unless the tool is configured to
    // bypass)
    Site site = null;
    if (tool.getAccessSecurity() == Tool.AccessSecurity.PORTAL) {
      try {
        site = SiteService.getSiteVisit(siteTool.getSiteId());
      } catch (IdUnusedException e) {
        portal.doError(req, res, session, Portal.ERROR_WORKSITE);
        return;
      } catch (PermissionException e) {
        // if not logged in, give them a chance
        if (session.getUserId() == null) {
          portal.doLogin(req, res, session, URLUtils.getSafePathInfo(req), false);
        } else {
          portal.doError(req, res, session, Portal.ERROR_WORKSITE);
        }
        return;
      }
    }

    // Check to see if the tool is visible
    if (!ToolManager.isVisible(site, siteTool)) {
      portal.doError(req, res, session, Portal.ERROR_WORKSITE);
      return;
    }

    if (portal.isPortletPlacement(siteTool)) {

      String siteType = portal.calcSiteType(siteTool.getSiteId());

      // form a context sensitive title
      String title =
          ServerConfigurationService.getString("ui.service", "Sakai")
              + " : "
              + portal.getSiteHelper().getUserSpecificSiteTitle(site, false)
              + " : "
              + siteTool.getTitle();

      PortalRenderContext rcontext =
          portal.startPageContext(siteType, title, siteTool.getSkin(), req);

      Map m = portal.includeTool(res, req, siteTool);
      rcontext.put("tool", m);

      portal.sendResponse(rcontext, res, "tool", null);

    } else {
      M_log.debug("forwardtool in ToolHandler");
      portal.forwardTool(
          tool, req, res, siteTool, siteTool.getSkin(), toolContextPath, toolPathInfo);
    }
  }