diff --git a/core/build.xml b/core/build.xml index 9b178defe..61d86bd97 100644 --- a/core/build.xml +++ b/core/build.xml @@ -68,7 +68,7 @@ - + @@ -104,7 +104,13 @@ - + + + + @@ -126,7 +132,7 @@ classpathref="run-classpath" failonerror="true"> - + diff --git a/core/resources/datafiles/presets/Estes.orc b/core/resources-src/datafiles/presets/Estes.orc similarity index 100% rename from core/resources/datafiles/presets/Estes.orc rename to core/resources-src/datafiles/presets/Estes.orc diff --git a/core/resources/datafiles/presets/Quest.orc b/core/resources-src/datafiles/presets/Quest.orc similarity index 100% rename from core/resources/datafiles/presets/Quest.orc rename to core/resources-src/datafiles/presets/Quest.orc diff --git a/core/resources/datafiles/presets/bluetube.orc b/core/resources-src/datafiles/presets/bluetube.orc similarity index 100% rename from core/resources/datafiles/presets/bluetube.orc rename to core/resources-src/datafiles/presets/bluetube.orc diff --git a/core/resources/datafiles/presets/bms.orc b/core/resources-src/datafiles/presets/bms.orc similarity index 100% rename from core/resources/datafiles/presets/bms.orc rename to core/resources-src/datafiles/presets/bms.orc diff --git a/core/resources/datafiles/presets/fliskits.orc b/core/resources-src/datafiles/presets/fliskits.orc similarity index 100% rename from core/resources/datafiles/presets/fliskits.orc rename to core/resources-src/datafiles/presets/fliskits.orc diff --git a/core/resources/datafiles/presets/giantleaprocketry.orc b/core/resources-src/datafiles/presets/giantleaprocketry.orc similarity index 100% rename from core/resources/datafiles/presets/giantleaprocketry.orc rename to core/resources-src/datafiles/presets/giantleaprocketry.orc diff --git a/core/resources/datafiles/presets/publicmissiles.orc b/core/resources-src/datafiles/presets/publicmissiles.orc similarity index 100% rename from core/resources/datafiles/presets/publicmissiles.orc rename to core/resources-src/datafiles/presets/publicmissiles.orc diff --git a/core/resources/datafiles/presets/semroc.orc b/core/resources-src/datafiles/presets/semroc.orc similarity index 100% rename from core/resources/datafiles/presets/semroc.orc rename to core/resources-src/datafiles/presets/semroc.orc diff --git a/core/resources/datafiles/presets/system.ser b/core/resources/datafiles/presets/system.ser new file mode 100644 index 000000000..8e9325601 Binary files /dev/null and b/core/resources/datafiles/presets/system.ser differ diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index 0d1885b52..604c3778a 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -2,6 +2,11 @@ package net.sf.openrocket.preset; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.Field; import java.security.MessageDigest; import java.util.ArrayList; import java.util.Arrays; @@ -10,6 +15,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import net.sf.openrocket.material.Material; import net.sf.openrocket.motor.Manufacturer; @@ -28,12 +34,12 @@ import net.sf.openrocket.util.TextUtil; * * @author Sampo Niskanen */ -public class ComponentPreset implements Comparable { - +public class ComponentPreset implements Comparable, Serializable { + private final TypedPropertyMap properties = new TypedPropertyMap(); - + private String digest = ""; - + public enum Type { BODY_TUBE(new TypedKey[] { ComponentPreset.MANUFACTURER, @@ -42,105 +48,105 @@ public class ComponentPreset implements Comparable { ComponentPreset.INNER_DIAMETER, ComponentPreset.OUTER_DIAMETER, ComponentPreset.LENGTH }), - - NOSE_CONE(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.SHAPE, - ComponentPreset.AFT_OUTER_DIAMETER, - ComponentPreset.AFT_SHOULDER_DIAMETER, - ComponentPreset.AFT_SHOULDER_LENGTH, - ComponentPreset.LENGTH }), - - TRANSITION(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.SHAPE, - ComponentPreset.FORE_OUTER_DIAMETER, - ComponentPreset.FORE_SHOULDER_DIAMETER, - ComponentPreset.FORE_SHOULDER_LENGTH, - ComponentPreset.AFT_OUTER_DIAMETER, - ComponentPreset.AFT_SHOULDER_DIAMETER, - ComponentPreset.AFT_SHOULDER_LENGTH, - ComponentPreset.LENGTH }), - - TUBE_COUPLER(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.OUTER_DIAMETER, - ComponentPreset.INNER_DIAMETER, - ComponentPreset.LENGTH }), - - BULK_HEAD(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.OUTER_DIAMETER, - ComponentPreset.LENGTH }), - - CENTERING_RING(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.INNER_DIAMETER, - ComponentPreset.OUTER_DIAMETER, - ComponentPreset.LENGTH }), - - ENGINE_BLOCK(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.INNER_DIAMETER, - ComponentPreset.OUTER_DIAMETER, - ComponentPreset.LENGTH }), - - LAUNCH_LUG(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.INNER_DIAMETER, - ComponentPreset.OUTER_DIAMETER, - ComponentPreset.LENGTH }), - - STREAMER(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.LENGTH, - ComponentPreset.WIDTH, - ComponentPreset.THICKNESS, - ComponentPreset.MATERIAL }), - - PARACHUTE(new TypedKey[] { - ComponentPreset.MANUFACTURER, - ComponentPreset.PARTNO, - ComponentPreset.DESCRIPTION, - ComponentPreset.DIAMETER, - ComponentPreset.SIDES, - ComponentPreset.LINE_COUNT, - ComponentPreset.LINE_LENGTH, - ComponentPreset.LINE_MATERIAL, - ComponentPreset.MATERIAL }); - + + NOSE_CONE(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.SHAPE, + ComponentPreset.AFT_OUTER_DIAMETER, + ComponentPreset.AFT_SHOULDER_DIAMETER, + ComponentPreset.AFT_SHOULDER_LENGTH, + ComponentPreset.LENGTH }), + + TRANSITION(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.SHAPE, + ComponentPreset.FORE_OUTER_DIAMETER, + ComponentPreset.FORE_SHOULDER_DIAMETER, + ComponentPreset.FORE_SHOULDER_LENGTH, + ComponentPreset.AFT_OUTER_DIAMETER, + ComponentPreset.AFT_SHOULDER_DIAMETER, + ComponentPreset.AFT_SHOULDER_LENGTH, + ComponentPreset.LENGTH }), + + TUBE_COUPLER(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.LENGTH }), + + BULK_HEAD(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.LENGTH }), + + CENTERING_RING(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.LENGTH }), + + ENGINE_BLOCK(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.LENGTH }), + + LAUNCH_LUG(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.LENGTH }), + + STREAMER(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.LENGTH, + ComponentPreset.WIDTH, + ComponentPreset.THICKNESS, + ComponentPreset.MATERIAL }), + + PARACHUTE(new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.DESCRIPTION, + ComponentPreset.DIAMETER, + ComponentPreset.SIDES, + ComponentPreset.LINE_COUNT, + ComponentPreset.LINE_LENGTH, + ComponentPreset.LINE_MATERIAL, + ComponentPreset.MATERIAL }); + TypedKey[] displayedColumns; - + Type(TypedKey[] displayedColumns) { this.displayedColumns = displayedColumns; } - + public List getCompatibleTypes() { return compatibleTypeMap.get(Type.this); } - + public TypedKey[] getDisplayedColumns() { return displayedColumns; } - + private static Map> compatibleTypeMap = new HashMap>(); - + static { compatibleTypeMap.put(BODY_TUBE, Arrays.asList(BODY_TUBE, TUBE_COUPLER, LAUNCH_LUG)); compatibleTypeMap.put(TUBE_COUPLER, Arrays.asList(BODY_TUBE, TUBE_COUPLER, LAUNCH_LUG)); @@ -148,9 +154,9 @@ public class ComponentPreset implements Comparable { compatibleTypeMap.put(CENTERING_RING, Arrays.asList(CENTERING_RING, ENGINE_BLOCK)); compatibleTypeMap.put(NOSE_CONE, Arrays.asList(NOSE_CONE, TRANSITION)); } - + } - + public final static TypedKey MANUFACTURER = new TypedKey("Manufacturer", Manufacturer.class); public final static TypedKey PARTNO = new TypedKey("PartNo", String.class); public final static TypedKey DESCRIPTION = new TypedKey("Description", String.class); @@ -177,7 +183,7 @@ public class ComponentPreset implements Comparable { public final static TypedKey LINE_LENGTH = new TypedKey("LineLength", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey LINE_MATERIAL = new TypedKey("LineMaterial", Material.class); public final static TypedKey IMAGE = new TypedKey("Image", byte[].class); - + public final static List> ORDERED_KEY_LIST = Collections.unmodifiableList(Arrays.> asList( MANUFACTURER, PARTNO, @@ -204,12 +210,12 @@ public class ComponentPreset implements Comparable { FINISH, MATERIAL )); - - + + // package scope constructor to encourage use of factory. ComponentPreset() { } - + /** * Convenience method to retrieve the Type of this ComponentPreset. * @@ -218,7 +224,7 @@ public class ComponentPreset implements Comparable { public Type getType() { return properties.get(TYPE); } - + /** * Convenience method to retrieve the Manufacturer of this ComponentPreset. * @return @@ -226,7 +232,7 @@ public class ComponentPreset implements Comparable { public Manufacturer getManufacturer() { return properties.get(MANUFACTURER); } - + /** * Convenience method to retrieve the PartNo of this ComponentPreset. * @return @@ -234,15 +240,15 @@ public class ComponentPreset implements Comparable { public String getPartNo() { return properties.get(PARTNO); } - + public String getDigest() { return digest; } - + public boolean has(Object key) { return properties.containsKey(key); } - + /** * Package scope so the ComponentPresetFactory can call it. * @param other @@ -253,7 +259,7 @@ public class ComponentPreset implements Comparable { } properties.putAll(other); } - + /** * Package scope so the ComponentPresetFactory can call it. * @param key @@ -262,7 +268,7 @@ public class ComponentPreset implements Comparable { void put(TypedKey key, T value) { properties.put(key, value); } - + public T get(TypedKey key) { T value = properties.get(key); if (value == null) { @@ -270,26 +276,26 @@ public class ComponentPreset implements Comparable { } return value; } - + @Override public int compareTo(ComponentPreset p2) { int manuCompare = this.getManufacturer().getSimpleName().compareTo(p2.getManufacturer().getSimpleName()); if (manuCompare != 0) return manuCompare; - + int partNoCompare = this.getPartNo().compareTo(p2.getPartNo()); return partNoCompare; } - + @Override public String toString() { return get(PARTNO); } - + public String preferenceKey() { return String.valueOf(get(MANUFACTURER)) + "|" + String.valueOf(get(PARTNO)); } - + @Override public boolean equals(final Object o) { if (this == o) { @@ -298,45 +304,45 @@ public class ComponentPreset implements Comparable { if (o == null || getClass() != o.getClass()) { return false; } - + ComponentPreset that = (ComponentPreset) o; - + if (digest != null ? !digest.equals(that.digest) : that.digest != null) { return false; } - + return true; } - + @Override public int hashCode() { return digest != null ? digest.hashCode() : 0; } - + /** * Package scope so the factory can call it. */ void computeDigest() { - + try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream os = new DataOutputStream(bos); - + List> keys = new ArrayList>(properties.keySet()); - + Collections.sort(keys, new Comparator>() { @Override public int compare(TypedKey a, TypedKey b) { return a.getName().compareTo(b.getName()); } }); - + for (TypedKey key : keys) { - + Object value = properties.get(key); - + os.writeBytes(key.getName()); - + if (key.getType() == Double.class) { Double d = (Double) value; os.writeDouble(d); @@ -363,9 +369,9 @@ public class ComponentPreset implements Comparable { int i = ((Shape) value).ordinal(); os.writeInt(i); } - + } - + MessageDigest md5 = MessageDigest.getInstance("MD5"); digest = TextUtil.hexString(md5.digest(bos.toByteArray())); } catch (Exception e) { @@ -373,5 +379,70 @@ public class ComponentPreset implements Comparable { throw new BugException(e); } } - + + private static class MaterialDTO implements Serializable { + String name; + String type; + boolean userDefined; + Double density; + } + + private void writeObject( ObjectOutputStream oos ) throws IOException { + Map DTO = new HashMap(); + + for ( Entry, Object> entry :properties.entrySet() ) { + + TypedKey key = entry.getKey(); + Object value = entry.getValue(); + + String keyName = key.getName(); + if ( MANUFACTURER.getName().equals(keyName) ) { + value = ((Manufacturer) value).getDisplayName(); + } else if ( value instanceof Material ) { + Material material = (Material) value; + MaterialDTO m = new MaterialDTO(); + m.name = material.getName(); + m.type = material.getType().name(); + m.density = material.getDensity(); + m.userDefined = material.isUserDefined(); + value = m; + } + + DTO.put(keyName,value); + } + + oos.writeObject(DTO); + } + + private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + Map DTO = (Map) ois.readObject(); + + Field propField = ComponentPreset.class.getDeclaredField("properties"); + propField.setAccessible(true); + propField.set(this, new TypedPropertyMap()); + + for ( Entry entry : DTO.entrySet() ) { + String keyName = entry.getKey(); + Object value = entry.getValue(); + + if ( MANUFACTURER.getName().equals(keyName)) { + value = Manufacturer.getManufacturer((String) value); + } else if ( value instanceof MaterialDTO ) { + MaterialDTO m = (MaterialDTO) value; + value = Material.newMaterial(Material.Type.valueOf(m.type), m.name, m.density, m.userDefined); + } + if ( TYPE.getName().equals(keyName)) { + this.properties.put(TYPE, (ComponentPreset.Type) value); + } else { + for( TypedKey k : ORDERED_KEY_LIST ) { + if ( k.getName().equals(keyName)) { + this.properties.put( k, value ); + break; + } + } + } + } + + this.computeDigest(); + } } diff --git a/core/src/net/sf/openrocket/startup/ConcurrentComponentPresetDatabaseLoader.java b/core/src/net/sf/openrocket/startup/ConcurrentComponentPresetDatabaseLoader.java index c3d9eda2d..5b933a6e8 100644 --- a/core/src/net/sf/openrocket/startup/ConcurrentComponentPresetDatabaseLoader.java +++ b/core/src/net/sf/openrocket/startup/ConcurrentComponentPresetDatabaseLoader.java @@ -2,7 +2,9 @@ package net.sf.openrocket.startup; import java.io.IOException; import java.io.InputStream; +import java.io.ObjectInputStream; import java.util.Collection; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -17,6 +19,7 @@ import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.xml.OpenRocketComponentLoader; +import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.Pair; public class ConcurrentComponentPresetDatabaseLoader { @@ -90,19 +93,26 @@ public class ConcurrentComponentPresetDatabaseLoader { // Start loading log.info("Loading component presets from " + SYSTEM_PRESET_DIR); - SimpleFileFilter orcFilter = new SimpleFileFilter("", false, "orc"); - iterator = DirectoryIterator.findDirectory(SYSTEM_PRESET_DIR, orcFilter); + iterator = DirectoryIterator.findDirectory(SYSTEM_PRESET_DIR, new SimpleFileFilter("",false,"ser")); if (iterator != null) { while( iterator.hasNext() ) { Pair f = iterator.next(); - FileLoader loader = new FileLoader( f.getV(), f.getU() ); - loaderPool.execute(loader); - fileCount ++; + try { + ObjectInputStream ois = new ObjectInputStream(f.getV()); + List list = (List) ois.readObject(); + componentPresetDao.addAll(list); + fileCount++; + presetCount+=list.size(); + } + catch ( Exception ex ) { + throw new BugException(ex); + } } } try { + SimpleFileFilter orcFilter = new SimpleFileFilter("", false, "orc"); iterator = new DirectoryIterator( ((SwingPreferences) Application.getPreferences()).getDefaultUserComponentDirectory(), orcFilter, diff --git a/core/src/net/sf/openrocket/startup/SerializePresets.java b/core/src/net/sf/openrocket/startup/SerializePresets.java new file mode 100644 index 000000000..72f23c6a7 --- /dev/null +++ b/core/src/net/sf/openrocket/startup/SerializePresets.java @@ -0,0 +1,70 @@ +package net.sf.openrocket.startup; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.util.Collection; +import java.util.List; + +import net.sf.openrocket.database.ComponentPresetDatabase; +import net.sf.openrocket.file.iterator.DirectoryIterator; +import net.sf.openrocket.file.iterator.FileIterator; +import net.sf.openrocket.gui.util.SimpleFileFilter; +import net.sf.openrocket.gui.util.SwingPreferences; +import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.xml.OpenRocketComponentLoader; +import net.sf.openrocket.util.Pair; + +public class SerializePresets { + + /** + * @param args + */ + public static void main(String[] args) throws Exception { + + Application.setPreferences( new SwingPreferences() ); + + ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase() { + + @Override + protected void load() { + + FileIterator iterator = DirectoryIterator.findDirectory("resources-src/datafiles/presets", new SimpleFileFilter("",false,"orc")); + + if ( iterator == null ) { + throw new RuntimeException("Can't find resources-src/presets directory"); + } + while( iterator.hasNext() ) { + Pair f = iterator.next(); + String fileName = f.getU(); + InputStream is = f.getV(); + + OpenRocketComponentLoader loader = new OpenRocketComponentLoader(); + Collection presets = loader.load(is, fileName); + + this.addAll(presets); + + } + } + + }; + + componentPresetDao.startLoading(); + + List list = componentPresetDao.listAll(); + + Application.getLogger().info("Total number of presets = " + list.size()); + + File outFile = new File("resources/datafiles/presets","system.ser"); + + FileOutputStream ofs = new FileOutputStream(outFile); + ObjectOutputStream oos = new ObjectOutputStream(ofs); + + oos.writeObject(list); + + ofs.flush(); + ofs.close(); + } + +}