From 261ddf0fcf9a55fbb5b4e7c6c2cdb4c2f8c860fe Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 10 Apr 2014 18:58:09 -0400
Subject: [PATCH] Revise dispatchers and move command classes

---
 src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java      |    2 
 src/main/java/com/gitblit/transport/ssh/git/Receive.java                |    2 
 src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java    |   50 ++++++++++++++++
 src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java  |    4 
 src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java       |    1 
 src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java      |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java  |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java     |    2 
 src/main/java/com/gitblit/transport/ssh/SshDaemon.java                  |    1 
 src/main/java/com/gitblit/transport/ssh/git/Upload.java                 |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java          |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java     |    2 
 src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java |   28 +--------
 src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java   |   12 +--
 src/main/java/com/gitblit/transport/ssh/commands/CommandMetaData.java   |    2 
 src/main/java/com/gitblit/transport/ssh/WelcomeShell.java               |    1 
 src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java   |    2 
 src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java   |    2 
 src/main/java/com/gitblit/transport/ssh/commands/SshCommandContext.java |    3 
 src/main/java/com/gitblit/transport/ssh/git/GitDispatcher.java          |    6 +-
 20 files changed, 79 insertions(+), 49 deletions(-)

diff --git a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
index da9a372..aeb6ce5 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
+++ b/src/main/java/com/gitblit/transport/ssh/SshDaemon.java
@@ -34,6 +34,7 @@
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.manager.IGitblit;
+import com.gitblit.transport.ssh.commands.SshCommandFactory;
 import com.gitblit.utils.IdGenerator;
 import com.gitblit.utils.StringUtils;
 
diff --git a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
index 819028c..ccf2586 100644
--- a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
+++ b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java
@@ -35,6 +35,7 @@
 import com.gitblit.Keys;
 import com.gitblit.models.UserModel;
 import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.SshCommandFactory;
 import com.gitblit.utils.StringUtils;
 
 /**
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
index a3df787..7088fef 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java
@@ -37,7 +37,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.gitblit.transport.ssh.SshCommandContext;
 import com.gitblit.utils.IdGenerator;
 import com.gitblit.utils.WorkQueue;
 import com.gitblit.utils.WorkQueue.CancelableRunnable;
diff --git a/src/main/java/com/gitblit/transport/ssh/CommandMetaData.java b/src/main/java/com/gitblit/transport/ssh/commands/CommandMetaData.java
similarity index 95%
rename from src/main/java/com/gitblit/transport/ssh/CommandMetaData.java
rename to src/main/java/com/gitblit/transport/ssh/commands/CommandMetaData.java
index 0d39f33..133b9cb 100644
--- a/src/main/java/com/gitblit/transport/ssh/CommandMetaData.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/CommandMetaData.java
@@ -12,7 +12,7 @@
 //See the License for the specific language governing permissions and
 //limitations under the License.
 
-package com.gitblit.transport.ssh;
+package com.gitblit.transport.ssh.commands;
 
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
index dd581f4..f7c78d2 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
@@ -31,7 +31,6 @@
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.cli.SubcommandHandler;
 import com.google.common.base.Charsets;
@@ -48,15 +47,15 @@
 	@Argument(index = 1, multiValued = true, metaVar = "ARG")
 	private List<String> args = new ArrayList<String>();
 
-	private Set<Class<? extends BaseCommand>> commands;
+	private final Set<Class<? extends BaseCommand>> commands;
 	private Map<String, Class<? extends BaseCommand>> map;
 	private Map<String, BaseCommand> dispatchers;
 
-	public DispatchCommand() {
+	protected DispatchCommand() {
 		commands = new HashSet<Class<? extends BaseCommand>>();
 	}
 
-	public void registerDispatcher(UserModel user, Class<? extends DispatchCommand> cmd) {
+	protected void registerDispatcher(UserModel user, Class<? extends DispatchCommand> cmd) {
 		if (!cmd.isAnnotationPresent(CommandMetaData.class)) {
 			throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
 					CommandMetaData.class.getName()));
@@ -80,8 +79,7 @@
 		}
 	}
 
-	protected void registerCommands(UserModel user) {
-	}
+	protected abstract void registerCommands(UserModel user);
 
 
 	/**
@@ -90,7 +88,7 @@
 	 * @param user
 	 * @param cmd
 	 */
-	public void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
+	protected void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
 		if (!cmd.isAnnotationPresent(CommandMetaData.class)) {
 			throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
 					CommandMetaData.class.getName()));
