From 06ae63123c94038b90153f4847de2c57c0193db8 Mon Sep 17 00:00:00 2001
From: Rafael Cavazin <rafaelcavazin@gmail.com>
Date: Sun, 27 Jan 2013 09:46:50 -0500
Subject: [PATCH] updating current development

---
 src/com/gitblit/GitBlit.java |  206 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 132 insertions(+), 74 deletions(-)

diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index a607bd8..6bf75d7 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -85,6 +85,9 @@
 import com.gitblit.Constants.FederationToken;
 import com.gitblit.Constants.PermissionType;
 import com.gitblit.Constants.RegistrantType;
+import com.gitblit.fanout.FanoutNioService;
+import com.gitblit.fanout.FanoutService;
+import com.gitblit.fanout.FanoutSocketService;
 import com.gitblit.models.FederationModel;
 import com.gitblit.models.FederationProposal;
 import com.gitblit.models.FederationSet;
@@ -109,7 +112,6 @@
 import com.gitblit.utils.JGitUtils;
 import com.gitblit.utils.JsonUtils;
 import com.gitblit.utils.MetricUtils;
-import com.gitblit.utils.MultiConfigUtil;
 import com.gitblit.utils.ObjectCache;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.TimeUtils;
@@ -161,6 +163,8 @@
 	private final ObjectCache<String> projectRepositoriesMarkdownCache = new ObjectCache<String>();
 
 	private ServletContext servletContext;
+	
+	private File baseFolder;
 
 	private File repositoriesFolder;
 
@@ -182,7 +186,7 @@
 	
 	private FileBasedConfig projectConfigs;
 	
