From 7ec9d3d1b460db339db2770f3aa81af9826deed3 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 03 Jan 2013 17:21:32 -0500
Subject: [PATCH] Build project models from repository cache, when possible (issue-172)

---
 src/com/gitblit/GitBlit.java                         |   43 +++++++++++++++++++++
 docs/04_releases.mkd                                 |    1 
 src/com/gitblit/wicket/pages/ProjectPage.java        |    4 +-
 src/com/gitblit/wicket/pages/ProjectsPage.java       |    7 ---
 src/com/gitblit/wicket/panels/RepositoriesPanel.java |   18 +++-----
 5 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd
index faec56a..32fb029 100644
--- a/docs/04_releases.mkd
+++ b/docs/04_releases.mkd
@@ -7,6 +7,7 @@
 #### fixes
 
 - Fixed nullpointer when using web.allowForking = true && git.cacheRepositoryList = false (issue 182)
+- Build project models from the repository model cache, when possible, to reduce page load time (issue 172)
 - Fixed loading of Brazilian Portuguese translation from *nix server (github/inaiat)
 
 ### Older Releases
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index 3dcd5a0..96333a0 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -1526,6 +1526,49 @@
 	}
 	
 	/**
+	 * 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
+	 */
+	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());
+	}
+	
+	/**
 	 * Workaround JGit.  I need to access the raw config object directly in order
 	 * to see if the config is dirty so that I can reload a repository model.
 	 * If I use the stock JGit method to get the config it already reloads the
diff --git a/src/com/gitblit/wicket/pages/ProjectPage.java b/src/com/gitblit/wicket/pages/ProjectPage.java
index bc546df..e10ca90 100644
--- a/src/com/gitblit/wicket/pages/ProjectPage.java
+++ b/src/com/gitblit/wicket/pages/ProjectPage.java
@@ -300,8 +300,8 @@
 	@Override
 	protected List<ProjectModel> getProjectModels() {
 		if (projectModels.isEmpty()) {
-			final UserModel user = GitBlitWebSession.get().getUser();
-			List<ProjectModel> projects = GitBlit.self().getProjectModels(user, false);
+			List<RepositoryModel> repositories = getRepositoryModels();
+			List<ProjectModel> projects = GitBlit.self().getProjectModels(repositories, false);
 			projectModels.addAll(projects);
 		}
 		return projectModels;
diff --git a/src/com/gitblit/wicket/pages/ProjectsPage.java b/src/com/gitblit/wicket/pages/ProjectsPage.java
index 4e3e630..7f0b002 100644
--- a/src/com/gitblit/wicket/pages/ProjectsPage.java
+++ b/src/com/gitblit/wicket/pages/ProjectsPage.java
@@ -36,7 +36,6 @@
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
 import com.gitblit.models.ProjectModel;
-import com.gitblit.models.UserModel;
 import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
@@ -47,8 +46,6 @@
 import com.gitblit.wicket.panels.LinkPanel;
 
 public class ProjectsPage extends RootPage {
-
-	List<ProjectModel> projectModels = new ArrayList<ProjectModel>();
 
 	public ProjectsPage() {
 		super();
@@ -67,9 +64,7 @@
 	
 	@Override
 	protected List<ProjectModel> getProjectModels() {
-		final UserModel user = GitBlitWebSession.get().getUser();
-		List<ProjectModel> projects = GitBlit.self().getProjectModels(user, false);
-		return projects;
+		return GitBlit.self().getProjectModels(getRepositoryModels(), false);
 	}
 
 	private void setup(PageParameters params) {
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
index d3b8ddb..976c517 100644
--- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java
+++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
@@ -123,22 +123,18 @@
 
 			if (rootRepositories.size() > 0) {
 				// inject the root repositories at the top of the page
-				String rootPath = GitBlit.getString(Keys.web.repositoryRootGroupName, " ");
-				roots.add(0, rootPath);
-				groups.put(rootPath, rootRepositories);
+				roots.add(0, "");
+				groups.put("", rootRepositories);
 			}
 						
-			Map<String, ProjectModel> projects = new HashMap<String, ProjectModel>();
-			for (ProjectModel project : GitBlit.self().getProjectModels(user, true)) {
-				projects.put(project.name, project);
-			}
 			List<RepositoryModel> groupedModels = new ArrayList<RepositoryModel>();
 			for (String root : roots) {
 				List<RepositoryModel> subModels = groups.get(root);
-				GroupRepositoryModel group = new GroupRepositoryModel(root, subModels.size());
-				if (projects.containsKey(root)) {
-					group.title = projects.get(root).title;
-					group.description = projects.get(root).description;
+				ProjectModel project = GitBlit.self().getProjectModel(root);
+				GroupRepositoryModel group = new GroupRepositoryModel(project.name, subModels.size());
+				if (project != null) {
+					group.title = project.title;
+					group.description = project.description;
 				}
 				groupedModels.add(group);
 				Collections.sort(subModels);

--
Gitblit v1.9.1