From 3f5b8f5d9203aa7ffb7fbe9cdbaf9dba3da6cae6 Mon Sep 17 00:00:00 2001
From: Hybris95 <hybris_95@hotmail.com>
Date: Thu, 01 May 2014 16:14:15 -0400
Subject: [PATCH] Fixes sort, page building and search functions on "my tickets" page.

---
 src/main/java/com/gitblit/GitBlit.java |  963 +++++++++++++++++++-------------------------------------
 1 files changed, 330 insertions(+), 633 deletions(-)

diff --git a/src/main/java/com/gitblit/GitBlit.java b/src/main/java/com/gitblit/GitBlit.java
index d4e89b0..3db5f08 100644
--- a/src/main/java/com/gitblit/GitBlit.java
+++ b/src/main/java/com/gitblit/GitBlit.java
@@ -15,740 +15,437 @@
  */
 package com.gitblit;
 
-import java.io.File;
-import java.util.Collection;
-import java.util.Date;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.TimeZone;
+import java.util.Set;
 
+import javax.inject.Singleton;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
-import org.eclipse.jgit.lib.Repository;
-
-import com.gitblit.Constants.FederationRequest;
-import com.gitblit.Constants.FederationToken;
+import com.gitblit.Constants.AccessPermission;
+import com.gitblit.Constants.Transport;
+import com.gitblit.manager.GitblitManager;
 import com.gitblit.manager.IAuthenticationManager;
 import com.gitblit.manager.IFederationManager;
-import com.gitblit.manager.IGitblitManager;
+import com.gitblit.manager.IGitblit;
 import com.gitblit.manager.INotificationManager;
+import com.gitblit.manager.IPluginManager;
 import com.gitblit.manager.IProjectManager;
 import com.gitblit.manager.IRepositoryManager;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
-import com.gitblit.models.FederationModel;
-import com.gitblit.models.FederationProposal;
-import com.gitblit.models.FederationSet;
-import com.gitblit.models.ForkModel;
-import com.gitblit.models.GitClientApplication;
-import com.gitblit.models.Metric;
-import com.gitblit.models.ProjectModel;
-import com.gitblit.models.RegistrantAccessPermission;
+import com.gitblit.manager.ServicesManager;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.RepositoryUrl;
-import com.gitblit.models.SearchResult;
-import com.gitblit.models.ServerSettings;
-import com.gitblit.models.ServerStatus;
-import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
+import com.gitblit.tickets.BranchTicketService;
+import com.gitblit.tickets.FileTicketService;
+import com.gitblit.tickets.ITicketService;
+import com.gitblit.tickets.NullTicketService;
+import com.gitblit.tickets.RedisTicketService;
+import com.gitblit.transport.ssh.IPublicKeyManager;
+import com.gitblit.utils.StringUtils;
+
+import dagger.Module;
+import dagger.ObjectGraph;
+import dagger.Provides;
 
 /**
- * GitBlit is an aggregate interface delegate.  It implements all the manager
- * interfaces and delegates all methods calls to the actual manager implementations.
- * It's primary purpose is to provide complete management control to the git
- * upload and receive pack functions.
+ * GitBlit is the aggregate manager for the Gitblit webapp.  It provides all
+ * management functions and also manages some long-running services.
  *
  * @author James Moger
  *
  */