diff --git a/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java b/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java
new file mode 100644
index 0000000..5d9eb19
--- /dev/null
+++ b/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 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.transport.ssh.commands;
+
+import com.gitblit.manager.IGitblit;
+import com.gitblit.models.UserModel;
+import com.gitblit.transport.ssh.SshDaemonClient;
+import com.gitblit.transport.ssh.git.GitDispatcher;
+import com.gitblit.transport.ssh.gitblit.GitblitDispatcher;
+
+/**
+ * The root dispatcher is the dispatch command that handles registering all
+ * other commands.
+ *
+ */
+public class RootDispatcher extends DispatchCommand {
+
+	public RootDispatcher(IGitblit gitblit, SshDaemonClient client, String cmdLine) {
+		super();
+		setContext(new SshCommandContext(gitblit, client, cmdLine));
+
+		final UserModel user = client.getUser();
+		registerDispatcher(user, GitblitDispatcher.class);
+		registerDispatcher(user, GitDispatcher.class);
+
+		// TODO register plugin dispatchers here
+	}
+
+	@Override
+	protected final void registerCommands(UserModel user) {
+	}
+
+	@Override
+	protected final void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
+		throw new RuntimeException("The root dispatcher does not accept commands, only dispatchers!");
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/transport/ssh/SshCommandContext.java b/src/main/java/com/gitblit/transport/ssh/commands/SshCommandContext.java
similarity index 92%
rename from src/main/java/com/gitblit/transport/ssh/SshCommandContext.java
rename to src/main/java/com/gitblit/transport/ssh/commands/SshCommandContext.java
index 163d079..15f7a8f 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshCommandContext.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/SshCommandContext.java
@@ -13,9 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.gitblit.transport.ssh;
+package com.gitblit.transport.ssh.commands;
 
 import com.gitblit.manager.IGitblit;
+import com.gitblit.transport.ssh.SshDaemonClient;
 
 public class SshCommandContext {
 
diff --git a/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java b/src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java
similarity index 87%
rename from src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java
rename to src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java
index 2b2093e..3eefcae 100644
--- a/src/main/java/com/gitblit/transport/ssh/SshCommandFactory.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.gitblit.transport.ssh;
+package com.gitblit.transport.ssh.commands;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -35,10 +35,7 @@
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.manager.IGitblit;
-import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.commands.DispatchCommand;
-import com.gitblit.transport.ssh.git.GitDispatchCommand;
-import com.gitblit.transport.ssh.gitblit.GitblitDispatchCommand;
+import com.gitblit.transport.ssh.SshDaemonClient;
 import com.gitblit.utils.IdGenerator;
 import com.gitblit.utils.WorkQueue;
 import com.google.common.util.concurrent.Atomics;
@@ -62,25 +59,8 @@
 		startExecutor = workQueue.createQueue(threads, "SshCommandStart");
 	}
 
-	/**
-	 * Creates the root dispatcher command which builds up the available commands.
-	 *
-	 * @param the client
-	 * @param the command line
-	 * @return the root dispatcher command
-	 */
-	protected DispatchCommand createRootDispatcher(SshDaemonClient client, String cmdLine) {
-		final UserModel user = client.getUser();
-
-		DispatchCommand root = new DispatchCommand() {
-		};
-		root.setContext(new SshCommandContext(gitblit, client, cmdLine));
-
-		// TODO convert these dispatchers to plugin extension points
-		root.registerDispatcher(user, GitblitDispatchCommand.class);
-		root.registerDispatcher(user, GitDispatchCommand.class);
-
-		return root;
+	public RootDispatcher createRootDispatcher(SshDaemonClient client, String commandLine) {
+		return new RootDispatcher(gitblit, client, commandLine);
 	}
 
 	@Override
diff --git a/src/main/java/com/gitblit/transport/ssh/git/GitDispatchCommand.java b/src/main/java/com/gitblit/transport/ssh/git/GitDispatcher.java
similarity index 92%
rename from src/main/java/com/gitblit/transport/ssh/git/GitDispatchCommand.java
rename to src/main/java/com/gitblit/transport/ssh/git/GitDispatcher.java
index adeace5..fa1dfbd 100644
--- a/src/main/java/com/gitblit/transport/ssh/git/GitDispatchCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/git/GitDispatcher.java
@@ -20,14 +20,14 @@
 import com.gitblit.git.RepositoryResolver;
 import com.gitblit.manager.IGitblit;
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
-import com.gitblit.transport.ssh.SshCommandContext;
 import com.gitblit.transport.ssh.SshDaemonClient;
 import com.gitblit.transport.ssh.commands.BaseCommand;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.SshCommandContext;
 
 @CommandMetaData(name = "git", description="Dispatcher for git receive and upload commands", hidden = true)
-public class GitDispatchCommand extends DispatchCommand {
+public class GitDispatcher extends DispatchCommand {
 
 	protected RepositoryResolver<SshDaemonClient> repositoryResolver;
 	protected GitblitUploadPackFactory<SshDaemonClient> uploadPackFactory;
diff --git a/src/main/java/com/gitblit/transport/ssh/git/Receive.java b/src/main/java/com/gitblit/transport/ssh/git/Receive.java
index 4089f1d..9597eb4 100644
--- a/src/main/java/com/gitblit/transport/ssh/git/Receive.java
+++ b/src/main/java/com/gitblit/transport/ssh/git/Receive.java
@@ -17,7 +17,7 @@
 
 import org.eclipse.jgit.transport.ReceivePack;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 
 @CommandMetaData(name = "git-receive-pack", description = "Receives pushes from a client")
 public class Receive extends BaseGitCommand {
diff --git a/src/main/java/com/gitblit/transport/ssh/git/Upload.java b/src/main/java/com/gitblit/transport/ssh/git/Upload.java
index 5793c3e..5de6b4d 100644
--- a/src/main/java/com/gitblit/transport/ssh/git/Upload.java
+++ b/src/main/java/com/gitblit/transport/ssh/git/Upload.java
@@ -17,7 +17,7 @@
 
 import org.eclipse.jgit.transport.UploadPack;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 
 @CommandMetaData(name = "git-upload-pack", description = "Sends packs to a client for clone and fetch")
 public class Upload extends BaseGitCommand {
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java
index 6d5c85c..ae24dfb 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java
@@ -23,7 +23,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 
 /**
  * Add a key to the current user's authorized keys list.
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java b/src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java
index b2e1b1b..2917b6d 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java
@@ -18,7 +18,7 @@
 
 import org.kohsuke.args4j.Option;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.SshCommand;
 
 @CommandMetaData(name = "create-repository", description = "Create new GIT repository", admin = true, hidden = true)
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatchCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java
similarity index 91%
rename from src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatchCommand.java
rename to src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java
index 9eff9bd..eb3bb0c 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatchCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java
@@ -16,11 +16,11 @@
 package com.gitblit.transport.ssh.gitblit;
 
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.DispatchCommand;
 
 @CommandMetaData(name = "gitblit", description = "Gitblit server commands")
-public class GitblitDispatchCommand extends DispatchCommand {
+public class GitblitDispatcher extends DispatchCommand {
 
 	@Override
 	protected void registerCommands(UserModel user) {
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java
index cf50a2e..75cb2d8 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java
@@ -27,7 +27,7 @@
 import com.gitblit.models.ProjectModel;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.SshCommand;
 
 @CommandMetaData(name = "ls", description = "List repositories or projects")
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java
index dd26921..752afaf 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java
@@ -24,7 +24,7 @@
 
 import com.gitblit.manager.IGitblit;
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.SshCommand;
 
 @CommandMetaData(name = "ls-users", description = "List users", admin = true)
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java
index 7c9abfd..af30730 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java
@@ -23,7 +23,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 
 
 /**
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java
index 9e4d8ba..b3691cb 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java
@@ -25,7 +25,7 @@
 import com.gitblit.models.TicketModel.Patchset;
 import com.gitblit.models.TicketModel.Score;
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.SshCommand;
 import com.gitblit.wicket.GitBlitWebSession;
 
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java
index 28ac9e1..aebe3b1 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java
@@ -22,7 +22,7 @@
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
 
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 
 /** Set a user's account settings. **/
 @CommandMetaData(name = "set-account", description = "Change an account's settings", admin = true)
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java
index 513f6d9..384c6ce 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java
@@ -17,7 +17,7 @@
 package com.gitblit.transport.ssh.gitblit;
 
 import com.gitblit.Constants;
-import com.gitblit.transport.ssh.CommandMetaData;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.SshCommand;
 
 @CommandMetaData(name="version", description = "Display the Gitblit version")

--
Gitblit v1.9.1