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.top;
019
020import edu.umd.cs.findbugs.annotations.Nullable;
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024import java.util.Objects;
025import java.util.function.Function;
026import org.apache.hadoop.hbase.hbtop.screen.ScreenView;
027import org.apache.yetus.audience.InterfaceAudience;
028
029/**
030 * The presentation logic for the input mode.
031 */
032@InterfaceAudience.Private
033public class InputModeScreenPresenter {
034  private final InputModeScreenView inputModeScreenView;
035  private final String message;
036  private final List<String> histories;
037  private final Function<String, ScreenView> resultListener;
038
039  private StringBuilder inputString = new StringBuilder();
040  private int cursorPosition;
041  private int historyPosition = -1;
042
043  public InputModeScreenPresenter(InputModeScreenView inputModeScreenView, String message,
044    @Nullable List<String> histories, Function<String, ScreenView> resultListener) {
045    this.inputModeScreenView = Objects.requireNonNull(inputModeScreenView);
046    this.message = Objects.requireNonNull(message);
047
048    if (histories != null) {
049      this.histories = Collections.unmodifiableList(new ArrayList<>(histories));
050    } else {
051      this.histories = Collections.emptyList();
052    }
053
054    this.resultListener = Objects.requireNonNull(resultListener);
055  }
056
057  public void init() {
058    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
059    inputModeScreenView.refreshTerminal();
060  }
061
062  public ScreenView returnToNextScreen() {
063    inputModeScreenView.hideCursor();
064    String result = inputString.toString();
065
066    return resultListener.apply(result);
067  }
068
069  public void character(Character character) {
070    inputString.insert(cursorPosition, character);
071    cursorPosition += 1;
072    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
073    inputModeScreenView.refreshTerminal();
074  }
075
076  public void backspace() {
077    if (cursorPosition == 0) {
078      return;
079    }
080
081    inputString.deleteCharAt(cursorPosition - 1);
082    cursorPosition -= 1;
083    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
084    inputModeScreenView.refreshTerminal();
085  }
086
087  public void delete() {
088    if (inputString.length() == 0 || cursorPosition > inputString.length() - 1) {
089      return;
090    }
091
092    inputString.deleteCharAt(cursorPosition);
093    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
094    inputModeScreenView.refreshTerminal();
095  }
096
097  public void arrowLeft() {
098    if (cursorPosition == 0) {
099      return;
100    }
101
102    cursorPosition -= 1;
103    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
104    inputModeScreenView.refreshTerminal();
105  }
106
107  public void arrowRight() {
108    if (cursorPosition > inputString.length() - 1) {
109      return;
110    }
111
112    cursorPosition += 1;
113    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
114    inputModeScreenView.refreshTerminal();
115  }
116
117  public void home() {
118    cursorPosition = 0;
119    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
120    inputModeScreenView.refreshTerminal();
121  }
122
123  public void end() {
124    cursorPosition = inputString.length();
125    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
126    inputModeScreenView.refreshTerminal();
127  }
128
129  public void arrowUp() {
130    if (historyPosition == 0 || histories.isEmpty()) {
131      return;
132    }
133
134    if (historyPosition == -1) {
135      historyPosition = histories.size() - 1;
136    } else {
137      historyPosition -= 1;
138    }
139
140    inputString = new StringBuilder(histories.get(historyPosition));
141
142    cursorPosition = inputString.length();
143    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
144    inputModeScreenView.refreshTerminal();
145  }
146
147  public void arrowDown() {
148    if (historyPosition == -1 || histories.isEmpty()) {
149      return;
150    }
151
152    if (historyPosition == histories.size() - 1) {
153      historyPosition = -1;
154      inputString = new StringBuilder();
155    } else {
156      historyPosition += 1;
157      inputString = new StringBuilder(histories.get(historyPosition));
158    }
159
160    cursorPosition = inputString.length();
161    inputModeScreenView.showInput(message, inputString.toString(), cursorPosition);
162    inputModeScreenView.refreshTerminal();
163  }
164}