001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.hbtop.screen.field;
019
020import java.util.EnumMap;
021import java.util.List;
022import org.apache.hadoop.hbase.hbtop.field.Field;
023import org.apache.hadoop.hbase.hbtop.screen.AbstractScreenView;
024import org.apache.hadoop.hbase.hbtop.screen.Screen;
025import org.apache.hadoop.hbase.hbtop.screen.ScreenView;
026import org.apache.hadoop.hbase.hbtop.terminal.KeyPress;
027import org.apache.hadoop.hbase.hbtop.terminal.Terminal;
028import org.apache.hadoop.hbase.hbtop.terminal.TerminalPrinter;
029import org.apache.yetus.audience.InterfaceAudience;
030
031/**
032 * The screen where we can change the displayed fields, the sort key and the order of the fields.
033 */
034@InterfaceAudience.Private
035public class FieldScreenView extends AbstractScreenView {
036
037  private static final int SCREEN_DESCRIPTION_START_ROW = 0;
038  private static final int FIELD_START_ROW = 5;
039
040  private final FieldScreenPresenter fieldScreenPresenter;
041
042  public FieldScreenView(Screen screen, Terminal terminal, Field sortField, List<Field> fields,
043    EnumMap<Field, Boolean> fieldDisplayMap, FieldScreenPresenter.ResultListener resultListener,
044    ScreenView nextScreenView) {
045    super(screen, terminal);
046    this.fieldScreenPresenter = new FieldScreenPresenter(this, sortField, fields, fieldDisplayMap,
047      resultListener, nextScreenView);
048  }
049
050  @Override
051  public void init() {
052    fieldScreenPresenter.init();
053  }
054
055  @Override
056  public ScreenView handleKeyPress(KeyPress keyPress) {
057    switch (keyPress.getType()) {
058      case Escape:
059        return fieldScreenPresenter.transitionToNextScreen();
060
061      case ArrowUp:
062        fieldScreenPresenter.arrowUp();
063        return this;
064
065      case ArrowDown:
066        fieldScreenPresenter.arrowDown();
067        return this;
068
069      case PageUp:
070      case Home:
071        fieldScreenPresenter.pageUp();
072        return this;
073
074      case PageDown:
075      case End:
076        fieldScreenPresenter.pageDown();
077        return this;
078
079      case ArrowRight:
080        fieldScreenPresenter.turnOnMoveMode();
081        return this;
082
083      case ArrowLeft:
084      case Enter:
085        fieldScreenPresenter.turnOffMoveMode();
086        return this;
087
088      default:
089        // Do nothing
090        break;
091    }
092
093    if (keyPress.getType() != KeyPress.Type.Character) {
094      return this;
095    }
096
097    assert keyPress.getCharacter() != null;
098    switch (keyPress.getCharacter()) {
099      case 'd':
100      case ' ':
101        fieldScreenPresenter.switchFieldDisplay();
102        break;
103
104      case 's':
105        fieldScreenPresenter.setSortField();
106        break;
107
108      case 'q':
109        return fieldScreenPresenter.transitionToNextScreen();
110
111      default:
112        // Do nothing
113        break;
114    }
115
116    return this;
117  }
118
119  public void showFieldScreen(String sortFieldHeader, List<Field> fields,
120    EnumMap<Field, Boolean> fieldDisplayMap, int currentPosition, int headerMaxLength,
121    int descriptionMaxLength, boolean moveMode) {
122    showScreenDescription(sortFieldHeader);
123
124    for (int i = 0; i < fields.size(); i++) {
125      Field field = fields.get(i);
126      showField(i, field, fieldDisplayMap.get(field), i == currentPosition, headerMaxLength,
127        descriptionMaxLength, moveMode);
128    }
129  }
130
131  public void showScreenDescription(String sortFieldHeader) {
132    TerminalPrinter printer = getTerminalPrinter(SCREEN_DESCRIPTION_START_ROW);
133    printer.startBold().print("Fields Management").stopBold().endOfLine();
134    printer.print("Current Sort Field: ").startBold().print(sortFieldHeader).stopBold().endOfLine();
135    printer.print("Navigate with up/down, Right selects for move then <Enter> or Left commits,")
136      .endOfLine();
137    printer.print("'d' or <Space> toggles display, 's' sets sort. Use 'q' or <Esc> to end!")
138      .endOfLine();
139  }
140
141  public void showField(int pos, Field field, boolean display, boolean selected,
142    int fieldHeaderMaxLength, int fieldDescriptionMaxLength, boolean moveMode) {
143
144    String fieldHeader = String.format("%-" + fieldHeaderMaxLength + "s", field.getHeader());
145    String fieldDescription =
146      String.format("%-" + fieldDescriptionMaxLength + "s", field.getDescription());
147
148    int row = FIELD_START_ROW + pos;
149    TerminalPrinter printer = getTerminalPrinter(row);
150    if (selected) {
151      String prefix = display ? "* " : "  ";
152      if (moveMode) {
153        printer.print(prefix);
154
155        if (display) {
156          printer.startBold();
157        }
158
159        printer.startHighlight().printFormat("%s = %s", fieldHeader, fieldDescription)
160          .stopHighlight();
161
162        if (display) {
163          printer.stopBold();
164        }
165
166        printer.endOfLine();
167      } else {
168        printer.print(prefix);
169
170        if (display) {
171          printer.startBold();
172        }
173
174        printer.startHighlight().print(fieldHeader).stopHighlight().printFormat(" = %s",
175          fieldDescription);
176
177        if (display) {
178          printer.stopBold();
179        }
180
181        printer.endOfLine();
182      }
183    } else {
184      if (display) {
185        printer.print("* ").startBold().printFormat("%s = %s", fieldHeader, fieldDescription)
186          .stopBold().endOfLine();
187      } else {
188        printer.printFormat("  %s = %s", fieldHeader, fieldDescription).endOfLine();
189      }
190    }
191  }
192}