Line data Source code
1 1 : /**
2 :
3 : @file CalculatorApp.java
4 : @brief This file serves as the main application file for the Calculator App.
5 : @details This file contains the entry point of the application, which is the main method. It initializes the necessary components and executes the Calculator App.
6 : */
7 : /**
8 :
9 : @package com.ucoruh.calculator
10 : @brief The com.ucoruh.calculator package contains all the classes and files related to the Calculator App.
11 : */
12 : package com.ucoruh.calculator;
13 :
14 : import org.slf4j.LoggerFactory;
15 :
16 : import ch.qos.logback.classic.Logger;
17 :
18 : /**
19 : *
20 : * @class CalculatorApp
21 : * @brief This class represents the main application class for the Calculator
22 : * App.
23 : * @details The CalculatorApp class provides the entry point for the Calculator
24 : * App. It parses three command-line arguments (operand, operator,
25 : * operand), computes the result with {@link Calculator} and prints
26 : * it. It never reads from standard input, so it is safe to run from
27 : * a non-interactive script and to unit test directly.
28 : * @author ugur.coruh
29 : */
30 1 : public class CalculatorApp {
31 : /**
32 : * @brief Logger for the CalculatorApp class.
33 : */
34 1 : private static final Logger logger = (Logger) LoggerFactory.getLogger(CalculatorApp.class);
35 :
36 : /**
37 : * @brief Usage message shown when the arguments do not describe a single
38 : * binary operation.
39 : */
40 : static final String USAGE = "Usage: CalculatorApp <number> <+|-|*|/> <number>";
41 :
42 0 : private CalculatorApp() {
43 : // Utility/entry-point class: not meant to be instantiated.
44 : }
45 :
46 : /**
47 : * @brief The main entry point of the Calculator App.
48 : *
49 : * @details Delegates all the work to {@link #run(String[])} and prints its
50 : * result. Kept deliberately thin so that the parsing/calculation
51 : * logic in `run` can be unit tested without touching the console.
52 : *
53 : * @param args The command-line arguments passed to the application:
54 : * `<number> <operator> <number>`.
55 : */
56 1 : public static void main(String[] args) {
57 : System.out.println(run(args));
58 : }
59 :
60 : /**
61 : * @brief Parses `args` as `<number> <operator> <number>` and computes the
62 : * result.
63 : *
64 : * @details This is the testable core of the application: it performs no
65 : * I/O (it neither reads from `System.in` nor writes to
66 : * `System.out`) and never blocks, so it can be called directly
67 : * from tests and from scripts alike. Recognized operators are
68 : * `+`, `-`, `*` and `/`. Invalid input (wrong argument count,
69 : * non-numeric operand, unknown operator, division by zero) is
70 : * reported as a descriptive `"Error: ..."` string instead of an
71 : * uncaught exception, so the process always exits cleanly with a
72 : * printable message.
73 : *
74 : * @param args The command-line arguments.
75 : * @return A human-readable result or error message.
76 : */
77 : static String run(String[] args) {
78 : if (args == null || args.length != 3) {
79 : logger.warn("Expected 3 arguments, got {}", args == null ? 0 : args.length);
80 : return USAGE;
81 : }
82 :
83 : final int left;
84 : final int right;
85 :
86 : try {
87 : left = Integer.parseInt(args[0]);
88 : right = Integer.parseInt(args[2]);
89 : } catch (NumberFormatException e) {
90 : logger.error("Invalid operand: {}", e.toString());
91 : return "Error: operands must be integers. " + USAGE;
92 : }
93 :
94 : String operator = args[1];
95 : Calculator calculator = new Calculator();
96 :
97 : switch (operator) {
98 : case "+":
99 : return String.valueOf(calculator.add(left, right));
100 :
101 : case "-":
102 : return String.valueOf(calculator.subtract(left, right));
103 :
104 : case "*":
105 : return String.valueOf(calculator.multiply(left, right));
106 :
107 : case "/":
108 : try {
109 : return String.valueOf(calculator.divide(left, right));
110 : } catch (ArithmeticException e) {
111 : logger.error("Division by zero requested");
112 : return "Error: division by zero";
113 : }
114 :
115 : default:
116 : logger.warn("Unknown operator: {}", operator);
117 : return "Error: unknown operator '" + operator + "'. " + USAGE;
118 : }
119 : }
120 : }
|