View Javadoc
1   package calculator.atoms.visitor;
2   
3   import java.math.BigDecimal;
4   
5   import calculator.atoms.*;
6   
7   /**
8    * AtomCaster is an AtomVisitor whose goal is to cast
9    * the visited atom to the specified type
10   * and throws errors if this cast is impossible e.g a complex to an Integer
11   *
12   * @see AtomVisitor
13   */
14  public class AtomCaster extends AtomVisitor {
15  
16  	/* The type to Cast the visited Atom to */
17  	private AtomType type;
18  
19  	/* The Result of the casting after the visit */
20  	private Atom result;
21  
22  	/**
23  	 * returns the result of the cast of the visited to the specified type
24  	 * 
25  	 * @return the Result of the cast from the visited Atom to the specified type
26  	 */
27  	public Atom getResult() {
28  		return result;
29  	}
30  
31  	/**
32  	 * Constructs an AtomCaster to cast to the specified type
33  	 *
34  	 * @param type The type to Cast the visited Atom to
35  	 */
36  	public AtomCaster(AtomType type) {
37  		this.type = type;
38  	}
39  
40  	/**
41  	 * Visiting a Real Atom to cast it to the specified type of the visitor
42  	 *
43  	 * @param r The visited Real to be cast
44  	 * @throws IllegalAtomCast in case of an impossible cast
45  	 */
46  	@Override
47  	public void visit(Real r) {
48  		switch (type) {
49  			case REAL:
50  				result = r;
51  				break;
52  
53  			case INTEGER:
54  				throw new IllegalAtomCast("Impossible to cast Real to Integer");
55  
56  			case RATIONNAL:
57  				if (r.isNan() || r.isPlusInf() || r.isMinusInf()) {
58  					throw new IllegalAtomCast("Impossible to cast NaN or Infinity Real to Rationnal");
59  				}
60  				result = new Rationnal(org.apache.commons.numbers.fraction.Fraction.from(r.getValue().doubleValue()));
61  				break;
62  
63  			case COMPLEX:
64  				if (r.isNan()) {
65  					result = Complex.nan();
66  					break;
67  				}
68  				result = new Complex(r.getValue().doubleValue(), 0);
69  				break;
70  
71  			default:
72  				result = null;
73  				throw new UnsupportedOperationException("Cast Not implemented");
74  		}
75  	}
76  
77  	/**
78  	 * Visiting a Complex Atom to cast it to the specified type of the visitor
79  	 *
80  	 * @param c The visited Complex to be cast
81  	 * @throws IllegalAtomCast in case of an impossible cast
82  	 */
83  	@Override
84  	public void visit(Complex c) {
85  		switch (type) {
86  			case COMPLEX:
87  				result = c;
88  				break;
89  
90  			case REAL:
91  			case INTEGER:
92  			case RATIONNAL:
93  				throw new IllegalAtomCast("Impossible to cast Complex to " + type);
94  
95  			default:
96  				result = null;
97  				throw new UnsupportedOperationException("Cast Not implemented");
98  		}
99  	}
100 
101 	/**
102 	 * Visiting a Rationnal Atom to cast it to the specified type of the visitor
103 	 *
104 	 * @param q The visited Rationnal to be cast
105 	 * @throws IllegalAtomCast in case of an impossible cast
106 	 */
107 	@Override
108 	public void visit(Rationnal q) {
109 		switch (type) {
110 			case RATIONNAL:
111 				result = q;
112 				break;
113 
114 			case REAL:
115 				BigDecimal num = new BigDecimal(q.getNumerator());
116 				BigDecimal denom = new BigDecimal(q.getDenominator());
117 				result = new Real(num.divide(denom, Real.context));
118 
119 				break;
120 
121 			case COMPLEX:
122 				result = new Complex(q.getValue().doubleValue(), 0);
123 				break;
124 
125 			case INTEGER:
126 				throw new IllegalAtomCast("Impossible to cast Rationnal to Integer");
127 
128 			default:
129 				result = null;
130 				throw new UnsupportedOperationException("Cast Not implemented");
131 		}
132 	}
133 
134 	/**
135 	 * Visiting a Integer Atom to cast it to the specified type of the visitor
136 	 *
137 	 * @param i The visited IntegerAtom to be cast
138 	 * @throws IllegalAtomCast in case of an impossible cast
139 	 */
140 	@Override
141 	public void visit(IntegerAtom i) {
142 		switch (type) {
143 			case INTEGER:
144 				result = i;
145 				break;
146 
147 			case REAL:
148 				result = new Real(i.getValue());
149 				break;
150 
151 			case RATIONNAL:
152 				result = new Rationnal(i.getValue(), 1);
153 				break;
154 
155 			case COMPLEX:
156 				result = new Complex(i.getValue(), 0);
157 				break;
158 
159 			default:
160 				result = null;
161 				throw new UnsupportedOperationException("Cast Not implemented");
162 		}
163 	}
164 
165 }