f2cb67f77b0a43d52579fc8337cfd4a675aca3d4
[debian/openrocket] / src / net / sf / openrocket / optimization / rocketoptimization / modifiers / GenericModifier.java
1 package net.sf.openrocket.optimization.rocketoptimization.modifiers;
2
3 import net.sf.openrocket.document.Simulation;
4 import net.sf.openrocket.optimization.general.OptimizationException;
5 import net.sf.openrocket.unit.UnitGroup;
6 import net.sf.openrocket.util.BugException;
7 import net.sf.openrocket.util.MathUtil;
8 import net.sf.openrocket.util.Reflection.Method;
9
10 /**
11  * A generic SimulationModifier that uses reflection to get and set a double value.
12  * Implementations need to implement the {@link #getModifiedObject(Simulation)} method
13  * to return which object is modified.
14  * 
15  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
16  */
17 public abstract class GenericModifier<T> extends AbstractSimulationModifier {
18         
19         private final double multiplier;
20         
21         private final Class<? extends T> modifiedClass;
22         private final String methodName;
23         
24         private final Method getter;
25         private final Method setter;
26         
27         
28         /**
29          * Sole constructor.
30          * 
31          * @param modifierName          the name of this modifier (returned by {@link #getName()})
32          * @param relatedObject         the related object (returned by {@link #getRelatedObject()})
33          * @param unitGroup                     the unit group (returned by {@link #getUnitGroup()})
34          * @param multiplier            the multiplier by which the value returned by the getter is multiplied
35          *                                                      to obtain the desired value
36          * @param modifiedClass         the class type that {@link #getModifiedObject(Simulation)} returns
37          * @param methodName            the base name of the getter/setter methods (without "get"/"set")
38          */
39         public GenericModifier(String modifierName, Object relatedObject, UnitGroup unitGroup, double multiplier,
40                         Class<? extends T> modifiedClass, String methodName) {
41                 super(modifierName, relatedObject, unitGroup);
42                 this.multiplier = multiplier;
43                 
44                 this.modifiedClass = modifiedClass;
45                 this.methodName = methodName;
46                 
47                 if (MathUtil.equals(multiplier, 0)) {
48                         throw new IllegalArgumentException("multiplier is zero");
49                 }
50                 
51                 try {
52                         methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
53                         getter = new Method(modifiedClass.getMethod("get" + methodName));
54                         setter = new Method(modifiedClass.getMethod("set" + methodName, double.class));
55                 } catch (SecurityException e) {
56                         throw new BugException("Trying to find method get/set" + methodName + " in class " + modifiedClass, e);
57                 } catch (NoSuchMethodException e) {
58                         throw new BugException("Trying to find method get/set" + methodName + " in class " + modifiedClass, e);
59                 }
60         }
61         
62         
63
64         @Override
65         public double getCurrentSIValue(Simulation simulation) throws OptimizationException {
66                 T modifiable = getModifiedObject(simulation);
67                 if (modifiable == null) {
68                         throw new OptimizationException("BUG: getModifiedObject() returned null");
69                 }
70                 return ((Double) getter.invoke(modifiable)) * multiplier;
71         }
72         
73         
74         @Override
75         public void modify(Simulation simulation, double scaledValue) throws OptimizationException {
76                 T modifiable = getModifiedObject(simulation);
77                 if (modifiable == null) {
78                         throw new OptimizationException("BUG: getModifiedObject() returned null");
79                 }
80                 double siValue = toBaseValue(scaledValue) / multiplier;
81                 System.out.println("Setting setter=" + setter + " modifiable=" + modifiable + " siValue=" + siValue + "scaledValue=" + scaledValue);
82                 setter.invoke(modifiable, siValue);
83         }
84         
85         
86         /**
87          * Return the object from the simulation that will be modified.
88          * @param simulation    the simulation
89          * @return                              the object to modify
90          * 
91          * @throws OptimizationException        if the object cannot be found
92          */
93         protected abstract T getModifiedObject(Simulation simulation) throws OptimizationException;
94         
95         
96
97         @Override
98         public String toString() {
99                 return "GenericModifier[modifiedClass=" + modifiedClass.getCanonicalName() + ", methodName=" + methodName + ", multiplier=" + multiplier + "]";
100         }
101         
102 }