-public class GitBlit implements IRuntimeManager,
-								INotificationManager,
-								IUserManager,
-								IAuthenticationManager,
-								IRepositoryManager,
-								IProjectManager,
-								IGitblitManager,
-								IFederationManager {
+public class GitBlit extends GitblitManager {
 
-	private final IRuntimeManager runtimeManager;
+	private final ObjectGraph injector;
 
-	private final INotificationManager notificationManager;
+	private final ServicesManager servicesManager;
 
-	private final IUserManager userManager;
-
-	private final IAuthenticationManager authenticationManager;
-
-	private final IRepositoryManager repositoryManager;
-
-	private final IProjectManager projectManager;
-
-	private final IGitblitManager gitblitManager;
-
-	private final IFederationManager federationManager;
+	private ITicketService ticketService;
 
 	public GitBlit(
 			IRuntimeManager runtimeManager,
+			IPluginManager pluginManager,
 			INotificationManager notificationManager,
 			IUserManager userManager,
 			IAuthenticationManager authenticationManager,
+			IPublicKeyManager publicKeyManager,
 			IRepositoryManager repositoryManager,
 			IProjectManager projectManager,
-			IGitblitManager gitblitManager,
 			IFederationManager federationManager) {
 
-		this.runtimeManager = runtimeManager;
-		this.notificationManager = notificationManager;
-		this.userManager = userManager;
-		this.authenticationManager = authenticationManager;
-		this.repositoryManager = repositoryManager;
-		this.projectManager = projectManager;
-		this.gitblitManager = gitblitManager;
-		this.federationManager = federationManager;
+		super(runtimeManager,
+				pluginManager,
+				notificationManager,
+				userManager,
+				authenticationManager,
+				publicKeyManager,
+				repositoryManager,
+				projectManager,
+				federationManager);
+
+		this.injector = ObjectGraph.create(getModules());
+
+		this.servicesManager = new ServicesManager(this);
 	}
 
 	@Override
 	public GitBlit start() {
+		super.start();
+		logger.info("Starting services manager...");
+		servicesManager.start();
+		configureTicketService();
 		return this;
 	}
 
 	@Override
 	public GitBlit stop() {
+		super.stop();
+		servicesManager.stop();
+		ticketService.stop();
 		return this;
-	}
-
-	/*
-	 * ISTOREDSETTINGS
-	 *
-	 * these methods are necessary for (nearly) seamless Groovy hook operation
-	 * after the massive refactor.
-	 */
-
-	public boolean getBoolean(String key, boolean defaultValue) {
-		return runtimeManager.getSettings().getBoolean(key, defaultValue);
-	}
-
-	public String getString(String key, String defaultValue) {
-		return runtimeManager.getSettings().getString(key, defaultValue);
-	}
-
-	public int getInteger(String key, int defaultValue) {
-		return runtimeManager.getSettings().getInteger(key, defaultValue);
-	}
-
-	public List<String> getStrings(String key) {
-		return runtimeManager.getSettings().getStrings(key);
-	}
-
-	/*
-	 * RUNTIME MANAGER
-	 */
-
-	@Override
-	public File getBaseFolder() {
-		return runtimeManager.getBaseFolder();
-	}
-
-	@Override
-	public void setBaseFolder(File folder) {
-		runtimeManager.setBaseFolder(folder);
-	}
-
-	@Override
-	public Date getBootDate() {
-		return runtimeManager.getBootDate();
-	}
-
-	@Override
-	public ServerSettings getSettingsModel() {
-		return runtimeManager.getSettingsModel();
 	}
 
 	@Override
 	public boolean isServingRepositories() {
-		return runtimeManager.isServingRepositories();
+		return servicesManager.isServingRepositories();
 	}
 
-	@Override
-	public TimeZone getTimezone() {
-		return runtimeManager.getTimezone();
+	protected Object [] getModules() {
+		return new Object [] { new GitBlitModule()};
 	}
 
-	@Override
-	public boolean isDebugMode() {
-		return runtimeManager.isDebugMode();
+	protected boolean acceptPush(Transport byTransport) {
+		if (byTransport == null) {
+			logger.info("Unknown transport, push rejected!");
+			return false;
+		}
+
+		Set<Transport> transports = new HashSet<Transport>();
+		for (String value : getSettings().getStrings(Keys.git.acceptedPushTransports)) {
+			Transport transport = Transport.fromString(value);
+			if (transport == null) {
+				logger.info(String.format("Ignoring unknown registered transport %s", value));
+				continue;
+			}
+
+			transports.add(transport);
+		}
+
+		if (transports.isEmpty()) {
+			// no transports are explicitly specified, all are acceptable
+			return true;
+		}
+
+		// verify that the transport is permitted
+		return transports.contains(byTransport);
 	}
 
-	@Override
-	public File getFileOrFolder(String key, String defaultFileOrFolder) {
-		return runtimeManager.getFileOrFolder(key, defaultFileOrFolder);
-	}
-
-	@Override
-	public File getFileOrFolder(String fileOrFolder) {
-		return runtimeManager.getFileOrFolder(fileOrFolder);
-	}
-
-	@Override
-	public IStoredSettings getSettings() {
-		return runtimeManager.getSettings();
-	}
-
-	@Override
-	public boolean updateSettings(Map<String, String> updatedSettings) {
-		return runtimeManager.updateSettings(updatedSettings);
-	}
-
-	@Override
-	public ServerStatus getStatus() {
-		return runtimeManager.getStatus();
-	}
-
-	/*
-	 * NOTIFICATION MANAGER
+	/**
+	 * Returns a list of repository URLs and the user access permission.
+	 *
+	 * @param request
+	 * @param user
+	 * @param repository
+	 * @return a list of repository urls
 	 */
-
 	@Override
-	public void sendMailToAdministrators(String subject, String message) {
-		notificationManager.sendMailToAdministrators(subject, message);
+	public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
+		if (user == null) {
+			user = UserModel.ANONYMOUS;
+		}
+		String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username);
+
+		List<RepositoryUrl> list = new ArrayList<RepositoryUrl>();
+
+		// http/https url
+		if (settings.getBoolean(Keys.git.enableGitServlet, true)) {
+			AccessPermission permission = user.getRepositoryPermission(repository).permission;
+			if (permission.exceeds(AccessPermission.NONE)) {
+				Transport transport = Transport.fromString(request.getScheme());
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(transport)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+				list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), permission));
+			}
+		}
+
+		// ssh daemon url
+		String sshDaemonUrl = servicesManager.getSshDaemonUrl(request, user, repository);
+		if (!StringUtils.isEmpty(sshDaemonUrl)) {
+			AccessPermission permission = user.getRepositoryPermission(repository).permission;
+			if (permission.exceeds(AccessPermission.NONE)) {
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.SSH)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+
+				list.add(new RepositoryUrl(sshDaemonUrl, permission));
+			}
+		}
+
+		// git daemon url
+		String gitDaemonUrl = servicesManager.getGitDaemonUrl(request, user, repository);
+		if (!StringUtils.isEmpty(gitDaemonUrl)) {
+			AccessPermission permission = servicesManager.getGitDaemonAccessPermission(user, repository);
+			if (permission.exceeds(AccessPermission.NONE)) {
+				if (permission.atLeast(AccessPermission.PUSH) && !acceptPush(Transport.GIT)) {
+					// downgrade the repo permission for this transport
+					// because it is not an acceptable PUSH transport
+					permission = AccessPermission.CLONE;
+				}
+				list.add(new RepositoryUrl(gitDaemonUrl, permission));
+			}
+		}
+
+		// add all other urls
+		// {0} = repository
+		// {1} = username
+		for (String url : settings.getStrings(Keys.web.otherUrls)) {
+			if (url.contains("{1}")) {
+				// external url requires username, only add url IF we have one
+				if (!StringUtils.isEmpty(username)) {
+					list.add(new RepositoryUrl(MessageFormat.format(url, repository.name, username), null));
+				}
+			} else {
+				// external url does not require username
+				list.add(new RepositoryUrl(MessageFormat.format(url, repository.name), null));
+			}
+		}
+
+		// sort transports by highest permission and then by transport security
+		Collections.sort(list, new Comparator<RepositoryUrl>() {
+
+			@Override
+			public int compare(RepositoryUrl o1, RepositoryUrl o2) {
+				if (!o1.isExternal() && o2.isExternal()) {
+					// prefer Gitblit over external
+					return -1;
+				} else if (o1.isExternal() && !o2.isExternal()) {
+					// prefer Gitblit over external
+					return 1;
+				} else if (o1.isExternal() && o2.isExternal()) {
+					// sort by Transport ordinal
+					return o1.transport.compareTo(o2.transport);
+				} else if (o1.permission.exceeds(o2.permission)) {
+					// prefer highest permission
+					return -1;
+				} else if (o2.permission.exceeds(o1.permission)) {
+					// prefer highest permission
+					return 1;
+				}
+
+				// prefer more secure transports
+				return o1.transport.compareTo(o2.transport);
+			}
+		});
+
+		return list;
 	}
 
