updates for 0.9.4
[debian/openrocket] / src / net / sf / openrocket / database / Databases.java
1 package net.sf.openrocket.database;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.URL;
6 import java.util.ArrayList;
7
8 import net.sf.openrocket.file.GeneralMotorLoader;
9 import net.sf.openrocket.material.Material;
10 import net.sf.openrocket.material.MaterialStorage;
11 import net.sf.openrocket.motor.Motor;
12 import net.sf.openrocket.util.JarUtil;
13 import net.sf.openrocket.util.MathUtil;
14 import net.sf.openrocket.util.Prefs;
15
16
17 /**
18  * A class that contains single instances of {@link Database} for specific purposes.
19  * 
20  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
21  */
22 public class Databases {
23
24         /* Static implementations of specific databases: */
25         /**
26          * The motor database.
27          */
28         public static final Database<Motor> MOTOR = new Database<Motor>(new GeneralMotorLoader());
29         
30         
31         /**
32          * A database of bulk materials (with bulk densities).
33          */
34         public static final Database<Material> BULK_MATERIAL = new Database<Material>();
35         /**
36          * A database of surface materials (with surface densities).
37          */
38         public static final Database<Material> SURFACE_MATERIAL = new Database<Material>();
39         /**
40          * A database of linear material (with length densities).
41          */
42         public static final Database<Material> LINE_MATERIAL = new Database<Material>();
43         
44         
45
46         // TODO: HIGH: loading the thrust curves and other databases
47         static {
48                 
49                 try {
50                         MOTOR.loadJarDirectory("datafiles/thrustcurves/", ".*\\.[eE][nN][gG]$");
51                 } catch (IOException e) {
52                         System.out.println("Could not read thrust curves from JAR: "+e.getMessage());
53                         
54                         // Try to find directory as a system resource
55                         File dir;
56                         URL url = ClassLoader.getSystemResource("datafiles/thrustcurves/");
57                         
58                         try {
59                                 dir = JarUtil.urlToFile(url);
60                         } catch (Exception e1) {
61                                 dir = new File("datafiles/thrustcurves/");
62                         }
63                                 
64                         try {
65                                 MOTOR.loadDirectory(dir, ".*\\.[eE][nN][gG]$");
66                         } catch (IOException e1) {
67                                 System.out.println("Could not read thrust curves from directory either.");
68                                 throw new RuntimeException(e1);
69                         }
70                 }
71         }
72         
73         static {
74                 
75                 // Add default materials
76                 BULK_MATERIAL.add(new Material.Bulk("Acrylic",          1190, false));
77                 BULK_MATERIAL.add(new Material.Bulk("Balsa",             170, false));
78                 BULK_MATERIAL.add(new Material.Bulk("Birch",             670, false));
79                 BULK_MATERIAL.add(new Material.Bulk("Cardboard",         680, false));
80                 BULK_MATERIAL.add(new Material.Bulk("Carbon fiber",     1780, false));
81                 BULK_MATERIAL.add(new Material.Bulk("Cork",                      240, false));
82                 BULK_MATERIAL.add(new Material.Bulk("Depron (XPS)",       40, false));
83                 BULK_MATERIAL.add(new Material.Bulk("Fiberglass",       1850, false));
84                 BULK_MATERIAL.add(new Material.Bulk("Kraft phenolic",950, false));
85                 BULK_MATERIAL.add(new Material.Bulk("Maple",             755, false));
86                 BULK_MATERIAL.add(new Material.Bulk("Paper (office)",820, false));
87                 BULK_MATERIAL.add(new Material.Bulk("Pine",                      530, false));
88                 BULK_MATERIAL.add(new Material.Bulk("Plywood (birch)",630, false));
89                 BULK_MATERIAL.add(new Material.Bulk("Polycarbonate (Lexan)",1200, false));
90                 BULK_MATERIAL.add(new Material.Bulk("Polystyrene",  1050, false));
91                 BULK_MATERIAL.add(new Material.Bulk("PVC",                      1390, false));
92                 BULK_MATERIAL.add(new Material.Bulk("Spruce",            450, false));
93                 BULK_MATERIAL.add(new Material.Bulk("Styrofoam generic (EPS)", 20, false));
94                 BULK_MATERIAL.add(new Material.Bulk("Styrofoam / Blue Foam (XPS)", 32, false));
95                 BULK_MATERIAL.add(new Material.Bulk("Quantum tubing",1050, false));
96                 
97                 SURFACE_MATERIAL.add(new Material.Surface("Ripstop nylon",                      0.067, false));
98                 SURFACE_MATERIAL.add(new Material.Surface("Mylar",                                      0.021, false));
99                 SURFACE_MATERIAL.add(new Material.Surface("Polyethylene (thin)",        0.015, false));
100                 SURFACE_MATERIAL.add(new Material.Surface("Polyethylene (heavy)",       0.040, false));
101                 SURFACE_MATERIAL.add(new Material.Surface("Silk",                                       0.060, false));
102                 SURFACE_MATERIAL.add(new Material.Surface("Paper (office)",                     0.080, false));
103                 SURFACE_MATERIAL.add(new Material.Surface("Cellophane",                         0.018, false));
104                 SURFACE_MATERIAL.add(new Material.Surface("Cr\u00eape paper",           0.025, false));
105                 
106                 LINE_MATERIAL.add(new Material.Line("Thread (heavy-duty)",                              0.0003, false));
107                 LINE_MATERIAL.add(new Material.Line("Elastic cord (round 2mm, 1/16 in)",0.0018, false));
108                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat  6mm, 1/4 in)", 0.0043, false));
109                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 12mm, 1/2 in)", 0.008, false));
110                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 19mm, 3/4 in)", 0.0012, false));
111                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 25mm, 1 in)",   0.0016, false));
112                 LINE_MATERIAL.add(new Material.Line("Braided nylon (2 mm, 1/16 in)",    0.001, false));
113                 LINE_MATERIAL.add(new Material.Line("Braided nylon (3 mm, 1/8 in)",     0.0035, false));
114                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (11 mm, 7/16 in)",   0.013, false));
115                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (14 mm, 9/16 in)",   0.016, false));
116                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (25 mm, 1 in)",              0.029, false));
117                 
118                 
119                 // Add user-defined materials
120                 for (Material m: Prefs.getUserMaterials()) {
121                         switch (m.getType()) {
122                         case LINE:
123                                 LINE_MATERIAL.add(m);
124                                 break;
125                                 
126                         case SURFACE:
127                                 SURFACE_MATERIAL.add(m);
128                                 break;
129                                 
130                         case BULK:
131                                 BULK_MATERIAL.add(m);
132                                 break;
133                                 
134                         default:
135                                 System.err.println("ERROR: Unknown material type " + m);
136                         }
137                 }
138                 
139                 // Add database storage listener
140                 MaterialStorage listener = new MaterialStorage();
141                 LINE_MATERIAL.addDatabaseListener(listener);
142                 SURFACE_MATERIAL.addDatabaseListener(listener);
143                 BULK_MATERIAL.addDatabaseListener(listener);
144         }
145         
146         
147         /*
148          * Used just for ensuring initialization of the class.
149          */
150         public static void fakeMethod() {
151                 
152         }
153         
154         
155         /**
156          * Find a material from the database with the specified type and name.  Returns
157          * <code>null</code> if the specified material could not be found.
158          * 
159          * @param type  the material type.
160          * @param name  the material name in the database.
161          * @return              the material, or <code>null</code> if not found.
162          */
163         public static Material findMaterial(Material.Type type, String name) {
164                 Database<Material> db;
165                 switch (type) {
166                 case BULK:
167                         db = BULK_MATERIAL;
168                         break;
169                 case SURFACE:
170                         db = SURFACE_MATERIAL;
171                         break;
172                 case LINE:
173                         db = LINE_MATERIAL;
174                         break;
175                 default:
176                         throw new IllegalArgumentException("Illegal material type: "+type);
177                 }
178                 
179                 for (Material m: db) {
180                         if (m.getName().equalsIgnoreCase(name)) {
181                                 return m;
182                         }
183                 }
184                 return null;
185         }
186         
187         
188         /**
189          * Find a material from the database or return a new material if the specified
190          * material with the specified density is not found.
191          * 
192          * @param type                  the material type.
193          * @param name                  the material name.
194          * @param density               the density of the material.
195          * @param userDefined   whether a newly created material should be user-defined.
196          * @return                              the material object from the database or a new material.
197          */
198         public static Material findMaterial(Material.Type type, String name, double density,
199                         boolean userDefined) {
200                 Database<Material> db;
201                 switch (type) {
202                 case BULK:
203                         db = BULK_MATERIAL;
204                         break;
205                 case SURFACE:
206                         db = SURFACE_MATERIAL;
207                         break;
208                 case LINE:
209                         db = LINE_MATERIAL;
210                         break;
211                 default:
212                         throw new IllegalArgumentException("Illegal material type: "+type);
213                 }
214
215                 for (Material m: db) {
216                         if (m.getName().equalsIgnoreCase(name) && MathUtil.equals(m.getDensity(), density)) {
217                                 return m;
218                         }
219                 }
220                 return Material.newMaterial(type, name, density, userDefined);
221         }       
222         
223         
224
225         /**
226          * Return all motor in the database matching a search criteria.  Any search criteria that
227          * is null or NaN is ignored.
228          * 
229          * @param type                  the motor type, or null.
230          * @param manufacturer  the manufacturer, or null.
231          * @param designation   the designation, or null.
232          * @param diameter              the diameter, or NaN.
233          * @param length                the length, or NaN.
234          * @return                              an array of all the matching motors.
235          */
236         public static Motor[] findMotors(Motor.Type type, String manufacturer, String designation, double diameter, double length) {
237                 ArrayList<Motor> results = new ArrayList<Motor>();
238                 
239                 for (Motor m: MOTOR) {
240                         boolean match = true;
241                         if (type != null  &&  type != m.getMotorType())
242                                 match = false;
243                         else if (manufacturer != null  &&  !m.getManufacturer().matches(manufacturer))
244                                 match = false;
245                         else if (designation != null  &&  !designation.equalsIgnoreCase(m.getDesignation()))
246                                 match = false;
247                         else if (!Double.isNaN(diameter)  &&  (Math.abs(diameter - m.getDiameter()) > 0.0015))
248                                 match = false;
249                         else if (!Double.isNaN(length) && (Math.abs(length - m.getLength()) > 0.0015))
250                                 match = false;
251                         
252                         if (match)
253                                 results.add(m);
254                 }
255                 
256                 return results.toArray(new Motor[0]);
257         }
258
259 }