1 package net.sf.openrocket.optimization.rocketoptimization.modifiers;
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;
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.
15 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
17 public abstract class GenericModifier<T> extends AbstractSimulationModifier {
19 private final double multiplier;
21 private final Method getter;
22 private final Method setter;
28 * @param modifierName the name of this modifier (returned by {@link #getName()})
29 * @param relatedObject the related object (returned by {@link #getRelatedObject()})
30 * @param unitGroup the unit group (returned by {@link #getUnitGroup()})
31 * @param multiplier the multiplier by which the value returned by the getter is multiplied
32 * to obtain the desired value
33 * @param modifiedClass the class type that {@link #getModifiedObject(Simulation)} returns
34 * @param methodName the base name of the getter/setter methods (without "get"/"set")
36 public GenericModifier(String modifierName, Object relatedObject, UnitGroup unitGroup, double multiplier,
37 Class<T> modifiedClass, String methodName) {
38 super(modifierName, relatedObject, unitGroup);
39 this.multiplier = multiplier;
41 if (MathUtil.equals(multiplier, 0)) {
42 throw new IllegalArgumentException("multiplier is zero");
46 methodName = methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
47 getter = new Method(modifiedClass.getMethod("get" + methodName));
48 setter = new Method(modifiedClass.getMethod("set" + methodName, double.class));
49 } catch (SecurityException e) {
50 throw new BugException("Trying to find method get/set" + methodName + " in class " + modifiedClass, e);
51 } catch (NoSuchMethodException e) {
52 throw new BugException("Trying to find method get/set" + methodName + " in class " + modifiedClass, e);
59 public double getCurrentValue(Simulation simulation) throws OptimizationException {
60 T modifiable = getModifiedObject(simulation);
61 if (modifiable == null) {
62 throw new OptimizationException("BUG: getModifiedObject() returned null");
64 return ((Double) getter.invoke(modifiable)) * multiplier;
69 public void modify(Simulation simulation, double scaledValue) throws OptimizationException {
70 T modifiable = getModifiedObject(simulation);
71 if (modifiable == null) {
72 throw new OptimizationException("BUG: getModifiedObject() returned null");
74 double siValue = toBaseValue(scaledValue) / multiplier;
75 setter.invoke(modifiable, siValue);
80 * Return the object from the simulation that will be modified.
81 * @param simulation the simulation
82 * @return the object to modify
84 * @throws OptimizationException if the object cannot be found
86 protected abstract T getModifiedObject(Simulation simulation) throws OptimizationException;