/* * Copyright (c) 2008, Manuel Mausz * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the copyright holders nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ import java.io.InputStream; import java.util.HashMap; import java.util.Scanner; import java.lang.Class; import java.lang.Boolean; import java.lang.reflect.*; import java.util.InputMismatchException; import java.lang.NoSuchMethodException; /** * CalcOperator encapsulate an Operator * NOTE: This class isn't public due to EPROG limitations. * EPROG doesn't allow shipping files not specified * * @version 1.0 * @author Manuel Mausz (manuel at mausz.at) * @author http://manuel.mausz.at/ */ class CalcOperator { private String op; /** * Constructor * * @param value init value */ CalcOperator(String op) { this.op = op; } /** * @return encapsulated operator */ public String get() { return op; } /** * Indicates whether some other object is "equal to" this one * * @param obj the reference object with which to compare * @return true if this object is the same as the obj argument; false otherwise */ public boolean equals(Object op2) { if (op2 == null) return false; else if (op2 instanceof CalcOperator) return this.op.equals(((CalcOperator) op2).get()); else return false; } /** * Returns a hash code value for the object * * @return string */ public int hashCode() { return op.hashCode(); } /** * Converts instance to string * * @return string */ public String toString() { return op; } } /** * Abstract for CalcValue * * @version 1.0 * @author Manuel Mausz (manuel at mausz.at) * @author http://manuel.mausz.at/ */ abstract class CalcValue { protected static HashMap operators = new HashMap(); /** * Assigns an operator to a method * * @param op operator * @param func method name */ protected void addOp(CalcOperator op, String func) { operators.put(op, func); } /** * Checks if instance has an method assigned to operater * * @param op operator * @return boolean */ public boolean isSupported(CalcOperator op) { return operators.containsKey(op); } /** * Invokes the method assigned to operator * passes value as argument * * @param value argument passed to the invoked method * @param op operator * @return object return by invoked method * @throws NoSuchMethodException * @throws InvocationTargetException */ public Object calc(CalcValue value, CalcOperator op) throws NoSuchMethodException, InvocationTargetException { Object ret = null; String methodname = operators.get(op); if (methodname == null) throw new NoSuchMethodException("Method for operator '" + op.get() + "' not found"); try { Method method = this.getClass().getMethod(methodname, new Class[] { value.getClass() }); ret = method.invoke(this, new Object[] { value } ); } catch(IllegalAccessException e) { throw new NoSuchMethodException(e.getMessage()); } return ret; } } /** * CalcInteger encapsulate an Integer value * NOTE: This class isn't public due to EPROG limitations. * EPROG doesn't allow shipping files not specified * * @version 1.0 * @author Manuel Mausz (manuel at mausz.at) * @author http://manuel.mausz.at/ */ class CalcInteger extends CalcValue { private int value; /** * Constructor * * @param value init value */ CalcInteger(int value) { addOps(); this.value = value; } /** * Add supported operations */ private void addOps() { addOp(new CalcOperator("+"), "add"); addOp(new CalcOperator("-"), "sub"); addOp(new CalcOperator("*"), "mul"); addOp(new CalcOperator("/"), "div"); } /** * @return encapsulated integer */ public int get() { return value; } /** * Converts instance to string * * @return string */ public String toString() { return Integer.toString(value); } /** * Addition * * @param val * @return new CalcInteger instance */ public CalcInteger add(CalcInteger val) { return new CalcInteger(value + val.get()); } /** * Subtraction * * @param val * @return new CalcInteger instance */ public CalcInteger sub(CalcInteger val) { return new CalcInteger(value - val.get()); } /** * Multiplication * * @param val * @return new CalcInteger instance */ public CalcInteger mul(CalcInteger val) { return new CalcInteger(value * val.get()); } /** * Division * * @param val * @return new CalcInteger instance */ public CalcInteger div(CalcInteger val) { return new CalcInteger(value / val.get()); } } /** * Calculator * * @version 1.0 * @author Manuel Mausz (manuel at mausz.at) * @author http://manuel.mausz.at/ */ public class Calculator { private static CalcInteger val1; private static CalcInteger val2; private static CalcOperator op; /** * read values and operator from src * only allow syntax: "int int op" * * @param src input stream * @return boolean always true * @throws InputMismatchException * @throws NoSuchMethodException * @throws InvocationTargetException */ public static boolean parse(InputStream src) throws InputMismatchException, NoSuchMethodException, InvocationTargetException { /* get first line only */ Scanner scanner = new Scanner(System.in); String line1 = scanner.nextLine(); scanner.close(); /* parse first line */ scanner = new Scanner(line1); if (!scanner.hasNextInt()) throw new InputMismatchException("Invalid first param. No integer"); val1 = new CalcInteger(scanner.nextInt()); if (!scanner.hasNextInt()) throw new InputMismatchException("Invalid second param. No integer"); val2 = new CalcInteger(scanner.nextInt()); if (!scanner.hasNext()) throw new InputMismatchException("Invalid operator"); op = new CalcOperator(scanner.next()); /* check for additional chars */ if (scanner.hasNext()) throw new InputMismatchException("Invalid chars at the end of line"); scanner.close(); return true; } /** * main method * * @param args not used */ public static void main(String[] args) { try { /* parse stdin */ parse(System.in); /* do calculation */ Object newval = val1.calc(val2, op); if (!(newval instanceof CalcInteger)) throw new InputMismatchException("Unrecognized classtype returned from operation"); /* print result to stdout */ System.out.println(((CalcInteger) newval).get()); } catch(Throwable e) { System.out.println("FALSCHE EINGABE"); } } }