-	private MultiConfigUtil multiConfigUtil = new MultiConfigUtil();
+	private FanoutService fanoutService;
 
 	public GitBlit() {
 		if (gitblit == null) {
@@ -392,12 +396,8 @@
 	 * @return the file
 	 */
 	public static File getFileOrFolder(String fileOrFolder) {
-		String openShift = System.getenv("OPENSHIFT_DATA_DIR");
-		if (!StringUtils.isEmpty(openShift)) {
-			// running on RedHat OpenShift
-			return new File(openShift, fileOrFolder);
-		}
-		return new File(fileOrFolder);
+		return com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$,
+				self().baseFolder, fileOrFolder);
 	}
 
 	/**
@@ -407,7 +407,7 @@
 	 * @return the repositories folder path
 	 */
 	public static File getRepositoriesFolder() {
-		return getFileOrFolder(Keys.git.repositoriesFolder, "git");
+		return getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
 	}
 
 	/**
@@ -417,7 +417,7 @@
 	 * @return the proposals folder path
 	 */
 	public static File getProposalsFolder() {
-		return getFileOrFolder(Keys.federation.proposalsFolder, "proposals");
+		return getFileOrFolder(Keys.federation.proposalsFolder, "${baseFolder}/proposals");
 	}
 
 	/**
@@ -427,9 +427,9 @@
 	 * @return the Groovy scripts folder path
 	 */
 	public static File getGroovyScriptsFolder() {
-		return getFileOrFolder(Keys.groovy.scriptsFolder, "groovy");
+		return getFileOrFolder(Keys.groovy.scriptsFolder, "${baseFolder}/groovy");
 	}
-
+	
 	/**
 	 * Updates the list of server settings.
 	 * 
@@ -825,7 +825,7 @@
 		// TODO reconsider ownership as a user property
 		// manually specify personal repository ownerships
 		for (RepositoryModel rm : repositoryListCache.values()) {
-			if (rm.isUsersPersonalRepository(user.username) || rm.isRepoAdministrator(user.username)) {
+			if (rm.isUsersPersonalRepository(user.username) || rm.isOwner(user.username)) {
 				RegistrantAccessPermission rp = new RegistrantAccessPermission(rm.name, AccessPermission.REWIND,
 						PermissionType.OWNER, RegistrantType.REPOSITORY, null, false);
 				// user may be owner of a repository to which they've inherited
@@ -939,14 +939,14 @@
 			for (RepositoryModel model : getRepositoryModels(user)) {
 				if (model.isUsersPersonalRepository(username)) {
 					// personal repository
-					model.addRepoAdministrator(user.username);
+					model.addOwner(user.username);
 					String oldRepositoryName = model.name;
 					model.name = "~" + user.username + model.name.substring(model.projectPath.length());
 					model.projectPath = "~" + user.username;
 					updateRepositoryModel(oldRepositoryName, model, false);
-				} else if (model.isRepoAdministrator(username)) {
+				} else if (model.isOwner(username)) {
 					// common/shared repo
-					model.addRepoAdministrator(user.username);
+					model.addOwner(user.username);
 					updateRepositoryModel(model.name, model, false);
 				}
 			}
@@ -1650,7 +1650,7 @@
 		}
 		RepositoryModel model = new RepositoryModel();
 		model.isBare = r.isBare();
-		File basePath = getFileOrFolder(Keys.git.repositoriesFolder, "git");
+		File basePath = getFileOrFolder(Keys.git.repositoriesFolder, "${baseFolder}/git");
 		if (model.isBare) {
 			model.name = com.gitblit.utils.FileUtils.getRelativePath(basePath, r.getDirectory());
 		} else {
@@ -1665,7 +1665,7 @@
 		
 		if (config != null) {
 			model.description = getConfig(config, "description", "");
-			model.addRepoAdministrators(multiConfigUtil.convertStringToSet(getConfig(config, "owner", "")));
+			model.addOwners(ArrayUtils.fromString(getConfig(config, "owner", "")));
 			model.useTickets = getConfig(config, "useTickets", false);
 			model.useDocs = getConfig(config, "useDocs", false);
 			model.allowForks = getConfig(config, "allowForks", true);
@@ -1713,6 +1713,7 @@
 		}
 		model.HEAD = JGitUtils.getHEADRef(r);
 		model.availableRefs = JGitUtils.getAvailableHeadTargets(r);
+		model.sparkleshareId = JGitUtils.getSparkleshareId(r);
 		r.close();
 		
 		if (model.origin != null && model.origin.startsWith("file://")) {
@@ -1869,11 +1870,16 @@
 	
 	private ForkModel getForkModelFromCache(String repository) {
 		RepositoryModel model = repositoryListCache.get(repository.toLowerCase());
+		if (model == null) {
+			return null;
+		}
 		ForkModel fork = new ForkModel(model);
 		if (!ArrayUtils.isEmpty(model.forks)) {
 			for (String aFork : model.forks) {
 				ForkModel fm = getForkModelFromCache(aFork);
-				fork.forks.add(fm);
+				if (fm != null) {
+					fork.forks.add(fm);
+				}
 			}
 		}
 		return fork;
@@ -1881,11 +1887,16 @@
 	
 	private ForkModel getForkModel(String repository) {
 		RepositoryModel model = getRepositoryModel(repository.toLowerCase());
+		if (model == null) {
+			return null;
+		}
 		ForkModel fork = new ForkModel(model);
 		if (!ArrayUtils.isEmpty(model.forks)) {
 			for (String aFork : model.forks) {
 				ForkModel fm = getForkModel(aFork);
-				fork.forks.add(fm);
+				if (fm != null) {
+					fork.forks.add(fm);
+				}
 			}
 		}
 		return fork;
@@ -2172,7 +2183,7 @@
 	public void updateConfiguration(Repository r, RepositoryModel repository) {
 		StoredConfig config = r.getConfig();
 		config.setString(Constants.CONFIG_GITBLIT, null, "description", repository.description);
-		config.setString(Constants.CONFIG_GITBLIT, null, "owner", multiConfigUtil.convertCollectionToSingleLineString(repository.getRepoAdministrators()));
+		config.setString(Constants.CONFIG_GITBLIT, null, "owner", ArrayUtils.toString(repository.owners));
 		config.setBoolean(Constants.CONFIG_GITBLIT, null, "useTickets", repository.useTickets);
 		config.setBoolean(Constants.CONFIG_GITBLIT, null, "useDocs", repository.useDocs);
 		config.setBoolean(Constants.CONFIG_GITBLIT, null, "allowForks", repository.allowForks);
@@ -3030,12 +3041,15 @@
 	 * 
 	 * @param settings
 	 */
-	public void configureContext(IStoredSettings settings, boolean startFederation) {
-		logger.info("Reading configuration from " + settings.toString());
+	public void configureContext(IStoredSettings settings, File folder, boolean startFederation) {
 		this.settings = settings;
+		this.baseFolder = folder;
 
 		repositoriesFolder = getRepositoriesFolder();
-		logger.info("Git repositories folder " + repositoriesFolder.getAbsolutePath());
+
+		logger.info("Gitblit base folder     = " + folder.getAbsolutePath());
+		logger.info("Git repositories folder = " + repositoriesFolder.getAbsolutePath());
+		logger.info("Gitblit settings        = " + settings.toString());
 
 		// prepare service executors
 		mailExecutor = new MailExecutor(settings);
@@ -3057,7 +3071,7 @@
 		serverStatus = new ServerStatus(isGO());
 
 		if (this.userService == null) {
-			String realm = settings.getString(Keys.realm.userService, "users.properties");
+			String realm = settings.getString(Keys.realm.userService, "${baseFolder}/users.properties");
 			IUserService loginService = null;
 			try {
 				// check to see if this "file" is a login service class
@@ -3070,7 +3084,7 @@
 		}
 		
 		// load and cache the project metadata
-		projectConfigs = new FileBasedConfig(getFileOrFolder(Keys.web.projectsFile, "projects.conf"), FS.detect());
+		projectConfigs = new FileBasedConfig(getFileOrFolder(Keys.web.projectsFile, "${baseFolder}/projects.conf"), FS.detect());
 		getProjectConfigs();
 		
 		// schedule mail engine
@@ -3082,15 +3096,9 @@
 		}
 		
 		// schedule lucene engine
-		boolean branchIndexingActivated = settings.getBoolean(
-				Keys.git.branchIndexingActivated, true);
-		logger.info("Branch indexing is "
-				+ (branchIndexingActivated ? "" : "not") + " activated");
-		if (branchIndexingActivated) {
-			logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes.");
-			scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2,
-					TimeUnit.MINUTES);
-		}
+		logger.info("Lucene executor is scheduled to process indexed branches every 2 minutes.");
+		scheduledExecutor.scheduleAtFixedRate(luceneExecutor, 1, 2, TimeUnit.MINUTES);
+		
 		// schedule gc engine
 		if (gcExecutor.isReady()) {
 			logger.info("GC executor is scheduled to scan repositories every 24 hours.");
@@ -3142,6 +3150,32 @@
 		}
 
 		ContainerUtils.CVE_2007_0450.test();
+		
+		// startup Fanout PubSub service
+		if (settings.getInteger(Keys.fanout.port, 0) > 0) {
+			String bindInterface = settings.getString(Keys.fanout.bindInterface, null);
+			int port = settings.getInteger(Keys.fanout.port, FanoutService.DEFAULT_PORT);
+			boolean useNio = settings.getBoolean(Keys.fanout.useNio, true);
+			int limit = settings.getInteger(Keys.fanout.connectionLimit, 0);
+			
+			if (useNio) {
+				if (StringUtils.isEmpty(bindInterface)) {
+					fanoutService = new FanoutNioService(port);
+				} else {
+					fanoutService = new FanoutNioService(bindInterface, port);
+				}
+			} else {
+				if (StringUtils.isEmpty(bindInterface)) {
+					fanoutService = new FanoutSocketService(port);
+				} else {
+					fanoutService = new FanoutSocketService(bindInterface, port);
+				}
+			}
+			
+			fanoutService.setConcurrentConnectionLimit(limit);
+			fanoutService.setAllowAllChannelAnnouncements(false);
+			fanoutService.start();
+		}
 	}
 	
 	private void logTimezone(String type, TimeZone zone) {
@@ -3165,39 +3199,63 @@
 	public void contextInitialized(ServletContextEvent contextEvent, InputStream referencePropertiesInputStream) {
 		servletContext = contextEvent.getServletContext();
 		if (settings == null) {
-			// Gitblit WAR is running in a servlet container
+			// Gitblit is running in a servlet container
 			ServletContext context = contextEvent.getServletContext();
 			WebXmlSettings webxmlSettings = new WebXmlSettings(context);
-
-			// gitblit.properties file located within the webapp
-			String webProps = context.getRealPath("/WEB-INF/gitblit.properties");
-			if (!StringUtils.isEmpty(webProps)) {
-				File overrideFile = new File(webProps);
-				webxmlSettings.applyOverrides(overrideFile);
-			}
+			File contextFolder = new File(context.getRealPath("/"));
+			String openShift = System.getenv("OPENSHIFT_DATA_DIR");
 			
-			// gitblit.properties file located outside the deployed war
-			// folder lie, for example, on RedHat OpenShift.
-			File overrideFile = getFileOrFolder("gitblit.properties");
-			if (!overrideFile.getPath().equals("gitblit.properties")) {
-				webxmlSettings.applyOverrides(overrideFile);
-			}
-			
-			configureContext(webxmlSettings, true);
+			if (!StringUtils.isEmpty(openShift)) {
+				// Gitblit is running in OpenShift/JBoss
+				File base = new File(openShift);
 
-			// Copy the included scripts to the configured groovy folder
-			File localScripts = getFileOrFolder(Keys.groovy.scriptsFolder, "groovy");
-			if (!localScripts.exists()) {
-				File includedScripts = new File(context.getRealPath("/WEB-INF/groovy"));
-				if (!includedScripts.equals(localScripts)) {
-					try {
-						com.gitblit.utils.FileUtils.copy(localScripts, includedScripts.listFiles());
-					} catch (IOException e) {
-						logger.error(MessageFormat.format(
-								"Failed to copy included Groovy scripts from {0} to {1}",
-								includedScripts, localScripts));
+				// gitblit.properties setting overrides
+				File overrideFile = new File(base, "gitblit.properties");
+				webxmlSettings.applyOverrides(overrideFile);
+				
+				// Copy the included scripts to the configured groovy folder
+				File localScripts = new File(base, webxmlSettings.getString(Keys.groovy.scriptsFolder, "groovy"));
+				if (!localScripts.exists()) {
+					File warScripts = new File(contextFolder, "/WEB-INF/data/groovy");
+					if (!warScripts.equals(localScripts)) {
+						try {
+							com.gitblit.utils.FileUtils.copy(localScripts, warScripts.listFiles());
+						} catch (IOException e) {
+							logger.error(MessageFormat.format(
+									"Failed to copy included Groovy scripts from {0} to {1}",
+									warScripts, localScripts));
+						}
 					}
 				}
+				
+				// configure context using the web.xml
+				configureContext(webxmlSettings, base, true);
+			} else {
+				// Gitblit is running in a standard servlet container
+				logger.info("WAR contextFolder is " + contextFolder.getAbsolutePath());
+				
+				String path = webxmlSettings.getString(Constants.baseFolder, Constants.contextFolder$ + "/WEB-INF/data");
+				File base = com.gitblit.utils.FileUtils.resolveParameter(Constants.contextFolder$, contextFolder, path);
+				base.mkdirs();
+				
+				// try to copy the data folder contents to the baseFolder
+				File localSettings = new File(base, "gitblit.properties");
+				if (!localSettings.exists()) {
+					File contextData = new File(contextFolder, "/WEB-INF/data");
+					if (!base.equals(contextData)) {
+						try {
+							com.gitblit.utils.FileUtils.copy(base, contextData.listFiles());
+						} catch (IOException e) {
+							logger.error(MessageFormat.format(
+									"Failed to copy included data from {0} to {1}",
+								contextData, base));
+						}
+					}
+				}
+				
+				// delegate all config to baseFolder/gitblit.properties file
+				FileSettings settings = new FileSettings(localSettings.getAbsolutePath());				
+				configureContext(settings, base, true);
 			}
 		}
 		
@@ -3215,6 +3273,9 @@
 		scheduledExecutor.shutdownNow();
 		luceneExecutor.close();
 		gcExecutor.close();
+		if (fanoutService != null) {
+			fanoutService.stop();
+		}
 	}
 	
 	/**
@@ -3258,23 +3319,20 @@
 
 		// create a Gitblit repository model for the clone
 		RepositoryModel cloneModel = repository.cloneAs(cloneName);
-		// owner has REWIND/RW+ permissions		
-		cloneModel.addRepoAdministrator(user.username);
+		// owner has REWIND/RW+ permissions
+		cloneModel.addOwner(user.username);
 		updateRepositoryModel(cloneName, cloneModel, false);
 
 		// add the owner of the source repository to the clone's access list
-		Set<String> repoAdministrators = repository.getRepoAdministrators();
-		if (repoAdministrators != null) {
-			for (String repoAdministrator : repoAdministrators) {
-				if (!StringUtils.isEmpty(repoAdministrator)) {
-					UserModel originOwner = getUserModel(repoAdministrator);
-					if (originOwner != null) {
-						originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
-						updateUserModel(originOwner.username, originOwner, false);
-					}
+		if (!ArrayUtils.isEmpty(repository.owners)) {
+			for (String owner : repository.owners) {
+				UserModel originOwner = getUserModel(owner);
+				if (originOwner != null) {
+					originOwner.setRepositoryPermission(cloneName, AccessPermission.CLONE);
+					updateUserModel(originOwner.username, originOwner, false);
 				}
 			}
-		}		
+		}
 
 		// grant origin's user list clone permission to fork
 		List<String> users = getRepositoryUsers(repository);

--
Gitblit v1.9.1