-	@Override
-	public void sendMail(String subject, String message, Collection<String> toAddresses) {
-		notificationManager.sendMail(subject, message, toAddresses);
-	}
-
-	@Override
-	public void sendMail(String subject, String message, String... toAddresses) {
-		notificationManager.sendMail(subject, message, toAddresses);
-	}
-
-	@Override
-	public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
-		notificationManager.sendHtmlMail(subject, message, toAddresses);
-	}
-
-	@Override
-	public void sendHtmlMail(String subject, String message, String... toAddresses) {
-		notificationManager.sendHtmlMail(subject, message, toAddresses);
-	}
-
-	/*
-	 * SESSION MANAGER
+	/**
+	 * Detect renames and reindex as appropriate.
 	 */
-
 	@Override
-	public UserModel authenticate(String username, char[] password) {
-		return authenticationManager.authenticate(username, password);
+	public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
+			boolean isCreate) throws GitBlitException {
+		RepositoryModel oldModel = null;
+		boolean isRename = !isCreate && !repositoryName.equalsIgnoreCase(repository.name);
+		if (isRename) {
+			oldModel = repositoryManager.getRepositoryModel(repositoryName);
+		}
+
+		super.updateRepositoryModel(repositoryName, repository, isCreate);
+
+		if (isRename && ticketService != null) {
+			ticketService.rename(oldModel, repository);
+		}
 	}
 
