From a1f27e2fac7b38b87645bd53b7e023484c796f1c Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Fri, 29 Nov 2013 11:05:51 -0500
Subject: [PATCH] Extract ProjectManager from the GitBlit singleton

---
 src/main/java/com/gitblit/GitBlit.java |  256 --------------------------------------------------
 1 files changed, 3 insertions(+), 253 deletions(-)

diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java
index 4e8822b..493f8fc 100644
--- a/src/main/java/com/gitblit/GitBlit.java
+++ b/src/main/java/com/gitblit/GitBlit.java
@@ -32,10 +32,8 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
@@ -50,8 +48,6 @@
 
 import org.apache.wicket.resource.ContextRelativeResource;
 import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
-import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.FS;
 import org.slf4j.Logger;
 
 import com.gitblit.Constants.AccessPermission;
@@ -77,7 +73,6 @@
 import com.gitblit.models.FederationProposal;
 import com.gitblit.models.FederationSet;
 import com.gitblit.models.GitClientApplication;
-import com.gitblit.models.ProjectModel;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.RepositoryUrl;
 import com.gitblit.models.ServerSettings;
@@ -86,12 +81,10 @@
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.ContainerUtils;
-import com.gitblit.utils.DeepCopier;
 import com.gitblit.utils.FederationUtils;
 import com.gitblit.utils.HttpUtils;
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.JsonUtils;
-import com.gitblit.utils.ModelUtils;
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitblitWicketFilter;
@@ -117,8 +110,7 @@
  */
 @WebListener
 public class GitBlit extends DaggerContextListener
-					 implements IProjectManager,
-								IFederationManager,
+					 implements IFederationManager,
 								IGitblitManager {
 
 	private static GitBlit gitblit;
@@ -138,15 +130,7 @@
 
 	private final Map<String, FederationModel> federationPullResults = new ConcurrentHashMap<String, FederationModel>();
 
-	private final Map<String, ProjectModel> projectCache = new ConcurrentHashMap<String, ProjectModel>();
-
-	private final ObjectCache<String> projectMarkdownCache = new ObjectCache<String>();
-
-	private final ObjectCache<String> projectRepositoriesMarkdownCache = new ObjectCache<String>();
-
 	private IStoredSettings settings;
-
-	private FileBasedConfig projectConfigs;
 
 	private FanoutService fanoutService;
 
@@ -442,237 +426,6 @@
 		}
 	}
 
