From f81ed74578eb1d0fed26c56ddcfbb39f08a4e47c Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 10 Apr 2014 18:58:10 -0400
Subject: [PATCH] Support querying in tickets ls and accept Object[][] for table data

---
 src/main/java/com/gitblit/utils/FlipTable.java                              |   22 +++---
 src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java      |   55 ++++++++++++-----
 src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java     |    8 +-
 src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java |   10 +-
 src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java         |    4 
 src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java        |   34 +++++-----
 6 files changed, 77 insertions(+), 56 deletions(-)

diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
index 3422f50..8c4aa22 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
@@ -163,12 +163,12 @@
 		protected void asTable(List<SshKey> keys) {
 			String[] headers = { "#", "Fingerprint", "Comment", "Type" };
 			int len = keys == null ? 0 : keys.size();
-			String[][] data = new String[len][];
+			Object[][] data = new Object[len][];
 			for (int i = 0; i < len; i++) {
 				// show 1-based index numbers with the fingerprint
 				// this is useful for comparing with "ssh-add -l"
 				SshKey k = keys.get(i);
-				data[i] = new String[] { "" + (i + 1), k.getFingerprint(), k.getComment(), k.getAlgorithm() };
+				data[i] = new Object[] { (i + 1), k.getFingerprint(), k.getComment(), k.getAlgorithm() };
 			}
 
 			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java
index 500d6ae..1984ebc 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java
@@ -46,7 +46,7 @@
 			List<ProjectModel> projects = gitblit.getProjectModels(user, false);
 			return projects;
 		}
-		
+
 		@Override
 		protected boolean matches(ProjectModel p) {
 			return p.name.matches(regexFilter);
@@ -63,14 +63,14 @@
 				headers = h;
 			}
 
-			String[][] data = new String[list.size()][];
+			Object[][] data = new Object[list.size()][];
 			for (int i = 0; i < list.size(); i++) {
 				ProjectModel p = list.get(i);
 
 				if (verbose) {
-					data[i] = new String[] { p.name, p.description, formatDate(p.lastChange), "" + p.repositories.size() };
+					data[i] = new Object[] { p.name, p.description, formatDate(p.lastChange), p.repositories.size() };
 				} else {
-					data[i] = new String[] { p.name, formatDate(p.lastChange), "" + p.repositories.size() };
+					data[i] = new Object[] { p.name, formatDate(p.lastChange), p.repositories.size() };
 				}
 			}
 			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java
index 4e42eef..4798c6d 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java
@@ -47,12 +47,12 @@
 			List<RepositoryModel> repositories = gitblit.getRepositoryModels(user);
 			return repositories;
 		}
-		
+
 		@Override
 		protected boolean matches(RepositoryModel r) {
 			return r.name.matches(regexFilter);
 		}
-		
+
 		@Override
 		protected void asTable(List<RepositoryModel> list) {
 			String[] headers;
@@ -64,7 +64,7 @@
 				headers = h;
 			}
 
-			String[][] data = new String[list.size()][];
+			Object[][] data = new Object[list.size()][];
 			for (int i = 0; i < list.size(); i++) {
 				RepositoryModel r = list.get(i);
 
@@ -79,9 +79,9 @@
 					if (!ArrayUtils.isEmpty(r.owners)) {
 						owners = Joiner.on(",").join(r.owners);
 					}
-					data[i] = new String[] { r.name, r.description, owners, lm, size };
+					data[i] = new Object[] { r.name, r.description, owners, lm, size };
 				} else {
-					data[i] = new String[] { r.name, lm, size };
+					data[i] = new Object[] { r.name, lm, size };
 				}
 			}
 			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java
index 484121b..dd29b6a 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java
@@ -30,6 +30,7 @@
 import com.gitblit.transport.ssh.commands.CommandMetaData;
 import com.gitblit.transport.ssh.commands.DispatchCommand;
 import com.gitblit.transport.ssh.commands.ListCommand;
+import com.gitblit.utils.ArrayUtils;
 import com.gitblit.utils.FlipTable;
 import com.gitblit.utils.FlipTable.Borders;
 import com.gitblit.utils.StringUtils;
@@ -42,35 +43,53 @@
 		register(user, ReviewCommand.class);
 		register(user, ListTickets.class);
 	}
-	
+
 	/* List tickets */
-	@CommandMetaData(name = "list", aliases= { "ls" }, description = "List tickets")
+	@CommandMetaData(name = "list", aliases = { "ls" }, description = "List tickets")
 	public static class ListTickets extends ListCommand<QueryResult> {
 
-		@Argument(index = 0, metaVar = "REPOSITORY", usage = "repository")
+		private final String ALL = "ALL";
+
+		@Argument(index = 0, metaVar = "ALL|REPOSITORY", usage = "the repository or ALL")
 		protected String repository;
-		
+
+		@Argument(index = 1, multiValued = true, metaVar="CONDITION", usage = "query condition")
+		protected List<String> query;
+
+		protected String userQuery;
+
 		@Override
 		protected List<QueryResult> getItems() throws UnloggedFailure {
 			IGitblit gitblit = getContext().getGitblit();
 			ITicketService tickets = gitblit.getTicketService();
 
 			QueryBuilder sb = new QueryBuilder();
-			sb.and(Lucene.status.matches(Status.New.toString())).or(Lucene.status.matches(Status.Open.toString()));
+			if (ArrayUtils.isEmpty(query)) {
+				sb.and(Lucene.status.matches(Status.New.toString())).or(Lucene.status.matches(Status.Open.toString()));
+			} else {
+				StringBuilder b = new StringBuilder();
+				for (String q : query) {
+					b.append(q).append(' ');
+				}
+				b.setLength(b.length() - 1);
+				sb.and(b.toString());
+			}
 
 			QueryBuilder qb;
-			if (StringUtils.isEmpty(repository)) {
+			if (StringUtils.isEmpty(repository) || ALL.equalsIgnoreCase(repository)) {
 				qb = sb;
+				userQuery = sb.build();
 			} else {
 				qb = new QueryBuilder();
 				RepositoryModel r = gitblit.getRepositoryModel(repository);
 				if (r == null) {
-					throw new UnloggedFailure(1,  String.format("%s not found!", repository));
+					throw new UnloggedFailure(1,  String.format("%s is not a repository!", repository));
 				}
 				qb.and(Lucene.rid.matches(r.getRID()));
 				qb.and(sb.toSubquery().toString());
+				userQuery = sb.build();
 			}
-			
+
 			String query = qb.build();
 			List<QueryResult> list = tickets.queryFor(query, 0, 0, null, true);
 			return list;
@@ -78,14 +97,14 @@
 
 		@Override
 		protected void asTable(List<QueryResult> list) {
-			boolean forRepo = !StringUtils.isEmpty(repository);
+			boolean forRepo = !StringUtils.isEmpty(repository) && !ALL.equalsIgnoreCase(repository);
 			String[] headers;
 			if (verbose) {
 				if (forRepo) {
-					String[] h = { "ID", "Title", "Status", "Last Modified" };
+					String[] h = { "ID", "Title", "Status", "Last Modified", "Votes", "Commits" };
 					headers = h;
 				} else {
-					String[] h = { "Repository", "ID", "Title", "Status", "Last Modified" };
+					String[] h = { "Repository", "ID", "Title", "Status", "Last Modified", "Votes", "Commits" };
 					headers = h;
 				}
 			} else {
@@ -98,25 +117,27 @@
 				}
 			}
 
-			String[][] data = new String[list.size()][];
+			Object[][] data = new Object[list.size()][];
 			for (int i = 0; i < list.size(); i++) {
 				QueryResult q = list.get(i);
 
 				if (verbose) {
 					if (forRepo) {
-						data[i] = new String[] { "" + q.number, q.title, q.status.toString(), formatDate(q.getDate()) };
+						data[i] = new Object[] { q.number, q.title, q.status, formatDate(q.getDate()), q.votesCount, q.patchset == null ? "": q.patchset.commits };
 					} else {
-						data[i] = new String[] { q.repository, "" + q.number, q.title, q.status.toString(), formatDate(q.getDate()) };
+						data[i] = new Object[] { q.repository, q.number, q.title, q.status, formatDate(q.getDate()), q.votesCount, q.patchset == null ? "": q.patchset.commits };
 					}
 				} else {
 					if (forRepo) {
-						data[i] = new String[] { "" + q.number, q.title, q.status.toString(), formatDate(q.getDate()) };
+						data[i] = new Object[] { q.number, q.title, q.status, formatDate(q.getDate()) };
 					} else {
-						data[i] = new String[] { q.repository, "" + q.number, q.title, q.status.toString(), formatDate(q.getDate()) };
+						data[i] = new Object[] { q.repository, q.number, q.title, q.status, formatDate(q.getDate()) };
 					}
 				}
 			}
-			stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS));
+			stdout.print(FlipTable.of(headers, data, Borders.BODY_HCOLS));
+			stdout.println("  " + repository + ": " + userQuery);
+			stdout.println();
 		}
 
 		@Override
diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java
index 14af7e7..c4fac3e 100644
--- a/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java
+++ b/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java
@@ -54,34 +54,34 @@
 
 			// fields
 			String [] fheaders = new String [] { "Field", "Value" };
-			String [][] fdata = new String[5][];
-			fdata[0] = new String [] { "Email", u.emailAddress };
-			fdata[1] = new String [] { "Type", u.accountType.toString() };
-			fdata[2] = new String [] { "Can Admin", u.canAdmin() ? "Y":"N" };
-			fdata[3] = new String [] { "Can Fork", u.canFork() ? "Y":"N" };
-			fdata[4] = new String [] { "Can Create", u.canCreate() ? "Y":"N" };
+			Object [][] fdata = new Object[5][];
+			fdata[0] = new Object [] { "Email", u.emailAddress };
+			fdata[1] = new Object [] { "Type", u.accountType };
+			fdata[2] = new Object [] { "Can Admin", u.canAdmin() ? "Y":"N" };
+			fdata[3] = new Object [] { "Can Fork", u.canFork() ? "Y":"N" };
+			fdata[4] = new Object [] { "Can Create", u.canCreate() ? "Y":"N" };
 			String fields = FlipTable.of(fheaders, fdata, Borders.COLS);
-			
+
 			// teams
 			String [] theaders = new String [] { "Team", "Type" };
-			String [][] tdata = new String[u.teams.size()][];
+			Object [][] tdata = new Object[u.teams.size()][];
 			int i = 0;
 			for (TeamModel t : u.teams) {
-				tdata[i] = new String [] { t.name, t.accountType.toString() };
+				tdata[i] = new Object [] { t.name, t.accountType };
 				i++;
 			}
 			String teams = FlipTable.of(theaders, tdata, Borders.COLS);
-			
+
 			// permissions
 			List<RegistrantAccessPermission> perms = u.getRepositoryPermissions();
 			String[] pheaders = { "Repository", "Permission", "Type", "Source", "Mutable" };
-			String [][] pdata = new String[perms.size()][];
+			Object [][] pdata = new Object[perms.size()][];
 			for (i = 0; i < perms.size(); i++) {
 				RegistrantAccessPermission ap = perms.get(i);
-				pdata[i] = new String[] { ap.registrant, ap.permission.toString(), ap.permissionType.toString(), ap.source, ap.mutable ? "Y":"N" };
+				pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType, ap.source, ap.mutable ? "Y":"N" };
 			}
 			String permissions = FlipTable.of(pheaders, pdata, Borders.COLS);
-			
+
 			// assemble user table
 			String [] headers = new String[] { u.getDisplayName() + (u.username.equals(u.getDisplayName()) ? "" : (" (" + u.username + ")")) };
 			String[][] data = new String[6][];
@@ -104,7 +104,7 @@
 			List<UserModel> users = gitblit.getAllUsers();
 			return users;
 		}
-		
+
 		@Override
 		protected boolean matches(UserModel u) {
 			return u.username.matches(regexFilter);
@@ -121,16 +121,16 @@
 				headers = h;
 			}
 
