/** * Licensed to jclouds, Inc. (jclouds) under one or more * contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. jclouds licenses this file * to you 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 org.jclouds.karaf.commands.table; import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.jclouds.karaf.commands.table.internal.AlphanumericComparator; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; public abstract class BasicShellTable<D extends Object> implements ShellTable<D> { private String type; private List<String> headers; private List<String> displayExpression; private List<String> alignments; private String sortBy; private boolean ascending; private D displayData; private final Comparator comparator = new AlphanumericComparator(); /** * Evaluate an expression on the given Object and return a {@link String} representation of the result. * @param object * @param expression * @return */ public abstract String evaluate(Object object, String expression); /** * Displays the content of the table to the specified {@link java.io.PrintStream}. * @param out */ public void display(PrintStream out, boolean showHeaders, boolean showData) { List<String[]> table = new ArrayList<String[]>(); Iterable iterableData = null; //If display data is an iterable use as is, else wrap data inside a collection. if (Iterable.class.isAssignableFrom(displayData.getClass())) { iterableData = (Iterable) displayData; } else { iterableData = Lists.newArrayList(displayData); } //Populate table for (Object obj : iterableData) { String[] values = new String[displayExpression.size()]; for (int i=0; i < displayExpression.size(); i++) { values[i] = evaluate(obj, displayExpression.get(i)); } table.add(values); } List<Integer> sizes = calculateSizes(headers, table); if (!Strings.isNullOrEmpty(sortBy) && headers.contains(sortBy)) Collections.sort(table, new Comparator<String[]>() { @Override public int compare(String[] left, String[] right) { int column = headers.indexOf(sortBy); String leftValue = left[column]; String rightValue = right[column]; return comparator.compare(leftValue,rightValue); } }); String dataFormat = getStringFormat(sizes, alignments); //Check if we need to display headers if (showHeaders) { out.println(String.format(dataFormat, headers.toArray(new String[headers.size()]))); } //Check if we need and can display data. if (showData && table != null) { for (String[] row : table) { //Populate display data out.println(String.format(dataFormat, row)); } } } /** * Scans the table and calculates the sizes. * @param headers * @param displayData * @return */ private List<Integer> calculateSizes(List<String> headers, List<String[]> displayData) { List<Integer> sizes = new LinkedList<Integer>(); for (int i=0; i < headers.size(); i ++) { String header = headers.get(i); int size = header.length(); for (String[] row : displayData) { String value = row[i]; int valueSize = value.length(); size = size > valueSize ? size : valueSize; } sizes.add(size); } return sizes; } private String getStringFormat(List<Integer> sizes, List<String> alignments) { StringBuilder sb = new StringBuilder(); for (int i=0; i < sizes.size(); i++) { //Add a separator if (i > 0) { sb.append(" "); } int size = sizes.get(i); String alignment = alignments != null && alignments.size() > i ? alignments.get(i) : LEFT; if (RIGHT.equals(alignment)){ sb.append("%").append(size).append("s"); } else { sb.append("%-").append(size).append("s"); } } return sb.toString(); } public String getType() { return type; } public void setType(String type) { this.type = type; } //Getters and Setters public List<String> getHeaders() { return headers; } public void setHeaders(List<String> headers) { this.headers = headers; } public List<String> getDisplayExpression() { return displayExpression; } public void setDisplayExpression(List<String> displayExpression) { this.displayExpression = displayExpression; } public List<String> getAlignments() { return alignments; } public void setAlignments(List<String> alignments) { this.alignments = alignments; } public String getSortBy() { return sortBy; } public void setSortBy(String sortBy) { this.sortBy = sortBy; } public boolean getAscending() { return ascending; } public void setAscending(boolean ascending) { this.ascending = ascending; } public D getDisplayData() { return displayData; } public void setDisplayData(D displayData) { this.displayData = displayData; } }