/* * Copyright 2013 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; import com.gitblit.Constants.AccessPermission; import com.gitblit.manager.GitblitManager; import com.gitblit.manager.IAuthenticationManager; import com.gitblit.manager.IFederationManager; import com.gitblit.manager.IGitblit; import com.gitblit.manager.INotificationManager; import com.gitblit.manager.IProjectManager; import com.gitblit.manager.IRepositoryManager; import com.gitblit.manager.IRuntimeManager; import com.gitblit.manager.IUserManager; import com.gitblit.manager.ServicesManager; import com.gitblit.models.RepositoryModel; import com.gitblit.models.RepositoryUrl; 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.utils.StringUtils; import dagger.Module; import dagger.ObjectGraph; import dagger.Provides; /** * 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 extends GitblitManager { private final ObjectGraph injector; private final ServicesManager servicesManager; private ITicketService ticketService; public GitBlit( IRuntimeManager runtimeManager, INotificationManager notificationManager, IUserManager userManager, IAuthenticationManager authenticationManager, IRepositoryManager repositoryManager, IProjectManager projectManager, IFederationManager federationManager) { super(runtimeManager, notificationManager, userManager, authenticationManager, 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; } protected Object [] getModules() { return new Object [] { new GitBlitModule()}; } /** * 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 List getRepositoryUrls(HttpServletRequest request, UserModel user, RepositoryModel repository) { if (user == null) { user = UserModel.ANONYMOUS; } String username = StringUtils.encodeUsername(UserModel.ANONYMOUS.equals(user) ? "" : user.username); List list = new ArrayList(); // http/https url if (settings.getBoolean(Keys.git.enableGitServlet, true)) { AccessPermission permission = user.getRepositoryPermission(repository).permission; if (permission.exceeds(AccessPermission.NONE)) { list.add(new RepositoryUrl(getRepositoryUrl(request, username, repository), 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)) { 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)); } } return list; } /** * Detect renames and reindex as appropriate. */ @Override 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); } } /** * Delete the repository and all associated tickets. */ @Override public boolean deleteRepository(String repositoryName) { RepositoryModel repository = repositoryManager.getRepositoryModel(repositoryName); boolean success = repositoryManager.deleteRepository(repositoryName); if (success && ticketService != null) { return ticketService.deleteAll(repository); } return success; } /** * Returns the configured ticket service. * * @return a ticket service */ @Override public ITicketService getTicketService() { return ticketService; } protected void configureTicketService() { String clazz = settings.getString(Keys.tickets.service, NullTicketService.class.getName()); if (StringUtils.isEmpty(clazz)) { clazz = NullTicketService.class.getName(); } try { Class serviceClass = (Class) Class.forName(clazz); ticketService = injector.get(serviceClass).start(); 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(); } } /** * A nested Dagger graph is used for constructor dependency injection of * complex classes. * * @author James Moger * */ @Module( library = true, injects = { IStoredSettings.class, // core managers IRuntimeManager.class, INotificationManager.class, IUserManager.class, IAuthenticationManager.class, IRepositoryManager.class, IProjectManager.class, IFederationManager.class, // the monolithic manager IGitblit.class, // ticket services NullTicketService.class, FileTicketService.class, BranchTicketService.class, RedisTicketService.class } ) class GitBlitModule { @Provides @Singleton IStoredSettings provideSettings() { return settings; } @Provides @Singleton IRuntimeManager provideRuntimeManager() { return runtimeManager; } @Provides @Singleton INotificationManager provideNotificationManager() { return notificationManager; } @Provides @Singleton IUserManager provideUserManager() { return userManager; } @Provides @Singleton IAuthenticationManager provideAuthenticationManager() { return authenticationManager; } @Provides @Singleton IRepositoryManager provideRepositoryManager() { return repositoryManager; } @Provides @Singleton IProjectManager provideProjectManager() { return projectManager; } @Provides @Singleton IFederationManager provideFederationManager() { return federationManager; } @Provides @Singleton IGitblit provideGitblit() { return GitBlit.this; } } }