private boolean handleDelete( HttpServletRequest request, HttpServletResponse response, String pathString) throws GitAPIException, CoreException, IOException, ServletException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); // expected path format is /file/{workspaceId}/{projectId}[/{directoryPath}] if (path.segment(0).equals("file") && path.segmentCount() > 2) { // $NON-NLS-1$ // make sure a clone is addressed WebProject webProject = GitUtils.projectFromPath(path); if (webProject != null && isAccessAllowed(request.getRemoteUser(), webProject)) { File gitDir = GitUtils.getGitDirs(path, Traverse.CURRENT).values().iterator().next(); Repository repo = new FileRepository(gitDir); repo.close(); FileUtils.delete(repo.getWorkTree(), FileUtils.RECURSIVE | FileUtils.RETRY); if (path.segmentCount() == 3) return statusHandler.handleRequest( request, response, removeProject(request.getRemoteUser(), webProject)); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } String msg = NLS.bind("Invalid delete request {0}", pathString); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }
/** * Returns the file representing the Git repository directory for the given file path or any of * its parent in the filesystem. If the file doesn't exits, is not a Git repository or an error * occurred while transforming the given path into a store <code>null</code> is returned. * * @param path expected format /file/{Workspace}/{projectName}[/{path}] * @return the .git folder if found or <code>null</code> the give path cannot be resolved to a * file or it's not under control of a git repository * @throws CoreException */ public static File getGitDir(IPath path) throws CoreException { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.GO_UP); if (gitDirs == null) return null; Collection<File> values = gitDirs.values(); if (values.isEmpty()) return null; return values.toArray(new File[] {})[0]; }
private boolean identifyNewDiffResource(HttpServletRequest request, HttpServletResponse response) throws ServletException { try { StringWriter writer = new StringWriter(); IOUtilities.pipe(request.getReader(), writer, false, false); JSONObject requestObject = new JSONObject(writer.toString()); URI u = getURI(request); IPath p = new Path(u.getPath()); IPath np = new Path("/"); // $NON-NLS-1$ for (int i = 0; i < p.segmentCount(); i++) { String s = p.segment(i); if (i == 2) { s += ".."; // $NON-NLS-1$ s += GitUtils.encode(requestObject.getString(GitConstants.KEY_COMMIT_NEW)); } np = np.append(s); } if (p.hasTrailingSeparator()) np = np.addTrailingSeparator(); URI nu = new URI( u.getScheme(), u.getUserInfo(), u.getHost(), u.getPort(), np.toString(), u.getQuery(), u.getFragment()); JSONObject result = new JSONObject(); result.put(ProtocolConstants.KEY_LOCATION, nu.toString()); OrionServlet.writeJSONResponse(request, response, result); response.setHeader( ProtocolConstants.HEADER_LOCATION, resovleOrionURI(request, nu).toString()); return true; } catch (Exception e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when identifying a new Diff resource.", e)); } }
/** * In order to determine which Revisions to build. * * <p>Does the following : 1. Find all the branch revisions 2. Filter out branches that we don't * care about from the revisions. Any Revisions with no interesting branches are dropped. 3. Get * rid of any revisions that are wholly subsumed by another revision we're considering. 4. Get rid * of any revisions that we've already built. 5. Sort revisions from old to new. * * <p>NB: Alternate BuildChooser implementations are possible - this may be beneficial if "only 1" * branch is to be built, as much of this work is irrelevant in that usecase. * * @throws IOException * @throws GitException */ private List<Revision> getAdvancedCandidateRevisions( boolean isPollCall, TaskListener listener, GitUtils utils, BuildData data, BuildChooserContext context) throws GitException, IOException, InterruptedException { EnvVars env = context.getBuild().getEnvironment(); // 1. Get all the (branch) revisions that exist List<Revision> revs = new ArrayList<Revision>(utils.getAllBranchRevisions()); verbose(listener, "Starting with all the branches: {0}", revs); // 2. Filter out any revisions that don't contain any branches that we // actually care about (spec) for (Iterator<Revision> i = revs.iterator(); i.hasNext(); ) { Revision r = i.next(); // filter out uninteresting branches for (Iterator<Branch> j = r.getBranches().iterator(); j.hasNext(); ) { Branch b = j.next(); boolean keep = false; for (BranchSpec bspec : gitSCM.getBranches()) { if (bspec.matches(b.getName(), env)) { keep = true; break; } } if (!keep) { verbose(listener, "Ignoring {0} because it doesn''t match branch specifier", b); j.remove(); } } // filter out HEAD ref if it's not the only ref if (r.getBranches().size() > 1) { for (Iterator<Branch> j = r.getBranches().iterator(); j.hasNext(); ) { Branch b = j.next(); if (HEAD.matches(b.getName(), env)) { verbose( listener, "Ignoring {0} because there''s named branch for this revision", b.getName()); j.remove(); } } } if (r.getBranches().size() == 0) { verbose( listener, "Ignoring {0} because we don''t care about any of the branches that point to it", r); i.remove(); } } verbose(listener, "After branch filtering: {0}", revs); // 3. We only want 'tip' revisions revs = utils.filterTipBranches(revs); verbose(listener, "After non-tip filtering: {0}", revs); // 4. Finally, remove any revisions that have already been built. verbose(listener, "Removing what''s already been built: {0}", data.getBuildsByBranchName()); Revision lastBuiltRevision = data.getLastBuiltRevision(); for (Iterator<Revision> i = revs.iterator(); i.hasNext(); ) { Revision r = i.next(); if (data.hasBeenBuilt(r.getSha1())) { i.remove(); // keep track of new branches pointing to the last built revision if (lastBuiltRevision != null && lastBuiltRevision.getSha1().equals(r.getSha1())) { lastBuiltRevision = r; } } } verbose(listener, "After filtering out what''s already been built: {0}", revs); // if we're trying to run a build (not an SCM poll) and nothing new // was found then just run the last build again but ensure that the branch list // is ordered according to the configuration. Sorting the branch list ensures // a deterministic value for GIT_BRANCH and allows a git-flow style workflow // with fast-forward merges between branches if (!isPollCall && revs.isEmpty() && lastBuiltRevision != null) { verbose( listener, "Nothing seems worth building, so falling back to the previously built revision: {0}", data.getLastBuiltRevision()); return Collections.singletonList( utils.sortBranchesForRevision(lastBuiltRevision, gitSCM.getBranches(), env)); } // 5. sort them by the date of commit, old to new // this ensures the fairness in scheduling. final List<Revision> in = revs; return utils.git.withRepository( new RepositoryCallback<List<Revision>>() { public List<Revision> invoke(Repository repo, VirtualChannel channel) throws IOException, InterruptedException { Collections.sort(in, new CommitTimeComparator(repo)); return in; } }); }
@Override protected boolean handlePost(RequestInfo requestInfo) throws ServletException { String gitSegment = requestInfo.gitSegment; HttpServletRequest request = requestInfo.request; HttpServletResponse response = requestInfo.response; Repository db = requestInfo.db; String pattern = requestInfo.relativePath; JSONObject requestObject = requestInfo.getJSONRequest(); try { String commitToMerge = requestObject.optString(GitConstants.KEY_MERGE, null); if (commitToMerge != null) { boolean squash = requestObject.optBoolean(GitConstants.KEY_SQUASH, false); return merge(request, response, db, commitToMerge, squash); } String commitToRebase = requestObject.optString(GitConstants.KEY_REBASE, null); String rebaseOperation = requestObject.optString(GitConstants.KEY_OPERATION, null); if (commitToRebase != null) { return rebase(request, response, db, commitToRebase, rebaseOperation); } String commitToCherryPick = requestObject.optString(GitConstants.KEY_CHERRY_PICK, null); if (commitToCherryPick != null) { return cherryPick(request, response, db, commitToCherryPick); } String commitToRevert = requestObject.optString(GitConstants.KEY_REVERT, null); if (commitToRevert != null) { return revert(request, response, db, commitToRevert); } String newCommit = requestObject.optString(GitConstants.KEY_COMMIT_NEW, null); if (newCommit != null) return identifyNewCommitResource(request, response, db, newCommit); String reviewReqLogin = requestObject.optString(GitConstants.KEY_REVIEW_REQ_NOTIFY_LOGIN); if (reviewReqLogin != null && reviewReqLogin.length() != 0) { String reviewReqUrl = requestObject.optString(GitConstants.KEY_REVIEW_REQ_URL); String ReviewReqCommit = requestObject.optString(GitConstants.KEY_REVIEW_REQ_COMMIT); String ReviewReqAuthorName = requestObject.optString(GitConstants.KEY_REVIEW_REQ_AUTHOR_NAME); String ReviewMessage = requestObject.optString(GitConstants.KEY_REVIEW_REQ_MESSAGE); return sendNotification( request, response, db, reviewReqLogin, ReviewReqCommit, reviewReqUrl, ReviewReqAuthorName, ReviewMessage); } ObjectId refId = db.resolve(gitSegment); if (refId == null || !Constants.HEAD.equals(gitSegment)) { String msg = NLS.bind("Commit failed. Ref must be HEAD and is {0}", gitSegment); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } String message = requestObject.optString(GitConstants.KEY_COMMIT_MESSAGE, null); if (message == null || message.isEmpty()) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Missing commit message.", null)); } Git git = new Git(db); CommitCommand cc = git.commit(); Config config = git.getRepository().getConfig(); boolean amend = Boolean.parseBoolean(requestObject.optString(GitConstants.KEY_COMMIT_AMEND, null)); boolean insertChangeId = GitUtils.isGerrit(config) || Boolean.parseBoolean(requestObject.optString(GitConstants.KEY_CHANGE_ID, null)); String committerName = requestObject.optString(GitConstants.KEY_COMMITTER_NAME, null); String committerEmail = requestObject.optString(GitConstants.KEY_COMMITTER_EMAIL, null); String authorName = requestObject.optString(GitConstants.KEY_AUTHOR_NAME, null); String authorEmail = requestObject.optString(GitConstants.KEY_AUTHOR_EMAIL, null); // workaround of a bug in JGit which causes invalid // support of null values of author/committer name/email, see bug 352984 PersonIdent defPersonIdent = new PersonIdent(db); if (committerName == null) committerName = defPersonIdent.getName(); if (committerEmail == null) committerEmail = defPersonIdent.getEmailAddress(); if (authorName == null) authorName = committerName; if (authorEmail == null) authorEmail = committerEmail; cc.setCommitter(committerName, committerEmail); cc.setAuthor(authorName, authorEmail); if (insertChangeId) cc.setInsertChangeId(true); // support for committing by path: "git commit -o path" if (!pattern.isEmpty()) { cc.setOnly(pattern); } try { // "git commit [--amend] -m '{message}' [-a|{path}]" RevCommit lastCommit = cc.setAmend(amend).setMessage(message).call(); URI cloneLocation = BaseToCloneConverter.getCloneLocation( getURI(request), BaseToCloneConverter.COMMIT_REFRANGE); Commit commit = new Commit(cloneLocation, db, lastCommit, pattern); JSONObject result = commit.toJSON(); OrionServlet.writeJSONResponse( request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT); return true; } catch (GitAPIException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "An error occured when commiting.", e)); } catch (UnmergedPathException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An internal error occured when commiting.", e)); } } catch (Exception e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when requesting a commit info.", e)); } }
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); }
private boolean handlePut( HttpServletRequest request, HttpServletResponse response, String pathString) throws GitAPIException, CoreException, IOException, JSONException, ServletException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); if (path.segment(0).equals("file") && path.segmentCount() > 1) { // $NON-NLS-1$ // make sure a clone is addressed WebProject webProject = GitUtils.projectFromPath(path); if (isAccessAllowed(request.getRemoteUser(), webProject)) { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.CURRENT); if (gitDirs.isEmpty()) { String msg = NLS.bind("Request path is not a git repository: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } File gitDir = gitDirs.values().iterator().next(); // make sure required fields are set JSONObject toCheckout = OrionServlet.readJSONRequest(request); JSONArray paths = toCheckout.optJSONArray(ProtocolConstants.KEY_PATH); String branch = toCheckout.optString(GitConstants.KEY_BRANCH_NAME, null); String tag = toCheckout.optString(GitConstants.KEY_TAG_NAME, null); boolean removeUntracked = toCheckout.optBoolean(GitConstants.KEY_REMOVE_UNTRACKED, false); if ((paths == null || paths.length() == 0) && branch == null && tag == null) { String msg = NLS.bind( "Either '{0}' or '{1}' or '{2}' should be provided, got: {3}", new Object[] { ProtocolConstants.KEY_PATH, GitConstants.KEY_BRANCH_NAME, GitConstants.KEY_TAG_NAME, toCheckout }); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } Git git = new Git(new FileRepository(gitDir)); if (paths != null) { Set<String> toRemove = new HashSet<String>(); CheckoutCommand checkout = git.checkout(); for (int i = 0; i < paths.length(); i++) { String p = paths.getString(i); if (removeUntracked && !isInIndex(git.getRepository(), p)) toRemove.add(p); checkout.addPath(p); } checkout.call(); for (String p : toRemove) { File f = new File(git.getRepository().getWorkTree(), p); f.delete(); } return true; } else if (tag != null && branch != null) { CheckoutCommand co = git.checkout(); try { co.setName(branch).setStartPoint(tag).setCreateBranch(true).call(); return true; } catch (RefNotFoundException e) { String msg = NLS.bind("Tag not found: {0}", tag); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, e)); } catch (GitAPIException e) { if (org.eclipse.jgit.api.CheckoutResult.Status.CONFLICTS.equals( co.getResult().getStatus())) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_CONFLICT, "Checkout aborted.", e)); } // TODO: handle other exceptions } } else if (branch != null) { if (!isLocalBranch(git, branch)) { String msg = NLS.bind("{0} is not a branch.", branch); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } CheckoutCommand co = git.checkout(); try { co.setName(Constants.R_HEADS + branch).call(); return true; } catch (CheckoutConflictException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_CONFLICT, "Checkout aborted.", e)); } catch (RefNotFoundException e) { String msg = NLS.bind("Branch name not found: {0}", branch); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, e)); } // TODO: handle other exceptions } } else { String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } } String msg = NLS.bind("Invalid checkout request {0}", pathString); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }
private boolean handleGet( HttpServletRequest request, HttpServletResponse response, String pathString) throws IOException, JSONException, ServletException, URISyntaxException, CoreException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); URI baseLocation = getURI(request); String user = request.getRemoteUser(); // expected path format is 'workspace/{workspaceId}' or // 'file/{workspaceId}/{projectName}/{path}]' if ("workspace".equals(path.segment(0)) && path.segmentCount() == 2) { // $NON-NLS-1$ // all clones in the workspace if (WebWorkspace.exists(path.segment(1))) { WebWorkspace workspace = WebWorkspace.fromId(path.segment(1)); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (WebProject webProject : workspace.getProjects()) { // this is the location of the project metadata if (isAccessAllowed(user, webProject)) { IPath projectPath = GitUtils.pathFromProject(workspace, webProject); Map<IPath, File> gitDirs = GitUtils.getGitDirs(projectPath, Traverse.GO_DOWN); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } } } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } else if ("file".equals(path.segment(0)) && path.segmentCount() > 1) { // $NON-NLS-1$ // clones under given path WebProject webProject = GitUtils.projectFromPath(path); IPath projectRelativePath = path.removeFirstSegments(3); if (webProject != null && isAccessAllowed(user, webProject) && webProject.getProjectStore().getFileStore(projectRelativePath).fetchInfo().exists()) { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.GO_DOWN); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } // else the request is malformed String msg = NLS.bind("Invalid clone request: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }