/**
   * Returns paths constructed by rewriting pathInfo using rules from the hosted site's mappings.
   * Paths are ordered from most to least specific match.
   *
   * @param site The hosted site.
   * @param pathInfo Path to be rewritten.
   * @param queryString
   * @return The rewritten path. May be either:
   *     <ul>
   *       <li>A path to a file in the Orion workspace, eg. <code>/ProjectA/foo/bar.txt</code>
   *       <li>An absolute URL pointing to another site, eg. <code>http://foo.com/bar.txt</code>
   *     </ul>
   *
   * @return The rewritten paths.
   * @throws URISyntaxException
   */
  private URI[] getMapped(IHostedSite site, IPath pathInfo, String queryString)
      throws URISyntaxException {
    final Map<String, List<String>> map = site.getMappings();
    final IPath originalPath = pathInfo;
    IPath path = originalPath.removeTrailingSeparator();

    List<URI> uris = new ArrayList<URI>();
    String rest = null;
    final int count = path.segmentCount();
    for (int i = 0; i <= count; i++) {
      List<String> base = map.get(path.toString());
      if (base != null) {
        rest = originalPath.removeFirstSegments(count - i).toString();
        for (int j = 0; j < base.size(); j++) {
          URI uri =
              rest.equals("") ? new URI(base.get(j)) : URIUtil.append(new URI(base.get(j)), rest);
          uris.add(
              new URI(
                  uri.getScheme(),
                  uri.getUserInfo(),
                  uri.getHost(),
                  uri.getPort(),
                  uri.getPath(),
                  queryString,
                  uri.getFragment()));
        }
      }
      path = path.removeLastSegments(1);
    }
    if (uris.size() == 0)
      // No mapping for /
      return null;
    else return uris.toArray(new URI[uris.size()]);
  }
  // temp code for grabbing files from filesystem
  protected IFileStore tempGetFileStore(IPath path) {
    // first check if we have an alias registered
    if (path.segmentCount() > 0) {
      URI alias = aliasRegistry.lookupAlias(path.segment(0));
      if (alias != null)
        try {
          return EFS.getStore(alias).getFileStore(path.removeFirstSegments(1));
        } catch (CoreException e) {
          LogHelper.log(
              new Status(
                  IStatus.WARNING,
                  HostingActivator.PI_SERVER_HOSTING,
                  1,
                  "An error occured when getting file store for path '"
                      + path
                      + "' and alias '"
                      + alias
                      + '\'',
                  e)); //$NON-NLS-1$ //$NON-NLS-2$
          // fallback is to try the same path relatively to the root
        }
    }
    // assume it is relative to the root
    try {
      return EFS.getStore(rootStoreURI).getFileStore(path);
    } catch (CoreException e) {
      LogHelper.log(
          new Status(
              IStatus.WARNING,
              HostingActivator.PI_SERVER_HOSTING,
              1,
              "An error occured when getting file store for path '"
                  + path
                  + "' and root '"
                  + rootStoreURI
                  + '\'',
              e)); //$NON-NLS-1$ //$NON-NLS-2$
      // fallback and return null
    }

    return null;
  }
  // returns true if the request has been served, false if not (only if failEarlyOn404 is true)
  private boolean serveOrionFile(
      HttpServletRequest req,
      HttpServletResponse resp,
      IHostedSite site,
      IPath path,
      boolean failEarlyOn404)
      throws ServletException {
    String userName = site.getUserName();
    String workspaceId = site.getWorkspaceId();
    String workspaceUri = WORKSPACE_SERVLET_ALIAS + "/" + workspaceId; // $NON-NLS-1$
    boolean allow = false;
    // Check that user who launched the hosted site really has access to the workspace
    try {
      if (AuthorizationService.checkRights(userName, workspaceUri, "GET")) { // $NON-NLS-1$
        allow = true;
      }
    } catch (JSONException e) {
      throw new ServletException(e);
    }

    if (allow) {
      // FIXME: this code is copied from NewFileServlet, fix it
      // start copied
      String pathInfo = path.toString();
      IPath filePath = pathInfo == null ? Path.ROOT : new Path(pathInfo);
      IFileStore file = tempGetFileStore(filePath);
      if (file == null || !file.fetchInfo().exists()) {
        if (failEarlyOn404) {
          return false;
        }
        handleException(
            resp,
            new ServerStatus(IStatus.ERROR, 404, NLS.bind("File not found: {0}", filePath), null));
      }
      if (fileSerializer.handleRequest(req, resp, file)) {
        // return;
      }
      // end copied

      if (file != null) {
        addEditHeaders(resp, site, path);
        addContentTypeHeader(resp, path);
      }
    } else {
      String msg = NLS.bind("No rights to access {0}", workspaceUri);
      handleException(
          resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_FORBIDDEN, msg, null));
    }
    return true;
  }
 @Override
 protected void service(HttpServletRequest req, HttpServletResponse resp)
     throws ServletException, IOException {
   traceRequest(req);
   String pathInfoString = req.getPathInfo();
   String queryString = getQueryString(req);
   IPath pathInfo =
       new Path(
           null /*don't parse host:port as device*/,
           pathInfoString == null ? "" : pathInfoString); // $NON-NLS-1$
   if (pathInfo.segmentCount() > 0) {
     String hostedHost = pathInfo.segment(0);
     IHostedSite site = HostingActivator.getDefault().getHostingService().get(hostedHost);
     if (site != null) {
       IPath path = pathInfo.removeFirstSegments(1);
       IPath contextPath = new Path(req.getContextPath());
       IPath contextlessPath = path.makeRelativeTo(contextPath).makeAbsolute();
       URI[] mappedPaths;
       try {
         mappedPaths = getMapped(site, contextlessPath, queryString);
       } catch (URISyntaxException e) {
         handleException(
             resp,
             new ServerStatus(
                 IStatus.ERROR,
                 HttpServletResponse.SC_BAD_REQUEST,
                 "Could not create target URI	",
                 e));
         return;
       }
       if (mappedPaths != null) {
         serve(req, resp, site, mappedPaths);
       } else {
         handleException(
             resp,
             new ServerStatus(
                 IStatus.ERROR,
                 HttpServletResponse.SC_NOT_FOUND,
                 NLS.bind("No mappings matched {0}", path),
                 null));
       }
     } else {
       String msg = NLS.bind("Hosted site {0} is stopped", hostedHost);
       handleException(
           resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null));
     }
   } else {
     super.doGet(req, resp);
   }
 }
 private void addContentTypeHeader(HttpServletResponse resp, IPath path) {
   String mimeType = getServletContext().getMimeType(path.lastSegment());
   if (mimeType != null) resp.addHeader("Content-Type", mimeType);
 }
 private void addEditHeaders(HttpServletResponse resp, IHostedSite site, IPath path) {
   resp.addHeader(
       "X-Edit-Server", site.getEditServerUrl() + "/edit/edit.html#"); // $NON-NLS-1$ //$NON-NLS-2$
   resp.addHeader("X-Edit-Token", FILE_SERVLET_ALIAS + path.toString()); // $NON-NLS-1$
 }