1 /* 
2  * Copyright 2005 Paul Hinds
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.tp23.antinstaller.renderer.text;
17
18import java.io.BufferedReader;
19import java.io.IOException;
20import java.io.PrintStream;
21import java.util.ResourceBundle;
22
23import org.tp23.antinstaller.InstallerContext;
24import org.tp23.antinstaller.input.OutputField;
25import org.tp23.antinstaller.input.PasswordTextInput;
26
27
28public class PasswordTextInputRenderer extends ValidatedTextInputRenderer
29
30    implements TextOutputFieldRenderer {
31
32    private static final ResourceBundle res = ResourceBundle.getBundle("org.tp23.antinstaller.renderer.text.Res");
33    
34    public PasswordTextInputRenderer() {
35    }
36
37    public void setContext(InstallerContext ctx) {
38        this.ctx = ctx;
39    }
40
41    public void renderOutput(OutputField field, BufferedReader reader, PrintStream out) throws IOException {
42        PasswordTextInput iField = (PasswordTextInput) field;
43        StringBuffer displayText = new StringBuffer();
44        displayText.append(field.getDisplayText());
45        displayText.append("   [");
46        displayText.append(res.getString("_default_"));
47        displayText.append(":");
48        displayText.append(iField.getDefaultValue());
49        displayText.append("]");
50
51        String input = null;
52        if(OutputField.isTrue(iField.getTextMask())){
53            input = new PasswordField().getPassword(displayText.toString());
54            System.out.print("\r                                                      ");
55        }
56        else {
57            out.println(displayText.toString());
58            input = reader.readLine();
59        }
60
61        out.println();
62        out.println();
63        if(input == null || input.equals("")){
64            input = iField.getDefaultValue();
65        }
66        iField.setInputResult(input);
67    }
68    public void renderError(OutputField field, BufferedReader reader, PrintStream out) throws IOException{
69        out.println(getErrorMessage());
70        renderOutput(field, reader, out);
71    }
72    public boolean isAbort(){
73        return false;
74    }
75
76    protected String getErrorMessage(){
77        return res.getString("notCorrectPasswordFormat");
78    }
79    
80    // shame this does not work
81    // does any one know a way to not echo passwords?
82//  private String readInput(InputStreamReader reader, PrintStream out) throws IOException{
83//      StringBuffer sb = new StringBuffer();
84//      char c = 0;
85//      while((c=(char)reader.read())!='\n'){
86//          if(c==8)sb.setLength(sb.length()-1);
87//          sb.append(c);
88//          out.print((char)8);
89//          out.flush();
90//      }
91//      return sb.toString();
92//  }
93    
94    /*
95     * 
96     * Taken from the SUN website
97     * @author Paul Hinds
98     * @version $Id: PasswordTextInputRenderer.java,v 1.4 2007/01/04 22:57:18 teknopaul Exp $
99     */
00    class MaskingThread extends Thread {
01        private boolean stop = false;
02        private int index;
03        private String prompt;
04
05        public MaskingThread(String prompt) {
06            this.prompt = prompt;
07        }
08
09        public void run() {
10            while (!stop) {
11                try {
12                    // attempt masking at this rate
13                    this.sleep(1);
14                }
15                catch (InterruptedException iex) {
16                    iex.printStackTrace();
17                }
18                if (!stop) {
19                    System.out.print("\r" + prompt + " \r" + prompt);
20                }
21                System.out.flush();
22            }
23        }
24
25        public void stopMasking() {
26            this.stop = true;
27        }
28    }
29    
30    public class PasswordField {
31
32        /**
33         *@param prompt The prompt to display to the user.
34         *@return The password as entered by the user.
35         */
36        String getPassword(String prompt) throws IOException {
37            // password holder
38            StringBuffer password = new StringBuffer();
39            MaskingThread maskingthread = new MaskingThread(prompt);
40            Thread thread = new Thread(maskingthread);
41            thread.start();
42            // block until enter is pressed
43            while (true) {
44                char c = (char) System.in.read();
45                // assume enter pressed, stop masking
46                maskingthread.stopMasking();
47                if (c == '\r') {
48                    c = (char) System.in.read();
49                    if (c == '\n') {
50                        break;
51                    }
52                    else {
53                        continue;
54                    }
55                }
56                else if (c == '\n') {
57                    break;
58                }
59                else {
60                    // store the password
61                    password.append(c);
62                }
63            }
64            return password.toString();
65        }
66    }
67}
68