/*******************************************************************************
* Copyright (c) 2011, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.orion.server.git.servlets;
import java.net.URI;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jgit.api.CreateBranchCommand;
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
import org.eclipse.jgit.api.DeleteBranchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.internal.server.servlets.task.TaskJobHandler;
import org.eclipse.orion.server.core.LogHelper;
import org.eclipse.orion.server.core.ProtocolConstants;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.git.BaseToCloneConverter;
import org.eclipse.orion.server.git.GitConstants;
import org.eclipse.orion.server.git.jobs.ListBranchesJob;
import org.eclipse.orion.server.git.objects.Branch;
import org.eclipse.orion.server.servlets.JsonURIUnqualificationStrategy;
import org.eclipse.orion.server.servlets.OrionServlet;
import org.eclipse.osgi.util.NLS;
import org.json.JSONObject;
public class GitBranchHandlerV1 extends AbstractGitHandler {
public static int PAGE_SIZE = 50;
GitBranchHandlerV1(ServletResourceHandler<IStatus> statusHandler) {
super(statusHandler);
}
@Override
protected boolean handleGet(RequestInfo requestInfo) throws ServletException {
String gitSegment = requestInfo.gitSegment;
HttpServletRequest request = requestInfo.request;
HttpServletResponse response = requestInfo.response;
Repository db = requestInfo.db;
IPath filePath = requestInfo.filePath;
try {
if (gitSegment == null) {
// branch list: expected path /git/branch/file/{filePath}
ListBranchesJob job;
String nameFilter = request.getParameter("filter");
String commits = request.getParameter(GitConstants.KEY_TAG_COMMITS);
int commitsNumber = commits == null ? 0 : Integer.parseInt(commits);
String page = request.getParameter("page"); //$NON-NLS-1$
if (page != null) {
int pageNo = Integer.parseInt(page);
int pageSize = request.getParameter("pageSize") == null ? PAGE_SIZE : Integer.parseInt(request.getParameter("pageSize")); //$NON-NLS-1$ //$NON-NLS-2$
job = new ListBranchesJob(TaskJobHandler.getUserId(request), filePath, BaseToCloneConverter.getCloneLocation(getURI(request),
BaseToCloneConverter.BRANCH_LIST), commitsNumber, pageNo, pageSize, request.getRequestURI(), nameFilter);
} else {
job = new ListBranchesJob(TaskJobHandler.getUserId(request), filePath, BaseToCloneConverter.getCloneLocation(getURI(request),
BaseToCloneConverter.BRANCH_LIST), commitsNumber);
}
return TaskJobHandler.handleTaskJob(request, response, job, statusHandler, JsonURIUnqualificationStrategy.ALL_NO_GIT);
}
// branch details: expected path /git/branch/{name}/file/{filePath}
List<Ref> branches = new Git(db).branchList().call();
JSONObject result = null;
URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.BRANCH);
for (Ref ref : branches) {
if (Repository.shortenRefName(ref.getName()).equals(gitSegment)) {
result = new Branch(cloneLocation, db, ref).toJSON();
break;
}
}
if (result == null) {
String msg = NLS.bind("Branch {0} not found", gitSegment);
return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null));
}
OrionServlet.writeJSONResponse(request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
return true;
} catch (Exception e) {
final ServerStatus error = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"An error occured when looking for a branch.", e);
LogHelper.log(error);
return statusHandler.handleRequest(request, response, error);
}
}
@Override
protected boolean handlePost(RequestInfo requestInfo) throws ServletException {
String gitSegment = requestInfo.gitSegment;
HttpServletRequest request = requestInfo.request;
HttpServletResponse response = requestInfo.response;
Repository db = requestInfo.db;
IPath filePath = requestInfo.filePath;
JSONObject toCreate = requestInfo.getJSONRequest();
try {
if (gitSegment == null) {
// expected path /gitapi/branch/file/{filePath}
String branchName = toCreate.optString(ProtocolConstants.KEY_NAME, null);
String startPoint = toCreate.optString(GitConstants.KEY_BRANCH_NAME, null);
if (branchName == null || branchName.isEmpty()) {
if (startPoint == null || startPoint.isEmpty())
return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST,
"Branch name must be provided", null));
else {
String shortName = Repository.shortenRefName(startPoint);
branchName = shortName.substring(shortName.indexOf("/") + 1); //$NON-NLS-1$
}
}
CreateBranchCommand cc = new Git(db).branchCreate();
cc.setName(branchName);
if (startPoint != null && !startPoint.isEmpty()) {
cc.setStartPoint(startPoint);
cc.setUpstreamMode(SetupUpstreamMode.TRACK);
}
Ref ref = cc.call();
URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.BRANCH_LIST);
JSONObject result = new Branch(cloneLocation, db, ref).toJSON();
OrionServlet.writeJSONResponse(request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT);
response.setHeader(ProtocolConstants.HEADER_LOCATION, result.getString(ProtocolConstants.KEY_LOCATION));
response.setStatus(HttpServletResponse.SC_CREATED);
return true;
}
String msg = NLS.bind("Failed to create a branch for {0}", filePath); //$NON-NLS-1$
return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
} catch (Exception e) {
return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"An error occured when creating a branch.", e));
}
}
@Override
protected boolean handleDelete(RequestInfo requestInfo) throws ServletException {
String gitSegment = requestInfo.gitSegment;
HttpServletRequest request = requestInfo.request;
HttpServletResponse response = requestInfo.response;
Git git = requestInfo.git;
try {
if (gitSegment != null) {
DeleteBranchCommand cc = git.branchDelete();
cc.setBranchNames(gitSegment);
// TODO: the force flag should be passed in the API call
cc.setForce(true);
cc.call();
// TODO: do something with the result
return true;
}
return false;
} catch (Exception e) {
return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"An error occured when removing a branch.", e));
}
}
}