/******************************************************************************* * Copyright (c) 2015 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.jobs; import java.io.File; import java.net.URI; import java.util.Map.Entry; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.orion.server.core.ServerStatus; import org.eclipse.orion.server.git.GitActivator; import org.eclipse.orion.server.git.servlets.GitUtils; import org.eclipse.orion.server.git.servlets.GitUtils.Traverse; import org.eclipse.osgi.util.NLS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A job to perform a git status in the background. */ public class StatusJob extends GitJob { private static final int GIT_PERF_THRESHOLD = 10000;// 10 seconds private IPath filePath; private URI baseLocation; /** * Creates job with given the file path within a git repository. * * @param userRunningTask * @param filePath * @param baseLocation */ public StatusJob(String userRunningTask, Path filePath, URI baseLocation) { super(userRunningTask, false); this.filePath = filePath; this.baseLocation = baseLocation; } @Override protected IStatus performJob() { Logger logger = LoggerFactory.getLogger("org.eclipse.orion.server.git"); Repository db = null; try { long t0 = System.currentTimeMillis(); Set<Entry<IPath, File>> set = GitUtils.getGitDirs(this.filePath, Traverse.GO_UP).entrySet(); File gitDir = set.iterator().next().getValue(); if (gitDir == null) { logger.error("***** Git status failed to find Git directory for request: " + this.filePath); String msg = NLS.bind("Could not find repository for {0}", filePath); return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null); } long t1 = System.currentTimeMillis(); db = FileRepositoryBuilder.create(gitDir); Git git = Git.wrap(db); org.eclipse.jgit.api.Status gitStatus = git.status().call(); long t2 = System.currentTimeMillis(); String relativePath = GitUtils.getRelativePath(this.filePath, set.iterator().next().getKey()); IPath basePath = new Path(relativePath); org.eclipse.orion.server.git.objects.Status status = new org.eclipse.orion.server.git.objects.Status(this.baseLocation, db, gitStatus, basePath); ServerStatus result = new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, status.toJSON()); if (logger.isDebugEnabled() && (t2 - t0) > GIT_PERF_THRESHOLD) { logger.debug("Slow git status. Finding git dir: " + (t1 - t0) + "ms. JGit status call: " + (t2 - t1) + "ms"); } return result; } catch (Exception e) { String msg = NLS.bind("An error occured when generating status for ref {0}", this.filePath); return new Status(IStatus.ERROR, GitActivator.PI_GIT, msg, e); } finally { if (db != null) { db.close(); } } } }