-	@Override
-	public UserModel authenticate(HttpServletRequest httpRequest) {
-		return authenticationManager.authenticate(httpRequest, false);
-	}
-	@Override
-	public UserModel authenticate(HttpServletRequest httpRequest, boolean requiresCertificate) {
-		return authenticationManager.authenticate(httpRequest, requiresCertificate);
-	}
-
-	@Override
-	public void setCookie(HttpServletResponse response, UserModel user) {
-		authenticationManager.setCookie(response, user);
-	}
-
-	@Override
-	public void logout(HttpServletResponse response, UserModel user) {
-		authenticationManager.logout(response, user);
-	}
-
-	@Override
-	public boolean supportsCredentialChanges(UserModel user) {
-		return authenticationManager.supportsCredentialChanges(user);
-	}
-
-	@Override
-	public boolean supportsDisplayNameChanges(UserModel user) {
-		return authenticationManager.supportsDisplayNameChanges(user);
-	}
-
-	@Override
-	public boolean supportsEmailAddressChanges(UserModel user) {
-		return authenticationManager.supportsEmailAddressChanges(user);
-	}
-
-	@Override
-	public boolean supportsTeamMembershipChanges(UserModel user) {
-		return authenticationManager.supportsTeamMembershipChanges(user);
-	}
-
-	@Override
-	public boolean supportsTeamMembershipChanges(TeamModel team) {
-		return authenticationManager.supportsTeamMembershipChanges(team);
-	}
-
-	/*
-	 * USER MANAGER
+	/**
+	 * Delete the user and all associated public ssh keys.
 	 */
-
-	@Override
-	public void setup(IRuntimeManager runtimeManager) {
-	}
-
-	@Override
-	public List<String> getAllUsernames() {
-		return userManager.getAllUsernames();
-	}
-
-	@Override
-	public List<UserModel> getAllUsers() {
-		return userManager.getAllUsers();
-	}
-
 	@Override
 	public boolean deleteUser(String username) {
-		return userManager.deleteUser(username);
-	}
-
-	@Override
-	public UserModel getUserModel(String username) {
-		return userManager.getUserModel(username);
-	}
-
-	@Override
-	public List<TeamModel> getAllTeams() {
-		return userManager.getAllTeams();
-	}
-
-	@Override
-	public TeamModel getTeamModel(String teamname) {
-		return userManager.getTeamModel(teamname);
-	}
-
-	@Override
-	public String getCookie(UserModel model) {
-		return userManager.getCookie(model);
-	}
-
-	@Override
-	public UserModel getUserModel(char[] cookie) {
-		return userManager.getUserModel(cookie);
-	}
-
-	@Override
-	public boolean updateUserModel(UserModel model) {
-		return userManager.updateUserModel(model);
-	}
-
-	@Override
-	public boolean updateUserModels(Collection<UserModel> models) {
-		return userManager.updateUserModels(models);
-	}
-
-	@Override
-	public boolean updateUserModel(String username, UserModel model) {
-		return userManager.updateUserModel(username, model);
+		UserModel user = userManager.getUserModel(username);
+		return deleteUserModel(user);
 	}
 
 	@Override
 	public boolean deleteUserModel(UserModel model) {
-		return userManager.deleteUserModel(model);
+		boolean success = userManager.deleteUserModel(model);
+		if (success) {
+			getPublicKeyManager().removeAllKeys(model.username);
+		}
+		return success;
 	}
 
