Displaying differences for changeset
 
display as  

nbproject/ant-deploy.xml

@@ -20,18 +20,30 @@
     </target>
     <target name="-deploy-ant" if="deploy.ant.enabled" depends="-init,-check-credentials">
         <echo message="Deploying ${deploy.ant.archive} to ${Context(path)}"/>
-        <taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask"
-                 classpath="${tomcat.home}/server/lib/catalina-ant.jar"/>
-        <deploy url="${tomcat.url}/manager" username="${tomcat.username}"
+        <taskdef name="deploy" classname="org.apache.catalina.ant.DeployTask">
+            <classpath>
+                <pathelement path="${tomcat.home}/lib/catalina-ant.jar"/>
+                <pathelement path="${tomcat.home}/lib/tomcat-coyote.jar"/>
+                <pathelement path="${tomcat.home}/lib/tomcat-util.jar"/>
+                <pathelement path="${tomcat.home}/bin/tomcat-juli.jar"/>
+            </classpath>
+        </taskdef>
+        <deploy url="${tomcat.url}/manager/text" username="${tomcat.username}"
                 password="${tomcat.password}" path="${Context(path)}"
                 war="${deploy.ant.archive}"/>
         <property name="deploy.ant.client.url" value="${tomcat.url}${Context(path)}"/>
     </target>
     <target name="-undeploy-ant" if="deploy.ant.enabled" depends="-init,-check-credentials">
         <echo message="Undeploying ${Context(path)}"/>
-        <taskdef name="undeploy"  classname="org.apache.catalina.ant.UndeployTask"
-                classpath="${tomcat.home}/server/lib/catalina-ant.jar"/>
-        <undeploy url="${tomcat.url}/manager" username="${tomcat.username}" 
+        <taskdef name="undeploy"  classname="org.apache.catalina.ant.UndeployTask">
+            <classpath>
+                <pathelement path="${tomcat.home}/lib/catalina-ant.jar"/>
+                <pathelement path="${tomcat.home}/lib/tomcat-coyote.jar"/>
+                <pathelement path="${tomcat.home}/lib/tomcat-util.jar"/>
+                <pathelement path="${tomcat.home}/bin/tomcat-juli.jar"/>
+            </classpath>
+        </taskdef>
+        <undeploy url="${tomcat.url}/manager/text" username="${tomcat.username}" 
                   password="${tomcat.password}" path="${Context(path)}"/>
     </target>
 </project>

src/java/m/wqm/ApplicationConfig.java

@@ -34,6 +34,7 @@
         resources.add(csip.ArchiveService.class);
         resources.add(csip.CatalogService.class);
         resources.add(csip.ControlService.class);
+        resources.add(csip.ModelDataService.class);
         resources.add(csip.QueryService.class);
         resources.add(csip.ReportService.class);
         resources.add(m.wqm.NutrientSLP.V1_0.class);

src/java/m/wqm/nutappmgtscores/V1_0.java

@@ -24,6 +24,7 @@
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONObject;
 import java.util.concurrent.TimeUnit;
+import static wqm.utils.WQMTools.getConnection;
 
 @Name("WQM-16: Nutrient Application Management Scores (NutAppMgtScores)")
 @Description("This service computes scores for adjusting the rate, timing, and method of applying nutrients to mitigate nitrogen leaching, and nitrogen and phosphorus runoff loss potential.")
@@ -31,18 +32,7 @@
 @Polling(first = 10000, next = 2000)
 
 public class V1_0 extends ModelDataService {
-
-    //SQL params here for quick modification
-    private final String USER = "postgres";
-    private final String PASS = "admin";
-    private final String HOST = "localhost";
-    private final String PORT = "5432";
-    private final String DBNAME = "wqm";
-    private final String JDBC_TYPE = "jdbc:postgresql://";
-    private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
-    private final String CLASS_NAME = "org.postgresql.Driver";
-
-    //Request
+   //Request
     private ArrayList<Input> input;
     //Response
     private ArrayList<Result> result;
@@ -58,20 +48,15 @@
     @Override
     protected void preProcess() throws Exception {
         try{
-            Class.forName(CLASS_NAME);            
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
+            conn = wqm.utils.WQMTools.getConnection( "wqm", LOG );
             statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
         }
-        catch(ClassNotFoundException | SQLException ex) {
-            if (ex instanceof SQLException) {
-                LOG.info("Did not open database for WQM-16!");
+        catch( SQLException ex ) {
+
+                LOG.info("Did not open database for WQM-16.");
                 LOG.info(ex.getMessage());      
-                error_msg = "Could not open database for WQM-16!  " + ex.getMessage();
-            }
-            else{
-                error_msg = "Could not instantiate postgres database object: " + ex.getMessage();
-            }                                            
-        }
+                this.error_msg = "Could not open database for WQM-16.  " + ex.getMessage();
+            }                                         
 
         if (error_msg.isEmpty()){
             AoAId = getIntParam("aoa_id", 0);

src/java/m/wqm/nutrientslpsrp/V1_0.java

@@ -11,9 +11,11 @@
  */
 import csip.ModelDataService;
 import csip.utils.JSONUtils;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Map;
-import java.util.ArrayList;
 import javax.ws.rs.Path;
+import javax.ws.rs.core.UriBuilder;
 import oms3.annotations.Description;
 import oms3.annotations.Name;
 import org.codehaus.jettison.json.JSONArray;
@@ -22,20 +24,19 @@
 
 /**
  *
- * @author scase
+ * @author Shaun Case
  */
-
-//  It may be we will call this WQM-21a, with another service called WQM-21b...waiting on the decision process....
-@Name("WQM-21: Nutrient Soil Leaching and Runoff Loss Potentials (NutrientSLP+SRP)")
-@Description("Nutrient Technique Scores")
+@Name("WQM-21: Nutrient Soil Leaching and Runoff Loss Potentials for an Area of Analysis (NutrientSLP-SRP)")
+@Description("This service intersects area of analysis (AoA) and soil mapunit geometries, gets soil parameters, and computes nutrient soil leaching and runoff potentials as an end-to-end process. The services combines WQM-02, WQM-05, and WQM-06 services into a single service. It returns a results payload containing the relevant attributes for each soil component in the AoA, leaching (SLP) and runoff (SRP) potentials for each soil component, and weighted average leaching and runoff loss potential values for the AoA. The services allows for submitting parameter edits. For example, the request payload can contain just the AoA geometry and the services gets soil parameters and computes SLP and SRP and returns the results, including the parameters. If an application user edits the parameters, a subsequent request payload can contain the parameter edits and not the geometry.")
 @Path("m/nutrientslpsrp/1.0")
 
 
 public class V1_0 extends ModelDataService {
 
     //Quick Parameters, here for quick modification
-    private final String CHAINED_HOST = "http://localhost";
-    private final String CHAINED_HOST_PORT = "8084";
+    private final String WQM_02_Service_Path = "/csip-wqm/m/wqmsoilattributes/1.0";
+    private final String WQM_05_Service_Path = "/csip-wqm/m/nutrient_slp/1.0";
+    private final String WQM_06_Service_Path = "/csip-wqm/m/scsednut_srp/1.0";    
     
     
     private boolean aoa_comp_drained = false;
@@ -44,56 +45,65 @@
     private JSONObject aoaGeometry = null;
     private Boolean is_5_6_Only;
     private String error_msg = "";
+    
+    private wqm_21 Service;
 
     @Override
     // reading the inputs from the json file into input object and placing it in the arraylist
-    protected void preProcess() throws Exception {
-        int a;
+    protected void preProcess(){        
+        this.Service = null;
         
         JSONArray request = getRequest().optJSONArray("parameter");
         
-        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") ){
-            aoa_id = getStringParam("AoAId");
-            aoa_comp_drained = getBooleanParam("aoa_comp_drained");
-            //Get the entire aoa_geometry group as it matches the input payload exactly for WQM-2
-            aoaGeometry = getJSONParam("aoa_geometry");
-            this.is_5_6_Only = false;
-        }
-        else
-            if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "soilcomponents") ){
-                //  If this key exists then we have it at the top level by design, so keep the object as the payload
-                this.soilComponents = request;
-                this.is_5_6_Only = true;
-            }
-            else{
-                //  No valid input stream for this service
-                this.error_msg = "No valid input parameters found .";
-            }
-               
-
-                
+    try{
+        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") && JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "aoa_geometry") ){
+        aoa_id = getStringParam("AoAId");
+        aoa_comp_drained = getBooleanParam("aoa_comp_drained");
+        //Get the entire aoa_geometry group as it matches the input payload exactly for WQM-2
+        aoaGeometry = getJSONParam("aoa_geometry");
+        this.is_5_6_Only = false;
+        }
+        else
+        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "soilcomponents") ){
+            //  If this key exists then we have it at the top level by design, so keep the object as the payload
+            aoa_id = getStringParam("AoAId");
+            this.soilComponents = request;
+            this.is_5_6_Only = true;
+        }
+        else{
+            //  No valid input stream for this service
+            this.error_msg = "No valid input parameters found .";
+        }      
+    }
+    catch( Exception ex ){
+        this.error_msg = "Error reading JSON request: " + ex.getMessage();
+    }
     }
 
     @Override
-    protected String process() throws Exception {
-        //  Call WQM-2 processing member functions, then apply results to WQM-5() and WQM-6() objects inputs
-        wqm_21 Service;
+    protected String process(){
+    if ( this.error_msg.isEmpty() ){
+        try{
+        //  Call WQM-2 processing member functions, then apply results to WQM-5() and WQM-6() objects inputs        
+        if ( this.is_5_6_Only ){
+            //This is just a 5/6 combined request
+            Service = new wqm_21( this.soilComponents );           
+        }
+        else{
+            //This is a full combined request 2/5/6
+            Service = new wqm_21( this.aoa_id, this.aoa_comp_drained, this.aoaGeometry);
+        }
+
+        if ( !Service.process() ){
+            this.error_msg += " " + Service.getErrorMsg();
+        }
+        }
+        catch( Exception ex ){
+        this.error_msg += "Error processing this request: " + ex.getMessage();
+        }
+    }
         
-        if ( this.is_5_6_Only ){
-            //This is just a 5/6 combined request
-            Service = new wqm_21( this.soilComponents );           
-        }
-        else{
-            //This is a full combined request 2/5/6
-            Service = new wqm_21( this.aoa_id, this.aoa_comp_drained, this.aoaGeometry);
-        }
-        
-        if ( !Service.process() ){
-            this.error_msg += " " + Service.getErrorMsg();
-        }
-        
-        //return ( this.error_msg.isEmpty()? "EXEC_OK" : this.error_msg );
-        return "FAILURE: Service not yet completed.";
+        return ( this.error_msg.isEmpty()? EXEC_OK : this.error_msg );
     }
 
     @Override
@@ -102,33 +112,51 @@
         
         //  Return the result arrays produced by WQM-2, WQM-5, and WQM-6
         JSONArray resultArr = new JSONArray();
-        
+        if ( null != this.Service ){
+            putResult("AoAId", this.aoa_id, "Area of analysis identifier");  
+            putResult("aoa_nslp", this.Service.WQM_5.getAoaNSLP(), "Soil leaching potential of the area of analysis");
+            putResult("aoa_srp", this.Service.WQM_6.getAoaSRP(), "Soil runoff potential for the area of analysis");            
+            
+            resultArr.put( this.Service.createJSONResult() );
+            
+            putResult("soil_components", resultArr, "List of Soil Components");            
+        }               
     }
     
     
     //Inner classes
     class wqm_21{
-        private final String WQM2Service = CHAINED_HOST + ":" + CHAINED_HOST_PORT + "/csip-wqm/m/wqmsoilattributes/1.0";
-        private final String WQM5Service = CHAINED_HOST + ":" + CHAINED_HOST_PORT + "/csip-wqm/m/nutrient_slp/1.0";
-        private final String WQM6Service = CHAINED_HOST + ":" + CHAINED_HOST_PORT + "/csip-wqm/m/scsednut_srp/1.0";
+        private final String WQM2Service;
+        private final String WQM5Service;
+        private final String WQM6Service;
         private final String aoaId;
         private final Boolean aoa_comp_drained;
+        private String aoa_nslp;
+        private String aoa_srp;
         private final JSONObject aoaGeometry; 
         private final JSONArray soilComponents;
         private JSONObject results;
         private String error_msg;
         
         private wqm_2Result WQM_2;
+        private wqm_5Result WQM_5;
+        private wqm_6Result WQM_6;
         
         wqm_21( JSONArray soilComponents ){
             this.aoaId = "none";
             this.aoa_comp_drained = false;
             this.aoaGeometry = null;             
-            
+            this.aoa_nslp = "Error";
             this.soilComponents = soilComponents;
             this.error_msg = "";
             this.results = null;
             this.WQM_2 = null;
+            this.WQM_5 = null;
+            this.WQM_6 = null;            
+            
+            WQM2Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_02_Service_Path).toString();
+            WQM5Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_05_Service_Path).toString();
+            WQM6Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_06_Service_Path).toString();           
         }
         
         wqm_21( String AoAId, Boolean aoa_comp_drained, JSONObject AoAGeometry ){
@@ -140,48 +168,108 @@
             this.error_msg = "";
             this.results = null;
             this.WQM_2 = null;
+            this.WQM_5 = null;
+            this.WQM_6 = null; 
+            
+            WQM2Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_02_Service_Path).toString();
+            WQM5Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_05_Service_Path).toString();
+            WQM6Service = UriBuilder.fromUri(getRequestURL()).replacePath(WQM_06_Service_Path).toString();             
         }
         
         public Boolean process(){
             Boolean ret_val = true;
             JSONObject result;
+            JSONObject WQM5_input = null;                        
+            ServiceCall wqmService = new ServiceCall();             
             
             try{
-                JSONObject wqm2RequestString = this.createWQM2Request();
+                if (this.aoaGeometry != null ){
+                    JSONObject wqm2RequestString = this.createWQM2Request();
 
-                String testing = wqm2RequestString.toString();
+                    //  Call WQM-2           
+                    result = wqmService.getResult( this.WQM2Service, wqm2RequestString );
+
+                    if ( null != result ){            
+                        // Parse WQM-2 results and build WQM-5 and WQM-6 requests
+                        if ( this.parseWQM2Result( result ) ){                        
+                            WQM5_input = this.WQM_2.convertResultToWQM5Input( this.aoaId, this.aoa_comp_drained );
+                            
+                            if ( this.WQM_2.getError() || ( null == WQM5_input ) ){
+                                ret_val = false;
+                                this.error_msg += " " + wqmService.getErrorMsg();
+                            }                                                                    
+                        }
+                        else{
+                            ret_val = false;                            
+                        }                   
+                    }
+                    else{
+                        ret_val = false;
+                        this.error_msg += " " + wqmService.getErrorMsg();
+                    }                            
+                }//End WQM-02 request
+                else{
+                    WQM5_input = this.createWQM5Request();                                        
+                }
                 
-                //  Call WQM-2
-                ServiceCall wqmService = new ServiceCall(  );            
-                result = wqmService.getResult( this.WQM2Service, wqm2RequestString );
+                //  Send this input to the WQM5 service...
+                result = wqmService.getResult( this.WQM5Service, WQM5_input );
 
-                if ( null != result ){            
-                    // Parse WQM-2 results and build WQM-5 and WQM-6 requests
-                    if ( this.parseWQM2Result( result ) )
-                    {
-                        
-                        
-                    //  Call WQM-5 and WQM-6
+                if ( null != result ){
+                    // Got a return from WQM-05
+                    //Store result
+                    if ( this.parseWQM5Result( result ) ){                     
+                        //Call WQM-06
+                        //  NOTE:  WQM-06 uses the same input as WQM-05...no need to change here.
+                        result = wqmService.getResult( this.WQM6Service, WQM5_input );
 
-                    //  Parse WQM-5 and WQM-6 results
-
-                    //  Build WQM-21 results 
+                        //Store result
+                        if ( this.parseWQM6Result( result, this.WQM_5.getFinalComponentMap())){             
+                            this.aoa_nslp = this.WQM_5.getAoaNSLP();
+                            this.aoa_srp = this.WQM_6.getAoaSRP();
+                        }
+                        else{
+                            ret_val = false;
+                        }                        
                     }
+                    else{
+                        ret_val = false;
+                    } 
                 }
                 else{
                     ret_val = false;
                     this.error_msg += " " + wqmService.getErrorMsg();
-                }
-                
-            }
-            catch(Exception ex){
-                
+                }                
+            }  // End try block
+            catch(JSONException ex){
+                this.error_msg += " " + ex.getMessage();
+                ret_val = false;
             }
             
             return ret_val;
         }
         
-        
+        public JSONArray createJSONResult(){
+            JSONArray ret_val = new JSONArray();
+            ArrayList<V1_0.wqm_21.finalSoilComponent> componentList;
+            componentList = this.WQM_5.getFinalComponentList();
+            
+            try{
+                for ( V1_0.wqm_21.finalSoilComponent component : componentList) {
+                    JSONArray array = new JSONArray();
+                    array.put(component.getJSONCokey());
+                    array.put(component.getJSONCompNSLP());
+                    array.put(component.getJSONCompSRP());
+                    ret_val.put(JSONUtils.dataDesc("soil_component", array, "Soil Component"));
+                }   
+            }
+            catch (JSONException ex){
+                LOG.info("Did not finish building WQM-21 result output.");
+                LOG.info( ex.getMessage() );                
+            }
+            
+            return ret_val;
+        }
         
         private JSONObject createWQM2Request() throws JSONException{
            JSONObject ret_val;
@@ -203,7 +291,24 @@
             
            return ret_val;          
         }
-                
+
+        private JSONObject createWQM5Request() throws JSONException{
+           JSONObject ret_val;
+           JSONObject metainfo;
+           
+           metainfo = new JSONObject();
+           ret_val = new JSONObject();
+           
+           metainfo.put( "MultipartRequest", "Bundled Service Request WQM-21");
+           metainfo.put( "OriginalSource", getRequestHost() );
+           metainfo.put( "OriginalRequest", getRequestURL() );
+           metainfo.put( "OriginalSUID", getSUID() );
+           ret_val.put("metainfo", metainfo );                        
+           ret_val.put( "parameter", this.soilComponents);           
+            
+           return ret_val;          
+        }        
+        
         private Boolean parseWQM2Result( JSONObject result ){
             Boolean ret_val = true;
             
@@ -214,6 +319,29 @@
             }
             
             return ret_val;            
+        }        
+        
+        private Boolean parseWQM5Result( JSONObject result ){
+            Boolean ret_val = true;
+            
+            this.WQM_5 = new V1_0.wqm_21.wqm_5Result( result );
+            if ( this.WQM_5.getError() ){
+                this.error_msg += this.WQM_5.getErrorMsg();
+                ret_val = false;                
+            }
+            
+            return ret_val;
+        }
+
+        private Boolean parseWQM6Result( JSONObject result, HashMap<String, V1_0.wqm_21.finalSoilComponent> finalComponentMap ){
+            Boolean ret_val = true;
+            
+            this.WQM_6 = new V1_0.wqm_21.wqm_6Result( result, finalComponentMap );
+            if ( this.WQM_6.getError() ){
+                this.error_msg += this.WQM_6.getErrorMsg();
+                ret_val = false;                
+            }            
+            return ret_val;
         } 
         
         public JSONObject getResults(){return this.results;}
