1 package net.sf.openrocket.material;
3 import net.sf.openrocket.l10n.Translator;
4 import net.sf.openrocket.startup.Application;
5 import net.sf.openrocket.unit.Unit;
6 import net.sf.openrocket.unit.UnitGroup;
7 import net.sf.openrocket.util.MathUtil;
10 * A class for different material types. Each material has a name and density.
11 * The interpretation of the density depends on the material type. For
12 * {@link Type#BULK} it is kg/m^3, for {@link Type#SURFACE} km/m^2.
14 * Objects of this type are immutable.
16 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
19 public abstract class Material implements Comparable<Material> {
21 private static final Translator trans = Application.getTranslator();
24 LINE("Databases.materials.types.Line", UnitGroup.UNITS_DENSITY_LINE),
25 SURFACE("Databases.materials.types.Surface", UnitGroup.UNITS_DENSITY_SURFACE),
26 BULK("Databases.materials.types.Bulk", UnitGroup.UNITS_DENSITY_BULK);
28 private final String name;
29 private final UnitGroup units;
31 private Type(String nameKey, UnitGroup units) {
32 this.name = trans.get(nameKey);
36 public UnitGroup getUnitGroup() {
41 public String toString() {
47 ///// Definitions of different material types /////
49 public static class Line extends Material {
50 Line(String name, double density, boolean userDefined) {
51 super(name, density, userDefined);
55 public Type getType() {
60 public static class Surface extends Material {
62 Surface(String name, double density, boolean userDefined) {
63 super(name, density, userDefined);
67 public Type getType() {
72 public String toStorableString() {
73 return super.toStorableString();
77 public static class Bulk extends Material {
78 Bulk(String name, double density, boolean userDefined) {
79 super(name, density, userDefined);
83 public Type getType() {
90 private final String name;
91 private final double density;
92 private final boolean userDefined;
96 * Constructor for materials.
98 * @param name ignored when defining system materials.
99 * @param key ignored when defining user materials.
101 * @param userDefined true if this is a user defined material, false if it is a system material.
103 private Material(String name, double density, boolean userDefined) {
105 this.userDefined = userDefined;
106 this.density = density;
109 public double getDensity() {
113 public String getName() {
117 public String getName(Unit u) {
118 return name + " (" + u.toStringUnit(density) + ")";
121 public boolean isUserDefined() {
125 public abstract Type getType();
128 public String toString() {
129 return this.getName(this.getType().getUnitGroup().getDefaultUnit());
134 * Compares this object to another object. Material objects are equal if and only if
135 * their types, names and densities are identical.
138 public boolean equals(Object o) {
141 if (this.getClass() != o.getClass())
143 Material m = (Material) o;
144 return ((m.name.equals(this.name)) && MathUtil.equals(m.density, this.density));
149 * A hashCode() method giving a hash code compatible with the equals() method.
152 public int hashCode() {
153 return name.hashCode() + (int) (density * 1000);
158 * Order the materials according to their name, secondarily according to density.
161 public int compareTo(Material o) {
162 int c = this.name.compareTo(o.name);
166 return (int) ((this.density - o.density) * 1000);
172 * Return a new material. The name is used as-is, without any translation.
174 * @param type the material type
175 * @param name the material name
176 * @param density the material density
177 * @param userDefined whether the material is user-defined or not
178 * @return the new material
180 public static Material newMaterial(Type type, String name, double density, boolean userDefined) {
183 return new Material.Line(name, density, userDefined);
186 return new Material.Surface(name, density, userDefined);
189 return new Material.Bulk(name, density, userDefined);
192 throw new IllegalArgumentException("Unknown material type: " + type);
196 public String toStorableString() {
197 return getType().name() + "|" + name.replace('|', ' ') + '|' + density;
202 * Return a material defined by the provided string.
204 * @param str the material storage string.
205 * @param userDefined whether the created material is user-defined.
206 * @return a new <code>Material</code> object.
207 * @throws IllegalArgumentException if <code>str</code> is invalid or null.
209 public static Material fromStorableString(String str, boolean userDefined) {
211 throw new IllegalArgumentException("Material string is null");
213 String[] split = str.split("\\|", 3);
214 if (split.length < 3)
215 throw new IllegalArgumentException("Illegal material string: " + str);
222 type = Type.valueOf(split[0]);
223 } catch (Exception e) {
224 throw new IllegalArgumentException("Illegal material string: " + str, e);
230 density = Double.parseDouble(split[2]);
231 } catch (NumberFormatException e) {
232 throw new IllegalArgumentException("Illegal material string: " + str, e);
237 return new Material.Bulk(name, density, userDefined);
240 return new Material.Surface(name, density, userDefined);
243 return new Material.Line(name, density, userDefined);
246 throw new IllegalArgumentException("Illegal material string: " + str);