-	@Override
-	public List<String> getAllTeamNames() {
-		return userManager.getAllTeamNames();
-	}
-
-	@Override
-	public List<String> getTeamNamesForRepositoryRole(String role) {
-		return userManager.getTeamNamesForRepositoryRole(role);
-	}
-
-	@Override
-	public boolean updateTeamModel(TeamModel model) {
-		return userManager.updateTeamModel(model);
-	}
-
-	@Override
-	public boolean updateTeamModels(Collection<TeamModel> models) {
-		return userManager.updateTeamModels(models);
-	}
-
-	@Override
-	public boolean updateTeamModel(String teamname, TeamModel model) {
-		return userManager.updateTeamModel(teamname, model);
-	}
-
-	@Override
-	public boolean deleteTeamModel(TeamModel model) {
-		return userManager.deleteTeamModel(model);
-	}
-
-	@Override
-	public List<String> getUsernamesForRepositoryRole(String role) {
-		return userManager.getUsernamesForRepositoryRole(role);
-	}
-
-	@Override
-	public boolean renameRepositoryRole(String oldRole, String newRole) {
-		return userManager.renameRepositoryRole(oldRole, newRole);
-	}
-
-	@Override
-	public boolean deleteRepositoryRole(String role) {
-		return userManager.deleteRepositoryRole(role);
-	}
-
-	@Override
-	public boolean deleteTeam(String teamname) {
-		return userManager.deleteTeam(teamname);
-	}
-
-	/*
-	 * REPOSITORY MANAGER
+	/**
+	 * Delete the repository and all associated tickets.
 	 */
-
 	@Override
