@@ -12,8 +12,6 @@ |
import java.util.ArrayList; |
import java.util.Calendar; |
import java.util.GregorianCalendar; |
-import java.sql.Connection; |
-import java.sql.DriverManager; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.sql.Statement; |
@@ -21,167 +19,11 @@ |
import java.util.concurrent.TimeUnit; |
|
import org.codehaus.jettison.json.JSONArray; |
+import org.codehaus.jettison.json.JSONException; |
import org.codehaus.jettison.json.JSONObject; |
|
public class Crop { |
|
- // Inner Classes |
- class NutrientApplication { |
- |
- class Nutrient { |
- private String error_msg = ""; |
- private String nutrientApplied; |
- private double applicationRate; |
- |
- public Nutrient(String nutrientApplied, double applicationRate) { |
- this.nutrientApplied = nutrientApplied; |
- this.applicationRate = applicationRate; |
- |
- if ( !nutrientApplied.equals("Nitrogen") && !nutrientApplied.equals("Phosphorus") ) { |
- this.error_msg += "Invalid input data. Bad nutrient name"; |
- } |
- } |
- |
- //Get Methods |
- public String getNutrientApplied() { |
- return this.nutrientApplied; |
- } |
- |
- public double getApplicationRate() { |
- return this.applicationRate; |
- } |
- |
- public String getErrorMsg(){ |
- return this.error_msg; |
- } |
- |
- public Boolean validate(){ |
- return (this.error_msg.isEmpty()); |
- } |
- } |
- |
- private String error_msg = ""; |
- private String applicationDate; |
- private boolean incorporated; |
- private ArrayList<Crop.NutrientApplication.Nutrient> nutrientList; |
- private int appMethodScore = 0; |
- private int[] nutrientTimingScores = new int[2]; |
- |
- public NutrientApplication(String applicationDate, String incorporated, JSONArray applications) { |
- this.applicationDate = applicationDate; |
- nutrientTimingScores[N_APP_TIMING_SCORE] = nutrientTimingScores[P_APP_TIMING_SCORE] = -1; |
- |
- if ( ( !"true".equalsIgnoreCase(incorporated) ) && ( !"false".equalsIgnoreCase(incorporated) ) ) { |
- this.error_msg += "Invalid incorporation value for nutrient application " + applicationDate; |
- } |
- else{ |
- this.incorporated = Boolean.parseBoolean(incorporated); |
- nutrientList = new ArrayList<>(); |
- |
- try{ |
- for (int k = 0; k < applications.length(); k++) { |
- Map<String, JSONObject> nutrient = JSONUtils.preprocess(applications.getJSONArray(k)); |
- nutrientList.add(new Crop.NutrientApplication.Nutrient(JSONUtils.getStringParam(nutrient, "nutrient_applied", "err"), JSONUtils.getDoubleParam(nutrient, "application_rate", 0))); |
- } |
- } |
- catch(Exception ex){ |
- this.error_msg += "Cannot process applied nutrient list. " + ex.getMessage(); |
- } |
- } |
- } |
- |
- //Get Methods |
- public Date getApplicationDate() throws Exception { |
- String[] parse = this.applicationDate.split("-"); |
- //Some say should set to use UTC first...do we wanna do that? |
- Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]), |
- Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2])); |
- return date.getTime(); |
- } |
- |
- public boolean isIncorporated() { |
- return this.incorporated; |
- } |
- |
- public ArrayList getNutrientList() { |
- return this.nutrientList; |
- } |
- |
- public String getErrorMsg(){ |
- for (Crop.NutrientApplication.Nutrient nutrient : this.nutrientList ){ |
- this.error_msg += nutrient.getErrorMsg(); |
- } |
- return this.error_msg; |
- } |
- |
- public Boolean validate(){ |
- for( Crop.NutrientApplication.Nutrient nutrient : nutrientList ) |
- if ( !nutrient.validate() ) |
- this.error_msg += "; " + nutrient.getErrorMsg(); |
- |
- return (this.error_msg.isEmpty()); |
- } |
- |
- public int[] getNutrientTimingScores( Boolean split ){ |
- if ( ( nutrientTimingScores[N_APP_TIMING_SCORE] < 0 ) || ( nutrientTimingScores[P_APP_TIMING_SCORE] < 0 ) ){ |
- int tempNScore = 100; |
- int tempPScore = 100; |
- ResultSet resultSet; |
- |
- for ( Crop.NutrientApplication.Nutrient nutrient : nutrientList ){ |
- int app_timing_score; |
- |
- try{ |
- long app_day_diff = Dates.diffInMillis( getCropPlantDate(), getApplicationDate() ); |
- app_day_diff = TimeUnit.MILLISECONDS.toDays(app_day_diff); |
- |
- String query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='"; |
- |
- query += nutrient.getNutrientApplied() + "' "; |
- query += "AND app_mgt_kind='Timing' AND app_mgt_factor='" + (split? "split":"nosplit") + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";"; |
- |
- resultSet = statement.executeQuery(query); |
- if ( !resultSet.first() ) { |
- app_timing_score = -1; |
- } |
- else { |
- app_timing_score = resultSet.getInt("app_mgt_score"); |
- } |
- |
- switch (nutrient.getNutrientApplied()) |
- { |
- case "Nitrogen": |
- if ( app_timing_score < tempNScore ) |
- tempNScore = app_timing_score; |
- break; |
- |
- case "Phosphorus": |
- if ( app_timing_score < tempPScore ) |
- tempPScore = app_timing_score; |
- break; |
- |
- default: |
- this.error_msg += "Invalid nutrient name specified"; |
- } |
- } |
- catch (Exception ex){ |
- this.error_msg += "Cannot calculate nutrient application timing scores: " + ex.getMessage(); |
- } |
- |
- if ( this.error_msg.isEmpty() ){ |
- nutrientTimingScores[N_APP_TIMING_SCORE] = tempNScore; |
- nutrientTimingScores[P_APP_TIMING_SCORE] = tempPScore; |
- } |
- } |
- } |
- |
- return nutrientTimingScores; |
- } |
- |
- public Boolean allNutrientsIncorporated(){ |
- return this.incorporated; |
- } |
- } |
|
|
// Begin Crop Class |
@@ -260,7 +102,7 @@ |
cropType = resultSet.getString("wqm_crop_type"); |
} |
} |
- catch( Exception ex ) { |
+ catch( SQLException ex ) { |
error_msg += ex.getMessage(); |
} |
} |
@@ -296,12 +138,14 @@ |
String queryPhosporous = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='Phosphorus' AND app_mgt_kind='Rate' AND app_mgt_factor='none' AND soil_test_result='" + pSoilTestResult + "';"; |
|
resultSet = statement.executeQuery(queryNitrogen); |
- if ( resultSet.first() ) |
+ if ( resultSet.first() ) { |
appRateScore[N_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score"); |
+ } |
|
resultSet = statement.executeQuery(queryPhosporous); |
- if ( resultSet.first() ) |
+ if ( resultSet.first() ) { |
appRateScore[P_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score"); |
+ } |
} |
else{ |
ResultSet resultSet; |
@@ -323,10 +167,10 @@ |
for (Crop.NutrientApplication.Nutrient nApplied : nutrientAppliedList) { |
switch(nApplied.getNutrientApplied()){ //Note: This switch requires JDK 1.7 or above |
case "Nitrogen": |
- nrate = nrate + nApplied.getApplicationRate(); |
+ nrate += nApplied.getApplicationRate(); |
break; |
case "Phosphorus": |
- prate = prate + nApplied.getApplicationRate(); |
+ prate += nApplied.getApplicationRate(); |
break; |
} |
} |
@@ -409,7 +253,7 @@ |
} |
} |
} |
- catch (Exception ex) { |
+ catch (SQLException ex) { |
error_msg += ex.getMessage(); |
} |
} |
@@ -426,11 +270,13 @@ |
// Call each application compare its results to the last and adjust main score if necessary. |
int[] tempAppTimingScores = nutrientApplication.getNutrientTimingScores( this.multipleNutrientApplication ); |
|
- if ( tempAppTimingScores[N_APP_TIMING_SCORE] < tempNScore ) |
+ if ( tempAppTimingScores[N_APP_TIMING_SCORE] < tempNScore ) { |
tempNScore = tempAppTimingScores[N_APP_TIMING_SCORE]; |
+ } |
|
- if ( tempAppTimingScores[P_APP_TIMING_SCORE] < tempPScore ) |
+ if ( tempAppTimingScores[P_APP_TIMING_SCORE] < tempPScore ) { |
tempPScore = tempAppTimingScores[P_APP_TIMING_SCORE]; |
+ } |
} |
|
appNutrientTimingScore[P_APP_TIMING_SCORE] = tempPScore; |
@@ -459,11 +305,158 @@ |
} |
|
public Boolean validate(){ |
- for( Crop.NutrientApplication tNutrientApplication : nutrientApplicationList ) |
- if ( !tNutrientApplication.validate() ) |
+ for( Crop.NutrientApplication tNutrientApplication : nutrientApplicationList ) { |
+ if (!tNutrientApplication.validate()) { |
error_msg += "; " + tNutrientApplication.getErrorMsg(); |
+ } |
+ } |
|
|
return ( error_msg.isEmpty() ); |
} |
+ |
+ // Inner Classes |
+ class NutrientApplication { |
+ |
+ class Nutrient { |
+ |
+ private String error_msg = ""; |
+ private final String nutrientApplied; |
+ private final double applicationRate; |
+ |
+ Nutrient(String nutrientApplied, double applicationRate) { |
+ this.nutrientApplied = nutrientApplied; |
+ this.applicationRate = applicationRate; |
+ |
+ if ( !nutrientApplied.equals("Nitrogen") && !nutrientApplied.equals("Phosphorus") ) { |
+ this.error_msg += "Invalid input data. Bad nutrient name"; |
+ } |
+ } |
+ |
+ //Get Methods |
+ public String getNutrientApplied() { |
+ return this.nutrientApplied; |
+ } |
+ |
+ public double getApplicationRate() { |
+ return this.applicationRate; |
+ } |
+ |
+ public String getErrorMsg(){ |
+ return this.error_msg; |
+ } |
+ |
+ public Boolean validate(){ |
+ return (this.error_msg.isEmpty()); |
+ } |
+ } |
+ private String error_msg = ""; |
+ private String applicationDate; |
+ private boolean incorporated; |
+ private ArrayList<Crop.NutrientApplication.Nutrient> nutrientList; |
+ private int appMethodScore = 0; |
+ private int[] nutrientTimingScores = new int[2]; |
+ |
+ NutrientApplication(String applicationDate, String incorporated, JSONArray applications) { |
+ this.applicationDate = applicationDate; |
+ nutrientTimingScores[N_APP_TIMING_SCORE] = nutrientTimingScores[P_APP_TIMING_SCORE] = -1; |
+ if (( !"true".equalsIgnoreCase(incorporated) ) && ( !"false".equalsIgnoreCase(incorporated) )) { |
+ this.error_msg += "Invalid incorporation value for nutrient application " + applicationDate; |
+ } else { |
+ this.incorporated = Boolean.parseBoolean(incorporated); |
+ nutrientList = new ArrayList<>(); |
+ try { |
+ for (int k = 0; k < applications.length(); k++) { |
+ Map<String, JSONObject> nutrient = JSONUtils.preprocess(applications.getJSONArray(k)); |
+ nutrientList.add(new Crop.NutrientApplication.Nutrient(JSONUtils.getStringParam(nutrient, "nutrient_applied", "err"), JSONUtils.getDoubleParam(nutrient, "application_rate", 0))); |
+ } |
+ } catch (JSONException ex) { |
+ this.error_msg += "Cannot process applied nutrient list. " + ex.getMessage(); |
+ } |
+ } |
+ } |
+ |
+ //Get Methods |
+ public Date getApplicationDate() throws Exception { |
+ String[] parse = this.applicationDate.split("-"); |
+ //Some say should set to use UTC first...do we wanna do that? |
+ Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]), |
+ Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2])); |
+ return date.getTime(); |
+ } |
+ |
+ public boolean isIncorporated() { |
+ return this.incorporated; |
+ } |
+ |
+ public ArrayList getNutrientList() { |
+ return this.nutrientList; |
+ } |
+ |
+ public String getErrorMsg(){ |
+ for (Crop.NutrientApplication.Nutrient nutrient : this.nutrientList ){ |
+ this.error_msg += nutrient.getErrorMsg(); |
+ } |
+ return this.error_msg; |
+ } |
+ |
+ public Boolean validate() { |
+ for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) { |
+ if (!nutrient.validate()) { |
+ this.error_msg += "; " + nutrient.getErrorMsg(); |
+ } |
+ } |
+ return (this.error_msg.isEmpty()); |
+ } |
+ |
+ public int[] getNutrientTimingScores(Boolean split) { |
+ if (( nutrientTimingScores[N_APP_TIMING_SCORE] < 0 ) || ( nutrientTimingScores[P_APP_TIMING_SCORE] < 0 )) { |
+ int tempNScore = 100; |
+ int tempPScore = 100; |
+ ResultSet resultSet; |
+ for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) { |
+ int app_timing_score; |
+ try { |
+ long app_day_diff = Dates.diffInMillis( getCropPlantDate(), getApplicationDate() ); |
+ app_day_diff = TimeUnit.MILLISECONDS.toDays(app_day_diff); |
+ String query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='"; |
+ query += nutrient.getNutrientApplied() + "' "; |
+ query += "AND app_mgt_kind='Timing' AND app_mgt_factor='" + (split? "split":"nosplit") + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";"; |
+ resultSet = statement.executeQuery(query); |
+ if ( !resultSet.first() ) { |
+ app_timing_score = -1; |
+ } |
+ else { |
+ app_timing_score = resultSet.getInt("app_mgt_score"); |
+ } |
+ switch (nutrient.getNutrientApplied()) { |
+ case "Nitrogen": |
+ if (app_timing_score < tempNScore) { |
+ tempNScore = app_timing_score; |
+ } |
+ break; |
+ case "Phosphorus": |
+ if (app_timing_score < tempPScore) { |
+ tempPScore = app_timing_score; |
+ } |
+ break; |
+ default: |
+ this.error_msg += "Invalid nutrient name specified"; |
+ } |
+ }catch (Exception ex){ |
+ this.error_msg += "Cannot calculate nutrient application timing scores: " + ex.getMessage(); |
+ } |
+ if ( this.error_msg.isEmpty() ){ |
+ nutrientTimingScores[N_APP_TIMING_SCORE] = tempNScore; |
+ nutrientTimingScores[P_APP_TIMING_SCORE] = tempPScore; |
+ } |
+ } |
+ } |
+ return nutrientTimingScores; |
+ } |
+ |
+ public Boolean allNutrientsIncorporated(){ |
+ return this.incorporated; |
+ } |
+ } |
} |