Add associative lookup of columns for arbitrary (and more intuitive) ordering.
% curl 'localhost:9200/_cat/nodes?v&headers=jdk,ip,name' jdk ip name 1.7.0_40 127.0.0.1 Mordo, Karl Closes #4433.
This commit is contained in:
parent
c2b41f8ad9
commit
08ddfcd731
|
@ -20,12 +20,10 @@
|
||||||
package org.elasticsearch.common;
|
package org.elasticsearch.common;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -34,6 +32,8 @@ public class Table {
|
||||||
protected List<Cell> headers = new ArrayList<Cell>();
|
protected List<Cell> headers = new ArrayList<Cell>();
|
||||||
protected List<List<Cell>> rows = new ArrayList<List<Cell>>();
|
protected List<List<Cell>> rows = new ArrayList<List<Cell>>();
|
||||||
|
|
||||||
|
protected Map<String,List<Cell>> map = Maps.newHashMap();
|
||||||
|
|
||||||
protected List<Cell> currentCells;
|
protected List<Cell> currentCells;
|
||||||
|
|
||||||
protected boolean inHeaders = false;
|
protected boolean inHeaders = false;
|
||||||
|
@ -48,6 +48,18 @@ public class Table {
|
||||||
inHeaders = false;
|
inHeaders = false;
|
||||||
headers = currentCells;
|
headers = currentCells;
|
||||||
currentCells = null;
|
currentCells = null;
|
||||||
|
|
||||||
|
/* Create associative structure for columns that
|
||||||
|
* contain the same cells as the rows:
|
||||||
|
*
|
||||||
|
* header1 => [Cell, Cell, ...]
|
||||||
|
* header2 => [Cell, Cell, ...]
|
||||||
|
* header3 => [Cell, Cell, ...]
|
||||||
|
*/
|
||||||
|
for (Cell header : headers) {
|
||||||
|
map.put((String) header.value, new ArrayList<Cell>());
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +87,13 @@ public class Table {
|
||||||
|
|
||||||
public Table addCell(Cell cell) {
|
public Table addCell(Cell cell) {
|
||||||
currentCells.add(cell);
|
currentCells.add(cell);
|
||||||
|
|
||||||
|
// If we're in a value row, also populate the named column.
|
||||||
|
if (!inHeaders) {
|
||||||
|
String hdr = (String) headers.get(currentCells.indexOf(cell)).value;
|
||||||
|
map.get(hdr).add(cell);
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +130,7 @@ public class Table {
|
||||||
mAttr.put(sAttr.substring(0, idx), sAttr.substring(idx + 1));
|
mAttr.put(sAttr.substring(0, idx), sAttr.substring(idx + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentCells.add(new Cell(value, mAttr));
|
addCell(new Cell(value, mAttr));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +138,9 @@ public class Table {
|
||||||
return this.headers;
|
return this.headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<List<Cell>> getRows() {
|
public Iterable<List<Cell>> rowIterator() { return rows; }
|
||||||
|
|
||||||
|
public List<List<Cell>> getRows() {
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +148,20 @@ public class Table {
|
||||||
return (List<Cell>[]) rows.toArray();
|
return (List<Cell>[]) rows.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, List<Cell>> getAsMap() { return this.map; }
|
||||||
|
|
||||||
|
public List<Cell> getHeadersFromNames(List<String> headerNames) {
|
||||||
|
List<Cell> hdrs = new ArrayList<Cell>();
|
||||||
|
for (String hdrToFind : headerNames) {
|
||||||
|
for (Cell header : headers) {
|
||||||
|
if (((String) header.value).equalsIgnoreCase(hdrToFind)) {
|
||||||
|
hdrs.add(header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hdrs;
|
||||||
|
}
|
||||||
|
|
||||||
public Table addTable(Table t2) {
|
public Table addTable(Table t2) {
|
||||||
Table t1 = this;
|
Table t1 = this;
|
||||||
Table t = new Table();
|
Table t = new Table();
|
||||||
|
|
|
@ -29,9 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.rest.*;
|
import org.elasticsearch.rest.*;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -47,19 +45,16 @@ public class RestTable {
|
||||||
|
|
||||||
public static RestResponse buildXContentBuilder(Table table, RestRequest request, RestChannel channel) throws Exception {
|
public static RestResponse buildXContentBuilder(Table table, RestRequest request, RestChannel channel) throws Exception {
|
||||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||||
Set<String> displayHeaders = buildDisplayHeaders(table, request);
|
List<String> displayHeaders = buildDisplayHeaders(table, request);
|
||||||
|
|
||||||
List<Table.Cell> headers = table.getHeaders();
|
|
||||||
builder.startArray();
|
builder.startArray();
|
||||||
for (List<Table.Cell> row : table.getRows()) {
|
for (int row = 0; row < table.getRows().size(); row++) {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
for (int i = 0; i < headers.size(); i++) {
|
for (String header : displayHeaders) {
|
||||||
String headerName = headers.get(i).value.toString();
|
builder.field(header, renderValue(request, table.getAsMap().get(header).get(row).value));
|
||||||
if (displayHeaders.contains(headerName)) {
|
|
||||||
builder.field(headerName, renderValue(request, row.get(i).value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
||||||
}
|
}
|
||||||
builder.endArray();
|
builder.endArray();
|
||||||
return new XContentRestResponse(request, RestStatus.OK, builder);
|
return new XContentRestResponse(request, RestStatus.OK, builder);
|
||||||
|
@ -81,28 +76,25 @@ public class RestTable {
|
||||||
return new StringRestResponse(RestStatus.OK, out.toString());
|
return new StringRestResponse(RestStatus.OK, out.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] width = buildWidths(table, request, verbose);
|
List<String> displayHeaders = buildDisplayHeaders(table, request);
|
||||||
Set<String> displayHeaders = buildDisplayHeaders(table, request);
|
int[] width = buildWidths(table, request, verbose, displayHeaders);
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
StringBuilder out = new StringBuilder();
|
StringBuilder out = new StringBuilder();
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
// print the headers
|
// print the headers
|
||||||
for (int i = 0; i < width.length; i++) {
|
for (Table.Cell header : table.getHeadersFromNames(displayHeaders)) {
|
||||||
String headerName = table.getHeaders().get(i).value.toString();
|
pad(header, width[col], request, out);
|
||||||
if (displayHeaders.contains(headerName)) {
|
out.append(" ");
|
||||||
pad(table.getHeaders().get(i), width[i], request, out);
|
col++;
|
||||||
out.append(" ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
}
|
}
|
||||||
for (List<Table.Cell> row : table.getRows()) {
|
|
||||||
for (int i = 0; i < width.length; i++) {
|
for (int row = 0; row < table.getRows().size(); row++) {
|
||||||
String headerName = table.getHeaders().get(i).value.toString();
|
for (String header : displayHeaders) {
|
||||||
if (displayHeaders.contains(headerName)) {
|
pad(table.getAsMap().get(header).get(row), width[displayHeaders.indexOf(header)], request, out);
|
||||||
pad(row.get(i), width[i], request, out);
|
out.append(" ");
|
||||||
out.append(" ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out.append("\n");
|
out.append("\n");
|
||||||
}
|
}
|
||||||
|
@ -110,13 +102,16 @@ public class RestTable {
|
||||||
return new StringRestResponse(RestStatus.OK, out.toString());
|
return new StringRestResponse(RestStatus.OK, out.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> buildDisplayHeaders(Table table, RestRequest request) {
|
private static List<String> buildDisplayHeaders(Table table, RestRequest request) {
|
||||||
String pHeaders = request.param("headers");
|
String pHeaders = request.param("headers");
|
||||||
Set<String> display;
|
List<String> display = new ArrayList<String>();
|
||||||
if (pHeaders != null) {
|
if (pHeaders != null) {
|
||||||
display = Strings.commaDelimitedListToSet(pHeaders);
|
for (String possibility : Arrays.asList(Strings.splitStringByCommaToArray(pHeaders))) {
|
||||||
|
if (table.getAsMap().containsKey(possibility)) {
|
||||||
|
display.add(possibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
display = new HashSet<String>();
|
|
||||||
for (Table.Cell cell : table.getHeaders()) {
|
for (Table.Cell cell : table.getHeaders()) {
|
||||||
String d = cell.attr.get("default");
|
String d = cell.attr.get("default");
|
||||||
if (Booleans.parseBoolean(d, true)) {
|
if (Booleans.parseBoolean(d, true)) {
|
||||||
|
@ -145,27 +140,31 @@ public class RestTable {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] buildWidths(Table table, RestRequest request, boolean verbose) {
|
private static int[] buildWidths(Table table, RestRequest request, boolean verbose, List<String> headers) {
|
||||||
int[] width = new int[table.getHeaders().size()];
|
int[] width = new int[headers.size()];
|
||||||
|
int i;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
for (int col = 0; col < width.length; col++) {
|
i = 0;
|
||||||
String v = renderValue(request, table.getHeaders().get(col).value);
|
for (String hdr : headers) {
|
||||||
int vWidth = v == null ? 0 : v.length();
|
int vWidth = hdr.length();
|
||||||
if (width[col] < vWidth) {
|
if (width[i] < vWidth) {
|
||||||
width[col] = vWidth;
|
width[i] = vWidth;
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (List<Table.Cell> row : table.getRows()) {
|
i = 0;
|
||||||
for (int col = 0; col < width.length; col++) {
|
for (String hdr : headers) {
|
||||||
String v = renderValue(request, row.get(col).value);
|
for (Table.Cell cell : table.getAsMap().get(hdr)) {
|
||||||
|
String v = renderValue(request, cell.value);
|
||||||
int vWidth = v == null ? 0 : v.length();
|
int vWidth = v == null ? 0 : v.length();
|
||||||
if (width[col] < vWidth) {
|
if (width[i] < vWidth) {
|
||||||
width[col] = vWidth;
|
width[i] = vWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue