kafka LsCommandHandler 源码
kafka LsCommandHandler 代码
文件路径:/shell/src/main/java/org/apache/kafka/shell/LsCommandHandler.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.kafka.shell;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.kafka.shell.GlobVisitor.MetadataNodeInfo;
import org.apache.kafka.shell.MetadataNode.DirectoryNode;
import org.apache.kafka.shell.MetadataNode.FileNode;
import org.jline.reader.Candidate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
/**
* Implements the ls command.
*/
public final class LsCommandHandler implements Commands.Handler {
private static final Logger log = LoggerFactory.getLogger(LsCommandHandler.class);
public final static Commands.Type TYPE = new LsCommandType();
public static class LsCommandType implements Commands.Type {
private LsCommandType() {
}
@Override
public String name() {
return "ls";
}
@Override
public String description() {
return "List metadata nodes.";
}
@Override
public boolean shellOnly() {
return false;
}
@Override
public void addArguments(ArgumentParser parser) {
parser.addArgument("targets").
nargs("*").
help("The metadata node paths to list.");
}
@Override
public Commands.Handler createHandler(Namespace namespace) {
return new LsCommandHandler(namespace.getList("targets"));
}
@Override
public void completeNext(MetadataNodeManager nodeManager, List<String> nextWords,
List<Candidate> candidates) throws Exception {
CommandUtils.completePath(nodeManager, nextWords.get(nextWords.size() - 1),
candidates);
}
}
private final List<String> targets;
public LsCommandHandler(List<String> targets) {
this.targets = targets;
}
static class TargetDirectory {
private final String name;
private final List<String> children;
TargetDirectory(String name, List<String> children) {
this.name = name;
this.children = children;
}
}
@Override
public void run(Optional<InteractiveShell> shell,
PrintWriter writer,
MetadataNodeManager manager) throws Exception {
List<String> targetFiles = new ArrayList<>();
List<TargetDirectory> targetDirectories = new ArrayList<>();
for (String target : CommandUtils.getEffectivePaths(targets)) {
manager.visit(new GlobVisitor(target, entryOption -> {
if (entryOption.isPresent()) {
MetadataNodeInfo info = entryOption.get();
MetadataNode node = info.node();
if (node instanceof DirectoryNode) {
DirectoryNode directory = (DirectoryNode) node;
List<String> children = new ArrayList<>();
children.addAll(directory.children().keySet());
targetDirectories.add(
new TargetDirectory(info.lastPathComponent(), children));
} else if (node instanceof FileNode) {
targetFiles.add(info.lastPathComponent());
}
} else {
writer.println("ls: " + target + ": no such file or directory.");
}
}));
}
OptionalInt screenWidth = shell.isPresent() ?
OptionalInt.of(shell.get().screenWidth()) : OptionalInt.empty();
log.trace("LS : targetFiles = {}, targetDirectories = {}, screenWidth = {}",
targetFiles, targetDirectories, screenWidth);
printTargets(writer, screenWidth, targetFiles, targetDirectories);
}
static void printTargets(PrintWriter writer,
OptionalInt screenWidth,
List<String> targetFiles,
List<TargetDirectory> targetDirectories) {
printEntries(writer, "", screenWidth, targetFiles);
boolean needIntro = targetFiles.size() > 0 || targetDirectories.size() > 1;
boolean firstIntro = targetFiles.isEmpty();
for (TargetDirectory targetDirectory : targetDirectories) {
String intro = "";
if (needIntro) {
if (!firstIntro) {
intro = intro + String.format("%n");
}
intro = intro + targetDirectory.name + ":";
firstIntro = false;
}
log.trace("LS : targetDirectory name = {}, children = {}",
targetDirectory.name, targetDirectory.children);
printEntries(writer, intro, screenWidth, targetDirectory.children);
}
}
static void printEntries(PrintWriter writer,
String intro,
OptionalInt screenWidth,
List<String> entries) {
if (entries.isEmpty()) {
return;
}
if (!intro.isEmpty()) {
writer.println(intro);
}
ColumnSchema columnSchema = calculateColumnSchema(screenWidth, entries);
int numColumns = columnSchema.numColumns();
int numLines = (entries.size() + numColumns - 1) / numColumns;
for (int line = 0; line < numLines; line++) {
StringBuilder output = new StringBuilder();
for (int column = 0; column < numColumns; column++) {
int entryIndex = line + (column * columnSchema.entriesPerColumn());
if (entryIndex < entries.size()) {
String entry = entries.get(entryIndex);
output.append(entry);
if (column < numColumns - 1) {
int width = columnSchema.columnWidth(column);
for (int i = 0; i < width - entry.length(); i++) {
output.append(" ");
}
}
}
}
writer.println(output.toString());
}
}
static ColumnSchema calculateColumnSchema(OptionalInt screenWidth,
List<String> entries) {
if (!screenWidth.isPresent()) {
return new ColumnSchema(1, entries.size());
}
int maxColumns = screenWidth.getAsInt() / 4;
if (maxColumns <= 1) {
return new ColumnSchema(1, entries.size());
}
ColumnSchema[] schemas = new ColumnSchema[maxColumns];
for (int numColumns = 1; numColumns <= maxColumns; numColumns++) {
schemas[numColumns - 1] = new ColumnSchema(numColumns,
(entries.size() + numColumns - 1) / numColumns);
}
for (int i = 0; i < entries.size(); i++) {
String entry = entries.get(i);
for (int s = 0; s < schemas.length; s++) {
ColumnSchema schema = schemas[s];
schema.process(i, entry);
}
}
for (int s = schemas.length - 1; s > 0; s--) {
ColumnSchema schema = schemas[s];
if (schema.columnWidths[schema.columnWidths.length - 1] != 0 &&
schema.totalWidth() <= screenWidth.getAsInt()) {
return schema;
}
}
return schemas[0];
}
static class ColumnSchema {
private final int[] columnWidths;
private final int entriesPerColumn;
ColumnSchema(int numColumns, int entriesPerColumn) {
this.columnWidths = new int[numColumns];
this.entriesPerColumn = entriesPerColumn;
}
ColumnSchema setColumnWidths(Integer... widths) {
for (int i = 0; i < widths.length; i++) {
columnWidths[i] = widths[i];
}
return this;
}
void process(int entryIndex, String output) {
int columnIndex = entryIndex / entriesPerColumn;
columnWidths[columnIndex] = Math.max(
columnWidths[columnIndex], output.length() + 2);
}
int totalWidth() {
int total = 0;
for (int i = 0; i < columnWidths.length; i++) {
total += columnWidths[i];
}
return total;
}
int numColumns() {
return columnWidths.length;
}
int columnWidth(int columnIndex) {
return columnWidths[columnIndex];
}
int entriesPerColumn() {
return entriesPerColumn;
}
@Override
public int hashCode() {
return Objects.hash(columnWidths, entriesPerColumn);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ColumnSchema)) return false;
ColumnSchema other = (ColumnSchema) o;
if (entriesPerColumn != other.entriesPerColumn) return false;
if (!Arrays.equals(columnWidths, other.columnWidths)) return false;
return true;
}
@Override
public String toString() {
StringBuilder bld = new StringBuilder("ColumnSchema(columnWidths=[");
String prefix = "";
for (int i = 0; i < columnWidths.length; i++) {
bld.append(prefix);
bld.append(columnWidths[i]);
prefix = ", ";
}
bld.append("], entriesPerColumn=").append(entriesPerColumn).append(")");
return bld.toString();
}
}
@Override
public int hashCode() {
return Objects.hashCode(targets);
}
@Override
public boolean equals(Object other) {
if (!(other instanceof LsCommandHandler)) return false;
LsCommandHandler o = (LsCommandHandler) other;
if (!Objects.equals(o.targets, targets)) return false;
return true;
}
}
相关信息
相关文章
0
赞