X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Fpreset%2FComponentPreset.java;h=97a02226253f51e1977ea424a5889131cb7c505a;hb=00fab975b3bea3b01f51d5bb119de0dae980f108;hp=c06c0708900d0b811790ed1f2e6f6ff2e23d16a9;hpb=3ad331a1a95273625d88268ed7bc12c17cfcfee4;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index c06c0708..97a02226 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -1,6 +1,13 @@ package net.sf.openrocket.preset; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.List; import java.util.Map; import net.sf.openrocket.material.Material; @@ -9,6 +16,7 @@ import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.util.BugException; +import net.sf.openrocket.util.TextUtil; /** @@ -20,38 +28,58 @@ import net.sf.openrocket.util.BugException; * @author Sampo Niskanen */ // FIXME - Implement clone. -public class ComponentPreset { - +public class ComponentPreset implements Comparable { + private final TypedPropertyMap properties = new TypedPropertyMap(); - + private boolean favorite = false; - + private String digest = ""; + public enum Type { - BODY_TUBE, - NOSE_CONE; + BODY_TUBE( new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.LENGTH} ), + + NOSE_CONE( new TypedKey[] { + ComponentPreset.MANUFACTURER, + ComponentPreset.PARTNO, + ComponentPreset.OUTER_DIAMETER, + ComponentPreset.INNER_DIAMETER, + ComponentPreset.LENGTH} ) ; Type[] compatibleTypes; - - Type () { + TypedKey[] displayedColumns; + + Type( TypedKey[] displayedColumns) { compatibleTypes = new Type[1]; compatibleTypes[0] = this; + this.displayedColumns = displayedColumns; } - - Type( Type ... t ) { - + + Type( Type[] t, TypedKey[] displayedColumns ) { + compatibleTypes = new Type[t.length+1]; compatibleTypes[0] = this; for( int i=0; i[] getDisplayedColumns() { + return displayedColumns; + } + } - + public final static TypedKey MANUFACTURER = new TypedKey("Manufacturer", Manufacturer.class); public final static TypedKey PARTNO = new TypedKey("PartNo",String.class); public final static TypedKey TYPE = new TypedKey("Type",Type.class); @@ -63,7 +91,7 @@ public class ComponentPreset { public final static TypedKey THICKNESS = new TypedKey("Thickness", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey FILLED = new TypedKey("Filled", Boolean.class); public final static TypedKey MASS = new TypedKey("Mass", Double.class, UnitGroup.UNITS_MASS); - + public final static Map> keyMap = new HashMap>(); static { keyMap.put(MANUFACTURER.getName(), MANUFACTURER); @@ -78,15 +106,15 @@ public class ComponentPreset { keyMap.put(FILLED.getName(), FILLED); keyMap.put(MASS.getName(), MASS); } - + public static ComponentPreset create( TypedPropertyMap props ) throws InvalidComponentPresetException { - + ComponentPreset preset = new ComponentPreset(); // First do validation. if ( !props.containsKey(TYPE)) { throw new InvalidComponentPresetException("No Type specified " + props.toString() ); } - + if (!props.containsKey(MANUFACTURER)) { throw new InvalidComponentPresetException("No Manufacturer specified " + props.toString() ); } @@ -96,25 +124,25 @@ public class ComponentPreset { } preset.properties.putAll(props); - + // Should check for various bits of each of the types. Type t = props.get(TYPE); switch ( t ) { case BODY_TUBE: { - + if ( !props.containsKey(LENGTH) ) { throw new InvalidComponentPresetException( "No Length specified for body tube preset " + props.toString()); } - + BodyTube bt = new BodyTube(); - + bt.setLength(props.get(LENGTH)); - + // Need to verify contains 2 of OD, thickness, ID. Compute the third. boolean hasOd = props.containsKey(OUTER_DIAMETER); boolean hasId = props.containsKey(INNER_DIAMETER); boolean hasThickness = props.containsKey(THICKNESS); - + if ( hasOd ) { double outerRadius = props.get(OUTER_DIAMETER)/2.0; double thickness = 0; @@ -140,7 +168,7 @@ public class ComponentPreset { preset.properties.put(OUTER_DIAMETER, bt.getOuterRadius() *2.0); preset.properties.put(INNER_DIAMETER, bt.getInnerRadius() *2.0); preset.properties.put(THICKNESS, bt.getThickness()); - + // Need to translate Mass to Density. if ( props.containsKey(MASS) ) { String materialName = "TubeCustom"; @@ -150,27 +178,57 @@ public class ComponentPreset { Material m = Material.newMaterial(Material.Type.BULK, materialName, props.get(MASS)/bt.getComponentVolume(), false); preset.properties.put(MATERIAL, m); } - + break; } case NOSE_CONE: { break; } } - + + preset.computeDigest(); + return preset; } // Private constructor to encourage use of factory. private ComponentPreset() { - } - + + /** + * Convenience method to retrieve the Type of this ComponentPreset. + * + * @return + */ + public Type getType() { + return properties.get(TYPE); + } + + /** + * Convenience method to retrieve the Manufacturer of this ComponentPreset. + * @return + */ + public Manufacturer getManufacturer() { + return properties.get(MANUFACTURER); + } + + /** + * Convenience method to retrieve the PartNo of this ComponentPreset. + * @return + */ + public String getPartNo() { + return properties.get(PARTNO); + } + + public String getDigest() { + return digest; + } + public boolean has(Object key) { return properties.containsKey(key); } - + public T get(TypedKey key) { T value = properties.get(key); if (value == null) { @@ -178,7 +236,7 @@ public class ComponentPreset { } return (T) value; } - + public boolean isFavorite() { return favorite; } @@ -187,12 +245,77 @@ public class ComponentPreset { this.favorite = favorite; } + @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(MANUFACTURER).toString() + " " + get(PARTNO); } - + public String preferenceKey() { return get(MANUFACTURER).toString() + "|" + get(PARTNO); } + + private 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); + } else if (key.getType() == String.class ) { + String s = (String) value; + os.writeBytes(s); + } else if (key.getType() == Manufacturer.class ) { + String s = ((Manufacturer)value).getSimpleName(); + os.writeBytes(s); + } else if ( key.getType() == Finish.class ) { + String s = ((Finish)value).name(); + os.writeBytes(s); + } else if ( key.getType() == Type.class ) { + String s = ((Type)value).name(); + os.writeBytes(s); + } else if ( key.getType() == Boolean.class ) { + Boolean b = (Boolean) value; + os.writeBoolean(b); + } else if ( key.getType() == Material.class ) { + double d = ((Material)value).getDensity(); + os.writeDouble(d); + } + + } + + MessageDigest md5 = MessageDigest.getInstance("MD5"); + digest = TextUtil.hexString(md5.digest( bos.toByteArray() )); + } + catch ( Exception e ) { + throw new BugException(e); + } + } + }