-			String[][] data = new String[list.size()][];
+			Object[][] data = new Object[list.size()][];
 			for (int i = 0; i < list.size(); i++) {
 				UserModel u = list.get(i);
 
 				String name = u.disabled ? "-" : ((u.canAdmin() ? "*" : " ")) + u.username;
 				if (verbose) {
-					data[i] = new String[] { name, u.displayName, u.accountType.name(),
+					data[i] = new Object[] { name, u.displayName, u.accountType,
 							u.emailAddress,	u.canCreate() ? "Y":"", u.canFork() ? "Y" : ""};
 				} else {
-					data[i] = new String[] { name, u.displayName, u.accountType.name(),
+					data[i] = new Object[] { name, u.displayName, u.accountType,
 							u.emailAddress };
 				}
 			}
diff --git a/src/main/java/com/gitblit/utils/FlipTable.java b/src/main/java/com/gitblit/utils/FlipTable.java
index 666b70c..7aa5f0b 100644
--- a/src/main/java/com/gitblit/utils/FlipTable.java
+++ b/src/main/java/com/gitblit/utils/FlipTable.java
@@ -46,7 +46,7 @@
 		private Borders(int bitmask) {
 			this.bitmask = bitmask;
 		}
-		
+
 		boolean header() {
 			return isset(0x8);
 		}
@@ -69,12 +69,12 @@
 	}
 
 	/** Create a new table with the specified headers and row data. */
-	public static String of(String[] headers, String[][] data) {
+	public static String of(String[] headers, Object[][] data) {
 		return of(headers, data, Borders.FULL);
 	}
 
 	/** Create a new table with the specified headers and row data. */
-	public static String of(String[] headers, String[][] data, Borders borders) {
+	public static String of(String[] headers, Object[][] data, Borders borders) {
 		if (headers == null)
 			throw new NullPointerException("headers == null");
 		if (headers.length == 0)
@@ -85,13 +85,13 @@
 	}
 
 	private final String[] headers;
-	private final String[][] data;
+	private final Object[][] data;
 	private final Borders borders;
 	private final int columns;
 	private final int[] columnWidths;
 	private final int emptyWidth;
 
-	private FlipTable(String[] headers, String[][] data, Borders borders) {
+	private FlipTable(String[] headers, Object[][] data, Borders borders) {
 		this.headers = headers;
 		this.data = data;
 		this.borders = borders;
@@ -99,17 +99,17 @@
 		columns = headers.length;
 		columnWidths = new int[columns];
 		for (int row = -1; row < data.length; row++) {
-			String[] rowData = (row == -1) ? headers : data[row];
+			Object[] rowData = (row == -1) ? headers : data[row];
 			if (rowData.length != columns) {
 				throw new IllegalArgumentException(String.format("Row %s's %s columns != %s columns", row + 1,
 						rowData.length, columns));
 			}
 			for (int column = 0; column < columns; column++) {
-				String cell = rowData[column];
+				Object cell = rowData[column];
 				if (cell == null) {
 					continue;
 				}
-				for (String rowDataLine : cell.split("\\n")) {
+				for (String rowDataLine : cell.toString().split("\\n")) {
 					columnWidths[column] = Math.max(columnWidths[column], rowDataLine.length());
 				}
 			}
@@ -194,7 +194,7 @@
 		out.append(format.charAt(4)).append('\n');
 	}
 
-	private void printData(StringBuilder out, String[] data, boolean isHeader) {
+	private void printData(StringBuilder out, Object[] data, boolean isHeader) {
 		for (int line = 0, lines = 1; line < lines; line++) {
 			for (int column = 0; column < columns; column++) {
 				if (column == 0) {
@@ -208,11 +208,11 @@
 				} else {
 					out.append(' ');
 				}
-				String cell = data[column];
+				Object cell = data[column];
 				if (cell == null) {
 					cell = "";
 				}
-				String[] cellLines = cell.split("\\n");
+				String[] cellLines = cell.toString().split("\\n");
 				lines = Math.max(lines, cellLines.length);
 				String cellLine = line < cellLines.length ? cellLines[line] : "";
 				out.append(pad(columnWidths[column], cellLine));

--
Gitblit v1.9.1