-	public Date getLastActivityDate() {
-		return repositoryManager.getLastActivityDate();
-	}
-
-	@Override
-	public File getRepositoriesFolder() {
-		return repositoryManager.getRepositoriesFolder();
-	}
-
-	@Override
-	public File getHooksFolder() {
-		return repositoryManager.getHooksFolder();
-	}
-
-	@Override
-	public File getGrapesFolder() {
-		return repositoryManager.getGrapesFolder();
-	}
-
-	@Override
-	public List<RegistrantAccessPermission> getUserAccessPermissions(UserModel user) {
-		return repositoryManager.getUserAccessPermissions(user);
-	}
-
-	@Override
-	public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {
-		return repositoryManager.getUserAccessPermissions(repository);
-	}
-
-	@Override
-	public boolean setUserAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
-		return repositoryManager.setUserAccessPermissions(repository, permissions);
-	}
-
-	@Override
-	public List<String> getRepositoryUsers(RepositoryModel repository) {
-		return repositoryManager.getRepositoryUsers(repository);
-	}
-
-	@Override
-	public List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {
-		return repositoryManager.getTeamAccessPermissions(repository);
-	}
-
-	@Override
-	public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
-		return repositoryManager.setTeamAccessPermissions(repository, permissions);
-	}
-
-	@Override
-	public List<String> getRepositoryTeams(RepositoryModel repository) {
-		return repositoryManager.getRepositoryTeams(repository);
-	}
-	@Override
-	public void addToCachedRepositoryList(RepositoryModel model) {
-		repositoryManager.addToCachedRepositoryList(model);
-	}
-
-	@Override
-	public void resetRepositoryListCache() {
-		repositoryManager.resetRepositoryListCache();
-	}
-
-	@Override
-	public List<String> getRepositoryList() {
-		return repositoryManager.getRepositoryList();
-	}
-
-	@Override
-	public Repository getRepository(String repositoryName) {
-		return repositoryManager.getRepository(repositoryName);
-	}
-
-	@Override
-	public Repository getRepository(String repositoryName, boolean logError) {
-		return repositoryManager.getRepository(repositoryName, logError);
-	}
-
-	@Override
-	public List<RepositoryModel> getRepositoryModels(UserModel user) {
-		return repositoryManager.getRepositoryModels(user);
-	}
-
-	@Override
-	public RepositoryModel getRepositoryModel(UserModel user, String repositoryName) {
-		return repositoryManager.getRepositoryModel(repositoryName);
-	}
-
-	@Override
-	public RepositoryModel getRepositoryModel(String repositoryName) {
-		return repositoryManager.getRepositoryModel(repositoryName);
-	}
-
-	@Override
-	public long getStarCount(RepositoryModel repository) {
-		return repositoryManager.getStarCount(repository);
-	}
-
-	@Override
-	public boolean hasRepository(String repositoryName) {
-		return repositoryManager.hasRepository(repositoryName);
-	}
-
-	@Override
-	public boolean hasRepository(String repositoryName, boolean caseSensitiveCheck) {
-		return repositoryManager.hasRepository(repositoryName, caseSensitiveCheck);
-	}
-
-	@Override
-	public boolean hasFork(String username, String origin) {
-		return repositoryManager.hasFork(username, origin);
-	}
-
-	@Override
-	public String getFork(String username, String origin) {
-		return repositoryManager.getFork(username, origin);
-	}
-
-	@Override
-	public ForkModel getForkNetwork(String repository) {
-		return repositoryManager.getForkNetwork(repository);
-	}
-
-	@Override
-	public long updateLastChangeFields(Repository r, RepositoryModel model) {
-		return repositoryManager.updateLastChangeFields(r, model);
-	}
-
-	@Override
-	public List<Metric> getRepositoryDefaultMetrics(RepositoryModel model, Repository repository) {
-		return repositoryManager.getRepositoryDefaultMetrics(model, repository);
-	}
-
-	@Override
-	public void updateRepositoryModel(String repositoryName, RepositoryModel repository,
-			boolean isCreate) throws GitBlitException {
-		repositoryManager.updateRepositoryModel(repositoryName, repository, isCreate);
-	}
-
-	@Override
-	public void updateConfiguration(Repository r, RepositoryModel repository) {
-		repositoryManager.updateConfiguration(r, repository);
+	public boolean deleteRepository(String repositoryName) {
+		RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName);
+		return deleteRepositoryModel(repository);
 	}
 
 	@Override
 	public boolean deleteRepositoryModel(RepositoryModel model) {
-		return repositoryManager.deleteRepositoryModel(model);
+		boolean success = repositoryManager.deleteRepositoryModel(model);
+		if (success && ticketService != null) {
+			ticketService.deleteAll(model);
+		}
+		return success;
 	}
 
-	@Override
-	public boolean deleteRepository(String repositoryName) {
-		return repositoryManager.deleteRepository(repositoryName);
-	}
-
-	@Override
-	public List<String> getAllScripts() {
-		return repositoryManager.getAllScripts();
-	}
-
-	@Override
-	public List<String> getPreReceiveScriptsInherited(RepositoryModel repository) {
-		return repositoryManager.getPreReceiveScriptsInherited(repository);
-	}
-
-	@Override
-	public List<String> getPreReceiveScriptsUnused(RepositoryModel repository) {
-		return repositoryManager.getPreReceiveScriptsUnused(repository);
-	}
-
-	@Override
-	public List<String> getPostReceiveScriptsInherited(RepositoryModel repository) {
-		return repositoryManager.getPostReceiveScriptsInherited(repository);
-	}
-
-	@Override
-	public List<String> getPostReceiveScriptsUnused(RepositoryModel repository) {
-		return repositoryManager.getPostReceiveScriptsUnused(repository);
-	}
-
-	@Override
-	public List<SearchResult> search(String query, int page, int pageSize, List<String> repositories) {
-		return repositoryManager.search(query, page, pageSize, repositories);
-	}
-
-	@Override
-	public boolean isCollectingGarbage() {
-		return repositoryManager.isCollectingGarbage();
-	}
-
-	@Override
-	public boolean isCollectingGarbage(String repositoryName) {
-		return repositoryManager.isCollectingGarbage(repositoryName);
-	}
-
-	/*
-	 * PROJECT MANAGER
+	/**
+	 * Returns the configured ticket service.
+	 *
+	 * @return a ticket service
 	 */