@@ -226,75 +354,252 @@
         class wqm_2Result{
         
             private String error_msg;
-            private ArrayList <V1_0.wqm_21.SoilComponent> components;
+            private JSONObject originalResult;
+            private ArrayList <V1_0.wqm_21.wqm2SoilComponent> components;
             
             wqm_2Result( JSONObject result ){
                 this.error_msg = "";
+                this.originalResult = result;
+                components = new ArrayList<>();
                 
+                try{
+                    JSONArray resultArray = result.getJSONArray("result");  
+                    JSONObject soilsList = resultArray.optJSONObject(1);  //This should be the soil_component_list;
+                    JSONArray soils = soilsList.getJSONArray("value");                 
+                    
+                   
+                    //  for each array in this result...build a list of components.
+                    if ( soils.length() > 0 ){
+                        for( int i = 0; i < soils.length(); i++){
+                            V1_0.wqm_21.wqm2SoilComponent tComponent;       
+                            JSONArray componentData = soils.getJSONObject(i).getJSONArray("value");
+                            tComponent = new V1_0.wqm_21.wqm2SoilComponent( componentData );  
+                            this.components.add(tComponent);
+                        }
+                    } 
+                    else{
+                        this.error_msg += " There was no return result from the WQM-02 service. ";
+                    }
+                   
+                }
+                catch( JSONException ex ){
+                    this.error_msg += " Error parsing returned data from the WQM-02 service: " + ex.getMessage();
+                }                                                    
+            }
+            
+            public JSONObject convertResultToWQM5Input( String AoAId, Boolean aoa_comp_drained ){
+                JSONObject wqm5 = new JSONObject();
+                JSONObject metainfo = new JSONObject();
+                JSONArray headerArray = new JSONArray();
+                JSONArray soilsArray = new JSONArray();
                 
+                try{
+                //Put in necessary top level stuff here first
+                    metainfo.put( "MultipartRequest", "Bundled Service Request WQM-21");
+                    metainfo.put( "OriginalSource", getRequestHost() );
+                    metainfo.put( "OriginalRequest", getRequestURL() );
+                    metainfo.put( "OriginalSUID", getSUID() );
+                    wqm5.put("metainfo", metainfo );                     
+                    headerArray.put(JSONUtils.dataDesc("AoAId", AoAId, "Area of Analysis Identifier" ));
                 
+                    //Fill in all component data
+                    for ( V1_0.wqm_21.wqm2SoilComponent component : this.components ){
+                        soilsArray.put(component.getWQM5Array());
+                    }
+                    
+                    headerArray.put( JSONUtils.dataDesc("soilcomponents", soilsArray, null) );                    
+                    wqm5.put( "parameter", headerArray );                
+                }
+                catch( JSONException ex ){
+                    this.error_msg += " Cannot convert WQM-02 result to WQM-05 input: " + ex.getMessage();
+                }
                 
+                return wqm5;
             }
             
             public String getErrorMsg(){return this.error_msg;}
             public Boolean getError(){return !this.error_msg.isEmpty();}
         }
         
+        class wqm_5Result{
+            private final HashMap<String, V1_0.wqm_21.finalSoilComponent>finalComponentMap;
+            private final ArrayList<V1_0.wqm_21.finalSoilComponent> finalComponents;
+            private String error_msg;
+            private String aoa_nslp;
+            
+            wqm_5Result( JSONObject result ){
+                this.finalComponentMap = new HashMap<>();
+                finalComponents = new ArrayList<>();
+                this.error_msg = "";
+                this.aoa_nslp = "Error";
+                
+                if ( null != result ){
+
+                    try{
+                        JSONArray resultArray = result.getJSONArray("result");  
+                        Map<String, JSONObject> topLevel = JSONUtils.preprocess( resultArray );
+                        this.aoa_nslp = topLevel.get("aoa_nslp").getString("value");
+                                      
+                        JSONArray soils = topLevel.get("soil_components").getJSONArray("value");
+
+                        //  for each array in this result...build a list of components.
+                        if ( soils.length() > 0 ){
+                            for( int i = 0; i < soils.length(); i++){
+                                V1_0.wqm_21.finalSoilComponent tComponent;       
+                                Map<String, JSONObject> soilComponent;
+                                String cokey;
+                                String comp_nslp;
+                                JSONArray componentData = soils.getJSONObject(i).getJSONArray("value"); //Value of "soil_component"
+                                soilComponent = JSONUtils.preprocess( componentData );
+                                cokey = JSONUtils.getStringParam( soilComponent,"cokey", "Error" );
+                                comp_nslp = JSONUtils.getStringParam( soilComponent,"comp_nslp", "Error" );
+                                                                        
+                                tComponent = new V1_0.wqm_21.finalSoilComponent( cokey );  
+                                tComponent.setCompNSLP( comp_nslp );
+                                this.finalComponents.add( tComponent );
+                                if ( !this.finalComponentMap.containsKey(cokey) ){
+                                    this.finalComponentMap.put( cokey, tComponent );
+                                }
+                                else{
+                                    //We've got a real problem if this ever happens
+                                    this.error_msg = " Duplicate soil component keys found in WQM-05 output results.  Cannot proceed. ";
+                                    break;
+                                }
+                            }
+                        } 
+                        else{
+                            this.error_msg += " There was no return result from the WQM-05 service. ";
+                        }                   
+                    }
+                    catch( JSONException ex ){
+                        this.error_msg += " Error parsing returned data from the WQM-05 service: " + ex.getMessage();
+                    }                                                                                                      
+                }
+                else{
+                    this.error_msg = " WQM-05 service results are empty. ";
+                }
+            }
+            
+            public HashMap<String, V1_0.wqm_21.finalSoilComponent>getFinalComponentMap(){return this.finalComponentMap;}
+            public ArrayList<V1_0.wqm_21.finalSoilComponent> getFinalComponentList(){ return this.finalComponents; }
+            public String getAoaNSLP(){ return this.aoa_nslp;}
+            public Boolean getError(){return !this.error_msg.isEmpty();}
+            public String getErrorMsg(){return this.error_msg;}
+        }   
         
-        class SoilComponent{
-            private String cokey;
-            private String compname;
-            private double aoa_comp_area;
-            private String aoa_comp_hsg;
-            private String aoa_comp_taxorder;
-            private double aoa_comp_kfact;
-            private double aoa_comp_slope;
-            private int aoa_comp_coarse_frag;
-            private double aoa_comp_om; 
-            private double aoa_comp_hzdepth;
-            private boolean aoa_comp_cracksgr24;
-            private boolean aoa_comp_slopegr15;
-            private boolean aoa_comp_hwt_lt_24;   
+        class wqm_6Result{
+            private String error_msg;
+            private String aoa_srp;
+            
+            wqm_6Result( JSONObject result, HashMap<String, V1_0.wqm_21.finalSoilComponent>finalComponentMap ){
+                this.error_msg = "";
+                this.aoa_srp = "Error";
+                
+                if ( null != result ){
+                    if ( !finalComponentMap.isEmpty() ){
+                        try{
+                            JSONArray resultArray = result.getJSONArray("result");  
+                            Map<String, JSONObject> topLevel = JSONUtils.preprocess( resultArray );
+                            this.aoa_srp = topLevel.get("aoa_srp").getString("value");
+                                      
+                            JSONArray soils = topLevel.get("soil_components").getJSONArray("value");           
+
+
+                            //  for each array in this result...build a list of components.
+                            if ( soils.length() > 0 ){
+                                for( int i = 0; i < soils.length(); i++){
+                                    V1_0.wqm_21.finalSoilComponent tComponent;       
+                                    Map<String, JSONObject> soilComponent;
+                                    String cokey;
+                                    String comp_srp;
+                                    JSONArray componentData = soils.getJSONObject(i).getJSONArray("value"); //Value of "soil_component"
+                                    soilComponent = JSONUtils.preprocess( componentData );
+                                    cokey = JSONUtils.getStringParam( soilComponent,"cokey", "Error" );
+                                    comp_srp = JSONUtils.getStringParam( soilComponent,"comp_srp", "Error" );
+
+                                    tComponent = finalComponentMap.get( cokey );
+                                    
+                                    if ( null != tComponent ){
+                                        tComponent.setCompSRP( comp_srp );
+                                    }
+                                    else{
+                                        //We've got a real problem if this ever happens
+                                        this.error_msg = " WQM-06 result parsing:  Cannot locate this soil component key in the WQM-05 output results.  Cannot proceed. ";
+                                        break;
+                                    }
+                                }
+                            } 
+                            else{
+                                this.error_msg += " There was no return result from the WQM-06 service. ";
+                            }                   
+                        }
+                        catch( JSONException ex ){
+                            this.error_msg += " Error parsing returned data from the WQM-06 service: " + ex.getMessage();
+                        }                                                                         
+                    }
+                    else{
+                        this.error_msg = " Cannot merge WQM-06 results with WQM-05 results.  Empty component map. ";
+                    }
+                }
+                else{
+                    this.error_msg = " WQM-06 service results are empty. ";
+                }
+            } 
+            
+            public String getAoaSRP(){ return this.aoa_srp;}
+            public Boolean getError(){return !this.error_msg.isEmpty();}
+            public String getErrorMsg(){return this.error_msg;}                        
+        }   
+        
+        class finalSoilComponent{
+            private final String cokey;
+            private String comp_nslp;
+            private String comp_srp;
+            
+            finalSoilComponent( String cokey ){
+                this.cokey = cokey;
+                this.comp_nslp = "Error";
+                this.comp_srp = "Error";
+            }
+            
+            public void setCompNSLP( String comp_nslp ){
+                this.comp_nslp = comp_nslp;
+            }
+            
+            public void setCompSRP( String comp_srp ){
+                this.comp_srp = comp_srp;
+            }
+            
+            public String getCompNSLP(){return this.comp_nslp;}
+            public String getCompSRP(){return this.comp_srp;}
+            public String getCokey(){return this.cokey;}
+            public JSONObject getJSONCompNSLP() throws JSONException{return JSONUtils.dataDesc("comp_nslp", this.comp_nslp, "Soil leaching potential of the soil component" );}
+            public JSONObject getJSONCompSRP() throws JSONException{return JSONUtils.dataDesc("comp_srp", this.comp_srp, "Soil runoff potential for soil component" );}
+            public JSONObject getJSONCokey() throws JSONException{return JSONUtils.dataDesc("cokey", this.cokey, "Soil component key" );}            
+        }
+        
+        class wqm2SoilComponent{            
+            private JSONArray orignalResult;
+            private JSONArray newResult;            
             
             private String error_msg = "";
             
-            SoilComponent( JSONArray soilComponent ){                
+            wqm2SoilComponent( JSONArray soilComponent ){    
+                this.orignalResult = soilComponent;
+                
                 try{
-                    Map<String, JSONObject> componentData = JSONUtils.preprocess( soilComponent );
-                    
-                    this.cokey =                JSONUtils.getStringParam(componentData,"cokey","err");
-                    this.compname =             JSONUtils.getStringParam(componentData,"compname","err");
-                    this.aoa_comp_area =        JSONUtils.getDoubleParam(componentData,"aoa_comp_area",0.0);
-                    this.aoa_comp_hsg =         JSONUtils.getStringParam(componentData,"aoa_comp_hsg","err");                    
-                    this.aoa_comp_taxorder =    JSONUtils.getStringParam(componentData,"aoa_comp_taxorder","err");
-                    this.aoa_comp_kfact =       JSONUtils.getDoubleParam(componentData,"aoa_comp_kfact",0.0);                    
-                    this.aoa_comp_slope =       JSONUtils.getDoubleParam(componentData,"aoa_comp_slope",0.0);
-                    this.aoa_comp_coarse_frag = JSONUtils.getIntParam(componentData,"aoa_comp_coarse_frag",0);
-                    this.aoa_comp_om =          JSONUtils.getDoubleParam(componentData,"aoa_comp_om",0.0);
-                    this.aoa_comp_hzdepth =     JSONUtils.getDoubleParam(componentData,"aoa_comp_hzdepth",0.0);                    
-                    this.aoa_comp_cracksgr24 =  JSONUtils.getBooleanParam(componentData,"aoa_comp_cracksgr24",false);
-                    this.aoa_comp_slopegr15 =   JSONUtils.getBooleanParam(componentData,"aoa_comp_slopegr15",false);                      
-                    this.aoa_comp_hwt_lt_24 =   JSONUtils.getBooleanParam(componentData,"aoa_comp_hwt_lt_24",false);  
-                    
+                    this.newResult = new JSONArray( soilComponent.toString() );
+                    this.newResult.put(JSONUtils.dataDesc("aoa_comp_drained", aoa_comp_drained, "Soil Component Key"));                    
                 }
-                catch( Exception ex ){
+                catch( JSONException ex ){
                     this.error_msg = ex.getMessage();
-                    //Fill-in the values with defaults 
-                    this.cokey = "err";
-                    this.compname = "err";
-                    this.aoa_comp_area = 0.0;
-                    this.aoa_comp_hsg = "err";
-                    this.aoa_comp_taxorder = "err";
-                    this.aoa_comp_kfact = 0.0;
-                    this.aoa_comp_slope = 0.0;
-                    this.aoa_comp_coarse_frag = 0;
-                    this.aoa_comp_om = 0.0; 
-                    this.aoa_comp_hzdepth = 0.0;
-                    this.aoa_comp_cracksgr24 = false;
-                    this.aoa_comp_slopegr15 = false;
-                    this.aoa_comp_hwt_lt_24 = false;                      
                 }                                    
             }
+            
+            public JSONArray getWQM5Array(){ return this.newResult; }
+            public Boolean getError(){ return (!this.error_msg.isEmpty()); }
+            public String getErrorMsg(){ return this.error_msg; }
+            
         }
     }
     
@@ -304,12 +609,11 @@
         
         ServiceCall(){            
             this.error_msg = "";
-            this.newClient = new csip.Client();             
+            this.newClient = new csip.Client();              
         }
         
         public JSONObject getResult( String URI, JSONObject request ){
             JSONObject ret_val = null;
-            String testret_val = request.toString();
             
             try {               
                 ret_val = this.newClient.doPOST( URI, request );                 
@@ -340,13 +644,4 @@
         public String getErrorMsg(){return this.error_msg;}
         public Boolean getError(){return !this.error_msg.isEmpty();}
     }
-
-    
-    class Result{
-        Result(){
-            
-        }
-        
-    }
-
-}
+}
\ No newline at end of file

src/java/m/wqm/nuttechscores/V1_0.java

@@ -4,6 +4,7 @@
  *
  * @author SrinivasReddy kontham
  * @ update Rumpal Sidhu
+ * @ update Sandeep Kasavaraju
  */
 import csip.ModelDataService;
 import static csip.ModelDataService.EXEC_OK;
@@ -23,17 +24,6 @@
 @Path("m/nut_tech_scores/1.0")
 
 public class V1_0 extends ModelDataService {
-
-    //SQL params names here for quick modification
-    private final String USER = "postgres";
-    private final String PASS = "admin";
-    private final String HOST = "localhost";
-    private final String PORT = "5432";
-    private final String DBNAME = "wqm";
-    private final String JDBC_TYPE = "jdbc:postgresql://";
-    private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
-    private final String CLASS_NAME = "org.postgresql.Driver";
-
     private ArrayList<Input> components; // store the set of all input soilcomponents as objects
     private ArrayList<Result1> result1;  // store the result as objects
     private int aoaId;
@@ -47,8 +37,8 @@
             Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
             aoaId = JSONUtils.getIntParam(group, "AoAid", 0);
             int plan_techn_id = JSONUtils.getIntParam(group, "plan_techn_id", 0);
-            String plan_techn_discrim_type = JSONUtils.getStringParam(group, "plan_techn_discrim_type", "err");
-            String plan_techn_discrim = JSONUtils.getStringParam(group, "plan_techn_discrim", "err");
+            String plan_techn_discrim_type = JSONUtils.getStringParam(group, "plan_techn_discrim_type", "");
+            String plan_techn_discrim = JSONUtils.getStringParam(group, "plan_techn_discrim", "");
             Input input = new Input(aoaId, plan_techn_id, plan_techn_discrim_type, plan_techn_discrim);
             components.add(input);
         }
@@ -60,8 +50,7 @@
         Connection conn = null;
         Statement statement = null;
         try {
-            Class.forName(CLASS_NAME);
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
+            conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
             conn.setAutoCommit(false);
             statement = conn.createStatement();
 
@@ -79,73 +68,57 @@
             int psurf_trap_techn_score = 0;
 
             for (Input ip : components) {
-                String query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern ='Nitrogen in Ground Water';";
+                String query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ip.plan_techn_id+" AND wqm_concern='Nitrogen in Ground Water';";
                 ResultSet resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int techn_score = resultset.getInt("nut_tech_score");
                     nleach_techn_score += techn_score;
                 }
-
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id= " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action = 'Avoid';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id="+ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action ='Avoid';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int avoid_techn_score = resultset.getInt("nut_tech_score");
                     nleach_avoid_techn_score += avoid_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action = 'Control';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id="+ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action = 'Control';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int control_techn_score = resultset.getInt("nut_tech_score");
                     nleach_control_techn_score += control_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action = 'Trap';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Ground Water' AND mode_of_action = 'Trap';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int trap_techn_score = resultset.getInt("nut_tech_score");
-                    nleach_trap_techn_score += trap_techn_score;
+                nleach_trap_techn_score += trap_techn_score;
+      
                 }
 
                 //  #Compute nutrient technique mitigation scores for Nitrogen in Surface Water concern and increment total scores           
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Surface Water';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Surface Water';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int techn_score = resultset.getInt("nut_tech_score");
                     nsurf_techn_score += techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Surface Water' AND mode_of_action = 'Avoid';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Surface Water' AND mode_of_action = 'Avoid';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int avoid_techn_score = resultset.getInt("nut_tech_score");
                     nsurf_avoid_techn_score += avoid_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Surface Water' AND mode_of_action = 'Control';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Nitrogen in Surface Water' AND mode_of_action= 'Control';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int control_techn_score = resultset.getInt("nut_tech_score");
                     nsurf_control_techn_score += control_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Nitrogen in Surface Water' AND mode_of_action = 'Trap';";
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id = " + ip.plan_techn_id+ " AND wqm_concern= 'Nitrogen in Surface Water' AND mode_of_action= 'Trap';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int trap_techn_score = resultset.getInt("nut_tech_score");
@@ -153,38 +126,46 @@
                 }
 
                 //#Compute nutrient technique mitigation scores for Phosphorus in Surface Water concern and increment total scores            
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Phosphorous in Surface Water'"
-                        + " AND tech_discrim_type ='" + ip.plan_techn_discrim_type
-                        + "' AND tech_discrim = '" + ip.plan_techn_discrim + "';";
+                if(ip.plan_techn_discrim.isEmpty())
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water';";
+                else
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND tech_discrim_type ='"+ ip.plan_techn_discrim_type+"' AND tech_discrim ='"+ip.plan_techn_discrim+"' ;";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int techn_score = resultset.getInt("nut_tech_score");
                     psurf_techn_score += techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Avoid';";
+                if(ip.plan_techn_discrim.isEmpty())
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Avoid';";
+                else
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND tech_discrim_type ='"+ ip.plan_techn_discrim_type+"' AND tech_discrim ='"+ip.plan_techn_discrim+"' AND mode_of_action = 'Avoid';";
+               
+              //  query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id = " + ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Avoid';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int avoid_techn_score = resultset.getInt("nut_tech_score");
                     psurf_avoid_techn_score += avoid_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + "AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Control';";
