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