View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.jline;
20  
21  import java.io.IOException;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import org.apache.maven.api.annotations.Experimental;
26  import org.apache.maven.api.di.Named;
27  import org.apache.maven.api.di.Singleton;
28  import org.apache.maven.api.services.Prompter;
29  import org.apache.maven.api.services.PrompterException;
30  
31  @Experimental
32  @Named
33  @Singleton
34  public class DefaultPrompter implements Prompter {
35  
36      @Override
37      public String prompt(String message, List<String> possibleValues, String defaultReply) throws PrompterException {
38          try {
39              return doPrompt(message, possibleValues, defaultReply, false);
40          } catch (IOException e) {
41              throw new PrompterException("Failed to prompt", e);
42          }
43      }
44  
45      @Override
46      public String promptForPassword(String message) throws PrompterException {
47          try {
48              return doPrompt(message, null, null, true);
49          } catch (IOException e) {
50              throw new PrompterException("Failed to prompt for password", e);
51          }
52      }
53  
54      @Override
55      public void showMessage(String message) throws PrompterException {
56          try {
57              doDisplay(message);
58          } catch (IOException e) {
59              throw new PrompterException("Failed to present message", e);
60          }
61      }
62  
63      /**
64       * Used by {@code LegacyPlexusInteractivity}
65       */
66      public String doPrompt(String message, boolean password) throws IOException {
67          try {
68              if (message != null) {
69                  if (!message.endsWith("\n")) {
70                      if (message.endsWith(":")) {
71                          message += " ";
72                      } else if (!message.endsWith(": ")) {
73                          message += ": ";
74                      }
75                  }
76                  int lastNl = message.lastIndexOf('\n');
77                  String begin = message.substring(0, lastNl + 1);
78                  message = message.substring(lastNl + 1);
79                  MessageUtils.terminal.writer().print(begin);
80                  MessageUtils.terminal.flush();
81              }
82              return MessageUtils.reader.readLine(message, password ? '*' : null);
83          } catch (Exception e) {
84              throw new IOException("Unable to prompt user", e);
85          }
86      }
87  
88      /**
89       * Used by {@code LegacyPlexusInteractivity}
90       */
91      public void doDisplay(String message) throws IOException {
92          try {
93              MessageUtils.terminal.writer().print(message);
94              MessageUtils.terminal.flush();
95          } catch (Exception e) {
96              throw new IOException("Unable to display message", e);
97          }
98      }
99  
100     private String doPrompt(String message, List<?> possibleValues, String defaultReply, boolean password)
101             throws IOException {
102         String formattedMessage = formatMessage(message, possibleValues, defaultReply);
103         String line;
104         do {
105             line = doPrompt(formattedMessage, password);
106             if (line == null && defaultReply == null) {
107                 throw new IOException("EOF");
108             }
109             if (line == null || line.isEmpty()) {
110                 line = defaultReply;
111             }
112             if (line != null && (possibleValues != null && !possibleValues.contains(line))) {
113                 doDisplay("Invalid selection.\n");
114             }
115         } while (line == null || (possibleValues != null && !possibleValues.contains(line)));
116         return line;
117     }
118 
119     private String formatMessage(String message, List<?> possibleValues, String defaultReply) {
120         StringBuilder formatted = new StringBuilder(message.length() * 2);
121         formatted.append(message);
122         if (possibleValues != null && !possibleValues.isEmpty()) {
123             formatted.append(" (");
124             for (Iterator<?> it = possibleValues.iterator(); it.hasNext(); ) {
125                 String possibleValue = String.valueOf(it.next());
126                 formatted.append(possibleValue);
127                 if (it.hasNext()) {
128                     formatted.append('/');
129                 }
130             }
131             formatted.append(')');
132         }
133         if (defaultReply != null) {
134             formatted.append(' ').append(defaultReply).append(": ");
135         }
136         return formatted.toString();
137     }
138 }