1 package net.sf.openrocket.material;
3 import net.sf.openrocket.unit.Unit;
4 import net.sf.openrocket.unit.UnitGroup;
5 import net.sf.openrocket.util.MathUtil;
8 * A class for different material types. Each material has a name and density.
9 * The interpretation of the density depends on the material type. For
10 * {@link Type#BULK} it is kg/m^3, for {@link Type#SURFACE} km/m^2.
12 * Objects of this type are immutable.
14 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
17 public abstract class Material implements Comparable<Material> {
20 LINE("Line", UnitGroup.UNITS_DENSITY_LINE),
21 SURFACE("Surface", UnitGroup.UNITS_DENSITY_SURFACE),
22 BULK("Bulk", UnitGroup.UNITS_DENSITY_BULK);
24 private final String name;
25 private final UnitGroup units;
27 private Type(String name, UnitGroup units) {
32 public UnitGroup getUnitGroup() {
37 public String toString() {
43 ///// Definitions of different material types /////
45 public static class Line extends Material {
46 public Line(String name, double density, boolean userDefined) {
47 super(name, density, userDefined);
51 public Type getType() {
56 public static class Surface extends Material {
58 public Surface(String name, double density, boolean userDefined) {
59 super(name, density, userDefined);
63 public Type getType() {
68 public String toStorableString() {
69 return super.toStorableString();
73 public static class Bulk extends Material {
74 public Bulk(String name, double density, boolean userDefined) {
75 super(name, density, userDefined);
79 public Type getType() {
86 private final String name;
87 private final double density;
88 private final boolean userDefined;
91 public Material(String name, double density, boolean userDefined) {
93 this.density = density;
94 this.userDefined = userDefined;
99 public double getDensity() {
103 public String getName() {
107 public String getName(Unit u) {
108 return name + " (" + u.toStringUnit(density) + ")";
111 public boolean isUserDefined() {
115 public abstract Type getType();
118 public String toString() {
119 return this.getName(this.getType().getUnitGroup().getDefaultUnit());
124 * Compares this object to another object. Material objects are equal if and only if
125 * their types, names and densities are identical.
128 public boolean equals(Object o) {
131 if (this.getClass() != o.getClass())
133 Material m = (Material) o;
134 return ((m.name.equals(this.name)) && MathUtil.equals(m.density, this.density));
139 * A hashCode() method giving a hash code compatible with the equals() method.
142 public int hashCode() {
143 return name.hashCode() + (int) (density * 1000);
148 * Order the materials according to their name, secondarily according to density.
151 public int compareTo(Material o) {
152 int c = this.name.compareTo(o.name);
156 return (int) ((this.density - o.density) * 1000);
162 * Return a new material of the specified type.
164 public static Material newMaterial(Type type, String name, double density,
165 boolean userDefined) {
168 return new Material.Line(name, density, userDefined);
171 return new Material.Surface(name, density, userDefined);
174 return new Material.Bulk(name, density, userDefined);
177 throw new IllegalArgumentException("Unknown material type: " + type);
182 public String toStorableString() {
183 return getType().name() + "|" + name.replace('|', ' ') + '|' + density;
188 * Return a material defined by the provided string.
190 * @param str the material storage string.
191 * @param userDefined whether the created material is user-defined.
192 * @return a new <code>Material</code> object.
193 * @throws IllegalArgumentException if <code>str</code> is invalid or null.
195 public static Material fromStorableString(String str, boolean userDefined) {
197 throw new IllegalArgumentException("Material string is null");
199 String[] split = str.split("\\|", 3);
200 if (split.length < 3)
201 throw new IllegalArgumentException("Illegal material string: " + str);
208 type = Type.valueOf(split[0]);
209 } catch (Exception e) {
210 throw new IllegalArgumentException("Illegal material string: " + str, e);
216 density = Double.parseDouble(split[2]);
217 } catch (NumberFormatException e) {
218 throw new IllegalArgumentException("Illegal material string: " + str, e);
223 return new Material.Bulk(name, density, userDefined);
226 return new Material.Surface(name, density, userDefined);
229 return new Material.Line(name, density, userDefined);
232 throw new IllegalArgumentException("Illegal material string: " + str);