/*
 * File: SimpleException.java -- A simple demonstration of exception handling.
 * 
 * Date		Author		Changes
 * ----------------------------------------------------------------
 * 5 Mar 1998	M Ravishankar	Created
 */


/**
 * Simple example of using exceptions.  This program demonstrates several
 * aspects of exception handling:
 *   - Propagation of exceptions up the function call hierarchy
 *   - Catching exceptions
 *   - Explicitly throwing predefined exceptions in Java
 *   - Declaring, throwing and catching new user-defined exceptions
 *   - The special nature of <code>RuntimeExceptions</code>, which do not have
 *     to be explicitly declared using the <code>throws</code> clause.
 *   - The use of the <code>Exception.getMessage()</code> method to retrieve
 *     descriptive messages.
**/


import java.io.*;


/**
 * Application-defined exception, to be thrown if dividing by a floating point 0.0.
 * (Note that floating point operations never cause (throw) exceptions.)
 * Typically, contains just one or more constructors, as shown below.  But can also
 * contain other user defined variables and methods if useful.
**/
class FloatDivZeroException extends ArithmeticException {
  public FloatDivZeroException (String s) {
    super (s);
  }
}


/**
 * Main application class.  Repeatedly reads two floating point numbers and divides
 * one by the other.  In the process there can be several possible exceptions:
 *   - <b>IOException</b>: thrown from inside <code>in.readLine()</code> upon any I/O
 *     error.  Usually it shouldn't occur, so we do not catch it in the <code>try</code>
 *     statement below.  If it does happen to be thrown inside readLine(), it will
 *     propagate out of it (since <code>readLine</code> doesn't catch it).  It will
 *     also propagate out of <code>main()</code> since it doesn't catch it either.
 *     At this point it will cause the program to terminate with an exception message.
 * 
 *   - <b>NumberFormatException</b>: a subclass of <b>RuntimeException</b>, which doesn't
 *     have to be declared.  This is also not caught, and will cause the program to
 *     terminate.
 * 
 *   - <b>EOFException</b>: Predefined exception in Java, explicitly thrown (and caught)
 *     by the try statement.
 * 
 *   - <b>FloatDivZeroException</b>: defined, thrown and caught in this program.
**/

public class SimpleException {
  public static void main (String[] args) throws IOException { // IOException not caught
    String str;
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    float f1, f2;
    
    for (;;) {
      // Group a block of code in which a number of exceptions might be thrown.
      try {
	// Read numerator
	System.out.print ("Numerator: ");

	// readLine() may throw IOException, but it is not caught
	if ((str = in.readLine()) == null)
	  break;

	// May throw NumberFormatException but does not have to be declared as it is
	// a subclass of RuntimeException.
	f1 = (new Float(str)).floatValue();
	
	// Read denominator
	System.out.print ("Denominator: ");
	
	// Explicitly throw EOFException if readLine returns null
	if ((str = in.readLine()) == null)	
	  throw new EOFException("EOF before denominator was input");

	f2 = (new Float(str)).floatValue();	// May throw NumberFormatException

	// Explicitly throw FloatDivZeroException if denominator is 0.
	if (f2 == 0.0)
	  throw new FloatDivZeroException ("Denominator cannot be 0");
	
	// Compute f1/f2 if everything succeeded.
	System.out.println ("Result: " + f1/f2);
      }
      catch (FloatDivZeroException e) {
	System.out.println ("Illegal expression: " + e.getMessage());
      }
      catch (EOFException e) {
	System.out.println (e.getMessage());
	break;
      }
    }
  }
}