+                if(ip.plan_techn_discrim.isEmpty())
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Control';";
+                else
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND tech_discrim_type ='"+ ip.plan_techn_discrim_type+"' AND tech_discrim ='"+ip.plan_techn_discrim+"' AND mode_of_action = 'Control';";
+               
+                //query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern ='Phosphorus in Surface Water' AND mode_of_action ='Control';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int control_techn_score = resultset.getInt("nut_tech_score");
                     psurf_control_techn_score += control_techn_score;
                 }
 
-                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores "
-                        + "WHERE nutrient_technique_id = " + ip.plan_techn_id
-                        + " AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Trap';";
+                if(ip.plan_techn_discrim.isEmpty())
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND mode_of_action = 'Trap';";
+                else
+                query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id ="+ ip.plan_techn_id+" AND wqm_concern = 'Phosphorus in Surface Water' AND tech_discrim_type ='"+ ip.plan_techn_discrim_type+"' AND tech_discrim ='"+ip.plan_techn_discrim+"' AND mode_of_action = 'Trap';";
+               
+                // query = "SELECT nut_tech_score FROM wqm_nutrient_technique_scores WHERE nutrient_technique_id =" +ip.plan_techn_id+" AND wqm_concern ='Phosphorus in Surface Water' AND mode_of_action ='Trap';";
                 resultset = statement.executeQuery(query);
                 while (resultset.next()) {
                     int trap_techn_score = resultset.getInt("nut_tech_score");
@@ -195,7 +176,7 @@
             result1.add(result);
 
         } catch (SQLException se) {
-            LOG.info("Did not open database for WQM-4!");
+            LOG.info("Did not open database for WQM-14");
             LOG.info(se.getMessage());
         } finally {
             if (statement != null) {

src/java/m/wqm/nuttechscores/V1_0.json

@@ -26,116 +26,6 @@
                         "value": "",
                         "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
                     }
-                ],
-                [
-                    {
-                        "name": "AoAid",
-                        "value": 1,
-                        "Description": "Area of Analysis Identifier"
-                    },
-                    {
-                        "name": "plan_techn_id",
-                        "value": 5,
-                        "Description": "nutrient management technique identifier corresponding to nutrient_technique_score_id value in WQM data mart"
-                    },
-                    {
-                        "name": "plan_techn_discrim_type",
-                        "value": "",
-                        "Description": "type of discriminator for varying nutrient management technique scores; value is “soil test result” otherwise NULL"
-                    },
-                    {
-                        "name": "plan_techn_discrim",
-                        "value": "",
-                        "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAid",
-                        "value": 1,
-                        "Description": "Area of Analysis Identifier"
-                    },
-                    {
-                        "name": "plan_techn_id",
-                        "value": 8,
-                        "Description": "nutrient management technique identifier corresponding to nutrient_technique_score_id value in WQM data mart"
-                    },
-                    {
-                        "name": "plan_techn_discrim_type",
-                        "value": "Soil test result",
-                        "Description": "type of discriminator for varying nutrient management technique scores; value is “soil test result” otherwise NULL"
-                    },
-                    {
-                        "name": "plan_techn_discrim",
-                        "value": "Medium",
-                        "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAid",
-                        "value": 1,
-                        "Description": "Area of Analysis Identifier"
-                    },
-                    {
-                        "name": "plan_techn_id",
-                        "value": 14,
-                        "Description": "nutrient management technique identifier corresponding to nutrient_technique_score_id value in WQM data mart"
-                    },
-                    {
-                        "name": "plan_techn_discrim_type",
-                        "value": "",
-                        "Description": "type of discriminator for varying nutrient management technique scores; value is “soil test result” otherwise NULL"
-                    },
-                    {
-                        "name": "plan_techn_discrim",
-                        "value": "",
-                        "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAid",
-                        "value": 1,
-                        "Description": "Area of Analysis Identifier"
-                    },
-                    {
-                        "name": "plan_techn_id",
-                        "value": 2,
-                        "Description": "nutrient management technique identifier corresponding to nutrient_technique_score_id value in WQM data mart"
-                    },
-                    {
-                        "name": "plan_techn_discrim_type",
-                        "value": "",
-                        "Description": "type of discriminator for varying nutrient management technique scores; value is “soil test result” otherwise NULL"
-                    },
-                    {
-                        "name": "plan_techn_discrim",
-                        "value": "",
-                        "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAid",
-                        "value": 1,
-                        "Description": "Area of Analysis Identifier"
-                    },
-                    {
-                        "name": "plan_techn_id",
-                        "value": 9,
-                        "Description": "nutrient management technique identifier corresponding to nutrient_technique_score_id value in WQM data mart"
-                    },
-                    {
-                        "name": "plan_techn_discrim_type",
-                        "value": "",
-                        "Description": "type of discriminator for varying nutrient management technique scores; value is “soil test result” otherwise NULL"
-                    },
-                    {
-                        "name": "plan_techn_discrim",
-                        "value": "",
-                        "Description": "value of the discriminator:  HIGH,MEDIUM, LOW, NO SOIL TEST"
-                    }
                 ]
             ]
         }

src/java/m/wqm/pesthazrating/V1_0.java

@@ -6,20 +6,25 @@
 package m.wqm.pesthazrating;
 import csip.ModelDataService;
 import static csip.ModelDataService.EXEC_OK;
+import csip.ServiceException;
+import csip.utils.JSONUtils;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.Map;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
 import oms3.annotations.Name;
 import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
-import csip.utils.JSONUtils;
-import java.util.Map;
-import java.sql.*;
-import java.util.concurrent.*;
 
 /**
  *
- * @ Srinivas
+ * @author  Srinivas
+ * @author Shaun Case
  */
 @Name("WQM-11: Pesticide Hazard Ratings (PestHazRating)")
 @Description("This service computes pesticide hazard ratings for leaching, solution runoff, and adsorbed runoff for each pesticide applied in an area of analysis, and then computes hazard ratings for each concern representing the area of analysis (AoA). The service consumes soil/pesticide interaction loss potentials from the WQM-10 service to compute the hazard ratings, which are used later by the WQM-13 service to compute mitigation threshold scores.")
