Changed propertylistening and quantitychecking to aspects
[sw/motorsim] / src / com / billkuker / rocketry / motorsim / QuantityChecking.aj
1 package com.billkuker.rocketry.motorsim;
2
3 import java.beans.BeanInfo;
4 import java.beans.Introspector;
5 import java.beans.PropertyDescriptor;
6 import java.beans.PropertyVetoException;
7 import java.lang.reflect.Field;
8 import java.lang.reflect.ParameterizedType;
9 import java.lang.reflect.Type;
10
11 import javax.measure.unit.Unit;
12
13 import org.jscience.physics.amount.Amount;
14 import com.billkuker.rocketry.motorsim.ChangeListening.Subject;
15 import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain;
16
17 public aspect QuantityChecking {
18
19         public interface Checked {
20         };
21
22         declare parents: Motor || Grain || Chamber || Nozzle || Fuel extends Checked;
23
24         void around(Checked c, Amount amt):
25                 execution(void Checked+.set*(Amount)) && target(c) && args(amt) {
26                 System.out.println(thisJoinPointStaticPart.getSignature().getName()
27                                 + " set to " + amt);
28                 try {
29                         BeanInfo b = Introspector.getBeanInfo(c.getClass());
30                         PropertyDescriptor ps[] = b.getPropertyDescriptors();
31                         String name = thisJoinPointStaticPart.getSignature().getName();
32                         name = name.replaceFirst("set", "");
33                         for (int i = 0; i < ps.length; i++) {
34                                 if (ps[i].getName().equals(name)) {
35                                         Type t = ps[i].getReadMethod().getGenericReturnType();
36                                         ParameterizedType p = (ParameterizedType) t;
37                                         Class expected = (Class) p.getActualTypeArguments()[0];
38                                         Field f = expected.getDeclaredField("UNIT");
39                                         Unit u = (Unit) f.get(null);
40
41                                         Amount a = amt;
42                                         if (!a.getUnit().isCompatible(u)) {
43                                                 System.err.println("Aspect Expected " + expected
44                                                                 + " got " + u);
45
46                                                 throw new Error(ps[i].getShortDescription()
47                                                                 + " must be in units of "
48                                                                 + expected.getSimpleName());
49                                         }
50                                 }
51                         }
52                 } catch (Exception e) {
53                         e.printStackTrace();
54                 }
55                 proceed(c, amt);
56         }
57 }