1 package net.sf.openrocket.aerodynamics;
3 import net.sf.openrocket.l10n.Translator;
4 import net.sf.openrocket.motor.Motor;
5 import net.sf.openrocket.startup.Application;
6 import net.sf.openrocket.unit.UnitGroup;
8 public abstract class Warning {
10 private static final Translator trans = Application.getTranslator();
13 * Return a Warning with the specific text.
15 public static Warning fromString(String text) {
16 return new Warning.Other(text);
21 * Return <code>true</code> if the <code>other</code> warning should replace
22 * this warning. The method should return <code>true</code> if the other
23 * warning indicates a "worse" condition than the current warning.
25 * @param other the warning to compare to
26 * @return whether this warning should be replaced
28 public abstract boolean replaceBy(Warning other);
32 * Two <code>Warning</code>s are by default considered equal if they are of
33 * the same class. Therefore only one instance of a particular warning type
34 * is stored in a {@link WarningSet}. Subclasses may override this method for
35 * more specific functionality.
38 public boolean equals(Object o) {
39 return o != null && (o.getClass() == this.getClass());
43 * A <code>hashCode</code> method compatible with the <code>equals</code> method.
46 public int hashCode() {
47 return this.getClass().hashCode();
53 ///////////// Specific warning classes /////////////
57 * A <code>Warning</code> indicating a large angle of attack was encountered.
59 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
61 public static class LargeAOA extends Warning {
65 * Sole constructor. The argument is the AOA that caused this warning.
67 * @param aoa the angle of attack that caused this warning
69 public LargeAOA(double aoa) {
74 public String toString() {
75 if (Double.isNaN(aoa))
76 //// Large angle of attack encountered.
77 return trans.get("Warning.LargeAOA.str1");
78 //// Large angle of attack encountered (
79 return (trans.get("Warning.LargeAOA.str2") +
80 UnitGroup.UNITS_ANGLE.getDefaultUnit().toString(aoa) + ").");
84 public boolean replaceBy(Warning other) {
85 if (!(other instanceof LargeAOA))
88 LargeAOA o = (LargeAOA)other;
89 if (Double.isNaN(this.aoa)) // If this has value NaN then replace
91 return (o.aoa > this.aoa);
95 public static class MissingMotor extends Warning {
97 private Motor.Type type = null;
98 private String manufacturer = null;
99 private String designation = null;
100 private String digest = null;
101 private double diameter = Double.NaN;
102 private double length = Double.NaN;
103 private double delay = Double.NaN;
106 public String toString() {
107 String str = "No motor with designation '" + designation + "'";
108 if (manufacturer != null)
109 str += " for manufacturer '" + manufacturer + "'";
114 public Motor.Type getType() {
119 public void setType(Motor.Type type) {
124 public String getManufacturer() {
129 public void setManufacturer(String manufacturer) {
130 this.manufacturer = manufacturer;
134 public String getDesignation() {
139 public void setDesignation(String designation) {
140 this.designation = designation;
144 public String getDigest() {
149 public void setDigest(String digest) {
150 this.digest = digest;
154 public double getDiameter() {
159 public void setDiameter(double diameter) {
160 this.diameter = diameter;
164 public double getLength() {
169 public void setLength(double length) {
170 this.length = length;
174 public double getDelay() {
179 public void setDelay(double delay) {
185 public boolean replaceBy(Warning other) {
190 public int hashCode() {
191 final int prime = 31;
192 int result = super.hashCode();
194 temp = Double.doubleToLongBits(delay);
195 result = prime * result + (int) (temp ^ (temp >>> 32));
196 result = prime * result
197 + ((designation == null) ? 0 : designation.hashCode());
198 temp = Double.doubleToLongBits(diameter);
199 result = prime * result + (int) (temp ^ (temp >>> 32));
200 result = prime * result
201 + ((digest == null) ? 0 : digest.hashCode());
202 temp = Double.doubleToLongBits(length);
203 result = prime * result + (int) (temp ^ (temp >>> 32));
204 result = prime * result
205 + ((manufacturer == null) ? 0 : manufacturer.hashCode());
206 result = prime * result + ((type == null) ? 0 : type.hashCode());
211 public boolean equals(Object obj) {
214 if (!super.equals(obj))
216 if (getClass() != obj.getClass())
218 MissingMotor other = (MissingMotor) obj;
219 if (Double.doubleToLongBits(delay) != Double
220 .doubleToLongBits(other.delay))
222 if (designation == null) {
223 if (other.designation != null)
225 } else if (!designation.equals(other.designation))
227 if (Double.doubleToLongBits(diameter) != Double
228 .doubleToLongBits(other.diameter))
230 if (digest == null) {
231 if (other.digest != null)
233 } else if (!digest.equals(other.digest))
235 if (Double.doubleToLongBits(length) != Double
236 .doubleToLongBits(other.length))
238 if (manufacturer == null) {
239 if (other.manufacturer != null)
241 } else if (!manufacturer.equals(other.manufacturer))
243 if (type != other.type)
252 * An unspecified warning type. This warning type holds a <code>String</code>
253 * describing it. Two warnings of this type are considered equal if the strings
256 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
258 public static class Other extends Warning {
259 private String description;
261 public Other(String description) {
262 this.description = description;
266 public String toString() {
271 public boolean equals(Object other) {
272 if (!(other instanceof Other))
275 Other o = (Other)other;
276 return (o.description.equals(this.description));
280 public int hashCode() {
281 return description.hashCode();
285 public boolean replaceBy(Warning other) {
291 /** A <code>Warning</code> that the body diameter is discontinuous. */
292 ////Discontinuity in rocket body diameter.
293 public static final Warning DISCONTINUITY =
294 new Other(trans.get("Warning.DISCONTINUITY"));
296 /** A <code>Warning</code> that the fins are thick compared to the rocket body. */
297 ////Thick fins may not be modeled accurately.
298 public static final Warning THICK_FIN =
299 new Other(trans.get("Warning.THICK_FIN"));
301 /** A <code>Warning</code> that the fins have jagged edges. */
302 ////Jagged-edged fin predictions may be inaccurate.
303 public static final Warning JAGGED_EDGED_FIN =
304 new Other(trans.get("Warning.JAGGED_EDGED_FIN"));
306 /** A <code>Warning</code> that simulation listeners have affected the simulation */
307 ////Listeners modified the flight simulation
308 public static final Warning LISTENERS_AFFECTED =
309 new Other(trans.get("Warning.LISTENERS_AFFECTED"));
311 ////Recovery device opened while motor still burning.
312 public static final Warning RECOVERY_DEPLOYMENT_WHILE_BURNING =
313 new Other(trans.get("Warning.RECOVERY_DEPLOYMENT_WHILE_BURNING"));
316 //// Invalid parameter encountered, ignoring.
317 public static final Warning FILE_INVALID_PARAMETER =
318 new Other(trans.get("Warning.FILE_INVALID_PARAMETER"));
320 public static final Warning PARALLEL_FINS =
321 new Other(trans.get("Warning.PARALLEL_FINS"));
323 public static final Warning SUPERSONIC =
324 new Other(trans.get("Warning.SUPERSONIC"));
326 public static final Warning RECOVERY_LAUNCH_ROD =
327 new Other(trans.get("Warning.RECOVERY_LAUNCH_ROD"));