-	private void reloadProjectMarkdown(ProjectModel project) {
-		// project markdown
-		File pmkd = new File(getManager(IRepositoryManager.class).getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/project.mkd");
-		if (pmkd.exists()) {
-			Date lm = new Date(pmkd.lastModified());
-			if (!projectMarkdownCache.hasCurrent(project.name, lm)) {
-				String mkd = com.gitblit.utils.FileUtils.readContent(pmkd,  "\n");
-				projectMarkdownCache.updateObject(project.name, lm, mkd);
-			}
-			project.projectMarkdown = projectMarkdownCache.getObject(project.name);
-		}
-
-		// project repositories markdown
-		File rmkd = new File(getManager(IRepositoryManager.class).getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/repositories.mkd");
-		if (rmkd.exists()) {
-			Date lm = new Date(rmkd.lastModified());
-			if (!projectRepositoriesMarkdownCache.hasCurrent(project.name, lm)) {
-				String mkd = com.gitblit.utils.FileUtils.readContent(rmkd,  "\n");
-				projectRepositoriesMarkdownCache.updateObject(project.name, lm, mkd);
-			}
-			project.repositoriesMarkdown = projectRepositoriesMarkdownCache.getObject(project.name);
-		}
-	}
-
-
-	/**
-	 * Returns the map of project config.  This map is cached and reloaded if
-	 * the underlying projects.conf file changes.
-	 *
-	 * @return project config map
-	 */
-	private Map<String, ProjectModel> getProjectConfigs() {
-		if (projectCache.isEmpty() || projectConfigs.isOutdated()) {
-
-			try {
-				projectConfigs.load();
-			} catch (Exception e) {
-			}
-
-			// project configs
-			String rootName = settings.getString(Keys.web.repositoryRootGroupName, "main");
-			ProjectModel rootProject = new ProjectModel(rootName, true);
-
-			Map<String, ProjectModel> configs = new HashMap<String, ProjectModel>();
-			// cache the root project under its alias and an empty path
-			configs.put("", rootProject);
-			configs.put(rootProject.name.toLowerCase(), rootProject);
-
-			for (String name : projectConfigs.getSubsections("project")) {
-				ProjectModel project;
-				if (name.equalsIgnoreCase(rootName)) {
-					project = rootProject;
-				} else {
-					project = new ProjectModel(name);
-				}
-				project.title = projectConfigs.getString("project", name, "title");
-				project.description = projectConfigs.getString("project", name, "description");
-
-				reloadProjectMarkdown(project);
-
-				configs.put(name.toLowerCase(), project);
-			}
-			projectCache.clear();
-			projectCache.putAll(configs);
-		}
-		return projectCache;
-	}
-
-	/**
-	 * Returns a list of project models for the user.
-	 *
-	 * @param user
-	 * @param includeUsers
-	 * @return list of projects that are accessible to the user
-	 */
-	@Override
-	public List<ProjectModel> getProjectModels(UserModel user, boolean includeUsers) {
-		Map<String, ProjectModel> configs = getProjectConfigs();
-
-		// per-user project lists, this accounts for security and visibility
-		Map<String, ProjectModel> map = new TreeMap<String, ProjectModel>();
-		// root project
-		map.put("", configs.get(""));
-
-		for (RepositoryModel model : getManager(IRepositoryManager.class).getRepositoryModels(user)) {
-			String rootPath = StringUtils.getRootPath(model.name).toLowerCase();
-			if (!map.containsKey(rootPath)) {
-				ProjectModel project;
-				if (configs.containsKey(rootPath)) {
-					// clone the project model because it's repository list will
-					// be tailored for the requesting user
-					project = DeepCopier.copy(configs.get(rootPath));
-				} else {
-					project = new ProjectModel(rootPath);
-				}
-				map.put(rootPath, project);
-			}
-			map.get(rootPath).addRepository(model);
-		}
-
-		// sort projects, root project first
-		List<ProjectModel> projects;
-		if (includeUsers) {
-			// all projects
-			projects = new ArrayList<ProjectModel>(map.values());
-			Collections.sort(projects);
-			projects.remove(map.get(""));
-			projects.add(0, map.get(""));
-		} else {
-			// all non-user projects
-			projects = new ArrayList<ProjectModel>();
-			ProjectModel root = map.remove("");
-			for (ProjectModel model : map.values()) {
-				if (!model.isUserProject()) {
-					projects.add(model);
-				}
-			}
-			Collections.sort(projects);
-			projects.add(0, root);
-		}
-		return projects;
-	}
-
-	/**
-	 * Returns the project model for the specified user.
-	 *
-	 * @param name
-	 * @param user
-	 * @return a project model, or null if it does not exist
-	 */
-	@Override
-	public ProjectModel getProjectModel(String name, UserModel user) {
-		for (ProjectModel project : getProjectModels(user, true)) {
-			if (project.name.equalsIgnoreCase(name)) {
-				return project;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns a project model for the Gitblit/system user.
-	 *
-	 * @param name a project name
-	 * @return a project model or null if the project does not exist
-	 */
-	@Override
-	public ProjectModel getProjectModel(String name) {
-		Map<String, ProjectModel> configs = getProjectConfigs();
-		ProjectModel project = configs.get(name.toLowerCase());
-		if (project == null) {
-			project = new ProjectModel(name);
-			if (ModelUtils.isPersonalRepository(name)) {
-				UserModel user = getManager(IUserManager.class).getUserModel(ModelUtils.getUserNameFromRepoPath(name));
-				if (user != null) {
-					project.title = user.getDisplayName();
-					project.description = "personal repositories";
-				}
-			}
-		} else {
-			// clone the object
-			project = DeepCopier.copy(project);
-		}
-		if (StringUtils.isEmpty(name)) {
-			// get root repositories
-			for (String repository : getManager(IRepositoryManager.class).getRepositoryList()) {
-				if (repository.indexOf('/') == -1) {
-					project.addRepository(repository);
-				}
-			}
-		} else {
-			// get repositories in subfolder
-			String folder = name.toLowerCase() + "/";
-			for (String repository : getManager(IRepositoryManager.class).getRepositoryList()) {
-				if (repository.toLowerCase().startsWith(folder)) {
-					project.addRepository(repository);
-				}
-			}
-		}
-		if (project.repositories.size() == 0) {
-			// no repositories == no project
-			return null;
-		}
-
-		reloadProjectMarkdown(project);
-		return project;
-	}
-
-	/**
-	 * Returns the list of project models that are referenced by the supplied
-	 * repository model	list.  This is an alternative method exists to ensure
-	 * Gitblit does not call getRepositoryModels(UserModel) twice in a request.
-	 *
-	 * @param repositoryModels
-	 * @param includeUsers
-	 * @return a list of project models
-	 */
-	@Override
-	public List<ProjectModel> getProjectModels(List<RepositoryModel> repositoryModels, boolean includeUsers) {
-		Map<String, ProjectModel> projects = new LinkedHashMap<String, ProjectModel>();
-		for (RepositoryModel repository : repositoryModels) {
-			if (!includeUsers && repository.isPersonalRepository()) {
-				// exclude personal repositories
-				continue;
-			}
-			if (!projects.containsKey(repository.projectPath)) {
-				ProjectModel project = getProjectModel(repository.projectPath);
-				if (project == null) {
-					logger.warn(MessageFormat.format("excluding project \"{0}\" from project list because it is empty!",
-							repository.projectPath));
-					continue;
-				}
-				projects.put(repository.projectPath, project);
-				// clear the repo list in the project because that is the system
-				// list, not the user-accessible list and start building the
-				// user-accessible list
-				project.repositories.clear();
-				project.repositories.add(repository.name);
-				project.lastChange = repository.lastChange;
-			} else {
-				// update the user-accessible list
-				// this is used for repository count
-				ProjectModel project = projects.get(repository.projectPath);
-				project.repositories.add(repository.name);
-				if (project.lastChange.before(repository.lastChange)) {
-					project.lastChange = repository.lastChange;
-				}
-			}
-		}
-		return new ArrayList<ProjectModel>(projects.values());
-	}
 
 	/**
 	 * Returns Gitblit's scheduled executor service for scheduling tasks.
@@ -1173,7 +926,7 @@
 						getManager(IUserManager.class),
 						getManager(ISessionManager.class),
 						getManager(IRepositoryManager.class),
-						this,
+						getManager(IProjectManager.class),
 						this,
 						this);
 				gitDaemon = new GitDaemon(gitblit);
@@ -1242,14 +995,11 @@
 		startManager(injector, IUserManager.class);
 		startManager(injector, ISessionManager.class);
 		startManager(injector, IRepositoryManager.class);
+		startManager(injector, IProjectManager.class);
 
 		logger.info("Gitblit base folder     = " + baseFolder.getAbsolutePath());
 
 		loadSettingModels(runtime.getSettingsModel());
-
-		// load and cache the project metadata
-		projectConfigs = new FileBasedConfig(runtime.getFileOrFolder(Keys.web.projectsFile, "${baseFolder}/projects.conf"), FS.detect());
-		getProjectConfigs();
 
 		if (true/*startFederation*/) {
 			configureFederation();

--
Gitblit v1.9.1