/* * Copyright 2013 The Generic MBean CLI Project * * The Generic MBean CLI Project licenses this file to you under the Apache License, version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. * See the License for the specific language governing permissions and limitations under the License. */ package com.sohail.alam.generic.mbean.cli.console.text; import com.sohail.alam.generic.mbean.cli.CliCommands; import com.sohail.alam.generic.mbean.cli.console.ConsoleIO; import com.sohail.alam.generic.mbean.cli.jmx.DefaultJMXInitializer; import com.sohail.alam.generic.mbean.cli.jmx.JMXInitializer; import com.sohail.alam.generic.mbean.cli.logger.Logger; import com.sohail.alam.generic.mbean.cli.security.Authentication; import com.sohail.alam.generic.mbean.cli.security.DefaultAuthentication; import java.io.BufferedReader; import java.io.Console; import java.io.InputStreamReader; /** * <p/> * This is the Implementation of {@link com.sohail.alam.generic.mbean.cli.console.ConsoleIO}. * This class is responsible for the Input/Output from the Console. * <p/> * * @author Sohail Alam * @version 1.0.0 Date: 19/5/13 * Time: 5:55 PM * @since 1.0.0 */ public class DefaultConsoleIO implements ConsoleIO { /** * The AUTHENTICATION. */ private final Authentication AUTHENTICATION = DefaultAuthentication.getInstance(); /** * The Input contains the un-escaped User's input. */ private String input = null; /** * The Buffered reader contains the raw input from the User. */ private BufferedReader bufferedReader = null; /** * The Enter key pressed counter. It maintains the state of the number of times the user presses * the Enter Key consecutively. It can be useful in many cases, such as to display the HELP after * say 5 consecutive Enter Key presses. */ private int enterKeyPressed = 0; /** * Instantiates a new Console iO implementation. */ private DefaultConsoleIO() { DefaultConsoleType.getInstance(); bufferedReader = new BufferedReader(new InputStreamReader(System.in)); } /** * Gets instance. * * @return the instance */ public static ConsoleIO getInstance() { return SingletonHolder.instance; } /** * Run forever. * An infinite loop that listens to User's Input and displays the results. */ private void runForever() { Logger.logTrace("Inside runForever() method", getClass(), false); Logger.logMessage("Please Wait while we connect to JMX Server\n"); // Connect to MBean Server JMXInitializer initializer = DefaultJMXInitializer.getInstance(); initializer.connect(); while (true) { if (AUTHENTICATION.isLoggedIn()) { Logger.logTrace("Successfully Logged In", getClass(), false); bringUserInterface(); if (input == null) { break; } } else { if (input == null) { break; } System.err.println("\nYou are not authorized!! Please try again...\n"); doAuthentication(); } } } /** * This method internally calls the * {@link DefaultConsoleIO#doAuthentication()} method to * authenticate the user and on success calls the * {@link DefaultConsoleIO#runForever()} method, otherwise * keeps prompting the user to enter the correct username/password combination. */ @Override public void run() { Logger.logTrace("Inside run() method", getClass(), false); AUTHENTICATION.login(AUTHENTICATION.USERNAME, AUTHENTICATION.PASSWORD); /* * TODO: Authentication Bypassed * DESCRIPTION: Do not bypass authentication once ready for production * DATE: 23/5/13 * TIME: 10:18 PM */ // doAuthentication(); runForever(); } /** * This method authenticates the User. */ private void doAuthentication() { Logger.logTrace("Inside doAuthentication() method", getClass(), false); try { Console console = System.console(); System.err.println(); System.err.print("Please Type in your Username: "); input = bufferedReader.readLine(); String username = input; System.err.println(); String password; if (console != null) { password = new String(console.readPassword("Please Type in your Password: ")); } else { System.err.print("Please Type in your Password: "); input = bufferedReader.readLine(); password = input; } AUTHENTICATION.login(username, password); } catch (Exception ex) { Logger.logException(ex, getClass()); } } /** * Bring user interface. */ private void bringUserInterface() { Logger.logTrace("Inside bringUserInterface() method", getClass(), false); try { System.out.println(); System.out.print("CLI>> "); input = bufferedReader.readLine(); if (input != null) { if (input.length() == 0) { enterKeyPressed++; if (enterKeyPressed == 5) { System.out.println(DefaultProcessUserInput.getInstance().process(CliCommands.HELP)); enterKeyPressed = 0; } } else { System.out.println(DefaultProcessUserInput.getInstance().process(input)); } } } catch (Exception ex) { Logger.logException(ex, getClass()); } } /** * The type Singleton holder. * <p/> * Initialization on Demand Holder (IODH) idiom which requires very little code and * has zero synchronization overhead. Zero, as in even faster than volatile. * IODH requires the same number of lines of code as plain old synchronization, and it's faster than DCL! * <p/> * {@code SOURCE: http://blog.crazybob.org/2007/01/lazy-loading-singletons.html} */ static class SingletonHolder { /** * The Instance. */ static ConsoleIO instance = new DefaultConsoleIO(); } }