diff --git a/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponse.java b/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponse.java index 453261044..99d097623 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponse.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponse.java @@ -1,28 +1,27 @@ package net.sf.openrocket.android.thrustcurve; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class DownloadResponse { - private Map data = new HashMap(); + private Map> data = new HashMap>(); private String error = null; public void add( MotorBurnFile mbd ) { - MotorBurnFile currentData = data.get(mbd.getMotorId()); - if ( currentData == null || currentData.getThrustCurveMotor() == null ) { - data.put(mbd.getMotorId(),mbd); - } else { - // Prefer RASP motors. - if ( "RockSim".equals(mbd.getFiletype()) && !"RockSim".equals(currentData.getFiletype()) ) { - data.put(mbd.getMotorId(), mbd); - } + List currentData = data.get(mbd.getMotorId()); + if ( currentData == null ) { + currentData = new ArrayList(); + data.put(mbd.getMotorId(), currentData); } + currentData.add(mbd); } - public MotorBurnFile getData(Integer motor_id) { + public List getData(Integer motor_id) { return data.get(motor_id); } diff --git a/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponseParser.java b/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponseParser.java index a38a4e042..abf9d99f8 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponseParser.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/DownloadResponseParser.java @@ -75,8 +75,8 @@ public class DownloadResponseParser { AndroidLogWrapper.d(DownloadResponseParser.class,"base64: " + ex.getMessage()); } currentMotor.decodeFile( s ); + ret.add((MotorBurnFile)currentMotor.clone()); } - ret.add((MotorBurnFile)currentMotor.clone()); } } ); diff --git a/android/src/net/sf/openrocket/android/thrustcurve/MotorBurnFile.java b/android/src/net/sf/openrocket/android/thrustcurve/MotorBurnFile.java index a42907685..85fdb3312 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/MotorBurnFile.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/MotorBurnFile.java @@ -81,11 +81,4 @@ public class MotorBurnFile { return thrustCurveMotor; } - /** - * @param thrustCurveMotor the thrustCurveMotor to set - */ - public void setThrustCurveMotor(ThrustCurveMotor thrustCurveMotor) { - this.thrustCurveMotor = thrustCurveMotor; - } - } diff --git a/android/src/net/sf/openrocket/android/thrustcurve/TCMissingMotorDownloadAction.java b/android/src/net/sf/openrocket/android/thrustcurve/TCMissingMotorDownloadAction.java index ce580e958..aafaf1bd5 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/TCMissingMotorDownloadAction.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/TCMissingMotorDownloadAction.java @@ -1,10 +1,12 @@ package net.sf.openrocket.android.thrustcurve; +import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.openrocket.android.util.AndroidLogWrapper; +import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.motor.ThrustCurveMotorPlaceholder; public class TCMissingMotorDownloadAction extends TCQueryAction { @@ -48,7 +50,7 @@ public class TCMissingMotorDownloadAction extends TCQueryAction { handler.post( new UpdateMessage("Looking for " + motor.getManufacturer() + " " + motor.getDesignation())); - SearchResponse res = new ThrustCurveAPI().doSearch(request); + SearchResponse res = ThrustCurveAPI.doSearch(request); int total = res.getResults().size(); int count = 1; @@ -72,9 +74,10 @@ public class TCMissingMotorDownloadAction extends TCQueryAction { AndroidLogWrapper.d(TCQueryAction.class, mi.toString()); - MotorBurnFile b = new ThrustCurveAPI().downloadData(mi.getMotor_id()); + List listOfMotors = ThrustCurveAPI.downloadData(mi.getMotor_id()); - writeMotor( mi, b); + ThrustCurveMotor bestMatch = ThrustCurveAPI.findBestMatch(motor, listOfMotors); + writeMotor( mi, bestMatch); } } diff --git a/android/src/net/sf/openrocket/android/thrustcurve/TCQueryAction.java b/android/src/net/sf/openrocket/android/thrustcurve/TCQueryAction.java index bccacd495..7516f7f11 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/TCQueryAction.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/TCQueryAction.java @@ -4,6 +4,7 @@ import net.sf.openrocket.android.db.DbAdapter; import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor; import net.sf.openrocket.android.util.AndroidLogWrapper; import net.sf.openrocket.android.util.ProgressDialogFragment; +import net.sf.openrocket.motor.ThrustCurveMotor; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; @@ -95,14 +96,14 @@ public abstract class TCQueryAction extends Fragment { } } - protected void writeMotor( TCMotor mi, MotorBurnFile b) throws Exception { + protected void writeMotor( TCMotor mi, ThrustCurveMotor thrustCurveMotor) throws Exception { DbAdapter mDbHelper = new DbAdapter(getActivity()); mDbHelper.open(); try { ExtendedThrustCurveMotor m = new ExtendedThrustCurveMotor(); - m.setThrustCurveMotor( b.getThrustCurveMotor() ); + m.setThrustCurveMotor( thrustCurveMotor ); // Convert impulse class. ThrustCurve puts mmx, 1/4a and 1/2a as A. m.setImpulseClass(mi.getImpulse_class()); diff --git a/android/src/net/sf/openrocket/android/thrustcurve/TCSearchAction.java b/android/src/net/sf/openrocket/android/thrustcurve/TCSearchAction.java index 1354e872f..fc05f4d05 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/TCSearchAction.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/TCSearchAction.java @@ -1,6 +1,9 @@ package net.sf.openrocket.android.thrustcurve; +import java.util.List; + import net.sf.openrocket.android.util.AndroidLogWrapper; +import net.sf.openrocket.motor.ThrustCurveMotor; public class TCSearchAction extends TCQueryAction { @@ -22,7 +25,7 @@ public class TCSearchAction extends TCQueryAction { protected String doInBackground(Void... params) { try { handler.post( new UpdateMessage("Quering Thrustcurve")); - SearchResponse res = new ThrustCurveAPI().doSearch(searchRequest); + SearchResponse res = ThrustCurveAPI.doSearch(searchRequest); int total = res.getResults().size(); int count = 1; @@ -46,9 +49,13 @@ public class TCSearchAction extends TCQueryAction { AndroidLogWrapper.d(TCQueryAction.class, mi.toString()); - MotorBurnFile b = new ThrustCurveAPI().downloadData(mi.getMotor_id()); - - writeMotor( mi, b); + List b = ThrustCurveAPI.downloadData(mi.getMotor_id()); + List motors = ThrustCurveAPI.extractAllMotors(b); + if ( motors != null && motors.size() > 0 ) { + for( ThrustCurveMotor motor : motors ) { + writeMotor( mi, motor); + } + } } if ( total < res.getMatches() ) { dismiss(); diff --git a/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java b/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java index 2f38a4224..bcb567da0 100644 --- a/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java +++ b/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java @@ -6,15 +6,21 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import net.sf.openrocket.android.util.AndroidLogWrapper; +import net.sf.openrocket.motor.ThrustCurveMotor; +import net.sf.openrocket.motor.ThrustCurveMotorPlaceholder; -public class ThrustCurveAPI { +public abstract class ThrustCurveAPI { - private String url_base = "http://www.thrustcurve.org/servlets/"; + private static String url_base = "http://www.thrustcurve.org/servlets/"; - public SearchResponse doSearch( SearchRequest request ) throws MalformedURLException, IOException { + public static SearchResponse doSearch( SearchRequest request ) throws MalformedURLException, IOException { String requestString = request.toString(); @@ -41,7 +47,7 @@ public class ThrustCurveAPI { return result; } - public MotorBurnFile downloadData( Integer motor_id ) throws MalformedURLException, IOException { + public static List downloadData( Integer motor_id ) throws MalformedURLException, IOException { if ( motor_id == null ) { return null; @@ -70,9 +76,73 @@ public class ThrustCurveAPI { DownloadResponse downloadResponse = DownloadResponseParser.parse(is); AndroidLogWrapper.d(ThrustCurveAPI.class,downloadResponse.toString()); - MotorBurnFile mbf = downloadResponse.getData(motor_id); - - return mbf; + return downloadResponse.getData(motor_id); } + + /** + * look through the listOfMotors to find the one which best matches the motor requested. + * + * The algorithm uses a score based method. Each entry in listOfMotors is assigned a score + * and the element with the highest score is returned. The score is computed as follows: + * + * 1) if the element matches the digest of the requested motor eactly, score += 1000 + * 1) if the element matches the designation in the requested motor exactly, score = 100 + * 2) if the element is a RockSim file score += 10 + * + * @param motor + * @param listOfMotors + * @return + */ + public static ThrustCurveMotor findBestMatch( ThrustCurveMotorPlaceholder motor, List listOfMotors ) { + + ThrustCurveMotor bestMatch = null; + int bestScore = -1; + + final String wantedDesignation = motor.getDesignation(); + final String wantedDigest = motor.getDigest(); + + for ( MotorBurnFile entry : listOfMotors ) { + int entryScore = 0; + ThrustCurveMotor entryMotor = entry.getThrustCurveMotor(); + + if ("RockSim".equals(entry.getFiletype()) ) { + entryScore += 10; + } + + if ( wantedDigest != null && wantedDigest.equals( entryMotor.getDigest() ) ) { + entryScore += 1000; + } + + if ( wantedDesignation != null && wantedDesignation.equals(entryMotor.getDesignation())) { + entryScore += 100; + } + + if ( entryScore > bestScore ) { + bestScore = entryScore; + bestMatch = entry.getThrustCurveMotor(); + } + + } + + return bestMatch; + } + + /** + * Extract all unique motors from the list based on designation. + * @param listOfMotors + * @return + */ + public static List extractAllMotors( List listOfMotors ) { + + Map motorsByDesignation = new HashMap(); + + for( MotorBurnFile entry : listOfMotors ) { + ThrustCurveMotor motor = entry.getThrustCurveMotor(); + motorsByDesignation.put( motor.getDesignation(), motor); + } + + return new ArrayList(motorsByDesignation.values()); + + } }