/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2003-2007 The Jmol Development Team * * Contact: cdk-devel@lists.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.io.listener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Reader; import java.io.Writer; import java.util.List; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.io.ReaderEvent; import org.openscience.cdk.io.setting.BooleanIOSetting; import org.openscience.cdk.io.setting.IOSetting; import org.openscience.cdk.io.setting.OptionIOSetting; /** * Allows processing of IOSetting quesions which are passed to the user * by using the System.out and System.in by default. * * <p>This listener can also be used to list all the questions a ChemObjectWriter * has, by using a dummy StringWriter, and a <code>null</code> Reader. * * @cdk.module io * @cdk.githash * * @author Egon Willighagen <egonw@sci.kun.nl> */ public class TextGUIListener implements IReaderListener, IWriterListener { private BufferedReader in; private PrintWriter out; private int level = 0; /** * 0 = ask no questions * 3 = ask all questions */ public TextGUIListener(int level) { this.level = level; this.setInputReader(new InputStreamReader(System.in)); this.setOutputWriter(new OutputStreamWriter(System.out)); } public void setLevel(int level) { this.level = level; } /** * Overwrites the default writer to which the output is directed. */ public void setOutputWriter(Writer writer) { if (writer instanceof PrintWriter) { this.out = (PrintWriter)writer; } else if (writer == null) { this.out = null; } else { this.out = new PrintWriter(writer); } } /** * Overwrites the default reader from which the input is taken. */ public void setInputReader(Reader reader) { if (reader instanceof BufferedReader) { this.in = (BufferedReader)reader; } else if (reader == null) { this.in = null; } else { this.in = new BufferedReader(reader); } } public void frameRead(ReaderEvent event) {} /** * Processes the IOSettings by listing the question, giving the options * and asking the user to provide their choice. * * <p>Note: if the input reader is <code>null</code>, then the method * does not wait for an answer, and takes the default. */ public void processIOSettingQuestion(IOSetting setting) { // post the question if (setting.getLevel() < this.level) { // output the option name this.out.print("[" + setting.getName() + "]: "); // post the question this.out.print(setting.getQuestion()); if (setting instanceof BooleanIOSetting) { BooleanIOSetting boolSet = (BooleanIOSetting)setting; boolean set = boolSet.isSet(); if (set) { this.out.print(" [Yn]"); } else { this.out.print(" [yN]"); } } else if (setting instanceof OptionIOSetting) { OptionIOSetting optionSet = (OptionIOSetting)setting; List<String> settings = optionSet.getOptions(); for (int i=0; i<settings.size(); i++) { this.out.println(); String option = (String)settings.get(i); this.out.print((i+1) + ". " + option); if (option.equals(setting.getSetting())) { this.out.print(" (Default)"); } } } else { this.out.print(" [" + setting.getSetting() + "]"); } this.out.println(); this.out.flush(); // get the answer, only if input != null if (this.in == null) { // don't really ask questions. This is intentional behaviour to // allow for listing all questions. The settings is now defaulted, // which is the intention too. } else { boolean gotAnswer = false; while (!gotAnswer) { try { this.out.print("> "); this.out.flush(); String answer = in.readLine(); if (answer.length() == 0) { // pressed ENTER -> take default } else if (setting instanceof OptionIOSetting) { ((OptionIOSetting)setting).setSetting(Integer.parseInt(answer)); } else if (setting instanceof BooleanIOSetting) { if (answer.equalsIgnoreCase("n") || answer.equalsIgnoreCase("no")) { answer = "false"; } if (answer.equalsIgnoreCase("y") || answer.equalsIgnoreCase("yes")) { answer = "true"; } setting.setSetting(answer); } else { setting.setSetting(answer); } gotAnswer = true; } catch (IOException exception) { this.out.println("Cannot read from STDIN. Skipping question."); } catch (NumberFormatException exception) { this.out.println("Answer is not a number."); } catch (CDKException exception) { this.out.println(); this.out.println(exception.toString()); } } } } } }