cdf39c2e41ab6897e62accbb2728f28d449f1d8a
[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("Styrofoam \"Blue foam\" (XPS)", 32, false));
96                 BULK_MATERIAL.add(new Material.Bulk("Quantum tubing",1050, false));
97                 
98                 SURFACE_MATERIAL.add(new Material.Surface("Ripstop nylon",                      0.067, false));
99                 SURFACE_MATERIAL.add(new Material.Surface("Mylar",                                      0.021, false));
100                 SURFACE_MATERIAL.add(new Material.Surface("Polyethylene (thin)",        0.015, false));
101                 SURFACE_MATERIAL.add(new Material.Surface("Polyethylene (heavy)",       0.040, false));
102                 SURFACE_MATERIAL.add(new Material.Surface("Silk",                                       0.060, false));
103                 SURFACE_MATERIAL.add(new Material.Surface("Paper (office)",                     0.080, false));
104                 SURFACE_MATERIAL.add(new Material.Surface("Cellophane",                         0.018, false));
105                 SURFACE_MATERIAL.add(new Material.Surface("Cr\u00eape paper",           0.025, false));
106                 
107                 LINE_MATERIAL.add(new Material.Line("Thread (heavy-duty)",                              0.0003, false));
108                 LINE_MATERIAL.add(new Material.Line("Elastic cord (round 2mm, 1/16 in)",0.0018, false));
109                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat  6mm, 1/4 in)", 0.0043, false));
110                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 12mm, 1/2 in)", 0.008, false));
111                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 19mm, 3/4 in)", 0.0012, false));
112                 LINE_MATERIAL.add(new Material.Line("Elastic cord (flat 25mm, 1 in)",   0.0016, false));
113                 LINE_MATERIAL.add(new Material.Line("Braided nylon (2 mm, 1/16 in)",    0.001, false));
114                 LINE_MATERIAL.add(new Material.Line("Braided nylon (3 mm, 1/8 in)",     0.0035, false));
115                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (11 mm, 7/16 in)",   0.013, false));
116                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (14 mm, 9/16 in)",   0.016, false));
117                 LINE_MATERIAL.add(new Material.Line("Tubular nylon (25 mm, 1 in)",              0.029, false));
118                 
119                 
120                 // Add user-defined materials
121                 for (Material m: Prefs.getUserMaterials()) {
122                         switch (m.getType()) {
123                         case LINE:
124                                 LINE_MATERIAL.add(m);
125                                 break;
126                                 
127                         case SURFACE:
128                                 SURFACE_MATERIAL.add(m);
129                                 break;
130                                 
131                         case BULK:
132                                 BULK_MATERIAL.add(m);
133                                 break;
134                                 
135                         default:
136                                 System.err.println("ERROR: Unknown material type " + m);
137                         }
138                 }
139                 
140                 // Add database storage listener
141                 MaterialStorage listener = new MaterialStorage();
142                 LINE_MATERIAL.addDatabaseListener(listener);
143                 SURFACE_MATERIAL.addDatabaseListener(listener);
144                 BULK_MATERIAL.addDatabaseListener(listener);
145         }
146         
147         
148         /*
149          * Used just for ensuring initialization of the class.
150          */
151         public static void fakeMethod() {
152                 
153         }
154         
155         
156         /**
157          * Find a material from the database with the specified type and name.  Returns
158          * <code>null</code> if the specified material could not be found.
159          * 
160          * @param type  the material type.
161          * @param name  the material name in the database.
162          * @return              the material, or <code>null</code> if not found.
163          */
164         public static Material findMaterial(Material.Type type, String name) {
165                 Database<Material> db;
166                 switch (type) {
167                 case BULK:
168                         db = BULK_MATERIAL;
169                         break;
170                 case SURFACE:
171                         db = SURFACE_MATERIAL;
172                         break;
173                 case LINE:
174                         db = LINE_MATERIAL;
175                         break;
176                 default:
177                         throw new IllegalArgumentException("Illegal material type: "+type);
178                 }
179                 
180                 for (Material m: db) {
181                         if (m.getName().equalsIgnoreCase(name)) {
182                                 return m;
183                         }
184                 }
185                 return null;
186         }
187         
188         
189         /**
190          * Find a material from the database or return a new material if the specified
191          * material with the specified density is not found.
192          * 
193          * @param type                  the material type.
194          * @param name                  the material name.
195          * @param density               the density of the material.
196          * @param userDefined   whether a newly created material should be user-defined.
197          * @return                              the material object from the database or a new material.
198          */
199         public static Material findMaterial(Material.Type type, String name, double density,
200                         boolean userDefined) {
201                 Database<Material> db;
202                 switch (type) {
203                 case BULK:
204                         db = BULK_MATERIAL;
205                         break;
206                 case SURFACE:
207                         db = SURFACE_MATERIAL;
208                         break;
209                 case LINE:
210                         db = LINE_MATERIAL;
211                         break;
212                 default:
213                         throw new IllegalArgumentException("Illegal material type: "+type);
214                 }
215
216                 for (Material m: db) {
217                         if (m.getName().equalsIgnoreCase(name) && MathUtil.equals(m.getDensity(), density)) {
218                                 return m;
219                         }
220                 }
221                 return Material.newMaterial(type, name, density, userDefined);
222         }       
223         
224         
225
226         /**
227          * Return all motor in the database matching a search criteria.  Any search criteria that
228          * is null or NaN is ignored.
229          * 
230          * @param type                  the motor type, or null.
231          * @param manufacturer  the manufacturer, or null.
232          * @param designation   the designation, or null.
233          * @param diameter              the diameter, or NaN.
234          * @param length                the length, or NaN.
235          * @return                              an array of all the matching motors.
236          */
237         public static Motor[] findMotors(Motor.Type type, String manufacturer, String designation, double diameter, double length) {
238                 ArrayList<Motor> results = new ArrayList<Motor>();
239                 
240                 for (Motor m: MOTOR) {
241                         boolean match = true;
242                         if (type != null  &&  type != m.getMotorType())
243                                 match = false;
244                         else if (manufacturer != null  &&  !m.getManufacturer().matches(manufacturer))
245                                 match = false;
246                         else if (designation != null  &&  !designation.equalsIgnoreCase(m.getDesignation()))
247                                 match = false;
248                         else if (!Double.isNaN(diameter)  &&  (Math.abs(diameter - m.getDiameter()) > 0.0015))
249                                 match = false;
250                         else if (!Double.isNaN(length) && (Math.abs(length - m.getLength()) > 0.0015))
251                                 match = false;
252                         
253                         if (match)
254                                 results.add(m);
255                 }
256                 
257                 return results.toArray(new Motor[0]);
258         }
259
260 }