001 /**
002 * Copyright (c) 2012, SIB. All rights reserved.
003 *
004 * SIB (Swiss Institute of Bioinformatics) - http://www.isb-sib.ch Host -
005 * https://sourceforge.net/projects/javaprotlib/
006 *
007 * Redistribution and use in source and binary forms, with or without
008 * modification, are permitted provided that the following conditions are met:
009 * Redistributions of source code must retain the above copyright notice, this
010 * list of conditions and the following disclaimer. Redistributions in binary
011 * form must reproduce the above copyright notice, this list of conditions and
012 * the following disclaimer in the documentation and/or other materials provided
013 * with the distribution. Neither the name of the SIB/GENEBIO nor the names of
014 * its contributors may be used to endorse or promote products derived from this
015 * software without specific prior written permission.
016 *
017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
020 * ARE DISCLAIMED. IN NO EVENT SHALL SIB/GENEBIO BE LIABLE FOR ANY DIRECT,
021 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
024 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027 */
028 package org.expasy.jpl.commons.app;
029
030
031 import java.io.BufferedReader;
032 import java.io.BufferedWriter;
033 import java.io.IOException;
034 import java.io.InputStream;
035 import java.io.InputStreamReader;
036 import java.io.OutputStream;
037 import java.io.OutputStreamWriter;
038 import java.util.regex.Matcher;
039 import java.util.regex.Pattern;
040 import org.expasy.jpl.commons.base.builder.BuilderException;
041 import org.expasy.jpl.commons.base.builder.InstanceBuilder;
042
043
044 public final class InteractiveInputScannerImpl implements
045 InteractiveInputScanner {
046
047 public static final Pattern YES_NO_PATTERN =
048 Pattern.compile("^[yn]$", Pattern.CASE_INSENSITIVE);
049
050 private BufferedReader in;
051 private BufferedWriter out;
052 private String prompt;
053 private Pattern inputPattern;
054 private Pattern exitPattern;
055 private String defaultInput;
056
057 private Matcher matcher;
058
059 public InteractiveInputScannerImpl(Builder builder) {
060 setInputStream(builder.is);
061 setOutputStream(builder.os);
062
063 this.prompt = builder.prompt;
064 this.inputPattern = builder.inputPattern;
065 this.exitPattern = builder.exitPattern;
066 this.defaultInput = builder.defaultInput;
067 }
068
069 public static class Builder implements
070 InstanceBuilder<InteractiveInputScannerImpl> {
071
072 private InputStream is;
073 private OutputStream os;
074 private String prompt;
075 private Pattern inputPattern;
076 private Pattern exitPattern;
077 private String defaultInput;
078
079 public Builder() {
080 is = System.in;
081 os = System.out;
082 prompt = "";
083 inputPattern = Pattern.compile("^.+$");
084 }
085
086 public Builder prompt(String prompt) {
087 this.prompt = prompt;
088 return this;
089 }
090
091 public Builder inputStream(InputStream is) {
092 this.is = is;
093 return this;
094 }
095
096 public Builder outputStream(OutputStream os) {
097 this.os = os;
098 return this;
099 }
100
101 public Builder inputPattern(Pattern pat) {
102 this.inputPattern = pat;
103 return this;
104 }
105
106 public Builder defaultInput(String defaultInput) {
107 this.defaultInput = defaultInput;
108 return this;
109 }
110
111 public Builder exitPattern(Pattern pat) {
112 this.exitPattern = pat;
113 return this;
114 }
115
116 public InteractiveInputScannerImpl build() throws BuilderException {
117 return new InteractiveInputScannerImpl(this);
118 }
119
120 }
121
122 // open up standard input
123 public void setInputStream(InputStream stream) {
124 in = new BufferedReader(new InputStreamReader(stream));
125 }
126
127 public void setOutputStream(OutputStream stream) {
128 out = new BufferedWriter(new OutputStreamWriter(stream));
129 }
130
131 public String waitInput() throws IOException {
132 String input = null;
133
134 while (true) {
135 if (prompt != null && prompt.length() > 0) {
136 out.append(prompt);
137 out.append(": ");
138 out.flush();
139 }
140
141 // read user input
142 input = in.readLine();
143
144 matcher = inputPattern.matcher(input);
145
146 // valid input format
147 if (matcher.find()) {
148 break;
149 }
150
151 if (defaultInput != null) {
152 return defaultInput;
153 }
154
155 // exit interruption
156 if (exitPattern != null) {
157 matcher = exitPattern.matcher(input);
158 if (matcher.find()) {
159 break;
160 }
161 }
162 }
163 return input;
164 }
165
166 @Override
167 public Pattern getInputPattern() {
168 return inputPattern;
169 }
170
171 @Override
172 public String getPrompt() {
173 return prompt;
174 }
175
176 @Override
177 public Pattern getExitPattern() {
178 return exitPattern;
179 }
180
181 @Override
182 public String getDefaultInput() {
183 return defaultInput;
184 }
185
186 }