001/* 002 * Stallion Core: A Modern Web Framework 003 * 004 * Copyright (C) 2015 - 2016 Stallion Software LLC. 005 * 006 * This program is free software: you can redistribute it and/or modify it under the terms of the 007 * GNU General Public License as published by the Free Software Foundation, either version 2 of 008 * the License, or (at your option) any later version. This program is distributed in the hope that 009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 011 * License for more details. You should have received a copy of the GNU General Public License 012 * along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>. 013 * 014 * 015 * 016 */ 017 018package io.stallion.utils; 019 020import org.apache.commons.lang3.StringUtils; 021 022import java.util.Arrays; 023import java.util.List; 024import java.util.Scanner; 025import java.util.regex.Pattern; 026 027import static io.stallion.utils.Literals.*; 028 029/** 030 * A helper class for building interactive, command-line prompts. 031 */ 032public class Prompter { 033 protected Scanner scanner; 034 protected String message; 035 protected List<String> choices; 036 protected Pattern validPattern; 037 protected boolean isPassword = false; 038 039 protected String lastErrorMessage = ""; 040 protected int minLength = 1; 041 042 public Prompter(String message) { 043 this.scanner = new Scanner(System.in); 044 this.message = message; 045 } 046 047 public Prompter(Scanner scanner, String message) { 048 this.scanner = scanner; 049 this.message = message; 050 } 051 052 public static String prompt(String msg) { 053 return new Prompter(msg).prompt(); 054 } 055 056 public boolean validate(String line) { 057 return true; 058 } 059 060 public String failAndPromptAgain() { 061 062 063 if (!empty(lastErrorMessage)) { 064 System.out.println(lastErrorMessage); 065 lastErrorMessage = ""; 066 } else { 067 System.out.println("Sorry, that was not a valid response."); 068 } 069 return prompt(); 070 } 071 072 public boolean yesNo() { 073 setChoices("Y", "yes", "y", "n", "N", "no"); 074 String line = prompt(); 075 if (line.equals("Y") || line.equals("yes") || line.equals("y")) { 076 return true; 077 } else { 078 return false; 079 } 080 } 081 082 public String prompt() { 083 System.out.print(message); 084 String line = ""; 085 if (isPassword && System.console() != null) { 086 line = new String(System.console().readPassword()); 087 } else { 088 line = this.scanner.nextLine(); 089 } 090 line = line.trim(); 091 if (line.length() < minLength && line.length() == 0) { 092 lastErrorMessage = "Sorry, your response must be at least " + minLength + " character(s) long. Please make a choice."; 093 return failAndPromptAgain(); 094 } 095 if (!empty(choices)) { 096 if (!choices.contains(line)) { 097 lastErrorMessage = "Sorry, that was not one of the allowed choices.\n" + 098 "The allowed choices are: " + StringUtils.join(choices, ", "); 099 100 return failAndPromptAgain(); 101 } 102 } 103 if (validPattern != null) { 104 if (!validPattern.matcher(line).matches()) { 105 lastErrorMessage = "Sorry, that was not a valid entry."; 106 return failAndPromptAgain(); 107 } 108 } 109 return line; 110 } 111 112 public Prompter setValidPattern(String patternString) { 113 this.validPattern = Pattern.compile(patternString); 114 return this; 115 } 116 117 public Prompter setChoices(String...choices) { 118 this.choices = Arrays.asList(choices); 119 return this; 120 } 121 122 public Prompter setChoices(List<String> choices) { 123 this.choices = choices; 124 return this; 125 } 126 127 128 public Prompter setAllowEmpty(boolean allow) { 129 if (allow) { 130 this.minLength = 0; 131 } else { 132 this.minLength = 1; 133 } 134 return this; 135 } 136 137 public Prompter setMinLength(int minLength) { 138 this.minLength = minLength; 139 return this; 140 } 141 142 143 public Prompter setIsPassword(boolean isPassword) { 144 this.isPassword = isPassword; 145 return this; 146 } 147 148 149 public String getLastErrorMessage() { 150 return lastErrorMessage; 151 } 152 153 public Prompter setLastErrorMessage(String lastErrorMessage) { 154 this.lastErrorMessage = lastErrorMessage; 155 return this; 156 } 157 158 159}