From 7f6c542e5d3bab95059750403c4e99ea052cd5b8 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Mon, 8 Oct 2012 16:37:02 -0500 Subject: [PATCH] Try to use Java Serializable to improve loading of included ComponentPresets. --- core/build.xml | 12 +- .../datafiles/presets/Estes.orc | 0 .../datafiles/presets/Quest.orc | 0 .../datafiles/presets/bluetube.orc | 0 .../datafiles/presets/bms.orc | 0 .../datafiles/presets/fliskits.orc | 0 .../datafiles/presets/giantleaprocketry.orc | 0 .../datafiles/presets/publicmissiles.orc | 0 .../datafiles/presets/semroc.orc | 0 core/resources/datafiles/presets/system.ser | Bin 0 -> 403654 bytes .../sf/openrocket/preset/ComponentPreset.java | 321 +++++++++++------- ...ncurrentComponentPresetDatabaseLoader.java | 20 +- .../openrocket/startup/SerializePresets.java | 70 ++++ 13 files changed, 290 insertions(+), 133 deletions(-) rename core/{resources => resources-src}/datafiles/presets/Estes.orc (100%) rename core/{resources => resources-src}/datafiles/presets/Quest.orc (100%) rename core/{resources => resources-src}/datafiles/presets/bluetube.orc (100%) rename core/{resources => resources-src}/datafiles/presets/bms.orc (100%) rename core/{resources => resources-src}/datafiles/presets/fliskits.orc (100%) rename core/{resources => resources-src}/datafiles/presets/giantleaprocketry.orc (100%) rename core/{resources => resources-src}/datafiles/presets/publicmissiles.orc (100%) rename core/{resources => resources-src}/datafiles/presets/semroc.orc (100%) create mode 100644 core/resources/datafiles/presets/system.ser create mode 100644 core/src/net/sf/openrocket/startup/SerializePresets.java 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 0000000000000000000000000000000000000000..8e93256013f7fd8eb14d29eca8d82ecde719ae87 GIT binary patch literal 403654 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

)Hw-NDsgH`j5J}i)npMcMN;h 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 z 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 */ -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(); + } + +}