James Moger
2011-07-22 b1dba764c201f4708b82767b2d91edb6e189ce6f
src/com/gitblit/GitBlit.java
@@ -17,6 +17,7 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,6 +25,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
@@ -32,11 +34,13 @@
import org.apache.wicket.protocol.http.WebResponse;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.resolver.FileResolver;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -124,6 +128,20 @@
    */
   public static int getInteger(String key, int defaultValue) {
      return self().settings.getInteger(key, defaultValue);
   }
   /**
    * Returns the char value for the specified key. If the key does not exist
    * or the value for the key can not be interpreted as a character, the
    * defaultValue is returned.
    *
    * @see IStoredSettings.getChar(String key, char defaultValue)
    * @param key
    * @param defaultValue
    * @return key value or defaultValue
    */
   public static char getChar(String key, char defaultValue) {
      return self().settings.getChar(key, defaultValue);
   }
   /**
@@ -433,7 +451,7 @@
      RepositoryModel model = new RepositoryModel();
      model.name = repositoryName;
      model.hasCommits = JGitUtils.hasCommits(r);
      model.lastChange = JGitUtils.getLastChange(r);
      model.lastChange = JGitUtils.getLastChange(r, null);
      StoredConfig config = JGitUtils.readConfig(r);
      if (config != null) {
         model.description = getConfig(config, "description", "");
@@ -448,6 +466,52 @@
      }
      r.close();
      return model;
   }
   /**
    * Returns the size in bytes of the repository.
    *
    * @param model
    * @return size in bytes
    */
   public long calculateSize(RepositoryModel model) {
      File gitDir = FileKey.resolve(new File(repositoriesFolder, model.name), FS.DETECTED);
      return com.gitblit.utils.FileUtils.folderSize(gitDir);
   }
   /**
    * Ensure that a cached repository is completely closed and its resources
    * are properly released.
    *
    * @param repositoryName
    */
   private void closeRepository(String repositoryName) {
      Repository repository = getRepository(repositoryName);
      // assume 2 uses in case reflection fails
      int uses = 2;
      try {
         // The FileResolver caches repositories which is very useful
         // for performance until you want to delete a repository.
         // I have to use reflection to call close() the correct
         // number of times to ensure that the object and ref databases
         // are properly closed before I can delete the repository from
         // the filesystem.
         Field useCnt = Repository.class.getDeclaredField("useCnt");
         useCnt.setAccessible(true);
         uses = ((AtomicInteger) useCnt.get(repository)).get();
      } catch (Exception e) {
         logger.warn(MessageFormat
               .format("Failed to reflectively determine use count for repository {0}",
                     repositoryName), e);
      }
      if (uses > 0) {
         logger.info(MessageFormat
               .format("{0}.useCnt={1}, calling close() {2} time(s) to close object and ref databases",
                     repositoryName, uses, uses));
         for (int i = 0; i < uses; i++) {
            repository.close();
         }
      }
   }
   /**
@@ -513,6 +577,7 @@
      } else {
         // rename repository
         if (!repositoryName.equalsIgnoreCase(repository.name)) {
            closeRepository(repositoryName);
            File folder = new File(repositoriesFolder, repositoryName);
            File destFolder = new File(repositoriesFolder, repository.name);
            if (destFolder.exists()) {
@@ -588,6 +653,7 @@
    */
   public boolean deleteRepository(String repositoryName) {
      try {
         closeRepository(repositoryName);
         File folder = new File(repositoriesFolder, repositoryName);
         if (folder.exists() && folder.isDirectory()) {
            FileUtils.delete(folder, FileUtils.RECURSIVE | FileUtils.RETRY);