コード例 #1
0
  private boolean handlePost(
      HttpServletRequest request, HttpServletResponse response, String pathString)
      throws IOException, JSONException, ServletException, URISyntaxException, CoreException,
          NoHeadException, NoMessageException, ConcurrentRefUpdateException,
          WrongRepositoryStateException {
    // make sure required fields are set
    JSONObject toAdd = OrionServlet.readJSONRequest(request);
    if (toAdd.optBoolean(GitConstants.KEY_PULL, false)) {
      GitUtils.createGitCredentialsProvider(toAdd);
      GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd);
      boolean force = toAdd.optBoolean(GitConstants.KEY_FORCE, false);
      return pull(request, response, cp, pathString, force);
    }

    Clone clone = new Clone();
    String url = toAdd.optString(GitConstants.KEY_URL, null);
    // method handles repository clone or just repository init
    // decision is based on existence of GitUrl argument
    boolean initOnly;
    if (url == null || url.isEmpty()) initOnly = true;
    else {
      initOnly = false;
      if (!validateCloneUrl(url, request, response)) return true;
      clone.setUrl(new URIish(url));
    }
    String cloneName = toAdd.optString(ProtocolConstants.KEY_NAME, null);
    if (cloneName == null) cloneName = request.getHeader(ProtocolConstants.HEADER_SLUG);
    // expected path /workspace/{workspaceId}
    String workspacePath = toAdd.optString(ProtocolConstants.KEY_LOCATION, null);
    // expected path /file/{workspaceId}/{projectName}[/{path}]
    String filePathString = toAdd.optString(ProtocolConstants.KEY_PATH, null);
    IPath filePath = filePathString == null ? null : new Path(filePathString);
    if (filePath != null && filePath.segmentCount() < 3) filePath = null;
    if (filePath == null && workspacePath == null) {
      String msg =
          NLS.bind(
              "Either {0} or {1} should be provided: {2}",
              new Object[] {ProtocolConstants.KEY_PATH, ProtocolConstants.KEY_LOCATION, toAdd});
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
    }
    // only during init operation filePath or cloneName must be provided
    // during clone operation, name can be obtained from URL
    if (initOnly && filePath == null && cloneName == null) {
      String msg =
          NLS.bind(
              "Either {0} or {1} should be provided: {2}",
              new Object[] {ProtocolConstants.KEY_PATH, GitConstants.KEY_NAME, toAdd});
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
    }
    if (!validateCloneName(cloneName, request, response)) return true;

    // prepare the WebClone object, create a new project if necessary
    WebProject webProject = null;
    boolean webProjectExists = false;
    if (filePath != null) {
      // path format is /file/{workspaceId}/{projectName}/[filePath]
      clone.setId(filePath.toString());
      webProject = GitUtils.projectFromPath(filePath);
      // workspace path format needs to be used if project does not exist
      if (webProject == null) {
        String msg = NLS.bind("Specified project does not exist: {0}", filePath.segment(2));
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
      }
      webProjectExists = true;
      clone.setContentLocation(
          webProject.getProjectStore().getFileStore(filePath.removeFirstSegments(3)).toURI());
      if (cloneName == null)
        cloneName = filePath.segmentCount() > 2 ? filePath.lastSegment() : webProject.getName();
    } else if (workspacePath != null) {
      IPath path = new Path(workspacePath);
      // TODO: move this to CloneJob
      // if so, modify init part to create a new project if necessary
      WebWorkspace workspace = WebWorkspace.fromId(path.segment(1));
      String id = WebProject.nextProjectId();
      if (cloneName == null) cloneName = new URIish(url).getHumanishName();
      cloneName = getUniqueProjectName(workspace, cloneName);
      webProjectExists = false;
      webProject = WebProject.fromId(id);
      webProject.setName(cloneName);

      try {
        WorkspaceResourceHandler.computeProjectLocation(request, webProject, null, false);
      } catch (CoreException e) {
        // we are unable to write in the platform location!
        String msg =
            NLS.bind(
                "Server content location could not be written: {0}",
                Activator.getDefault().getRootLocationURI());
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e));
      } catch (URISyntaxException e) {
        // should not happen, we do not allow linking at this point
      }

      try {
        // If all went well, add project to workspace
        WorkspaceResourceHandler.addProject(request.getRemoteUser(), workspace, webProject);
      } catch (CoreException e) {
        return statusHandler.handleRequest(
            request,
            response,
            new ServerStatus(
                IStatus.ERROR,
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "Error persisting project state",
                e));
      }

      URI baseLocation = getURI(request);
      baseLocation =
          new URI(
              baseLocation.getScheme(),
              baseLocation.getUserInfo(),
              baseLocation.getHost(),
              baseLocation.getPort(),
              workspacePath,
              baseLocation.getQuery(),
              baseLocation.getFragment());
      clone.setId(GitUtils.pathFromProject(workspace, webProject).toString());
      clone.setContentLocation(webProject.getProjectStore().toURI());
    }
    clone.setName(cloneName);
    clone.setBaseLocation(getURI(request));
    JSONObject cloneObject = clone.toJSON();
    String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION);

    if (initOnly) {
      // git init
      InitJob job =
          new InitJob(
              clone, TaskJobHandler.getUserId(request), request.getRemoteUser(), cloneLocation);
      return TaskJobHandler.handleTaskJob(request, response, job, statusHandler);
    }
    // git clone
    // prepare creds
    GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd);
    cp.setUri(new URIish(clone.getUrl()));

    // if all went well, clone
    CloneJob job =
        new CloneJob(
            clone,
            TaskJobHandler.getUserId(request),
            cp,
            request.getRemoteUser(),
            cloneLocation,
            webProjectExists
                ? null
                : webProject /* used for cleaning up, so null when not needed */);
    return TaskJobHandler.handleTaskJob(request, response, job, statusHandler);
  }