-
 	@Override
-	public List<ProjectModel> getProjectModels(UserModel user, boolean includeUsers) {
-		return projectManager.getProjectModels(user, includeUsers);
+	public ITicketService getTicketService() {
+		return ticketService;
 	}
 
-	@Override
-	public ProjectModel getProjectModel(String name, UserModel user) {
-		return projectManager.getProjectModel(name, user);
+	protected void configureTicketService() {
+		String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName());
+		if (StringUtils.isEmpty(clazz)) {
+			clazz = NullTicketService.class.getName();
+		}
+		try {
+			Class<? extends ITicketService> serviceClass = (Class<? extends ITicketService>) Class.forName(clazz);
+			ticketService = injector.get(serviceClass).start();
+			if (ticketService instanceof NullTicketService) {
+				logger.warn("No ticket service configured.");
+			} else if (ticketService.isReady()) {
+				logger.info("{} is ready.", ticketService);
+			} else {
+				logger.warn("{} is disabled.", ticketService);
+			}
+		} catch (Exception e) {
+			logger.error("failed to create ticket service " + clazz, e);
+			ticketService = injector.get(NullTicketService.class).start();
+		}
 	}
 
-	@Override
-	public ProjectModel getProjectModel(String name) {
-		return projectManager.getProjectModel(name);
-	}
-
-	@Override
-	public List<ProjectModel> getProjectModels(List<RepositoryModel> repositoryModels, boolean includeUsers) {
-		return projectManager.getProjectModels(repositoryModels, includeUsers);
-	}
-
-	/*
-	 * FEDERATION MANAGER
+	/**
+	 * A nested Dagger graph is used for constructor dependency injection of
+	 * complex classes.
+	 *
+	 * @author James Moger
+	 *
 	 */
+	@Module(
+			library = true,
+			injects = {
+					IStoredSettings.class,
 
-	@Override
-	public File getProposalsFolder() {
-		return federationManager.getProposalsFolder();
-	}
+					// core managers
+					IRuntimeManager.class,
+					IPluginManager.class,
+					INotificationManager.class,
+					IUserManager.class,
+					IAuthenticationManager.class,
+					IRepositoryManager.class,
+					IProjectManager.class,
+					IFederationManager.class,
 
-	@Override
-	public UserModel getFederationUser() {
-		return federationManager.getFederationUser();
-	}
+					// the monolithic manager
+					IGitblit.class,
 
-	@Override
-	public boolean canFederate() {
-		return federationManager.canFederate();
-	}
+					// ticket services
+					NullTicketService.class,
+					FileTicketService.class,
+					BranchTicketService.class,
+					RedisTicketService.class
+				}
+			)
+	class GitBlitModule {
 
-	@Override
-	public List<FederationModel> getFederationRegistrations() {
-		return federationManager.getFederationRegistrations();
-	}
+		@Provides @Singleton IStoredSettings provideSettings() {
+			return settings;
+		}
 
-	@Override
-	public FederationModel getFederationRegistration(String url, String name) {
-		return federationManager.getFederationRegistration(url, name);
-	}
+		@Provides @Singleton IRuntimeManager provideRuntimeManager() {
+			return runtimeManager;
+		}
 
-	@Override
-	public List<FederationSet> getFederationSets(String gitblitUrl) {
-		return federationManager.getFederationSets(gitblitUrl);
-	}
+		@Provides @Singleton IPluginManager providePluginManager() {
+			return pluginManager;
+		}
 
-	@Override
-	public List<String> getFederationTokens() {
-		return federationManager.getFederationTokens();
-	}
+		@Provides @Singleton INotificationManager provideNotificationManager() {
+			return notificationManager;
+		}
 
-	@Override
-	public String getFederationToken(FederationToken type) {
-		return federationManager.getFederationToken(type);
-	}
+		@Provides @Singleton IUserManager provideUserManager() {
+			return userManager;
+		}
 
-	@Override
-	public String getFederationToken(String value) {
-		return federationManager.getFederationToken(value);
-	}
+		@Provides @Singleton IAuthenticationManager provideAuthenticationManager() {
+			return authenticationManager;
+		}
 
-	@Override
-	public boolean validateFederationRequest(FederationRequest req, String token) {
-		return federationManager.validateFederationRequest(req, token);
-	}
+		@Provides @Singleton IRepositoryManager provideRepositoryManager() {
+			return repositoryManager;
+		}
 
-	@Override
-	public boolean acknowledgeFederationStatus(String identification, FederationModel registration) {
-		return federationManager.acknowledgeFederationStatus(identification, registration);
-	}
+		@Provides @Singleton IProjectManager provideProjectManager() {
+			return projectManager;
+		}
 
-	@Override
-	public List<FederationModel> getFederationResultRegistrations() {
-		return federationManager.getFederationResultRegistrations();
-	}
+		@Provides @Singleton IFederationManager provideFederationManager() {
+			return federationManager;
+		}
 
-	@Override
-	public boolean submitFederationProposal(FederationProposal proposal, String gitblitUrl) {
-		return federationManager.submitFederationProposal(proposal, gitblitUrl);
-	}
+		@Provides @Singleton IGitblit provideGitblit() {
+			return GitBlit.this;
+		}
 
-	@Override
-	public List<FederationProposal> getPendingFederationProposals() {
-		return federationManager.getPendingFederationProposals();
-	}
+		@Provides @Singleton NullTicketService provideNullTicketService() {
+			return new NullTicketService(
+					runtimeManager,
+					pluginManager,
+					notificationManager,
+					userManager,
+					repositoryManager);
+		}
 
-	@Override
-	public Map<String, RepositoryModel> getRepositories(String gitblitUrl, String token) {
-		return federationManager.getRepositories(gitblitUrl, token);
-	}
+		@Provides @Singleton FileTicketService provideFileTicketService() {
+			return new FileTicketService(
+					runtimeManager,
+					pluginManager,
+					notificationManager,
+					userManager,
+					repositoryManager);
+		}
 
-	@Override
-	public FederationProposal createFederationProposal(String gitblitUrl, String token) {
-		return federationManager.createFederationProposal(gitblitUrl, token);
-	}
+		@Provides @Singleton BranchTicketService provideBranchTicketService() {
+			return new BranchTicketService(
+					runtimeManager,
+					pluginManager,
+					notificationManager,
+					userManager,
+					repositoryManager);
+		}
 
-	@Override
-	public FederationProposal getPendingFederationProposal(String token) {
-		return federationManager.getPendingFederationProposal(token);
-	}
-
-	@Override
-	public boolean deletePendingFederationProposal(FederationProposal proposal) {
-		return federationManager.deletePendingFederationProposal(proposal);
-	}
-
-	/*
-	 * GITBLIT MANAGER
-	 */
-
-	@Override
-	public RepositoryModel fork(RepositoryModel repository, UserModel user) throws GitBlitException {
-		return gitblitManager.fork(repository, user);
-	}
-
-	@Override
-	public void updateTeamModel(String teamname, TeamModel team, boolean isCreate)
-			throws GitBlitException {
-		gitblitManager.updateTeamModel(teamname, team, isCreate);
-	}
-
-	@Override
-	public void updateUserModel(String username, UserModel user, boolean isCreate)
-			throws GitBlitException {
-		gitblitManager.updateUserModel(username, user, isCreate);
-	}
-
-	@Override
-	public List<RepositoryUrl> getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) {
-		return gitblitManager.getRepositoryUrls(request, user, repository);
-	}
-
-	@Override
-	public Collection<GitClientApplication> getClientApplications() {
-		return gitblitManager.getClientApplications();
+		@Provides @Singleton RedisTicketService provideRedisTicketService() {
+			return new RedisTicketService(
+					runtimeManager,
+					pluginManager,
+					notificationManager,
+					userManager,
+					repositoryManager);
+		}
 	}
 }

--
Gitblit v1.9.1