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