]> source.dussan.org Git - gitblit.git/commitdiff
Revise dispatcher setup and command registration
authorJames Moger <james.moger@gitblit.com>
Fri, 21 Mar 2014 22:12:40 +0000 (18:12 -0400)
committerJames Moger <james.moger@gitblit.com>
Thu, 10 Apr 2014 22:58:09 +0000 (18:58 -0400)
src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java
src/main/java/com/gitblit/transport/ssh/git/GitDispatcher.java
src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java
src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java
src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java [new file with mode: 0644]
src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java [new file with mode: 0644]
src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java
src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java [new file with mode: 0644]

index b5d131faf457b320dfb2e3add6a3bcffe47155df..b916bb1703af54a6a27b2b710aafff1939e2074b 100644 (file)
@@ -84,16 +84,54 @@ public abstract class DispatchCommand extends BaseCommand implements ExtensionPo
                dispatchers.clear();
        }
 
-       protected void registerDispatcher(UserModel user, Class<? extends DispatchCommand> cmd) {
+       /**
+        * Setup this dispatcher. Commands and nested dispatchers are normally
+        * registered within this method.
+        *
+        * @param user
+        */
+       protected abstract void setup(UserModel user);
+
+       /**
+        * Register a command or a dispatcher by it's class.
+        *
+        * @param user
+        * @param clazz
+        */
+       @SuppressWarnings("unchecked")
+       protected final void register(UserModel user, Class<? extends BaseCommand> clazz) {
+               if (DispatchCommand.class.isAssignableFrom(clazz)) {
+                       registerDispatcher(user, (Class<? extends DispatchCommand>) clazz);
+                       return;
+               }
+
+               registerCommand(user, clazz);
+       }
+
+       /**
+        * Register a command or a dispatcher instance.
+        *
+        * @param user
+        * @param cmd
+        */
+       protected final void register(UserModel user, BaseCommand cmd) {
+               if (cmd instanceof DispatchCommand) {
+                       registerDispatcher(user, (DispatchCommand) cmd);
+                       return;
+               }
+               registerCommand(user, cmd);
+       }
+
+       private void registerDispatcher(UserModel user, Class<? extends DispatchCommand> clazz) {
                try {
-                       DispatchCommand dispatcher = cmd.newInstance();
+                       DispatchCommand dispatcher = clazz.newInstance();
                        registerDispatcher(user, dispatcher);
                } catch (Exception e) {
-                       log.error("failed to instantiate {}", cmd.getName());
+                       log.error("failed to instantiate {}", clazz.getName());
                }
        }
 
-       protected void registerDispatcher(UserModel user, DispatchCommand dispatcher) {
+       private void registerDispatcher(UserModel user, DispatchCommand dispatcher) {
                Class<? extends DispatchCommand> dispatcherClass = dispatcher.getClass();
                if (!dispatcherClass.isAnnotationPresent(CommandMetaData.class)) {
                        throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", dispatcher.getName(),
@@ -108,7 +146,7 @@ public abstract class DispatchCommand extends BaseCommand implements ExtensionPo
                }
 
                try {
-                       dispatcher.registerCommands(user);
+                       dispatcher.setup(user);
                        if (dispatcher.commands.isEmpty() && dispatcher.dispatchers.isEmpty()) {
                                log.debug(MessageFormat.format("excluding empty dispatcher {0} for {1}",
                                                meta.name(), user.username));
@@ -129,30 +167,23 @@ public abstract class DispatchCommand extends BaseCommand implements ExtensionPo
                }
        }
 
-       protected abstract void registerCommands(UserModel user);
-
        /**
         * Registers a command as long as the user is permitted to execute it.
         *
         * @param user
-        * @param cmd
+        * @param clazz
         */
-       protected void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
-               if (DispatchCommand.class.isAssignableFrom(cmd)) {
-                       log.warn("{} tried to register {} with registerCommand", getName(), cmd.getName());
-                       registerDispatcher(user, (Class<? extends DispatchCommand>) cmd);
-                       return;
-               }
-               if (!cmd.isAnnotationPresent(CommandMetaData.class)) {
-                       throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
+       private void registerCommand(UserModel user, Class<? extends BaseCommand> clazz) {
+               if (!clazz.isAnnotationPresent(CommandMetaData.class)) {
+                       throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", clazz.getName(),
                                        CommandMetaData.class.getName()));
                }
-               CommandMetaData meta = cmd.getAnnotation(CommandMetaData.class);
+               CommandMetaData meta = clazz.getAnnotation(CommandMetaData.class);
                if (meta.admin() && !user.canAdmin()) {
                        log.debug(MessageFormat.format("excluding admin command {0} for {1}", meta.name(), user.username));
                        return;
                }
-               commands.add(cmd);
+               commands.add(clazz);
        }
 
        /**
@@ -161,12 +192,7 @@ public abstract class DispatchCommand extends BaseCommand implements ExtensionPo
         * @param user
         * @param cmd
         */
-       protected void registerCommand(UserModel user, BaseCommand cmd) {
-               if (DispatchCommand.class.isAssignableFrom(cmd.getClass())) {
-                       log.warn("{} tried to register {} dispatcher with registerCommand", getName(), cmd.getName());
-                       registerDispatcher(user, (DispatchCommand) cmd);
-                       return;
-               }
+       private void registerCommand(UserModel user, BaseCommand cmd) {
                if (!cmd.getClass().isAnnotationPresent(CommandMetaData.class)) {
                        throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
                                        CommandMetaData.class.getName()));
index 896391fa368d3335434f600f7eb0521b50d04d96..8a871ebbb8a61be7c5ee5ba7f13173ae954ee95d 100644 (file)
@@ -31,7 +31,8 @@ import com.gitblit.transport.ssh.gitblit.GitblitDispatcher;
  * other commands.
  *
  */
-public class RootDispatcher extends DispatchCommand {
+@CommandMetaData(name = "")
+class RootDispatcher extends DispatchCommand {
 
        private Logger log = LoggerFactory.getLogger(getClass());
 
@@ -39,9 +40,9 @@ public class RootDispatcher extends DispatchCommand {
                super();
                setContext(new SshCommandContext(gitblit, client, cmdLine));
 
-               final UserModel user = client.getUser();
-               registerDispatcher(user, GitblitDispatcher.class);
-               registerDispatcher(user, GitDispatcher.class);
+               UserModel user = client.getUser();
+               register(user, GitblitDispatcher.class);
+               register(user, GitDispatcher.class);
 
                List<DispatchCommand> exts = gitblit.getExtensions(DispatchCommand.class);
                for (DispatchCommand ext : exts) {
@@ -49,16 +50,11 @@ public class RootDispatcher extends DispatchCommand {
                        String plugin = gitblit.whichPlugin(extClass).getDescriptor().getPluginId();
                        CommandMetaData meta = extClass.getAnnotation(CommandMetaData.class);
                        log.info("Dispatcher {} is loaded from plugin {}", meta.name(), plugin);
-                       registerDispatcher(user, ext);
+                       register(user, ext);
                }
        }
 
        @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!");
+       protected final void setup(UserModel user) {
        }
 }
\ No newline at end of file
index 69dcd8110962f27a198463027a77b3f1f36a50f6..64f9c8d0f66d70f67d1492127d3971edae7b5115 100644 (file)
@@ -26,7 +26,7 @@ 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="Git commands")
+@CommandMetaData(name = "git", description="Git repository commands")
 public class GitDispatcher extends DispatchCommand {
 
        protected RepositoryResolver<SshDaemonClient> repositoryResolver;
@@ -53,10 +53,10 @@ public class GitDispatcher extends DispatchCommand {
        }
 
        @Override
-       protected void registerCommands(UserModel user) {
-               registerCommand(user, Upload.class);
-               registerCommand(user, Receive.class);
-               registerCommand(user, GarbageCollectionCommand.class);
+       protected void setup(UserModel user) {
+               register(user, Upload.class);
+               register(user, Receive.class);
+               register(user, GarbageCollectionCommand.class);
        }
 
        @Override
index f9b5f4fc970d0dc201e2b7de2a31aad466bef341..86d8a8c9219777af7b2e3826dda44f674c52b6bc 100644 (file)
@@ -23,16 +23,19 @@ import com.gitblit.transport.ssh.commands.DispatchCommand;
 public class GitblitDispatcher extends DispatchCommand {
 
        @Override
-       protected void registerCommands(UserModel user) {
+       protected void setup(UserModel user) {
                // commands in this dispatcher
-               registerCommand(user, VersionCommand.class);
-               registerCommand(user, CreateRepository.class);
-               registerCommand(user, SetAccountCommand.class);
-               registerCommand(user, ConfigCommand.class);
+               register(user, VersionCommand.class);
+               register(user, CreateRepository.class);
+               register(user, SetAccountCommand.class);
+               register(user, ConfigCommand.class);
 
                // nested dispatchers
-               registerDispatcher(user, ListDispatcher.class);
-               registerDispatcher(user, KeysDispatcher.class);
-               registerDispatcher(user, TicketsDispatcher.class);
+               register(user, ListDispatcher.class);
+               register(user, KeysDispatcher.class);
+               register(user, TicketsDispatcher.class);
+               register(user, UsersDispatcher.class);
+               register(user, ProjectsDispatcher.class);
+               register(user, RepositoriesDispatcher.class);
        }
 }
index a54196da6fba8fd129ec43292262a8d6ccd31e91..8c1bfd29f11384d76214d4a8069d467405f95d97 100644 (file)
@@ -42,10 +42,10 @@ import com.gitblit.transport.ssh.commands.SshCommand;
 public class KeysDispatcher extends DispatchCommand {
 
        @Override
-       protected void registerCommands(UserModel user) {
-               registerCommand(user, AddKey.class);
-               registerCommand(user, RemoveKey.class);
-               registerCommand(user, ListKeys.class);
+       protected void setup(UserModel user) {
+               register(user, AddKey.class);
+               register(user, RemoveKey.class);
+               register(user, ListKeys.class);
        }
 
        @CommandMetaData(name = "add", description = "Add an SSH public key to your account")
index 0c372df01e7c98f4a0cfe903778d88a05b6c5e9b..343e59aa2a26d78636792bd8868c96dc1da37398 100644 (file)
  */
 package com.gitblit.transport.ssh.gitblit;
 
-import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
-import java.util.List;
-
-import org.kohsuke.args4j.Option;
-import org.parboiled.common.StringUtils;
-
-import com.gitblit.manager.IGitblit;
-import com.gitblit.models.ProjectModel;
-import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.DispatchCommand;
-import com.gitblit.transport.ssh.commands.SshCommand;
 
 /**
  * The dispatcher and it's commands for Gitblit object listing.
@@ -40,11 +29,11 @@ import com.gitblit.transport.ssh.commands.SshCommand;
 public class ListDispatcher extends DispatchCommand {
 
        @Override
-       protected void registerCommands(UserModel user) {
-               registerCommand(user, ListRepositories.class);
-               registerCommand(user, ListProjects.class);
-               registerCommand(user, ListUsers.class);
-               registerCommand(user, ListKeys.class);
+       protected void setup(UserModel user) {
+               register(user, ListRepositories.class);
+               register(user, ListProjects.class);
+               register(user, ListUsers.class);
+               register(user, ListKeys.class);
        }
 
        /* List SSH public keys */
@@ -54,137 +43,16 @@ public class ListDispatcher extends DispatchCommand {
 
        /* List repositories */
        @CommandMetaData(name = "repositories", aliases = { "repos" }, description = "List repositories")
-       public static class ListRepositories extends SshCommand {
-
-               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
-               private boolean verbose;
-
-               @Override
-               public void run() {
-                       IGitblit gitblit = getContext().getGitblit();
-                       UserModel user = getContext().getClient().getUser();
-                       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
-
-                       List<RepositoryModel> repositories = gitblit.getRepositoryModels(user);
-                       int nameLen = 0;
-                       int descLen = 0;
-                       for (RepositoryModel repo : repositories) {
-                               int len = repo.name.length();
-                               if (len > nameLen) {
-                                       nameLen = len;
-                               }
-                               if (!StringUtils.isEmpty(repo.description)) {
-                                       len = repo.description.length();
-                                       if (len > descLen) {
-                                               descLen = len;
-                                       }
-                               }
-                       }
-
-                       String pattern;
-                       if (verbose) {
-                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
-                       } else {
-                               pattern = "%s";
-                       }
-
-                       for (RepositoryModel repo : repositories) {
-                               stdout.println(String.format(pattern,
-                                               repo.name,
-                                               repo.description == null ? "" : repo.description,
-                                               df.format(repo.lastChange)));
-                       }
-               }
+       public static class ListRepositories extends RepositoriesDispatcher.ListRepositories {
        }
 
        /* List projects */
        @CommandMetaData(name = "projects", description = "List projects")
-       public static class ListProjects extends SshCommand {
-
-               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
-               private boolean verbose;
-
-               @Override
-               public void run() {
-                       IGitblit gitblit = getContext().getGitblit();
-                       UserModel user = getContext().getClient().getUser();
-                       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
-
-                       List<ProjectModel> projects = gitblit.getProjectModels(user, false);
-                       int nameLen = 0;
-                       int descLen = 0;
-                       for (ProjectModel project : projects) {
-                               int len = project.name.length();
-                               if (len > nameLen) {
-                                       nameLen = len;
-                               }
-                               if (!StringUtils.isEmpty(project.description)) {
-                                       len = project.description.length();
-                                       if (len > descLen) {
-                                               descLen = len;
-                                       }
-                               }
-                       }
-
-                       String pattern;
-                       if (verbose) {
-                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
-                       } else {
-                               pattern = "%s";
-                       }
-
-                       for (ProjectModel project : projects) {
-                               stdout.println(String.format(pattern,
-                                               project.name,
-                                               project.description == null ? "" : project.description,
-                                               df.format(project.lastChange)));
-                       }
-               }
+       public static class ListProjects extends ProjectsDispatcher.ListProjects {
        }
 
        /* List users */
        @CommandMetaData(name = "users", description = "List users", admin = true)
-       public static class ListUsers extends SshCommand {
-
-               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
-               private boolean verbose;
-
-               @Override
-               public void run() {
-                       IGitblit gitblit = getContext().getGitblit();
-                       List<UserModel> users = gitblit.getAllUsers();
-                       int displaynameLen = 0;
-                       int usernameLen = 0;
-                       for (UserModel user : users) {
-                               int len = user.getDisplayName().length();
-                               if (len > displaynameLen) {
-                                       displaynameLen = len;
-                               }
-                               if (!StringUtils.isEmpty(user.username)) {
-                                       len = user.username.length();
-                                       if (len > usernameLen) {
-                                               usernameLen = len;
-                                       }
-                               }
-                       }
-
-                       String pattern;
-                       if (verbose) {
-                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%-10s\t%s", displaynameLen, usernameLen);
-                       } else {
-                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s", displaynameLen, usernameLen);
-                       }
-
-                       for (UserModel user : users) {
-                               if (user.disabled) {
-                                       continue;
-                               }
-                               stdout.println(String.format(pattern,
-                                               user.getDisplayName(),
-                                               (user.canAdmin() ? "*":" ") + user.username,
-                                               user.accountType,
-                                               user.emailAddress == null ? "" : user.emailAddress));
-                       }
-               }
+       public static class ListUsers extends UsersDispatcher.ListUsers {
        }
 }
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java
new file mode 100644 (file)
index 0000000..cd68754
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.gitblit;
+
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+import org.parboiled.common.StringUtils;
+
+import com.gitblit.manager.IGitblit;
+import com.gitblit.models.ProjectModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
+import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.SshCommand;
+
+@CommandMetaData(name = "projects", description = "Project management commands")
+public class ProjectsDispatcher extends DispatchCommand {
+
+       @Override
+       protected void setup(UserModel user) {
+               register(user, ListProjects.class);
+       }
+
+       /* List projects */
+       @CommandMetaData(name = "list", aliases= { "ls" }, description = "List projects")
+       public static class ListProjects extends SshCommand {
+
+               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
+               private boolean verbose;
+
+               @Override
+               public void run() {
+                       IGitblit gitblit = getContext().getGitblit();
+                       UserModel user = getContext().getClient().getUser();
+                       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+
+                       List<ProjectModel> projects = gitblit.getProjectModels(user, false);
+                       int nameLen = 0;
+                       int descLen = 0;
+                       for (ProjectModel project : projects) {
+                               int len = project.name.length();
+                               if (len > nameLen) {
+                                       nameLen = len;
+                               }
+                               if (!StringUtils.isEmpty(project.description)) {
+                                       len = project.description.length();
+                                       if (len > descLen) {
+                                               descLen = len;
+                                       }
+                               }
+                       }
+
+                       String pattern;
+                       if (verbose) {
+                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
+                       } else {
+                               pattern = "%s";
+                       }
+
+                       for (ProjectModel project : projects) {
+                               stdout.println(String.format(pattern,
+                                               project.name,
+                                               project.description == null ? "" : project.description,
+                                               df.format(project.lastChange)));
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java
new file mode 100644 (file)
index 0000000..3aaed54
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.gitblit;
+
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+import org.kohsuke.args4j.Option;
+import org.parboiled.common.StringUtils;
+
+import com.gitblit.manager.IGitblit;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.UserModel;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
+import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.SshCommand;
+
+@CommandMetaData(name = "repositories", aliases = { "repos" }, description = "Repository management commands")
+public class RepositoriesDispatcher extends DispatchCommand {
+
+       @Override
+       protected void setup(UserModel user) {
+               register(user, ListRepositories.class);
+       }
+
+       /* List repositories */
+       @CommandMetaData(name = "list", aliases = { "ls" }, description = "List repositories")
+       public static class ListRepositories extends SshCommand {
+
+               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
+               private boolean verbose;
+
+               @Override
+               public void run() {
+                       IGitblit gitblit = getContext().getGitblit();
+                       UserModel user = getContext().getClient().getUser();
+                       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+
+                       List<RepositoryModel> repositories = gitblit.getRepositoryModels(user);
+                       int nameLen = 0;
+                       int descLen = 0;
+                       for (RepositoryModel repo : repositories) {
+                               int len = repo.name.length();
+                               if (len > nameLen) {
+                                       nameLen = len;
+                               }
+                               if (!StringUtils.isEmpty(repo.description)) {
+                                       len = repo.description.length();
+                                       if (len > descLen) {
+                                               descLen = len;
+                                       }
+                               }
+                       }
+
+                       String pattern;
+                       if (verbose) {
+                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
+                       } else {
+                               pattern = "%s";
+                       }
+
+                       for (RepositoryModel repo : repositories) {
+                               stdout.println(String.format(pattern,
+                                               repo.name,
+                                               repo.description == null ? "" : repo.description,
+                                               df.format(repo.lastChange)));
+                       }
+               }
+       }
+}
\ No newline at end of file
index ca75a6c3b81b00bf95b9a40da60c47aef6faf246..f921798a9fa0709830ac64046a9cc55a43535ddf 100644 (file)
@@ -23,7 +23,7 @@ import com.gitblit.transport.ssh.commands.DispatchCommand;
 public class TicketsDispatcher extends DispatchCommand {
 
        @Override
-       protected void registerCommands(UserModel user) {
-               registerCommand(user, ReviewCommand.class);
+       protected void setup(UserModel user) {
+               register(user, ReviewCommand.class);
        }
 }
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java
new file mode 100644 (file)
index 0000000..0cbf354
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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.gitblit;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+import org.parboiled.common.StringUtils;
+
+import com.gitblit.manager.IGitblit;
+import com.gitblit.models.RegistrantAccessPermission;
+import com.gitblit.models.UserModel;
+import com.gitblit.transport.ssh.commands.CommandMetaData;
+import com.gitblit.transport.ssh.commands.DispatchCommand;
+import com.gitblit.transport.ssh.commands.SshCommand;
+
+@CommandMetaData(name = "users", description = "User management commands", admin = true)
+public class UsersDispatcher extends DispatchCommand {
+
+       @Override
+       protected void setup(UserModel user) {
+               register(user, ShowUser.class);
+               register(user, ListUsers.class);
+       }
+
+       @CommandMetaData(name = "show", description = "Show a user")
+       public static class ShowUser extends SshCommand {
+               @Argument(index = 0, required = true, metaVar = "USERNAME", usage = "username")
+               protected String username;
+
+               @Override
+               public void run() throws UnloggedFailure {
+                       IGitblit gitblit = getContext().getGitblit();
+                       UserModel user = gitblit.getUserModel(username);
+                       if (user == null) {
+                               throw new UnloggedFailure(1, String.format("Unknown user \"%s\"", username));
+                       }
+                       stdout.println();
+                       stdout.println(user.username);
+                       stdout.println();
+                       for (RegistrantAccessPermission ap : user.getRepositoryPermissions()) {
+                               stdout.println(String.format("%s %s", ap.registrant, ap.permission));
+                       }
+               }
+       }
+
+       @CommandMetaData(name = "list", aliases= { "ls" }, description = "List users")
+       public static class ListUsers extends SshCommand {
+
+               @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
+               private boolean verbose;
+
+               @Override
+               public void run() {
+                       IGitblit gitblit = getContext().getGitblit();
+                       List<UserModel> users = gitblit.getAllUsers();
+                       int displaynameLen = 0;
+                       int usernameLen = 0;
+                       for (UserModel user : users) {
+                               int len = user.getDisplayName().length();
+                               if (len > displaynameLen) {
+                                       displaynameLen = len;
+                               }
+                               if (!StringUtils.isEmpty(user.username)) {
+                                       len = user.username.length();
+                                       if (len > usernameLen) {
+                                               usernameLen = len;
+                                       }
+                               }
+                       }
+
+                       String pattern;
+                       if (verbose) {
+                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%-10s\t%s", displaynameLen, usernameLen);
+                       } else {
+                               pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s", displaynameLen, usernameLen);
+                       }
+
+                       for (UserModel user : users) {
+                               if (user.disabled) {
+                                       continue;
+                               }
+                               stdout.println(String.format(pattern,
+                                               user.getDisplayName(),
+                                               (user.canAdmin() ? "*":" ") + user.username,
+                                               user.accountType,
+                                               user.emailAddress == null ? "" : user.emailAddress));
+                       }
+               }
+       }
+}
\ No newline at end of file