@@ -28,177 +33,211 @@
 public class V1_0 extends ModelDataService{
     
   
-    ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
-    ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
-    String aoa_phr_leach_human="";
-    String aoa_phr_leach_matcfish="";
-    String aoa_phr_sorun_human="";
-    String aoa_phr_sorun_matcfish="";
-    String aoa_phr_adrun_human="";
-    String aoa_phr_adrun_stvfish="";
+    private ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
+    private ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
+    private String aoa_phr_leach_human;
+    private String aoa_phr_leach_matcfish;
+    private String aoa_phr_sorun_human;
+    private String aoa_phr_sorun_matcfish;
+    private String aoa_phr_adrun_human;
+    private String aoa_phr_adrun_stvfish;
+    
+    private String error_msg;
+    private Connection conn;
+    private Statement statement;
+    
     
     @Override
         // reading the inputs from the json file into input object and placing it in the arraylist
         protected void preProcess() throws Exception {
-        JSONArray groups = getJSONArrayParam("pestcomponents");
-            for(int i=0;i<groups.length();i++)
-            {
-                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
+            this.aoa_phr_leach_human="";
+            this.aoa_phr_leach_matcfish="";
+            this.aoa_phr_sorun_human="";
+            this.aoa_phr_sorun_matcfish="";
+            this.aoa_phr_adrun_human="";
+            this.aoa_phr_adrun_stvfish="";            
+            this.error_msg = "";
+            
+            this.components=new ArrayList<>(); 
+            this.result1=new ArrayList<>();  
+            this.conn = null;
+            this.statement = null;
+            
+            try{
+                JSONArray groups = getJSONArrayParam("pestcomponents");
+                for(int i=0;i<groups.length();i++)
+                {
+                    Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
 
-                
-                int operation_id = JSONUtils.getIntParam(group, "operation_id", 0);
-                String op_pest_id=JSONUtils.getStringParam(group,"op_pest_id","err");
-                String op_pest_ilp=JSONUtils.getStringParam(group,"op_pest_ilp","err");
-                String op_pest_isrp=JSONUtils.getStringParam(group,"op_pest_isrp","err");
-                String op_pest_iarp=JSONUtils.getStringParam(group,"op_pest_iarp","err");
-                double ai_eathuman=JSONUtils.getDoubleParam(group,"ai_eathuman",0);
-                double ai_eatmatc=JSONUtils.getDoubleParam(group,"ai_eatmatc",0);
-                double ai_koc=JSONUtils.getDoubleParam(group,"ai_koc",0);
-                
-                Input input=new Input(operation_id,op_pest_id,op_pest_ilp,op_pest_isrp,op_pest_iarp,ai_eathuman,ai_eatmatc,ai_koc);
-        components.add(input);
+                    int operation_id = JSONUtils.getIntParam(group, "operation_id", 0);
+                    String op_pest_id=JSONUtils.getStringParam(group,"op_pest_id","err");
+                    String op_pest_ilp=JSONUtils.getStringParam(group,"op_pest_ilp","err");
+                    String op_pest_isrp=JSONUtils.getStringParam(group,"op_pest_isrp","err");
+                    String op_pest_iarp=JSONUtils.getStringParam(group,"op_pest_iarp","err");
+                    double ai_eathuman=JSONUtils.getDoubleParam(group,"ai_eathuman",0);
+                    double ai_eatmatc=JSONUtils.getDoubleParam(group,"ai_eatmatc",0);
+                    double ai_koc=JSONUtils.getDoubleParam(group,"ai_koc",0);
+
+                    Input input=new Input(operation_id,op_pest_id,op_pest_ilp,op_pest_isrp,op_pest_iarp,ai_eathuman,ai_eatmatc,ai_koc);
+                    components.add(input);
+                }
             }
+            catch( ServiceException | JSONException ex ){
+                this.error_msg = "Cannot read input JSON: " + ex.getMessage();
+                LOG.warning( this.error_msg );
+            }            
         }
+        
 
     @Override
-        protected String process() throws Exception
+        protected String process() 
         {
             String eat_rating_human=null;
-            
-            for(Input ip:components)
-            {
-                if(ip.ai_eathuman<1)
-                {
-                    eat_rating_human="EXTRA HIGH";
+            if ( this.error_msg.isEmpty() ){            
+                try{
+                    conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
+                    statement = conn.createStatement();                    
+                    
+                    for(Input ip:components){                    
+                        if(ip.ai_eathuman<1)
+                        {
+                            eat_rating_human="EXTRA HIGH";
+                        }
+                        else if(ip.ai_eathuman>=1 && ip.ai_eathuman<10)
+                        {
+                            eat_rating_human="HIGH";
+                        }
+                        else if(ip.ai_eathuman>=10 && ip.ai_eathuman<50)
+                        {
+                            eat_rating_human="INTERMEDIATE";
+                        }
+                        else if(ip.ai_eathuman>=50 && ip.ai_eathuman<100)
+                        {
+                            eat_rating_human="LOW";
+                        }
+                        else if(ip.ai_eathuman>=100)
+                        {
+                            eat_rating_human="VERY LOW";
+                        }
+
+                        String eat_rating_human_temp="'"+eat_rating_human+"'";
+                        String op_pest_ilp_temp="'"+ip.op_pest_ilp+"'";
+                        String query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_ilp_temp+"AND wqm_eat="+ eat_rating_human_temp;
+                        String op_phr_leach_human="";
+                        ResultSet results = statement.executeQuery(query);
+                        while(results.next())
+                        {
+                            op_phr_leach_human=results.getString("wqm_phr");
+                        }
+                        String op_pest_isrp_temp="'"+ip.op_pest_isrp+"'";
+                        query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_isrp_temp+"AND wqm_eat="+ eat_rating_human_temp; 
+                        results = statement.executeQuery(query);
+                        String op_phr_sorun_human="";
+                        while(results.next())
+                        {
+                             op_phr_sorun_human=results.getString("wqm_phr");
+                        }
+                       String op_pest_iarp_temp="'"+ip.op_pest_iarp+"'";
+                        query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_iarp_temp+"AND wqm_eat="+ eat_rating_human_temp;
+                        results = statement.executeQuery(query);
+                        String op_phr_adrun_human="";
+                        while(results.next())
+                        {
+                            op_phr_adrun_human=results.getString("wqm_phr");
+                        }
+                        // #Compute pesticide hazard rating for adsorbed runoff adjusted for toxicity to fish (STV)
+
+                        double ai_eatstv=ip.ai_eatmatc*ip.ai_koc;
+                        String eat_rating_stvfish=null;
+                        if(ai_eatstv<10)
+                        {
+                            eat_rating_stvfish="EXTRA HIGH";
+                        }
+                        else if(ai_eatstv>=10 && ai_eatstv<100)
+                        {
+                            eat_rating_stvfish="HIGH";
+                        }
+                        else if(ai_eatstv>=100 && ai_eatstv<1500)
+                        {
+                            eat_rating_stvfish="INTERMEDIATE";
+                        }
+                        else if(ai_eatstv>=1500 && ai_eatstv<20000)
+                        {
+                            eat_rating_stvfish="LOW";
+                        }
+                        else if(ai_eatstv>=20000)
+                        {
+                            eat_rating_stvfish="VERY LOW";
+                        }
+                        String eat_rating_stvfish_temp="'"+eat_rating_stvfish+"'";
+            //            String op_pest_iarp_temp="'"+ip.op_pest_iarp+"'";
+                        query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_iarp_temp+"AND wqm_eat="+ eat_rating_stvfish_temp;
+                        results = statement.executeQuery(query);
+                        String op_phr_adrun_stvfish="";
+                        while(results.next())
+                        {
+                            op_phr_adrun_stvfish=results.getString("wqm_phr");
+                        }
+
+        // Compute pesticide hazard rating for leaching, solution runoff, and adsorbed runoff adjusted for toxicity to fish (MATC)      
+                        String eat_rating_matcfish=null;
+                        if(ip.ai_eatmatc<10)
+                        {
+                            eat_rating_matcfish="EXTRA HIGH";
+                        }
+                        else if(ip.ai_eatmatc>=10 && ip.ai_eatmatc<100)
+                        {  
+                            eat_rating_matcfish="HIGH";
+                        }
+                        else if(ip.ai_eatmatc>=100 && ip.ai_eatmatc<1500)
+                        {
+                            eat_rating_matcfish="INTERMEDIATE";
+                        }
+                        else if(ip.ai_eatmatc>=1500 && ip.ai_eatmatc<20000)
+                        {
+                            eat_rating_matcfish="LOW";
+                        }
+                        else if(ip.ai_eatmatc>=20000)
+                        {
+                            eat_rating_matcfish="VERY LOW";
+                        }
+                        String eat_rating_matcfish_temp="'"+eat_rating_matcfish+"'";
+                        query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_ilp_temp+"AND wqm_eat="+ eat_rating_matcfish_temp;
+                        results = statement.executeQuery(query);
+                        String op_phr_leach_matcfish="";
+                        while(results.next())
+                        {
+                            op_phr_leach_matcfish=results.getString("wqm_phr");
+                        }             
+                        query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_isrp_temp+"AND wqm_eat="+ eat_rating_matcfish_temp;
+                        results = statement.executeQuery(query);
+                        String op_phr_sorun_matcfish="";
+                        while(results.next())
+                        {
+                            op_phr_sorun_matcfish=results.getString("wqm_phr");
+                        }
+                        Result1 res1=new Result1(ip.operation_id,ip.op_pest_id,op_phr_leach_human,op_phr_leach_matcfish,op_phr_sorun_human,op_phr_sorun_matcfish,op_phr_adrun_human,op_phr_adrun_stvfish);
+                        result1.add(res1);                        
+                    }   
+                    
+                    calAoANutSLP(result1); 
                 }
-                else if(ip.ai_eathuman>=1 && ip.ai_eathuman<10)
-                {
-                    eat_rating_human="HIGH";
-                }
-                else if(ip.ai_eathuman>=10 && ip.ai_eathuman<50)
-                {
-                    eat_rating_human="INTERMEDIATE";
-                }
-                else if(ip.ai_eathuman>=50 && ip.ai_eathuman<100)
-                {
-                    eat_rating_human="LOW";
-                }
-                else if(ip.ai_eathuman>=100)
-                {
-                    eat_rating_human="VERY LOW";
-                }
-                Connection conn = null;
-                Statement statement = null;
-                Class.forName("org.postgresql.Driver");
-                conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/wqm", "postgres", "admin");
-                conn.setAutoCommit(false);
-                statement = conn.createStatement();
-                String eat_rating_human_temp="'"+eat_rating_human+"'";
-                String op_pest_ilp_temp="'"+ip.op_pest_ilp+"'";
-                String query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_ilp_temp+"AND wqm_eat="+ eat_rating_human_temp;
-                String op_phr_leach_human="";
-                ResultSet results = statement.executeQuery(query);
-                while(results.next())
-                {
-                    op_phr_leach_human=results.getString("wqm_phr");
-                }
-                String op_pest_isrp_temp="'"+ip.op_pest_isrp+"'";
-                query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_isrp_temp+"AND wqm_eat="+ eat_rating_human_temp; 
-                results = statement.executeQuery(query);
-                String op_phr_sorun_human="";
-                while(results.next())
-                {
-                     op_phr_sorun_human=results.getString("wqm_phr");
-                }
-               String op_pest_iarp_temp="'"+ip.op_pest_iarp+"'";
-                query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_iarp_temp+"AND wqm_eat="+ eat_rating_human_temp;
-                results = statement.executeQuery(query);
-                String op_phr_adrun_human="";
-                while(results.next())
-                {
-                    op_phr_adrun_human=results.getString("wqm_phr");
-                }
-                // #Compute pesticide hazard rating for adsorbed runoff adjusted for toxicity to fish (STV)
-                
-                double ai_eatstv=ip.ai_eatmatc*ip.ai_koc;
-                String eat_rating_stvfish=null;
-                if(ai_eatstv<10)
-                {
-                    eat_rating_stvfish="EXTRA HIGH";
-                }
-                else if(ai_eatstv>=10 && ai_eatstv<100)
-                {
-                    eat_rating_stvfish="HIGH";
-                }
-                else if(ai_eatstv>=100 && ai_eatstv<1500)
-                {
-                    eat_rating_stvfish="INTERMEDIATE";
-                }
-                else if(ai_eatstv>=1500 && ai_eatstv<20000)
-                {
-                    eat_rating_stvfish="LOW";
-                }
-                else if(ai_eatstv>=20000)
-                {
-                    eat_rating_stvfish="VERY LOW";
-                }
-                String eat_rating_stvfish_temp="'"+eat_rating_stvfish+"'";
-    //            String op_pest_iarp_temp="'"+ip.op_pest_iarp+"'";
-                query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_iarp_temp+"AND wqm_eat="+ eat_rating_stvfish_temp;
-                results = statement.executeQuery(query);
-                String op_phr_adrun_stvfish="";
-                while(results.next())
-                {
-                    op_phr_adrun_stvfish=results.getString("wqm_phr");
+                catch( ServiceException | SQLException ex ){
+                    this.error_msg = "Cannot process your request: " + ex.getMessage();
+                    LOG.warning( this.error_msg );
                 }
                 
-// Compute pesticide hazard rating for leaching, solution runoff, and adsorbed runoff adjusted for toxicity to fish (MATC)      
-                String eat_rating_matcfish=null;
-                if(ip.ai_eatmatc<10)
-                {
-                    eat_rating_matcfish="EXTRA HIGH";
-                }
-                else if(ip.ai_eatmatc>=10 && ip.ai_eatmatc<100)
-                {  
-                    eat_rating_matcfish="HIGH";
-                }
-                else if(ip.ai_eatmatc>=100 && ip.ai_eatmatc<1500)
-                {
-                    eat_rating_matcfish="INTERMEDIATE";
-                }
-                else if(ip.ai_eatmatc>=1500 && ip.ai_eatmatc<20000)
-                {
-                    eat_rating_matcfish="LOW";
-                }
-                else if(ip.ai_eatmatc>=20000)
-                {
-                    eat_rating_matcfish="VERY LOW";
-                }
-                String eat_rating_matcfish_temp="'"+eat_rating_matcfish+"'";
-                query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_ilp_temp+"AND wqm_eat="+ eat_rating_matcfish_temp;
-                results = statement.executeQuery(query);
-                String op_phr_leach_matcfish="";
-                while(results.next())
-                {
-                    op_phr_leach_matcfish=results.getString("wqm_phr");
-                }             
-                query="SELECT wqm_phr FROM wqm_pesticide_hazard_potential WHERE wqm_ilr="+op_pest_isrp_temp+"AND wqm_eat="+ eat_rating_matcfish_temp;
-                results = statement.executeQuery(query);
-                String op_phr_sorun_matcfish="";
-                while(results.next())
-                {
-                    op_phr_sorun_matcfish=results.getString("wqm_phr");
-                }
-                Result1 res1=new Result1(ip.operation_id,ip.op_pest_id,op_phr_leach_human,op_phr_leach_matcfish,op_phr_sorun_human,op_phr_sorun_matcfish,op_phr_adrun_human,op_phr_adrun_stvfish);
-                result1.add(res1);
-            }   
-        calAoANutSLP(result1);    
-        return EXEC_OK;       
+
+            }
+        
+        return ( this.error_msg.isEmpty()? EXEC_OK : this.error_msg );       
     }
     @Override
     //writing the results back to JSON
     protected void postProcess() throws Exception 
     {
+        if ( this.error_msg.isEmpty() ){
+            try{
                 JSONArray result1Arr = new JSONArray();
                 for(Result1 rs1:result1)
                 {
@@ -213,6 +252,7 @@
                     tmpArr.put(JSONUtils.dataDesc("op_phr_adrun_stvfish", rs1.op_phr_adrun_stvfish, "Farm Operation Pesticide Adsorbed Runoff Hazard Rating - Fish"));
                     result1Arr.put(JSONUtils.dataDesc("pesticide summary", tmpArr, "Pesticide Summary"));
                 }
+
                 putResult("operation", result1Arr);
                 putResult("aoa_phr_leach_human",aoa_phr_leach_human,"Pesticide Leaching Hazard Rating for Humans in the Area of Analysis");
                 putResult("aoa_phr_leach_matcfish",aoa_phr_leach_matcfish,"Pesticide Leaching Hazard Rating for Fish in the Area of Analysis");
@@ -220,7 +260,15 @@
                 putResult("aoa_phr_sorun_matcfish",aoa_phr_sorun_matcfish,"Pesticide Solution Runoff Hazard Rating for Fish in the Area of Analysis");
                 putResult("aoa_phr_adrun_human",aoa_phr_adrun_human,"Pesticide Adsorbed Runoff Hazard Rating for Humans in the Area of Analysis");
                 putResult("aoa_phr_adrun_stvfish",aoa_phr_adrun_stvfish,"Pesticide Adsorbed Runoff Hazard Rating for Fish in the Area of Analysis");   
+            }
+            catch (JSONException ex )
+            {
+                this.error_msg = "Cannot create output JSON: " + ex.getMessage();
+                LOG.warning( this.error_msg );
+            }
+        }
     }               
+    
     // calculate the aoa_nslp 
     void calAoANutSLP(ArrayList<Result1> source)
     {
@@ -235,25 +283,22 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_leach_human.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=5;
-            }
-            else if(rs1.op_phr_leach_human.equals("HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_leach_human.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_leach_human.equals("LOW"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_leach_human.equals("VERY LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_leach_human) {
+                case "EXTRA HIGH":
+                    phr_leach_new=5;
+                    break;
+                case "HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=3;
+                    break;
+                case "LOW":
+                    phr_leach_new=2;
+                    break;
+                case "VERY LOW":
+                    phr_leach_new=1;
+                    break;
             }
             if(phr_leach_new>phr_leach_high)
             {
@@ -261,7 +306,7 @@
             }
         }
         
-        String aoa_phr_leach_array[]={"","LOW","INTERMEDIATE","HIGH","EXTRA HIGH"};
+        String aoa_phr_leach_array[]={"","VERY LOW","LOW","INTERMEDIATE","HIGH","EXTRA HIGH"};
         aoa_phr_leach_human=aoa_phr_leach_array[phr_leach_high];
         
         phr_leach_new=1;
@@ -270,25 +315,22 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_leach_matcfish.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=5;
-            }
-            else if(rs1.op_phr_leach_matcfish.equals("HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_leach_matcfish.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_leach_matcfish.equals("LOW"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_leach_matcfish.equals("VERY LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_leach_matcfish) {
+                case "EXTRA HIGH":
+                    phr_leach_new=5;
+                    break;
+                case "HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=3;
+                    break;
+                case "LOW":
+                    phr_leach_new=2;
+                    break;
+                case "VERY LOW":
+                    phr_leach_new=1;
+                    break;
             }
             if(phr_leach_new>phr_leach_high)
             {
@@ -304,21 +346,19 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_sorun_human.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_sorun_human.equals("HIGH"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_sorun_human.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_sorun_human.equals("LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_sorun_human) {
+                case "EXTRA HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "HIGH":
+                    phr_leach_new=3;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=2;
+                    break;
+                case "LOW":
+                    phr_leach_new=1;
+                    break;
             }
             
             if(phr_leach_new>phr_leach_high)
@@ -335,21 +375,19 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_sorun_matcfish.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_sorun_matcfish.equals("HIGH"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_sorun_matcfish.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_sorun_matcfish.equals("LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_sorun_matcfish) {
+                case "EXTRA HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "HIGH":
+                    phr_leach_new=3;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=2;
+                    break;
+                case "LOW":
+                    phr_leach_new=1;
+                    break;
             }
             
             if(phr_leach_new>phr_leach_high)
@@ -366,21 +404,19 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_adrun_human.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_adrun_human.equals("HIGH"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_adrun_human.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_adrun_human.equals("LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_adrun_human) {
+                case "EXTRA HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "HIGH":
+                    phr_leach_new=3;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=2;
+                    break;
+                case "LOW":
+                    phr_leach_new=1;
+                    break;
             }
             
             if(phr_leach_new>phr_leach_high)
@@ -397,21 +433,19 @@
         
         for(Result1 rs1:source)
         {
-            if(rs1.op_phr_adrun_stvfish.equals("EXTRA HIGH"))
-            {
-                phr_leach_new=4;
-            }
-            else if(rs1.op_phr_adrun_stvfish.equals("HIGH"))
-            {
-                phr_leach_new=3;
-            }
-            else if(rs1.op_phr_adrun_stvfish.equals("INTERMEDIATE"))
-            {
-                phr_leach_new=2;
-            }
-            else if(rs1.op_phr_adrun_stvfish.equals("LOW"))
-            {
-                phr_leach_new=1;
+            switch (rs1.op_phr_adrun_stvfish) {
+                case "EXTRA HIGH":
+                    phr_leach_new=4;
+                    break;
+                case "HIGH":
+                    phr_leach_new=3;
+                    break;
+                case "INTERMEDIATE":
+                    phr_leach_new=2;
+                    break;
+                case "LOW":
+                    phr_leach_new=1;
+                    break;
             }
             
             if(phr_leach_new>phr_leach_high)

src/java/m/wqm/pestlosspot/V1_0.java

@@ -27,6 +27,7 @@
 public class V1_0 extends ModelDataService {
 
     //SQL params names here for quick modification
+/*    
     private final String USER = "postgres";
     private final String PASS = "admin";
     private final String HOST = "localhost";
@@ -35,14 +36,22 @@
     private final String JDBC_TYPE = "jdbc:postgresql://";
     private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
     private final String CLASS_NAME = "org.postgresql.Driver";
-
+*/
+    private Connection conn;
+    private Statement statement;
+    
     //JSONArray getArray
     private ArrayList<Input> components; // store the set of all input soilcomponents as objects
     private ArrayList<Result1> result1;  // store the result as objects
 
+    
+    
     @Override
     // reading the inputs from the json file into input object and placing it in the arraylist
     protected void preProcess() throws Exception {
+        this.conn = null;
+        this.statement = null;
+        
         components = new ArrayList<>();
         JSONArray groups = getJSONArrayParam("pestcomponents");
         for (int i = 0; i < groups.length(); i++) {
@@ -61,11 +70,10 @@
     @Override
     protected String process() throws Exception {
         result1 = new ArrayList<>();
-        Connection conn = null;
-        Statement statement = null;
         try {
-            Class.forName(CLASS_NAME);
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
+            //Class.forName(CLASS_NAME);
+            //conn = DriverManager.getConnection(CONNECTION, USER, PASS);
+            conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
             conn.setAutoCommit(false);
             statement = conn.createStatement();
 
@@ -225,11 +233,13 @@
             LOG.info("Did not open database for WQM-4!");
             LOG.info(se.getMessage());
         } finally {
-            if (statement != null) {
-                statement.close();
+            if (this.statement != null) {
+                this.statement.close();
+                this.statement = null;
             }
-            if (conn != null) {
-                conn.close();
+            if (this.conn != null) {
+                this.conn.close();
+                this.conn = null;
             }
         }
         return EXEC_OK;

src/java/m/wqm/pestpractscores/V1_0.java

@@ -9,12 +9,12 @@
 import csip.ServiceException;
 import csip.utils.JSONUtils;
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.logging.Level;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
 import oms3.annotations.Name;
@@ -22,6 +22,7 @@
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 
+
 /**
  *
  * @author dhawal
@@ -34,24 +35,15 @@
 
 public class V1_0 extends ModelDataService{
     
-    //SQL params here for quick modification
-    private final String USER = "postgres";
-    private final String PASS = "admin";
-    private final String HOST = "localhost";
-    private final String PORT = "5432";
-    private final String DBNAME = "wqm";
-    private final String JDBC_TYPE = "jdbc:postgresql://";
-    private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
-    private final String CLASS_NAME = "org.postgresql.Driver";
-    private String error_msg = "";    
-    private PestPractScores pestPractScores = null;
+    private String error_msg = "";        
+    private PestPractScores pestPractScores;
 
-    
-    
+        
     @Override
     protected void preProcess() throws Exception {
         // reading the inputs from the json file into input object and placing it in the arraylist
         int AoAId;
+        this.pestPractScores = null;
         
         JSONArray pestComponents;
         
@@ -69,11 +61,17 @@
     @Override
     protected String process() throws Exception
     {
-        if ( ( this.error_msg.isEmpty() ) && ( pestPractScores != null ) ){
-            if ( !pestPractScores.computeScores() ){
-                this.error_msg += pestPractScores.getErrorMsg();
+        try{
+            if ( ( this.error_msg.isEmpty() ) && ( pestPractScores != null ) ){
+                if ( !pestPractScores.computeScores() ){
+                    this.error_msg += pestPractScores.getErrorMsg();
+                }
             }
         }
+        catch( Exception ex ){
+            this.error_msg += pestPractScores.getErrorMsg() + " " + ex.getMessage();
+            LOG.log( Level.SEVERE, this.error_msg );
+        }
 
         return (this.error_msg.isEmpty()?  EXEC_OK : this.error_msg );       
     }
@@ -135,20 +133,18 @@
             return this.results;            
         }
         
-        boolean computeScores(){
+        boolean computeScores() throws Exception {
             boolean ret_val = false;
             
             if (  ( this.error_msg.isEmpty() ) && ( (null != this.ipmList) && (!this.ipmList.isEmpty()) ) ){
                 //Compute values here.
                 try{ 
-                    Class.forName(CLASS_NAME);                 
-                    conn = DriverManager.getConnection(CONNECTION, USER, PASS);
-                    conn.setAutoCommit(false);
-                    statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);                   
+                    this.conn = wqm.utils.WQMTools.getConnection( "wqm", LOG );
+                    this.statement = this.conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);                   
                 }
-                catch( ClassNotFoundException | SQLException se ){
+                catch( ServiceException | SQLException se ){
                     this.error_msg += " Cannot connect to database:  " + se.getMessage() + " ";
-                    
+                    LOG.log( Level.SEVERE, this.error_msg );
                 }
                 
                 if ( this.error_msg.isEmpty() ){                
@@ -162,13 +158,22 @@
                             break;
                         }
                     }
-
+                    
                     //Create Results here...
                     if ( this.error_msg.isEmpty() ){
                         results = new Result( this.AoAId, this.pleach_practice_score, this.psolsurf_practice_score, this.padsurf_practice_score, this.pdrift_practice_score);
                     }
                 }
                 
+                if ( this.statement != null ){
+                    this.statement.close();
+                    this.statement = null;
+                }
+                
+                if ( this.conn != null ){
+                    this.conn.close();
+                    this.conn = null;
+                }
             }
             
             return ret_val;                

src/java/m/wqm/rfactor/V1_0.java

@@ -1,24 +1,19 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
+
 package m.wqm.rfactor;
 
 import csip.ModelDataService;
 import csip.ServiceException;
 import csip.utils.JSONUtils;
 import java.io.IOException;
-import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Map;
+import java.util.logging.Level;
 import javax.ws.rs.Path;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -28,6 +23,7 @@
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
+import org.w3c.dom.DOMException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -37,173 +33,245 @@
 /**
  *
  * @author Sandeep
+ * @author Shaun Case
  */
 
 @Name("WQM-12: Climate R Factor for an Area of Analysis (AoARFactor)")
 @Description("This service intersects an area of analysis (AoA) with the Revised Universal Soil Loss Equation (RUSLE2) climate R Factor layer and computes an R Factor representing the AoA.")
 @Path("m/wqm/rfactor/1.0")
 
-
-
 public class V1_0 extends ModelDataService{
-   
-   private final String USER = "postgres";
-   private final String PASS = "admin";
-   private final String HOST = "csip.engr.colostate.edu";
-   private  final String PORT = "5435";
-   private  final String DBNAME = "r2gis";
-   private final String SERVER = "localhost:5432/postgres";
-   private final String JDBC_TYPE = "jdbc:postgresql://";
-   private final String CLASS_NAME = "org.postgresql.Driver";
-   private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
-        
+          
+    private Connection conn;
+    private Statement statement;
     
+    private String error_msg;    
+    private ArrayList<AoA> list;
     
-   private String aoaId;
-   private JSONArray polygon,coordinates;
-   private String rFactor;
-   String points,finalpoints="";
-   JSONArray aoaArr;
-   ArrayList<AoA> list;
-   ArrayList<String> rfactorList;
-   ArrayList<Double> temp;
     @Override
-    public void preProcess() throws ServiceException, JSONException
-    {
-        list=new ArrayList<AoA>();
-        rfactorList= new ArrayList<String>();
-    aoaArr = getJSONArrayParam("aoas");
-        for(int i = 0; i < aoaArr.length(); i++) {
-            //Map individual JSONObject & extract values
-        Map<String, JSONObject> thisAoA = JSONUtils.preprocess(aoaArr.getJSONArray(i));
-        aoaId=JSONUtils.getStringParam(thisAoA,"aoa_id","unknown");
-        polygon=JSONUtils.getJSONArrayParam(thisAoA,"aoa_geometry");
-       coordinates=polygon.getJSONArray(0);
-       points=coordinates.toString();
-       points=points.replace("[","");
-       points=points.replace("]","");
-       points=points.replace(","," ");
-       String temp[] = points.split(" ");
-       finalpoints="";
-       finalpoints+=temp[0];
-       for(int j=1;j<temp.length;j++)
-       {
-           if(j%2==0)
-           finalpoints+=","+temp[j];
-           else
-         finalpoints+=" "+temp[j];
-       }
-       list.add(new AoA(aoaId,finalpoints));
+    public void preProcess(){
+        this.error_msg = "";
+        this.conn = null;
+        this.statement = null;
+        String points;
+        String finalpoints;        
+        JSONArray aoaArr;
+        String aoaId;
+        JSONArray polygon,coordinates;
+    
+        try{            
+            this.list=new ArrayList<>();
+            
+            aoaArr = getJSONArrayParam("aoas");
+            
+            for(int i = 0; i < aoaArr.length(); i++) {
+                //Map individual JSONObject & extract values
+                Map<String, JSONObject> thisAoA = JSONUtils.preprocess(aoaArr.getJSONArray(i));
+                aoaId=JSONUtils.getStringParam(thisAoA,"aoa_id","unknown");
+                polygon=JSONUtils.getJSONArrayParam(thisAoA,"aoa_geometry");
+                coordinates=polygon.getJSONArray(0);
+                points=coordinates.toString();
+                points=points.replace("[","");
+                points=points.replace("]","");
+                points=points.replace(","," ");
+                String temp[] = points.split(" ");
+                finalpoints="";
+                finalpoints+=temp[0];
+                for(int j=1;j<temp.length;j++){
+                    if(j%2==0) {
+                        finalpoints+=","+temp[j];
+                    } else {
+                        finalpoints+=" "+temp[j];
+                    }
+                }
+                this.list.add(new AoA(aoaId,finalpoints));
+            }
         }
-    
-        }
+        catch( ServiceException | JSONException ex ){
+            this.error_msg = "Cannot process the input JSON: " + ex.getMessage();
+            LOG.log( Level.SEVERE, this.error_msg );
+        }    
+    }
     
     @Override
     public String process()
     {
+        String rFactor;  
+        ArrayList<String> rfactorList= new ArrayList<>();        
         
-       Connection tempCon=null;
-       Statement stmt=null;
-        try {
-          Class.forName(CLASS_NAME);
-          tempCon=DriverManager.getConnection(CONNECTION,"postgres","admin");
-          tempCon.setAutoCommit(false);
-          stmt=tempCon.createStatement();
-         // geometryPoint=geometryPoint.replace(",", " ");
-          for(int i=0;i<list.size();i++)
-          {
-              String points= list.get(i).getCoordinates();
-          String gisQuery="SELECT m.co_fips, r2_path, r2_name, m.ei_rang, st_area(st_intersection(ST_PolygonFromText('POLYGON(("+points+"))'), geometry)) / st_area(ST_PolygonFromText('POLYGON(("+points+"))'))*100 as percentAoi,st_area(st_intersection(ST_PolygonFromText('POLYGON(("+points+"))'), geometry))/43560 as sizeAoi FROM cli_geom AS g, map_climates AS m WHERE ST_Intersects(ST_PolygonFromText('POLYGON(("+points+"))'), g.geometry) AND ((g.co_fips = m.co_fips and st_isvalid(geometry)='t' and m.ei_rang is null) or (g.co_fips = m.co_fips and g.ei_rang = m.ei_rang and m.ei_rang is not null and st_isvalid(geometry)='t')) and st_isvalid(geometry)='t' and st_isvalid(ST_PolygonFromText('POLYGON(("+points+"))'))='t';";
-           //stmt.execute(gisQuery);
-         //statement.execute(query1);
-         
-         // statement.execute("create table temp;");
-          ResultSet results = stmt.executeQuery(gisQuery);
-          
-          String urlName=null;
-         while(results.next())    
-         {
-             //System.out.println(results.getString("co_fips"));
-             String path=results.getString("r2_path");
-             String county=results.getString("r2_name");
-             urlName="http://csip.engr.colostate.edu/r2/"+path.replace(" ","%20")+"/"+county.replace(" ","%20")+".xml";
-            
-             //System.out.println(results.getString("r2_path"));
-             //System.out.println(results.getString("r2_name"));
-             urlName=urlName.replace("\\","/");
-        //     System.out.println(urlName);
-             rFactor=getAndProcessXml(urlName);
-             rfactorList.add(rFactor);
-         }
-         list.get(i).setRFactor(rfactorList);
-        }  
+        if ( this.error_msg.isEmpty() ){
+            try {
+                this.conn = wqm.utils.WQMTools.getConnection( "r2gis", LOG );
+                statement = this.conn.createStatement();
+
+                for (AoA list1 : this.list) {
+                    String tPoints = list1.getCoordinates();
+                    String gisQuery="SELECT m.co_fips, r2_path, r2_name, m.ei_rang, st_area(st_intersection(ST_PolygonFromText('POLYGON(("+tPoints+"))'), geometry)) / st_area(ST_PolygonFromText('POLYGON(("+tPoints+"))'))*100 as percentAoi,st_area(st_intersection(ST_PolygonFromText('POLYGON(("+tPoints+"))'), geometry))/43560 as sizeAoi FROM cli_geom AS g, map_climates AS m WHERE ST_Intersects(ST_PolygonFromText('POLYGON(("+tPoints+"))'), g.geometry) AND ((g.co_fips = m.co_fips and st_isvalid(geometry)='t' and m.ei_rang is null) or (g.co_fips = m.co_fips and g.ei_rang = m.ei_rang and m.ei_rang is not null and st_isvalid(geometry)='t')) and st_isvalid(geometry)='t' and st_isvalid(ST_PolygonFromText('POLYGON(("+tPoints+"))'))='t';";
+                    ResultSet results = statement.executeQuery(gisQuery);
+                    while(results.next()){
+                        String urlName = wqm.utils.WQMTools.getR2GISFileURL( results.getString("r2_path"), results.getString("r2_name") );                                
+                        rFactor=getAndProcessXml(urlName);
+
+                        if ( null != rFactor ){
+                            rfactorList.add(rFactor);
+                        }
+                        else{
+                            break;
+                        }
+                    }
+                    
+                    if ( !this.error_msg.isEmpty() ){
+                        break;
+                    }
+                    
+                    if (rfactorList.size() > 0 ){
+                        list1.setRFactor(rfactorList);
+                    }
+                }  
+                
+                if ( this.statement != null ){
+                    this.statement.close();
+                    this.statement = null;
+                }
+                if ( this.conn != null ){
+                    this.conn.close();
+                    this.conn = null;
+                }
+            }          
+            catch( Exception ex )
+            {
+                this.error_msg = "Cannot process that request: " + ex.getMessage();
+                LOG.log( Level.SEVERE, this.error_msg );
+            } 
         }
-          
-      catch(Exception e)
-      {
-          e.printStackTrace();
-      } 
-          
-          return EXEC_OK;
+
+          return ( this.error_msg.isEmpty()? EXEC_OK : this.error_msg );
     }
     
     @Override
-    public void postProcess() throws JSONException
-    {
-    JSONArray finalArr= new JSONArray();
-    for(int i=0;i<list.size();i++){
-    JSONArray resultArr = new JSONArray();
-    temp=new ArrayList<Double>();
-    for(int j=0;j<list.get(i).getRFactor().size();j++)
-      temp.add(Double.parseDouble(list.get(i).getRFactor().get(j)));
-    
-    Collections.sort(temp);
-    resultArr.put(JSONUtils.dataDesc("AoAId",list.get(i).getAoAId(),"Area of Analysis Identifier"));
-    resultArr.put(JSONUtils.dataDesc("RFactor",temp.get(temp.size()-1),"R Factor"));
-    
-    finalArr.put(resultArr);
-    }
-    putResult("",finalArr);
+    public void postProcess() throws Exception{
+        ArrayList<Double> temp;
+        try{
+            if ( this.error_msg.isEmpty() ){
+                JSONArray finalArr= new JSONArray();
+                for (AoA list1 : this.list) {
+                    JSONArray resultArr = new JSONArray();
+                    temp=new ArrayList<>();
+                    for (int j = 0; j < list1.getRFactor().size(); j++) {
+                        temp.add(Double.parseDouble(list1.getRFactor().get(j)));
+                    }
+                    
+                    resultArr.put(JSONUtils.dataDesc("AoAId", list1.getAoAId(), "Area of Analysis Identifier"));                    
+                    
+                    if ( temp.size() > 0 ){
+                        Collections.sort(temp);
+                        resultArr.put(JSONUtils.dataDesc("RFactor",temp.get(temp.size()-1),"R Factor"));                      
+                    }
+                    else{
+                        resultArr.put(JSONUtils.dataDesc("RFactor","No polygon intersection found","R Factor"));                           
+                    }
+                    
+                    finalArr.put(resultArr);                      
+                }
+                putResult("",finalArr);
+            }
+        }
+        catch( NumberFormatException | JSONException ex ){
+            this.error_msg = "Could not create result JSON: " + ex.getMessage();
+            LOG.log(Level.SEVERE, this.error_msg );
+            throw new Exception( this.error_msg );            
+        }
     }
 
 
 
-public String getAndProcessXml(String url) throws ParserConfigurationException, MalformedURLException, SAXException, IOException
-{
-    
-     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-     DocumentBuilder db = dbf.newDocumentBuilder();
-     
-     URL Url = new URL(url);
-     URLConnection conn = Url.openConnection();
-     Document document = db.parse(conn.getInputStream());
-     document.getDocumentElement().normalize();
-     Element root=document.getDocumentElement();    
-     NodeList nList= document.getElementsByTagName("Flt");
-        
-        
-         
-        for (int temp = 0; temp < nList.getLength(); temp++)
-        {
-         Node node = nList.item(temp);
-        // System.out.println("");    //Just a separator
-         if (node.getNodeType() == Node.ELEMENT_NODE)
-         {
-            //Print each employee's detail
-            Element eElement = (Element) node;
-            
-            String Name=eElement.getElementsByTagName("Name").item(0).getTextContent();
-            if(Name.equals("R_FACTOR"))
-            {
-                return eElement.getElementsByTagName("Data").item(0).getTextContent();
-            }
-         }
-        }    
-        return null;
+    private String getAndProcessXml(String url){ 
+        String ret_val = null;
+        
+        try{
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+
+        URL Url = new URL(url);
+        URLConnection urlConnection = Url.openConnection();
+        Document document = db.parse(urlConnection.getInputStream());
+        document.getDocumentElement().normalize();
+        Element root=document.getDocumentElement();    
+        NodeList nList= document.getElementsByTagName("Flt");
+
+        for (int temp = 0; temp < nList.getLength(); temp++){
+            Node node = nList.item(temp);
+
+            if (node.getNodeType() == Node.ELEMENT_NODE){
+                Element eElement = (Element) node;
+                String Name=eElement.getElementsByTagName("Name").item(0).getTextContent();
+                if(Name.equals("R_FACTOR")){            
+                    ret_val =  eElement.getElementsByTagName("Data").item(0).getTextContent();
+                }
+            }
+        }
+        }
+        catch( ParserConfigurationException | IOException | SAXException | DOMException ex ){
+            this.error_msg = "Cannot parse the returned XML: " + ex.getMessage();
+            LOG.log( Level.SEVERE, this.error_msg );
+        }
+        
+    return ret_val;
+    }
+    
+    public class AoA {
+
+        private final String aoa_id;
+        private final String polygonCoordinates;
+        private ArrayList<String> rfactor;
+
+        /**
+         *
+         * @param aoa_id
+         * @param coordinates
+         */
+        public AoA(String aoa_id,String coordinates)
+        {
+            this.aoa_id=aoa_id;
+            this.polygonCoordinates=coordinates;
+            rfactor= new ArrayList<>();
+        }
+
+        /**
+         *
+         * @return
+         */
+        public String getAoAId()
+        {
+            return aoa_id;
+        }
+
+        /**
+         *
+         * @return
+         */
+        public ArrayList<String> getRFactor()
+        {
+            return rfactor;
+        }
+
+        /**
+         *
+         * @param rf
+         */
+        public void setRFactor(ArrayList<String> rf)
+        {
+            this.rfactor=rf;
+        }
+
+        /**
+         *
+         * @return
+         */
+        public String getCoordinates()
+        {
+            return polygonCoordinates;
+        }
+
+    }    
 }
-
-
-
-
-
-}

src/java/m/wqm/sednutpractscores/V1_0.java

@@ -1,11 +1,8 @@
 package m.wqm.sednutpractscores;
 
-/**
- *
- * @author SrinivasReddy kontham
- */
 import csip.ModelDataService;
 import static csip.ModelDataService.EXEC_OK;
+import csip.ServiceException;
 import java.util.ArrayList;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
@@ -15,43 +12,76 @@
 import csip.utils.JSONUtils;
 import java.util.Map;
 import java.sql.*;
-import java.util.concurrent.*;
+import java.util.logging.Level;
+import org.codehaus.jettison.json.JSONException;
 
 @Name("WQM-15: Sediment and Nutrient Practice Scores (SedNutPractScores)")
 @Description("This service computes scores for conservation practices applied to mitigate nitrogen leaching, sediment runoff, nitrogen runoff, and phosphorus runoff loss potential.")
 @Path("m/nut_pract_scores/1.0")
 
+/**
+ *
+ * @author SrinivasReddy kontham
+ * @author Shaun Case
+ */
 public class V1_0 extends ModelDataService
 {
-    ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
-    ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
-            int nleach_pract_score=0;
-            int nleach_avoid_pract_score=0;
-            int nleach_control_pract_score=0;
-            int nleach_trap_pract_score=0;
-            int nsurf_pract_score=0;
-            int nsurf_avoid_pract_score=0;
-            int nsurf_control_pract_score=0;
-            int nsurf_trap_pract_score=0;
-            int psurf_pract_score=0;
-            int psurf_avoid_pract_score=0;
-            int psurf_control_pract_score=0;
-            int psurf_trap_pract_score=0;
-            int ssurf_pract_score=0;
-            int ssurf_avoid_pract_score=0;
-            int ssurf_control_pract_score=0;
-            int ssurf_trap_pract_score=0;
-            
-            int AoAid;
-    @Override
-        // reading the inputs from the json file into input object and placing it in the arraylist
-        protected void preProcess() throws Exception {
-        JSONArray groups = getJSONArrayParam("pestcomponents");
-            for(int i=0;i<groups.length();i++)
-            {
+    private Connection conn;
+    private Statement statement;
+    
+    private ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
+    private ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
+    private int nleach_pract_score=0;
+    private int nleach_avoid_pract_score=0;
+    private int nleach_control_pract_score=0;
+    private int nleach_trap_pract_score=0;
+    private int nsurf_pract_score=0;
+    private int nsurf_avoid_pract_score=0;
+    private int nsurf_control_pract_score=0;
+    private int nsurf_trap_pract_score=0;
+    private int psurf_pract_score=0;
+    private int psurf_avoid_pract_score=0;
+    private int psurf_control_pract_score=0;
+    private int psurf_trap_pract_score=0;
+    private int ssurf_pract_score=0;
+    private int ssurf_avoid_pract_score=0;
+    private int ssurf_control_pract_score=0;
+    private int ssurf_trap_pract_score=0;            
+    private int AoAid;
+    
+    private String error_msg;
+    
+    @Override 
+    protected void preProcess(){
+        this.nleach_pract_score=0;
+        this.nleach_avoid_pract_score=0;
+        this.nleach_control_pract_score=0;
+        this.nleach_trap_pract_score=0;
+        this.nsurf_pract_score=0;
+        this.nsurf_avoid_pract_score=0;
+        this.nsurf_control_pract_score=0;
+        this.nsurf_trap_pract_score=0;
+        this.psurf_pract_score=0;
+        this.psurf_avoid_pract_score=0;
+        this.psurf_control_pract_score=0;
+        this.psurf_trap_pract_score=0;
+        this.ssurf_pract_score=0;
+        this.ssurf_avoid_pract_score=0;
+        this.ssurf_control_pract_score=0;
+        this.ssurf_trap_pract_score=0;  
+        this.error_msg = "";
+
+        this.components=new ArrayList<>();
+        this.result1=new ArrayList<>();            
+
+        try{
+            conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
+            statement = conn.createStatement();
+
+            JSONArray groups = getJSONArrayParam("pestcomponents");
+            for(int i=0;i<groups.length();i++){
                 Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
 
-                
                 AoAid = JSONUtils.getIntParam(group, "AoAid", 0);
                 int  plan_pract_id=JSONUtils.getIntParam(group,"plan_practice_id",0);
                 String plan_pract_discrim_type=JSONUtils.getStringParam(group,"plan_practice_discrim_type","err");
@@ -60,231 +90,252 @@
                 components.add(input);
             }
         }
-        @Override
-        protected String process() throws Exception
-        {
-            Connection conn = null;
-            Statement statement = null;
-            Class.forName("org.postgresql.Driver");
-            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/wqm", "postgres", "admin");
-            conn.setAutoCommit(false);
-            statement = conn.createStatement();
-            
-            for(Input ip:components)
-            {
-                String query;
-              //  #Compute practice mitigation scores for Nitrogen in Ground Water and increment total scores
-                if(ip.plan_practice_discrim_type.equals(""))
+        catch( ServiceException | SQLException | JSONException ex ){
+            this.error_msg = "Cannot process the input JSON: " + ex.getMessage();
+            LOG.log( Level.SEVERE, this.error_msg );
+        }
+    }
+        
+        
+    @Override
+    protected String process() throws Exception
+    {
+        if ( this.error_msg.isEmpty() ){
+            try{
+                for(Input ip:components)
                 {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id='"+ip.plan_practice_id+"'AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";
-                    
+                    String query;
+                  //  #Compute practice mitigation scores for Nitrogen in Ground Water and increment total scores
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id='"+ip.plan_practice_id+"'AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";
+
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id='"+ip.plan_practice_id+"'AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    ResultSet results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int nl_avoid_pract_score=results.getInt("nut_pract_score");
+                       nleach_avoid_pract_score += nl_avoid_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";                    
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int nl_control_pract_score=results.getInt("nut_pract_score");
+                       nleach_control_pract_score += nl_control_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";               }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int nl_trap_pract_score=results.getInt("nut_pract_score");
+                       nleach_trap_pract_score += nl_trap_pract_score;
+                    }
+                    nleach_pract_score=nleach_trap_pract_score+nleach_control_pract_score+nleach_avoid_pract_score;
+            // #Compute practice mitigation scores for Sediment in Surface Water and increment total scores   
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";        
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int sd_avoid_pract_score=results.getInt("nut_pract_score");
+                       ssurf_avoid_pract_score += sd_avoid_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";           
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int sd_control_pract_score=results.getInt("nut_pract_score");
+                       ssurf_control_pract_score += sd_control_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";      
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int sd_trap_pract_score=results.getInt("nut_pract_score");
+                       ssurf_trap_pract_score += sd_trap_pract_score;
+                    }
+                    ssurf_pract_score=ssurf_trap_pract_score+ssurf_control_pract_score+ssurf_avoid_pract_score;
+               // #Increment practice mitigation scores for Nitrogen in Surface Water and increment total scores
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";       
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ns_avoid_pract_score=results.getInt("nut_pract_score");
+                       nsurf_avoid_pract_score += ns_avoid_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";          
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ns_control_pract_score=results.getInt("nut_pract_score");
+                       nsurf_control_pract_score += ns_control_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";         
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ns_trap_pract_score=results.getInt("nut_pract_score");
+                       nsurf_trap_pract_score += ns_trap_pract_score;
+                    }
+                    nsurf_pract_score=nsurf_trap_pract_score+nsurf_control_pract_score+nsurf_avoid_pract_score;
+    // #Increment practice mitigation scores for Phosphorus in Surface Water and increment total scores                
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";     
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ps_avoid_pract_score=results.getInt("nut_pract_score");
+                       psurf_avoid_pract_score += ps_avoid_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";          
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ps_control_pract_score=results.getInt("nut_pract_score");
+                       psurf_control_pract_score += ps_control_pract_score;
+                    }
+                    if(ip.plan_practice_discrim_type.isEmpty())
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";          
+                    }
+                    else
+                    {
+                         query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                    }
+
+                    results = statement.executeQuery(query);
+
+                    while (results.next())
+                    {
+                       int ps_trap_pract_score=results.getInt("nut_pract_score");
+                       psurf_trap_pract_score += ps_trap_pract_score;
+                    }
+                    psurf_pract_score=psurf_trap_pract_score+psurf_control_pract_score+psurf_avoid_pract_score;
                 }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id='"+ip.plan_practice_id+"'AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
+                Result1 result=new Result1(AoAid,nleach_pract_score,ssurf_pract_score,nsurf_pract_score,psurf_pract_score,nleach_avoid_pract_score,nleach_control_pract_score,nleach_trap_pract_score,ssurf_avoid_pract_score,ssurf_control_pract_score,ssurf_trap_pract_score,nsurf_avoid_pract_score,nsurf_control_pract_score,nsurf_trap_pract_score,psurf_avoid_pract_score,psurf_control_pract_score,psurf_trap_pract_score);
+                result1.add(result);                   
+            }
+            catch( NumberFormatException | SQLException ex ){
+                this.error_msg = "Cannot process that request: " + ex.getMessage();
+                LOG.log( Level.SEVERE, this.error_msg );
+            }
+            finally{
+                if ( this.statement != null ){
+                    this.statement.close();
+                    this.statement = null;
                 }
                 
-                ResultSet results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int nl_avoid_pract_score=results.getInt("nut_pract_score");
-                   nleach_avoid_pract_score=nleach_avoid_pract_score+nl_avoid_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";                    
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int nl_control_pract_score=results.getInt("nut_pract_score");
-                   nleach_control_pract_score=nleach_control_pract_score+nl_control_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";               }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Ground Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int nl_trap_pract_score=results.getInt("nut_pract_score");
-                   nleach_trap_pract_score=nleach_trap_pract_score+nl_trap_pract_score;
-                }
-                nleach_pract_score=nleach_trap_pract_score+nleach_control_pract_score+nleach_avoid_pract_score;
-        // #Compute practice mitigation scores for Sediment in Surface Water and increment total scores   
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";        
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int sd_avoid_pract_score=results.getInt("nut_pract_score");
-                   ssurf_avoid_pract_score=ssurf_avoid_pract_score+sd_avoid_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";           
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int sd_control_pract_score=results.getInt("nut_pract_score");
-                   ssurf_control_pract_score=ssurf_control_pract_score+sd_control_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";      
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Sediment in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int sd_trap_pract_score=results.getInt("nut_pract_score");
-                   ssurf_trap_pract_score=ssurf_trap_pract_score+sd_trap_pract_score;
-                }
-                ssurf_pract_score=ssurf_trap_pract_score+ssurf_control_pract_score+ssurf_avoid_pract_score;
-           // #Increment practice mitigation scores for Nitrogen in Surface Water and increment total scores
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";       
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ns_avoid_pract_score=results.getInt("nut_pract_score");
-                   nsurf_avoid_pract_score=nsurf_avoid_pract_score+ns_avoid_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";          
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ns_control_pract_score=results.getInt("nut_pract_score");
-                   nsurf_control_pract_score=nsurf_control_pract_score+ns_control_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";         
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Nitrogen in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ns_trap_pract_score=results.getInt("nut_pract_score");
-                   nsurf_trap_pract_score=nsurf_trap_pract_score+ns_trap_pract_score;
-                }
-                nsurf_pract_score=nsurf_trap_pract_score+nsurf_control_pract_score+nsurf_avoid_pract_score;
-// #Increment practice mitigation scores for Phosphorus in Surface Water and increment total scores                
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"' AND COALESCE(pract_discrim_type, '') = ''";     
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Avoid"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ps_avoid_pract_score=results.getInt("nut_pract_score");
-                   psurf_avoid_pract_score=psurf_avoid_pract_score+ps_avoid_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"' AND COALESCE(pract_discrim_type, '') = ''";          
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Control"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ps_control_pract_score=results.getInt("nut_pract_score");
-                   psurf_control_pract_score=psurf_control_pract_score+ps_control_pract_score;
-                }
-                if(ip.plan_practice_discrim_type.equals(""))
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"' AND COALESCE(pract_discrim_type, '') = ''";          
-                }
-                else
-                {
-                     query="SELECT nut_pract_score FROM wqm_sediment_nutrient_practice_scores WHERE practice_id="+ip.plan_practice_id+"AND wqm_concern="+"'"+"Phosphorus in Surface Water"+"'AND mode_of_action="+"'"+"Trap"+"'AND CAST(min_pract_discrim AS int)<="+Integer.parseInt(ip.plan_practice_discrim_value)+"AND CAST(max_pract_discrim AS int)>"+Integer.parseInt(ip.plan_practice_discrim_value);
-                }
-                
-                results = statement.executeQuery(query);
-                
-                while (results.next())
-                {
-                   int ps_trap_pract_score=results.getInt("nut_pract_score");
-                   psurf_trap_pract_score=psurf_trap_pract_score+ps_trap_pract_score;
-                }
-                psurf_pract_score=psurf_trap_pract_score+psurf_control_pract_score+psurf_avoid_pract_score;
+                if ( this.conn != null ){
+                    this.conn.close();
+                    this.conn = null;
+                }                 
             }
-            Result1 result=new Result1(AoAid,nleach_pract_score,ssurf_pract_score,nsurf_pract_score,psurf_pract_score,nleach_avoid_pract_score,nleach_control_pract_score,nleach_trap_pract_score,ssurf_avoid_pract_score,ssurf_control_pract_score,ssurf_trap_pract_score,nsurf_avoid_pract_score,nsurf_control_pract_score,nsurf_trap_pract_score,psurf_avoid_pract_score,psurf_control_pract_score,psurf_trap_pract_score);
-            result1.add(result);
-            return EXEC_OK;
         }
-         @Override
-        //writing the results back to JSON
+        
+        return ( this.error_msg.isEmpty()? EXEC_OK : this.error_msg );
+    }
+    
+    @Override    
     protected void postProcess() throws Exception 
     {
+        if ( this.error_msg.isEmpty() ){
+            try{        
                 JSONArray result1Arr = new JSONArray();
-                 for(Result1 rs1:result1)
-                {
+                for(Result1 rs1:result1){
                     JSONArray tmpArr = new JSONArray();
                     tmpArr.put(JSONUtils.dataDesc("AoAId", AoAid, "Area of Analysis Identifier"));
                     tmpArr.put(JSONUtils.dataDesc("nleach_pract_score", rs1.nleach_pract_score, " Nitrogen Leaching Practice Mitigation Score"));
@@ -307,7 +358,12 @@
                 }
                 
                 putResult("operation", result1Arr);    
+            }
+            catch( JSONException ex ){
+                this.error_msg = "Could not create result JSON: " + ex.getMessage();
+                LOG.log(Level.SEVERE, this.error_msg );
+                throw new Exception( this.error_msg );                
+            }
+        }
     }
-    
-
 }

src/java/m/wqm/soilpestlosspot/V1_0.java

@@ -2,11 +2,13 @@
 
 
 import csip.ModelDataService;
+import csip.ServiceException;
 import csip.annotations.Polling;
 import csip.utils.JSONUtils;
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.ResultSet;
+import static java.sql.ResultSet.CONCUR_READ_ONLY;
+import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
@@ -33,6 +35,7 @@
 public class V1_0 extends ModelDataService {
 
     //SQL params here for quick modification
+    /*
     private final String USER = "postgres";
     private final String PASS = "admin";
     private final String HOST = "localhost";
@@ -41,6 +44,9 @@
     private final String JDBC_TYPE = "jdbc:postgresql://";
     private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
     private final String CLASS_NAME = "org.postgresql.Driver";
+    */
+    private Statement statement;
+    private Connection conn;
     private AoA aoa;
     private String error_msg;
     
@@ -51,6 +57,8 @@
     @Override
     protected void preProcess() throws Exception {
         this.error_msg = "";
+        this.statement = null;
+        this.conn = null;
         
         //  Always use a try catch block around these JSON calls, so that we can return meaningful failure messages to the user.
         //  Just letting the service crash and return a Java exception blob back to the user is not useful.
@@ -61,7 +69,7 @@
                             getStringParam("aoa_sarp"),getStringParam("aoa_rain_prob"), getJSONArrayParam("operationlist") );
             error_msg = aoa.getErrorMsg();        
         }
-        catch (Exception ex) {
+        catch (ServiceException ex) {
             error_msg += "  " + ex.getMessage() + ". ";
         }
     }
@@ -70,6 +78,9 @@
     protected String process() throws Exception {
         ResultSet resultSet;
         try {
+            conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
+            conn.setAutoCommit(false);
+            statement = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY);            
             if (error_msg.isEmpty() ){
                 if ( aoa.calculate() ) {
                     result = aoa.getResults();
@@ -78,15 +89,26 @@
                 }
             }           
         } 
-        catch (Exception ex) {            
+        catch (ServiceException | SQLException ex) {            
             LOG.info(ex.getMessage());
             error_msg += ex.getMessage();
         } 
+        finally{
+            if ( this.statement != null ){
+                this.statement.close();
+                this.statement = null;
+            }
+
+            if ( this.conn != null ){
+                this.conn.close();
+                this.conn = null;
+            }
+        }
         
         if ( result == null ){
             error_msg += "  No return data found, cannot validate input or results.  Please check your input parameters.";
-        }         
-            
+        }                     
+        
         return ( error_msg.isEmpty()? EXEC_OK: error_msg );
     }
 
@@ -223,8 +245,6 @@
         private final AoA aoa;
         private ArrayList<pesticide> pesticideList;
         private String error_msg = "";
-        private Statement statement;
-        Connection conn = null;
         
         pesticideOperation( String operation_id, AoA aoa, JSONArray pesticides ) {
             this.operation_id = operation_id;
@@ -232,14 +252,6 @@
             pesticideList = new ArrayList<>();
             
             try{     
-                // This database work creates a new connection for each operation instance.  
-                //  If the code is ever parallelized this will be a speed benefit, and will reduce the potential of errors 
-                //  caused by parallel threads or processes trying to compete for and use the same connection object.
-                // For now it just creates a handful of new connections, which isn't really an extra load on the DBMS.  
-                Class.forName(CLASS_NAME);                 
-                conn = DriverManager.getConnection(CONNECTION, USER, PASS);
-                conn.setAutoCommit(false);
-                statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
             
                 for (int i = 0; i < pesticides.length(); i++) {
                     Map<String, JSONObject> pesticidesData = JSONUtils.preprocess(pesticides.getJSONArray(i));
@@ -249,7 +261,7 @@
                                                         JSONUtils.getStringParam(pesticidesData, "ai_parp", "err") ) );                                
                 }
             }
-            catch( ClassNotFoundException | SQLException | JSONException ex){
+            catch( JSONException ex ){
                 this.error_msg = ex.getMessage();
             }
         }

src/java/m/wqm/thresholdscores/V1_0.java

@@ -1,22 +1,26 @@
 package m.wqm.thresholdscores;
 
 import csip.ModelDataService;
+import csip.ServiceException;
 import csip.utils.JSONUtils;
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.logging.Level;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
 import oms3.annotations.Name;
 import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 
 /**
  *
  * @author Srinivas Reddy Kontham
+ * @author Shaun Case
  */
 @Name("WQM-13: WQM Concern Treatment Level Threshold Scores (WQMThresholdScores)")
 @Description("This service computes treatment level threshold scores for each of the WQM concerns for an area of analysis. The service uses nutrient soil leaching potentials from WQM-5, sediment and nutrient soil runoff potentials from WQM-6, hazard ratings from pesticide-related WQM concerns from WQM-11, required treatment level from WQM-1, and the AoA climate R factor from WQM-12 to calculate the threshold scores.")
@@ -24,40 +28,57 @@
 
 public class V1_0 extends ModelDataService
 {
-        ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
-        ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
-        @Override
-        // reading the inputs from the json file into input object and placing it in the arraylist
-        protected void preProcess() throws Exception 
-        {
+    
+    private Connection conn;
+    private Statement statement;
+    
+    private String error_msg;
+    
+    ArrayList<Input> components; // store the set of all input soilcomponents as objects
+    ArrayList<Result1> result1;  // store the result as objects
+    @Override
+    // reading the inputs from the json file into input object and placing it in the arraylist
+    protected void preProcess() throws Exception 
+    {
+        this.conn = null;
+        this.statement = null;
+        this.components = new ArrayList<>();
+        this.result1 = new ArrayList<>();
+        this.error_msg = "";
+
+        try{
             JSONArray groups = getJSONArrayParam("components");
-            for(int i=0;i<groups.length();i++)
-            {
-                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
-                int AoAId = JSONUtils.getIntParam(group, "AoAId", 0);
-                String aoa_nslp=JSONUtils.getStringParam(group,"aoa_nslp","err");
-                String aoa_srp=JSONUtils.getStringParam(group,"aoa_srp","err");
-                String aoa_phr_leach_human=JSONUtils.getStringParam(group,"aoa_phr_leach_human","err");
-                String aoa_phr_leach_matcfish=JSONUtils.getStringParam(group,"aoa_phr_leach_matcfish","err");
-                String aoa_phr_sorun_human=JSONUtils.getStringParam(group,"aoa_phr_sorun_human","err");
-                String aoa_phr_sorun_matcfish=JSONUtils.getStringParam(group,"aoa_phr_sorun_matcfish","err");
-                String aoa_phr_adrun_human=JSONUtils.getStringParam(group,"aoa_phr_adrun_human","err");
-                String aoa_phr_adrun_stvfish=JSONUtils.getStringParam(group,"aoa_phr_adrun_stvfish","err");
-                String aoa_treatment_level=JSONUtils.getStringParam(group,"aoa_treatment_level","err");
-                int aoa_rfactor=JSONUtils.getIntParam(group,"aoa_rfactor",0);
-                Input input=new Input(AoAId,aoa_nslp,aoa_srp,aoa_phr_leach_human,aoa_phr_leach_matcfish,aoa_phr_sorun_human,aoa_phr_sorun_matcfish,aoa_phr_adrun_human,aoa_phr_adrun_stvfish,aoa_treatment_level,aoa_rfactor);
-                components.add(input);
+            for(int i=0;i<groups.length();i++){
+            Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
+            int AoAId = JSONUtils.getIntParam(group, "AoAId", 0);
+            String aoa_nslp=JSONUtils.getStringParam(group,"aoa_nslp","err");
+            String aoa_srp=JSONUtils.getStringParam(group,"aoa_srp","err");
+            String aoa_phr_leach_human=JSONUtils.getStringParam(group,"aoa_phr_leach_human","err");
+            String aoa_phr_leach_matcfish=JSONUtils.getStringParam(group,"aoa_phr_leach_matcfish","err");
+            String aoa_phr_sorun_human=JSONUtils.getStringParam(group,"aoa_phr_sorun_human","err");
+            String aoa_phr_sorun_matcfish=JSONUtils.getStringParam(group,"aoa_phr_sorun_matcfish","err");
+            String aoa_phr_adrun_human=JSONUtils.getStringParam(group,"aoa_phr_adrun_human","err");
+            String aoa_phr_adrun_stvfish=JSONUtils.getStringParam(group,"aoa_phr_adrun_stvfish","err");
+            String aoa_treatment_level=JSONUtils.getStringParam(group,"aoa_treatment_level","err");
+            int aoa_rfactor=JSONUtils.getIntParam(group,"aoa_rfactor",0);
+            Input input=new Input(AoAId,aoa_nslp,aoa_srp,aoa_phr_leach_human,aoa_phr_leach_matcfish,aoa_phr_sorun_human,aoa_phr_sorun_matcfish,aoa_phr_adrun_human,aoa_phr_adrun_stvfish,aoa_treatment_level,aoa_rfactor);
+            components.add(input);
             }
         }
-        @Override
-        protected String process() throws Exception
-        {
-                Connection conn = null;
-                Statement statement = null;
-                Class.forName("org.postgresql.Driver");
-                conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/wqm", "postgres", "admin");
-                conn.setAutoCommit(false);
+        catch( ServiceException | JSONException ex ){
+            this.error_msg = "Cannot process the input JSON: " + ex.getMessage();
+            LOG.log( Level.SEVERE, this.error_msg );
+        }
+    }
+    
+    @Override
+    protected String process() throws Exception
+    {
+        if ( this.error_msg.isEmpty() ){
+            try{
+                conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
                 statement = conn.createStatement();
+
                 for(Input ip:components)
                 {
                     String query="SELECT threshold_treatment_score FROM wqm_threshold_scores WHERE wqm_concern="+"'"+"Nitrogen in Ground Water"+"'"+"AND hazard_loss_rating ='"+ip.aoa_nslp+"' AND treatment_level='"+ip.aoa_treatment_level+"';";
@@ -145,19 +166,39 @@
                     {
                         aoa_pdrift_fish_threshold=results.getInt("threshold_treatment_score");
                     }
-                    
+
                     Result1 result=new Result1(ip.AoAId,aoa_nleach_threshold,aoa_nrun_threshold,aoa_sedrun_threshold,aoa_prun_threshold,aoa_pleach_human_threshold,aoa_pleach_matcfish_threshold,aoa_psorun_human_threshold,aoa_psorun_matcfish_threshold,aoa_padrun_human_threshold,aoa_padrun_stvfish_threshold,aoa_pdrift_human_threshold,aoa_pdrift_fish_threshold);
                     result1.add(result);
                 }
-               return EXEC_OK; 
+            }
+            catch( ServiceException | SQLException ex ){ 
+                this.error_msg = "Cannot process that request: " + ex.getMessage();
+                LOG.log( Level.SEVERE, this.error_msg );
+            }
+            finally{
+                if ( this.statement != null ){
+                    this.statement.close();
+                    this.statement = null;
+                }
+                
+                if ( this.conn != null ){
+                    this.conn.close();
+                    this.conn = null;
+                }                 
+            }            
         }
-        @Override
-        //writing the results back to JSON
+        
+        return ( this.error_msg.isEmpty()? EXEC_OK : this.error_msg ); 
+    }
+    
+    @Override
+    //writing the results back to JSON
     protected void postProcess() throws Exception 
     {
+        if ( this.error_msg.isEmpty() ){
+            try{
                 JSONArray result1Arr = new JSONArray();
-                for(Result1 rs1:result1)
-                {
+                for(Result1 rs1:result1){
                     JSONArray tmpArr = new JSONArray();
                     tmpArr.put(JSONUtils.dataDesc("AoAId", rs1.AoAId, "Area of Analysis Identifier"));
                     tmpArr.put(JSONUtils.dataDesc("aoa_nleach_threshold", rs1.aoa_nleach_threshold, "Nitrogen Leaching Threshold Score"));
@@ -175,6 +216,13 @@
                     result1Arr.put(JSONUtils.dataDesc("pesticide summary", tmpArr, "Pest"));
                 }
                 
-                putResult("operation", result1Arr);    
+                putResult("operation", result1Arr);  
+            }
+            catch( JSONException ex ){
+                this.error_msg = "Could not create result JSON: " + ex.getMessage();
+                LOG.log(Level.SEVERE, this.error_msg );
+                throw new Exception( this.error_msg );
+            }
+        }
     }
 }
\ No newline at end of file

src/java/m/wqm/wqmsoilattributes/V1_0.java

@@ -3,18 +3,14 @@
 /**
  *
  * @author RUMPAL SIDHU
+ * @author Shaun Case
  */
 import oms3.annotations.*;
 import csip.ModelDataService;
 import csip.annotations.*;
 import csip.utils.JSONUtils;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.UnsupportedCharsetException;
 import org.codehaus.jettison.json.JSONArray;
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -22,36 +18,25 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 import javax.ws.rs.Path;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.HttpClientBuilder;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 
+/**
+ *
+ * @author Shaun Case
+ */
 @Name("WQM-02: Soil Component Attributes (WQMSoilAttributes)")
 @Description("This service intersects area of analysis (AoA) geometry with SSURGO soil mapunit geometry, derives a list of distinct soil components for the AoA, and gets attributes from SSURGO tables required for computing nutrient and pesticide loss potentials.")
 @Path("m/wqmsoilattributes/1.0")
 @Polling(first = 10000, next = 2000)
 
 public class V1_0 extends ModelDataService {
-
-    //SQL params names here for quick modification
-    private final String USER = "gras_ssurgo";
-    private final String PASS = "admin";
-    private final String HOST = "csip.engr.colostate.edu";
-    private final String PORT = "5435";
-    private final String DBNAME = "ssurgo";
-    private final String JDBC_TYPE = "jdbc:postgresql://";
-    private final String CONNECTION = this.JDBC_TYPE + this.HOST + ":" + this.PORT + "/" + this.DBNAME;
-    private final String CLASS_NAME = "org.postgresql.Driver";
     
     //mapunit/ssurgo polygon intersect URI
-    private final String SSURGO_INTERSECT_URI = "http://csip.engr.colostate.edu:8081/csip/d/soils/1.1";        
+    private final String SSURGO_INTERSECT_URI = "http://csip.engr.colostate.edu:8086/csip-erosion/d/soils/1.2";        
 
     //Request
     private String aoaId;
@@ -59,6 +44,7 @@
 
     //Response
     private ArrayList<V1_0.Component> componentList;
+    private HashMap<String, V1_0.Component> componentMap;
 
     private String error_msg = "";
     private Connection conn = null;
@@ -78,9 +64,7 @@
             this.intersectCall = new ServiceCall( this.SSURGO_INTERSECT_URI );            
             
             try {
-                Class.forName(CLASS_NAME);
-                this.conn = DriverManager.getConnection( this.CONNECTION, this.USER, this.PASS);
-                this.conn.setAutoCommit(false);
+                this.conn = wqm.utils.WQMTools.getConnection( "ssurgo", LOG );
                 this.statement = this.conn.createStatement();
 
             } catch (SQLException se) {
@@ -91,113 +75,145 @@
         }
         else{
             //  No valid input stream for this service
-            this.error_msg = "No valid input parameters found .";
+            this.error_msg = "No valid input parameters were found.  Check your input JSON.";
         }                 
     }
 
     @Override
     protected String process() throws Exception {       
         if ( ( null != this.intersectCall ) && ( !this.intersectCall.getError() ) ){
-            HashMap<String, Double> aoa_mukeyList;            
+            HashMap<String, Double> aoa_mukeyList;               
             aoa_mukeyList = this.intersectCall.intersect( this.aoaGeometry );
-            if ( (!this.intersectCall.getError() ) && ( null != aoa_mukeyList) ){   
-                ResultSet resultSet;
-                String query;
-                this.componentList = new ArrayList();                
-                
-                Set keys = aoa_mukeyList.keySet();
-                Iterator ite = keys.iterator();
-                while (ite.hasNext()) {
-                    String mukey = ite.next().toString();
-                    double aoaArea = aoa_mukeyList.get( mukey );
-                    query = "SELECT cokey, compname, comppct_r FROM ssurgo.component "
-                            + "WHERE mukey='" + mukey + "' AND comppct_r IS NOT NULL ORDER BY cokey;";
+            try{
+                if ( (!this.intersectCall.getError() ) && ( null != aoa_mukeyList) && ( aoa_mukeyList.size() > 0) ){   
+                    ResultSet resultSet;
+                    String query;
+                    this.componentList = new ArrayList<>();   
+                    this.componentMap = new HashMap<>();
+                    int mapCount = 0;
+                    double totalAreas = 0.0;
+                    double aoa_comp_kfact = 0.0;
+                    String lastQueryWhere = "(";
+                    String lastQueryWhere2 = "(";
+
+                    Set keys = aoa_mukeyList.keySet();                                                
+                    Iterator ite = keys.iterator();
+
+                    query = "SELECT ssurgo.component.mukey, ssurgo.component.cokey, ssurgo.component.compname, ssurgo.component.comppct_r, ssurgo.component.hydgrp, "
+                            + " ssurgo.component.slope_r, ssurgo.component.taxorder, ssurgo.chorizon.chkey, ssurgo.chorizon.om_r, ssurgo.chorizon.hzthk_r, "
+                            + " ssurgo.chorizon.hzdept_r, ssurgo.chorizon.hzdepb_r, ssurgo.chorizon.kwfact, ssurgo.chorizon.kffact, ssurgo.chfrags.fragvol_r, ssurgo.chfrags.chfragskey FROM ssurgo.component "
+                            + " LEFT OUTER JOIN ssurgo.chorizon ON ssurgo.chorizon.cokey=ssurgo.component.cokey LEFT OUTER JOIN ssurgo.chfrags on ssurgo.chfrags.chkey=ssurgo.chorizon.chkey WHERE ssurgo.component.mukey='";
+
+                    while (ite.hasNext()) {
+                        if ( mapCount > 0 ){
+                            query += " OR ssurgo.component.mukey='" + ite.next().toString() + "' ";
+                        }
+                        else{
+                            query += ite.next().toString() + "' ";
+                        }   
+
+                        mapCount++;
+                    }
+                    query += "AND ssurgo.component.comppct_r IS NOT NULL ORDER BY ssurgo.component.mukey, ssurgo.component.cokey, ssurgo.chorizon.chkey, ssurgo.chorizon.hzdept_r;";
                     resultSet = this.statement.executeQuery( query );
-                    while (resultSet.next()) {
-                        Component component = new Component();
-                        component.setCokey(resultSet.getString("cokey"));
-                        component.setName(resultSet.getString("compname"));
-                        component.setArea(aoaArea * resultSet.getDouble("comppct_r"));
-                        this.componentList.add(component);
+                    while( resultSet.next() ){
+                        V1_0.Component tComponent;
+                        V1_0.Component component;
+
+                        String mukey = resultSet.getString( "mukey");                 
+                        String cokey = resultSet.getString("cokey");  
+                        String chkey = resultSet.getString("chkey"); 
+
+                        double aoa_Area = aoa_mukeyList.get( mukey );                   
+
+                        if ( !this.componentMap.containsKey( (cokey) )){
+                            component = new V1_0.Component( cokey, resultSet.getString("compname"), (aoa_Area * (resultSet.getDouble("comppct_r") / 100.0)), 
+                                                            resultSet.getString("hydgrp"), resultSet.getDouble("slope_r"), resultSet.getString("taxorder") );                           
+
+                            totalAreas += component.getArea();
+                            this.componentList.add( component );    
+                            this.componentMap.put( cokey, component );
+                            tComponent = component;                        
+                        }
+                        else{                 
+                            tComponent = this.componentMap.get( cokey );
+                        }
+
+                        //For the rest of these operations, we need to use the temp component pointer..
+                        //  Add chkeys to cokey object, some will be duplicates because they are unique by cokey:chkey:chfragkey
+                        double kwfact;
+                        Boolean kwfact_b;
+                        double kffact;
+                        Boolean kffact_b;
+                        double hzthk_r;
+                        Boolean hzthk_r_b;
+                        
+                        //  Keep these pairs of resultSet calls together..."wasNULL()" depends on the call previous to it.
+                        kwfact = resultSet.getDouble("kwfact");
+                        kwfact_b = resultSet.wasNull();
+                        kffact = resultSet.getDouble("kffact");
+                        kffact_b = resultSet.wasNull(); 
+                        hzthk_r = resultSet.getDouble("hzthk_r");
+                        hzthk_r_b = resultSet.wasNull();                        
+
+                        tComponent.addHorizon(chkey, resultSet.getString("chfragskey"), kwfact, kwfact_b, kffact, kffact_b, resultSet.getDouble("om_r"), hzthk_r, hzthk_r_b, resultSet.getDouble("hzdept_r"), resultSet.getDouble("hzdepb_r"), resultSet.getDouble("fragvol_r"));                    
                     }
-                }
+                    
+                    int componentsRemaining = 0;
+                    //Remove components having less than 10% of total area "totalAreas" here.                
+                    for( V1_0.Component component : this.componentList ){
+                        if ( (component.getArea() / totalAreas ) < 0.10 ){
+                            component.setDeleted(true);
+                        }
+                        else{
+                            componentsRemaining++;
+                            component.computeHorizonResults();   
+                            if ( lastQueryWhere.length() > 1 ){
+                                lastQueryWhere += " OR component.cokey='" + component.getCokey() + "'";
+                                lastQueryWhere2 += " OR WT1.cokey='" + component.getCokey() + "'";
+                            }
+                            else{
+                                lastQueryWhere += " component.cokey='" + component.getCokey() + "'";                            
+                                lastQueryWhere2 += "WT1.cokey='" + component.getCokey() + "'";
+                            }                        
+                        }                                        
+                    }                
 
-                //For each soil component (cokey) in the AoA
-                for (Component component : this.componentList) {
-                    //#Assign component-level parameters
-                    query = "SELECT hydgrp, slope_r, taxorder FROM ssurgo.component "
-                            + "WHERE cokey='" + component.getCokey() + "';";
-                    resultSet = statement.executeQuery(query);
-                    while (resultSet.next()) {
-                        component.setHsg(resultSet.getString("hydgrp"));
-                        component.setSlope(resultSet.getDouble("slope_r"));
-                        component.setTaxorder(resultSet.getString("taxorder"));
+                    if ( componentsRemaining > 0 ){
+                        lastQueryWhere += " ) ";
+                        lastQueryWhere2 += " ) ";   
+                        query = "With WT1 As (Select component.cokey, component.compname, component.comppct_r, MIN(cosoilmoist.soimoistdept_r) As wtbl_top_min, MAX(cosoilmoist.soimoistdepb_r) As wtbl_bot_max From ssurgo.component Inner Join ssurgo.comonth On component.cokey=comonth.cokey Inner Join ssurgo.cosoilmoist On comonth.comonthkey=cosoilmoist.comonthkey " 
+                               +"Where " + lastQueryWhere + "and cosoilmoist.soimoiststat='Wet' Group By component.cokey, component.compname, component.comppct_r Order By component.cokey), WT2 As (Select WT1.cokey, WT1.compname, WT1.comppct_r, WT1.wtbl_top_min, WT1.wtbl_bot_max, MAX(cosoilmoist.soimoistdept_r) As nonwet_top_max From WT1 Left Outer Join ssurgo.comonth On WT1.cokey=comonth.cokey Left Outer Join ssurgo.cosoilmoist On comonth.comonthkey=cosoilmoist.comonthkey " 
+                              + "Where " + lastQueryWhere2 + " and (cosoilmoist.soimoiststat NOT IN ('Wet') OR cosoilmoist.soimoiststat IS NULL) Group By WT1.cokey, WT1.compname, WT1.comppct_r, WT1.wtbl_top_min, WT1.wtbl_bot_max) Select WT2.cokey, WT2.compname, WT2.comppct_r, WT2.wtbl_top_min, WT2.wtbl_bot_max, WT2.nonwet_top_max, case when (wtbl_bot_max < 183 or nonwet_top_max >= wtbl_bot_max) then 'Perched' else 'Apparent' end as wtkind from WT2";
+                        resultSet = this.statement.executeQuery( query );
+
+                        while ( resultSet.next() ){
+                            String tCokey = resultSet.getString("cokey");
+                            V1_0.Component tcomponent = this.componentMap.get(tCokey);
+
+                            tcomponent.setWTBL( resultSet.getString("wtkind") );  //  If this is null, the set funciton will make the appropriate adjustment to "None".
+                            tcomponent.setWtblTopMin( resultSet.getDouble("wtbl_top_min") );
+                        }                                                    
                     }
-
-                    //#Find first mineral horizon layer and assign horizon-level parameters
-                    //For each chkey
-                    double aoa_comp_kfact;
-                    //For each cokey
-                    boolean check = false;
-                    query = "SELECT chkey, om_r, hzthk_r, kwfact, kffact FROM ssurgo.chorizon WHERE chkey IN (SELECT chkey FROM ssurgo.chorizon WHERE cokey='" + component.getCokey() + "');";
-                    resultSet = this.statement.executeQuery(query);
-                    while (resultSet.next()) {
-                        String chkey = resultSet.getString("chkey");
-                        double kwfact = resultSet.getDouble("kwfact");
-                        boolean kwfact_b = resultSet.wasNull();
-                        double kffact = resultSet.getDouble("kffact");
-                        boolean kffact_b = resultSet.wasNull();
-
-                        if (!kwfact_b || !kffact_b) {
-                            if (!kffact_b) {
-                                aoa_comp_kfact = kffact;
-                            } else {
-                                aoa_comp_kfact = kwfact;
-                            }
-
-                            component.setKfactor(aoa_comp_kfact);
-                            component.setOrganicMatter(resultSet.getDouble("om_r"));
-                            component.setHzdepth(resultSet.getDouble("hzthk_r"));
-                            String query2 = "SELECT fragvol_r FROM ssurgo.chfrags WHERE chkey ='" + chkey + "';";
-                            ResultSet resultSet2 = this.statement.executeQuery(query2);
-                            while (resultSet2.next()) {
-                                component.setCoarseFrag(resultSet2.getInt("fragvol_r"));
-                            }
-
-                            check = true;
-                            break;
-                        }
-                    }
-
-                    if (!check) {
-                        query = "SELECT chkey, om_r, hzthk_r FROM ssurgo.chorizon WHERE chkey IN (SELECT chkey FROM ssurgo.chorizon WHERE cokey='" + component.getCokey() + "');";
-                        resultSet = this.statement.executeQuery(query);
-                        while (resultSet.next()) {
-                            String chkey = resultSet.getString("chkey");
-
-                            component.setKfactor(0.02);
-                            component.setOrganicMatter(resultSet.getDouble("om_r"));
-                            component.setHzdepth(resultSet.getDouble("hzthk_r"));
-
-                            String query2 = "SELECT fragvol_r FROM ssurgo.chfrags WHERE chkey ='" + chkey + "';";
-                            ResultSet resultSet2 = this.statement.executeQuery(query2);
-                            while (resultSet2.next()) {
-                                component.setCoarseFrag(resultSet2.getInt("fragvol_r"));
-                            }
-                            break;
-                        }
-                    }
-                } // End For each component
-                                            
-            } // Actual Intersect Call failed.
-            else{
-                
+                } // Actual Intersect Call failed.
+                else{
+                    this.error_msg += " Could not intersect polygons. ";
+                }    
+            }
+            catch( SQLException se){
+                    this.error_msg += "Error executing SQL:  " + se.getMessage();                    
             }            
         }// Creation of Client objec to make call to intersect failed.
         else{
-            
+            this.error_msg += " Creation of intersect service call failed. ";            
         }
-                                     
+        
+        if ( null != this.conn ){
+            if ( null != this.statement ){
+                this.statement.close();                
+            }
+            this.conn.close();                
+        }
         return ( !this.error_msg.isEmpty()? this.error_msg : EXEC_OK );
     }
 
@@ -205,34 +221,38 @@
     protected void postProcess() throws Exception {
         putResult("AoaId", aoaId, "Area of Analysis Identifier");
         JSONArray resultArray = new JSONArray();
-        for (Component component : componentList) {
-            JSONArray tmpArr = new JSONArray();
-            tmpArr.put(JSONUtils.dataDesc("cokey", component.getCokey(), "Soil Component Key"));
-            tmpArr.put(JSONUtils.dataDesc("compname", component.getName(), "Soil Component Name"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_area", component.getArea(), "Soil Component Area (Acres) in the Area of Analysis"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_hsg", component.getHsg(), "Hydrologic Soil Group of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_taxorder", component.getTaxorder(), "Taxonomic Order of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_kfact", component.getKfactor(), "K factor of the Surface Mineral Horizon of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_slope", component.getSlope(), "Slope Percentage of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_coarse_frag", component.getCoarseFrag(), "Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_om", component.getOrganicMatter(), "Organic Matter Percentage of the  Surface Horizon of the Soil Componen"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_hzdepth", component.getHzdepth(), "Depth (inches) of the Surface Horizon of the Soil Component"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_cracksgr24", component.getCracksgr24(), "Surface Connected Macropores (Cracks) at Least 24 Inches Deep"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_slopegr15", component.getSlopegr15(), "Field Slope is Greater Than 15%"));
-            tmpArr.put(JSONUtils.dataDesc("aoa_comp_hwt_lt_24", component.getHwt_lt_24(), "High Water is Less than 24 Inches Under the Surface"));
-            resultArray.put(JSONUtils.dataDesc("soil_component", tmpArr, "Entry for Soil Component"));
+        for (Component component : componentList) {            
+            if ( !component.isDeleted() ){
+                JSONArray tmpArr = new JSONArray();            
+                tmpArr.put(JSONUtils.dataDesc("cokey", component.getCokey(), "Soil Component Key"));
+                tmpArr.put(JSONUtils.dataDesc("compname", component.getName(), "Soil Component Name"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_area", component.getArea(), "Soil Component Area (Acres) in the Area of Analysis"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_hsg", component.getHsg(), "Hydrologic Soil Group of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_taxorder", component.getTaxorder(), "Taxonomic Order of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_kfact", component.getKfactor(), "K factor of the Surface Mineral Horizon of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_slope", component.getSlope(), "Slope Percentage of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_coarse_frag", component.getCoarseFrag(), "Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_om", component.getOrganicMatter(), "Organic Matter Percentage of the  Surface Horizon of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_hzdepth", component.getHzdepth(), "Depth (inches) of the Surface Horizon of the Soil Component"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_wtbl", component.getWTBL(), "Kind of Water Table of the Soil Component; values are None, Apparent, Perched"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_cracksgr24", component.getCracksgr24(), "Surface Connected Macropores (Cracks) at Least 24 Inches Deep"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_slopegr15", component.getSlopegr15(), "Field Slope is Greater Than 15%"));
+                tmpArr.put(JSONUtils.dataDesc("aoa_comp_hwt_lt_24", component.getHwt_lt_24(), "High Water is Less than 24 Inches Under the Surface"));
+
+                resultArray.put(JSONUtils.dataDesc("soil_component", tmpArr, "Entry for Soil Component"));
+            };
         }
         putResult("soil_component_list", resultArray);
     }
         
     
     //Inner Classes
-        
+
     /**
      *
-     * @author RUMPAL SIDHU
-     * @author Shaun Case
      */
+            
+
     public class ServiceCall {
 
         private HashMap<String, Double> aoa_mukeyList;
@@ -252,6 +272,13 @@
 
         /*Calls the csip soil service to intersect AoA and SSURGO layers producing
          set of AoA x mapunit polygons */
+
+        /**
+         *
+         * @param aoaGeometry
+         * @return
+         */
+        
         public HashMap intersect(JSONObject aoaGeometry) {        
             if ( this.aoa_mukeyList.isEmpty() ){
                 try{            
@@ -265,28 +292,35 @@
                         JSONArray intersectResult = result.optJSONArray("result");
                         
                         if  (intersectResult.length() > 0 ){
-                            HashMap tempMap = new HashMap();                
+                            HashMap<String, Double> tempMap = new HashMap<>();                
                             String mukey;
                             double aoaArea;
                             ArrayList<String> keys = new ArrayList<String>();
-                            for (int i = 0; i < intersectResult.length(); i++) {
+                            JSONArray mukeyArray = intersectResult.getJSONArray(1).getJSONArray(0);
+                            
+                            for (int i = 0; i < mukeyArray.length(); i++) {
+                                Map<String, JSONObject> myResult = JSONUtils.preprocess( mukeyArray.getJSONArray(i) );
                                 
-                                mukey = intersectResult.getJSONArray(i+1).getJSONObject(1).getString("value");
-                                aoaArea = intersectResult.getJSONArray(i).getJSONObject(15).getDouble("value");
-                                boolean contains = tempMap.containsKey(aoaGeometry.toString());
-                                if (!contains) {
-                                    tempMap.put(mukey, aoaArea);
+                                mukey = JSONUtils.getStringParam (myResult,"ssurgo_mukey", "err" );
+                                aoaArea = JSONUtils.getDoubleParam( myResult, "acres_in_aoi", 0.0);
+
+                                /*
+                                //  Remember to sum the areas of same mukeys...
+                                if ( tempMap.containsKey( mukey ) ){
+                                    double tArea = tempMap.get( mukey );
+                                    aoaArea += tArea;
+                                }
+                                */
+                                
+                                tempMap.put(mukey, aoaArea);                                
+                                if ( !keys.contains( mukey ) ){
                                     keys.add(mukey);
-                                } else {
-                                    aoaArea = aoaArea + (Double) tempMap.get(mukey);
-                                    tempMap.remove(mukey);
-                                    tempMap.put(mukey, aoaArea);
                                 }
                             }  
 
                             Collections.sort(keys);
                             for (String i : keys) {
-                                this.aoa_mukeyList.put(i, (Double) tempMap.get(i));
+                                this.aoa_mukeyList.put(i, tempMap.get(i));
                             }                               
                         }
                         else{
@@ -303,21 +337,28 @@
             return this.aoa_mukeyList;
         }
 
+        /**
+         *
+         * @return
+         */
         public Boolean getError(){return (!this.error_msg.isEmpty());}
+
+        /**
+         *
+         * @return
+         */
         public String getErrorMsg(){return this.error_msg;}
 
 
 
         private JSONObject createRequest( JSONObject aoaGeometry) throws JSONException{
            JSONObject ret_val;
-           JSONArray headerArray1;
-           JSONArray headerArray2;
+           JSONArray headerArray;
            JSONObject metainfo;
 
            metainfo = new JSONObject();
            ret_val = new JSONObject();
-           headerArray1 = new JSONArray();
-           headerArray2 = new JSONArray();       
+           headerArray = new JSONArray();       
 
            metainfo.put( "MultipartRequest", "mapunit intersect request WQM-02");
            metainfo.put( "OriginalSource", getRequestHost() );
@@ -325,18 +366,16 @@
            metainfo.put( "OriginalSUID", getSUID() );
            ret_val.put("metainfo", metainfo );                     
 
-           headerArray2.put(JSONUtils.dataDesc( "AoAI", aoaGeometry, null ) );
+           headerArray.put(JSONUtils.dataDesc( "AoAI", aoaGeometry, null ) );
 
-           ret_val.put( "parameter", headerArray2);           
+           ret_val.put( "parameter", headerArray);           
 
            return ret_val;          
         }                        
     }
 
-
     /**
      *
-     * @author RUMPAL SIDHU
      */
     public class Component {
 
@@ -347,112 +386,408 @@
         private String taxorder; //Taxonomic Order of the Soil Component
         private double slope; //Slope Percentage of the Soil Component
         private double kfactor; //K factor of the Surface Mineral Horizon of the Soil Component
-        private int coarseFrag; //Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component
+        private double coarseFrag; //Weighted Average Coarse Rock Fragment Volume Percentage through the Profile of the Soil Component
         private double organicMatter; //Organic Matter Percentage of the  Surface Horizon of the Soil Component
         private double hzdepth; //Depth (inches) of the Surface Horizon of the Soil Component
         private boolean cracksgr24; //Surface Connected Macropores (Cracks) at Least 24 Inches Deep;  default is False
         private boolean slopegr15; //Field Slope is Greater Than 15%; default is False
         private boolean hwt_lt_24; //High Water is Less than 24 Inches Under the Surface; default is False
+        private double wtbl_top_min;
+        private String wtbl;
+        private double frag_vol_total;
+        Boolean Deleted;
+        
+        
+        private ArrayList<V1_0.Component.horizon> chKeys;
+        private HashMap<String, V1_0.Component.horizon> horizonMap;
 
-        public Component() {
-            cracksgr24 = false;
-            slopegr15 = false;
-            hwt_lt_24 = false;
+        /**
+         *
+         * @param cokey
+         * @param compname
+         * @param area
+         * @param hsg
+         * @param slope_r
+         * @param taxorder
+         */
+        public Component( String cokey, String compname, double area, String hsg, double slope_r, String taxorder) {
+            this.cracksgr24 = false;
+            this.slopegr15 = false;
+            this.hwt_lt_24 = false;
+            this.chKeys = new ArrayList<>();
+            this.horizonMap = new HashMap<>();
+            
+            this.cokey = cokey;
+            this.name = compname;
+            this.area = area;
+            this.hsg = hsg;
+            this.slope = slope_r;
+            this.taxorder = taxorder;
+            this.wtbl = "None";
+            this.wtbl_top_min = 0.0;
+            this.cracksgr24 = false;  //Set to default false, and is not updated by the current spec.
+            this.Deleted = false;
+            this.frag_vol_total = 0.0;
+            
+            this.slopegr15 = ( this.slope > 15.0 );                                   
         }
 
-        //Setter Methods
-        public void setCokey(String key) {
+        //Set Methods
+
+        /**
+         *
+         * @param key
+         */
+                public void setCokey(String key) {
             this.cokey = key;
         }
 
+        public void setDeleted( Boolean deleted ){
+            this.Deleted = deleted;
+        }
+        /**
+         *
+         * @param name
+         */
         public void setName(String name) {
             this.name = name;
         }
 
+        /**
+         *
+         * @param area
+         */
         public void setArea(double area) {
             this.area = area;
         }
 
+        /**
+         *
+         * @param hsg
+         */
         public void setHsg(String hsg) {
             this.hsg = hsg;
         }
 
+        /**
+         *
+         * @param taxorder
+         */
         public void setTaxorder(String taxorder) {
             this.taxorder = taxorder;
         }
 
+        /**
+         *
+         * @param slope
+         */
         public void setSlope(double slope) {
             this.slope = slope;
+            this.slopegr15 = ( this.slope > 15.0 );                                
         }
 
+        /**
+         *
+         * @param kfactor
+         */
         public void setKfactor(double kfactor) {
             this.kfactor = kfactor;
         }
 
+        /**
+         *
+         * @param coarseFrag
+         */
         public void setCoarseFrag(int coarseFrag) {
             this.coarseFrag = coarseFrag;
         }
 
+        /**
+         *
+         * @param organicMatter
+         */
         public void setOrganicMatter(double organicMatter) {
             this.organicMatter = organicMatter;
         }
 
+        /**
+         *
+         * @param depth
+         */
         public void setHzdepth(double depth) {
             this.hzdepth = depth;
         }
 
-        //Getter Methods
-        public String getCokey() {
+        public void setWTBL( String wtKind ){
+            if ( null == wtKind ){
+                this.wtbl = "None";
+            }
+            else{
+                this.wtbl = wtKind;
+            }                
+        }
+        
+        public void setWtblTopMin( double wtbl_top_min ){
+            this.wtbl_top_min = wtbl_top_min;
+            this.hwt_lt_24 = (wtbl_top_min <= 61);                
+        }
+        
+        //Get Methods
+
+        /**
+         *
+         * @return
+         */
+                public String getCokey() {
             return this.cokey;
         }
 
+        public Boolean isDeleted(){return this.Deleted;}
+        
+        /**
+         *
+         * @return
+         */
         public String getName() {
             return this.name;
         }
 
+        /**
+         *
+         * @return
+         */
         public double getArea() {
             return this.area;
         }
 
+        /**
+         *
+         * @return
+         */
         public String getHsg() {
             return this.hsg;
         }
 
+        /**
+         *
+         * @return
+         */
         public String getTaxorder() {
             return this.taxorder;
         }
 
+        /**
+         *
+         * @return
+         */
         public double getSlope() {
             return this.slope;
         }
 
+        /**
+         *
+         * @return
+         */
         public double getKfactor() {
             return this.kfactor;
         }
 
-        public int getCoarseFrag() {
+        /**
+         *
+         * @return
+         */
+        public double getCoarseFrag() {
             return this.coarseFrag;
         }
 
+        /**
+         *
+         * @return
+         */
         public double getOrganicMatter() {
             return this.organicMatter;
         }
 
+        /**
+         *
+         * @return
+         */
         public double getHzdepth() {
             return this.hzdepth;
         }
 
+        /**
+         *
+         * @return
+         */
         public boolean getCracksgr24() {
             return this.cracksgr24;
         }
 
+        /**
+         *
+         * @return
+         */
         public boolean getSlopegr15() {
             return this.slopegr15;
         }
 
+        /**
+         *
+         * @return
+         */
         public boolean getHwt_lt_24() {
             return this.hwt_lt_24;
         }
+        
+        public boolean getAoACompHwt(){return this.hwt_lt_24;}        
+        public String getWTBL(){return this.wtbl;}
+        public double getWtbltopMin(){return this.wtbl_top_min;}
+        
+        /**
+         *
+         * @param chkey
+         * @param chfragskey
+         * @param kwfact
+         * @param kwfact_b
+         * @param kffact
+         * @param kffact_b
+         * @param om_r
+         * @param hzthk_r
+         * @param hzdept_r
+         * @param hzdepb_r
+         */
+        public void addHorizon( String chkey, String chfragskey, double kwfact, boolean kwfact_b, double kffact, boolean kffact_b, double om_r, double hzthk_r, Boolean hzthk_r_b, double hzdept_r, double hzdepb_r, double fragvol_r ){                       
+            //  Each component can have mulitiple horizons...each horizon can have multiple fragment volumes...
+            V1_0.Component.horizon tHorizon;
+            if ( this.horizonMap.containsKey( chkey ) ){
+                tHorizon = this.horizonMap.get( chkey );
+                tHorizon.addFragKey( chfragskey, fragvol_r );
+            }
+            else{
+                tHorizon = new V1_0.Component.horizon(  chkey,  chfragskey, kwfact,  kwfact_b,  kffact,  kffact_b,  om_r,  hzthk_r, hzthk_r_b,  hzdept_r,  hzdepb_r, fragvol_r );            
+                this.chKeys.add( tHorizon );
+                this.horizonMap.put( chkey, tHorizon );
+            }
+        }
+        
+        public void computeHorizonResults(){
+            double profile_thk = 0.0;
+            Boolean haveKFactor = false;      
+            double comp_product = 0.0;
+                        
+            //If we remove the "order by" which includes hzdept_r in the first SQL statement in process(), then we need to sort this list before continuing...
+            //For now this "order by...hzdept_r" is currently in the SQL statement, so no sort is done here.  If we find that the SQL statement takes longer with
+            //The order by clause, and the sort is quicker here, then this code will change.
+
+             //#Get first horizon organic matter            
+            this.organicMatter = this.chKeys.get(0).getOm_r();
+            
+            for( V1_0.Component.horizon horizon : this.chKeys ){
+                double horizonThickness = 0.0;
+                double horizonProduct = 0.0;
+                
+                if ( !horizon.getHzthk_r_b() ){
+                    this.hzdepth = horizon.getHzdepb_r() - horizon.getHzdept_r();
+                }
+                else{
+                    this.hzdepth = horizon.getHzdept_r();
+                }
+
+                if ( this.hsg.equals("D") && this.taxorder.equals("Histosols") && horizon.getKffact_b() && horizon.getKwfact_b() ){
+                    this.kfactor = 0.02;
+                }
+                else{
+                    if ( !haveKFactor ){
+                        if ( !horizon.getKffact_b() && horizon.getKwfact_b() ){
+                            this.kfactor = horizon.getKffact();
+                            haveKFactor = true;
+                        }
+                        else{
+                            if( !horizon.getKwfact_b() && horizon.getKffact_b() ){
+                                this.kfactor = horizon.getKwfact();
+                                haveKFactor = true;
+                            }
+                        }
+                    }
+                }
+                
+                this.frag_vol_total += horizon.getFragVol();
+                if ( horizon.getHzthk_r_b() ){
+                    horizonThickness = horizon.getHzdepb_r() - horizon.getHzdept_r();
+                }
+                else{
+                    horizonThickness = horizon.getHzthk_r();                    
+                }
+                profile_thk += horizonThickness;
+                horizonProduct = horizonThickness * horizon.getFragVol();
+                comp_product += horizonProduct;                                              
+            }                        
+            
+            this.coarseFrag = comp_product / profile_thk;         
+        }
+        
+        class horizon implements Comparable<V1_0.Component.horizon> {
+            private final String chkey;
+            private final String chfragskey;            
+            private final double kwfact;
+            private final Boolean kwfact_b;
+            private final double kffact;
+            private final Boolean kffact_b;
+            private final double om_r;
+            private final double hzthk_r;
+            private final double hzdept_r;
+            private final double hzdepb_r;
+            private final Boolean hzthk_r_b;
+            private double frag_vol_total;
+            private HashMap <String, Double> fragkeyMap;
+                        
+            horizon( String chkey, String chfragskey, double kwfact, boolean kwfact_b, double kffact, boolean kffact_b, double om_r, double hzthk_r, Boolean hzthk_r_b, double hzdept_r, double hzdepb_r, double fragvol_r ){
+                this.chkey = chkey;
+                this.chfragskey = chfragskey;
+                this.kwfact = kwfact;
+                this.kwfact_b = kwfact_b;
+                this.kffact = kffact;
+                this.kffact_b = kffact_b;
+                this.om_r = om_r;
+                this.hzthk_r = hzthk_r;
+                this.hzthk_r_b = hzthk_r_b;
+                this.hzdept_r = hzdept_r;
+                this.hzdepb_r = hzdepb_r;                                
+                this.fragkeyMap = new HashMap<>();
+                
+                this.fragkeyMap.put(chfragskey, fragvol_r ); 
+                this.frag_vol_total = fragvol_r;
+            }
+            
+            @Override
+            public int compareTo(V1_0.Component.horizon tHorizon ){
+                int ret_val = 0;
+                //TODO:  Allow this to be sorted....by chkey:chfragskey:hzdept_r
+                //  This might be needed if the "order by" clause of the SQL statement 
+                //  used to get this data runs faster without the "order by" that includes this hzdept_r value....
+                
+                return ret_val;
+            }
+           
+            public void addFragKey( String chfragskey, double fragvol_r ){
+                this.fragkeyMap.put( chfragskey, fragvol_r );
+                this.frag_vol_total += fragvol_r;
+            }
+            
+            public double getFragVol(){ return this.frag_vol_total; }            
+            public String getChkey(){ return this.chkey;}
+            public String getChfragsKey(){ return this.chfragskey;}
+            public double getKwfact(){ return this.kwfact;}
+            public boolean getKwfact_b(){ return this.kwfact_b;}
+            public double getKffact(){ return this.kffact;}
+            public boolean getKffact_b(){ return this.kffact_b;}
+            public double getOm_r(){ return this.om_r;}
+            public double getHzthk_r(){ return this.hzthk_r;}
+            public Boolean getHzthk_r_b(){ return this.hzthk_r_b;}
+            public double getHzdept_r(){ return this.hzdept_r;}
+            public double getHzdepb_r(){ return this.hzdepb_r;}                                   
+        }
     }
     
 }

src/java/m/wqm/wqsr/V1_0.java

@@ -31,31 +31,36 @@
 @Path("m/wqm/wqsr/1.0")
 
 public class V1_0 extends ModelDataService {
-    
-    
+  
+/*
     private final String USER = "postgres";
-   private final String PASS = "admin";
-   private final String HOST = "csip.engr.colostate.edu";
-   private  final String PORT = "5435";
-   private  final String DBNAME = "ssurgo";
-   private final String SERVER = "localhost:5432/postgres";
-   private final String JDBC_TYPE = "jdbc:postgresql://";
-   private final String CLASS_NAME = "org.postgresql.Driver";
-   private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
-    
-   
-   private String aoaId;
-   private JSONArray polygon,coordinates;
-   String points,finalpoints="";
-   JSONArray aoaArr;
-   ArrayList<AoA> list;
- Double aoaBaseArea=0.0,aoaSensitiveArea=0.0,aoaCriticalArea=0.0;
+    private final String PASS = "admin";
+    private final String HOST = "csip.engr.colostate.edu";
+    private  final String PORT = "5435";
+    private  final String DBNAME = "ssurgo";
+    private final String SERVER = "localhost:5432/postgres";
+    private final String JDBC_TYPE = "jdbc:postgresql://";
+    private final String CLASS_NAME = "org.postgresql.Driver";
+    private final String CONNECTION = JDBC_TYPE + HOST + ":" + PORT + "/" + DBNAME;
+*/
+    private Connection tempCon;
+    private Statement stmt;
+
+    private String aoaId;
+    private JSONArray polygon,coordinates;
+    String points,finalpoints="";
+    JSONArray aoaArr;
+    ArrayList<AoA> list;
+    Double aoaBaseArea=0.0,aoaSensitiveArea=0.0,aoaCriticalArea=0.0;
     
     @Override
     public void preProcess() throws ServiceException, JSONException
     {
-         list=new ArrayList<AoA>();
-    aoaArr = getJSONArrayParam("aoas");
+        tempCon = null;
+        stmt = null;
+        list=new ArrayList<AoA>();
+         
+        aoaArr = getJSONArrayParam("aoas");
         for(int i = 0; i < aoaArr.length(); i++) {
             //Map individual JSONObject & extract values
         Map<String, JSONObject> thisAoA = JSONUtils.preprocess(aoaArr.getJSONArray(i));
@@ -85,11 +90,10 @@
     @Override
     public String process()
     {
-       Connection tempCon=null;
-       Statement stmt=null;
         try {
-          Class.forName(CLASS_NAME);
-          tempCon=DriverManager.getConnection(CONNECTION,"postgres","admin");
+          //Class.forName(CLASS_NAME);
+          //tempCon=DriverManager.getConnection(CONNECTION,"postgres","admin");
+          tempCon = wqm.utils.WQMTools.getConnection("ssurgo", LOG );
           tempCon.setAutoCommit(false);
           stmt=tempCon.createStatement();
          
@@ -99,7 +103,8 @@
           aoaSensitiveArea=0.0;
           aoaCriticalArea=0.0;
         //Query to select the area,rating and treatment level which given coordinates intersects wqsr_area geometry
-          ResultSet results=stmt.executeQuery("select shape_area,wqs_rating,wqs_treatment_level from wqm_huc12.wqsr_area WHERE ST_Intersects(ST_PolygonFromText('POLYGON(("+list.get(i).getCoordinates()+"))'),geom)");
+//          ResultSet results=stmt.executeQuery("select shape_area,wqs_rating,wqs_treatment_level from wqm_huc12.wqsr_area WHERE ST_Intersects(ST_PolygonFromText('POLYGON(("+list.get(i).getCoordinates()+"))'),geom)");
+            ResultSet results=stmt.executeQuery("select shape_area,wqs_rating,wqs_treatment_level from wqm_huc12.wqsr_area WHERE ST_Intersects('POLYGON(("+list.get(i).getCoordinates()+"))'::geography::geometry, geom)");
           while(results.next())
       { 
         String wqsRating=results.getString("wqs_rating");
@@ -138,17 +143,31 @@
     @Override
     public void postProcess() throws JSONException
     {
+        try{
+            if ( this.stmt != null ){
+                this.stmt.close();
+                this.stmt = null;
+            }
+            if ( this.tempCon != null ){
+                this.tempCon.close();
+                this.tempCon = null;
+            }
+        }
+        catch (Exception ex ){
+            LOG.warning(" Could not close database connection: " + ex.getMessage() );
+        }
+            
         JSONArray finalArr= new JSONArray();
-        for(int i=0;i<list.size();i++)
-        {
-    JSONArray resultArr = new JSONArray();
-    resultArr.put(JSONUtils.dataDesc("AoAId",list.get(i).getAoAId(),"Area of Analysis Identifier"));
-    resultArr.put(JSONUtils.dataDesc("wqs_Rating",list.get(i).getWQSRating(),"WQS Rating"));
-    resultArr.put(JSONUtils.dataDesc("wqs_treatment_level",list.get(i).getTreatmentLevel(),"WQS Treatment Level"));
+        for(int i=0;i<list.size();i++){
+            JSONArray resultArr = new JSONArray();
+            resultArr.put(JSONUtils.dataDesc("AoAId",list.get(i).getAoAId(),"Area of Analysis Identifier"));
+            resultArr.put(JSONUtils.dataDesc("wqs_Rating",list.get(i).getWQSRating(),"WQS Rating"));
+            resultArr.put(JSONUtils.dataDesc("wqs_treatment_level",list.get(i).getTreatmentLevel(),"WQS Treatment Level"));
+
+            finalArr.put(resultArr);
+        }
+        
+        putResult("",finalArr);
+    }
+}
     
-    finalArr.put(resultArr);
-    }
-    putResult("",finalArr);
-    }
-        }
-    

web/META-INF/csip-conf.json

@@ -1,5 +1,10 @@
-
-  "csip.archive.enabled"  : false,
-  "csip.logging.enabled"  : false,
-  "wqm.version" : "$version: ${out} $"
-}
+
+  "csip.archive.enabled"  : false,
+  "csip.logging.enabled"  : false,
+  "wqm.debugging"   : false,
+  "wqm.debug.db": "jdbc:postgresql://localhost:5432/wqm",
+  "wqm.db": "jdbc:postgresql://csip.engr.colostate.edu:5435/wqm",  
+  "ssurgo.db": "jdbc:postgresql://csip.engr.colostate.edu:5435/ssurgo", 
+  "r2gis.db": "jdbc:postgresql://csip.engr.colostate.edu:5435/r2gis", 
+  "wqm.version" : "$version: 0.1.110 5fef86c018df 2015-09-23 $"
+}