Displaying differences for changeset
 
display as  

nbproject/build-impl.xml

@@ -1,1459 +1,1488 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-        *** GENERATED FROM project.xml - DO NOT EDIT  ***
-        ***         EDIT ../build.xml INSTEAD         ***
-
-        For the purpose of easier reading the script
-        is divided into following sections:
-        - initialization
-        - compilation
-        - dist
-        - execution
-        - debugging
-        - javadoc
-        - test compilation
-        - test execution
-        - test debugging
-        - cleanup
-
-        -->
-<project xmlns:webproject1="http://www.netbeans.org/ns/web-project/1" xmlns:webproject2="http://www.netbeans.org/ns/web-project/2" xmlns:webproject3="http://www.netbeans.org/ns/web-project/3" basedir=".." default="default" name="csip-wqm-impl">
-    <import file="rest-build.xml"/>
-    <import file="ant-deploy.xml"/>
-    <fail message="Please build using Ant 1.7.1 or higher.">
-        <condition>
-            <not>
-                <antversion atleast="1.7.1"/>
-            </not>
-        </condition>
-    </fail>
-    <target depends="dist,javadoc" description="Build whole project." name="default"/>
-    <!--
-                INITIALIZATION SECTION
-            -->
-    <target name="-pre-init">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="-pre-init" name="-init-private">
-        <property file="nbproject/private/private.properties"/>
-    </target>
-    <target depends="-pre-init,-init-private" name="-init-user">
-        <property file="${user.properties.file}"/>
-        <!-- The two properties below are usually overridden -->
-        <!-- by the active platform. Just a fallback. -->
-        <property name="default.javac.source" value="1.4"/>
-        <property name="default.javac.target" value="1.4"/>
-    </target>
-    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
-        <property file="nbproject/project.properties"/>
-    </target>
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" if="dist.ear.dir" name="-do-ear-init"/>
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
-        <condition property="have.tests">
-            <or>
-                <available file="${test.src.dir}"/>
-            </or>
-        </condition>
-        <condition property="have.sources">
-            <or>
-                <available file="${src.dir}"/>
-            </or>
-        </condition>
-        <condition property="netbeans.home+have.tests">
-            <and>
-                <isset property="netbeans.home"/>
-                <isset property="have.tests"/>
-            </and>
-        </condition>
-        <condition property="no.javadoc.preview">
-            <isfalse value="${javadoc.preview}"/>
-        </condition>
-        <property name="javac.compilerargs" value=""/>
-        <condition property="no.deps">
-            <and>
-                <istrue value="${no.dependencies}"/>
-            </and>
-        </condition>
-        <condition property="no.dist.ear.dir">
-            <not>
-                <isset property="dist.ear.dir"/>
-            </not>
-        </condition>
-        <property name="build.web.excludes" value="${build.classes.excludes}"/>
-        <condition property="do.compile.jsps">
-            <istrue value="${compile.jsps}"/>
-        </condition>
-        <condition property="do.debug.server">
-            <or>
-                <not>
-                    <isset property="debug.server"/>
-                </not>
-                <istrue value="${debug.server}"/>
-                <and>
-                    <not>
-                        <istrue value="${debug.server}"/>
-                    </not>
-                    <not>
-                        <istrue value="${debug.client}"/>
-                    </not>
-                </and>
-            </or>
-        </condition>
-        <condition property="do.debug.client">
-            <istrue value="${debug.client}"/>
-        </condition>
-        <condition property="do.display.browser">
-            <istrue value="${display.browser}"/>
-        </condition>
-        <condition property="do.display.browser.debug.old">
-            <and>
-                <isset property="do.display.browser"/>
-                <not>
-                    <isset property="do.debug.client"/>
-                </not>
-                <not>
-                    <isset property="browser.context"/>
-                </not>
-            </and>
-        </condition>
-        <condition property="do.display.browser.debug">
-            <and>
-                <isset property="do.display.browser"/>
-                <not>
-                    <isset property="do.debug.client"/>
-                </not>
-                <isset property="browser.context"/>
-            </and>
-        </condition>
-        <available file="${conf.dir}/MANIFEST.MF" property="has.custom.manifest"/>
-        <available file="${persistence.xml.dir}/persistence.xml" property="has.persistence.xml"/>
-        <condition property="do.war.package.with.custom.manifest">
-            <isset property="has.custom.manifest"/>
-        </condition>
-        <condition property="do.war.package.without.custom.manifest">
-            <not>
-                <isset property="has.custom.manifest"/>
-            </not>
-        </condition>
-        <condition property="do.tmp.war.package.with.custom.manifest">
-            <and>
-                <isset property="has.custom.manifest"/>
-                <or>
-                    <isfalse value="${directory.deployment.supported}"/>
-                    <isset property="dist.ear.dir"/>
-                </or>
-            </and>
-        </condition>
-        <condition property="do.tmp.war.package.without.custom.manifest">
-            <and>
-                <not>
-                    <isset property="has.custom.manifest"/>
-                </not>
-                <or>
-                    <isfalse value="${directory.deployment.supported}"/>
-                    <isset property="dist.ear.dir"/>
-                </or>
-            </and>
-        </condition>
-        <condition property="do.tmp.war.package">
-            <or>
-                <isfalse value="${directory.deployment.supported}"/>
-                <isset property="dist.ear.dir"/>
-            </or>
-        </condition>
-        <property name="build.meta.inf.dir" value="${build.web.dir}/META-INF"/>
-        <condition else="" property="application.args.param" value="${application.args}">
-            <and>
-                <isset property="application.args"/>
-                <not>
-                    <equals arg1="${application.args}" arg2="" trim="true"/>
-                </not>
-            </and>
-        </condition>
-        <property name="source.encoding" value="${file.encoding}"/>
-        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
-            <and>
-                <isset property="javadoc.encoding"/>
-                <not>
-                    <equals arg1="${javadoc.encoding}" arg2=""/>
-                </not>
-            </and>
-        </condition>
-        <property name="javadoc.encoding.used" value="${source.encoding}"/>
-        <property name="includes" value="**"/>
-        <property name="excludes" value=""/>
-        <property name="runmain.jvmargs" value=""/>
-        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
-        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
-            <and>
-                <isset property="endorsed.classpath"/>
-                <length length="0" string="${endorsed.classpath}" when="greater"/>
-            </and>
-        </condition>
-        <condition else="false" property="jdkBug6558476">
-            <and>
-                <matches pattern="1\.[56]" string="${java.specification.version}"/>
-                <not>
-                    <os family="unix"/>
-                </not>
-            </and>
-        </condition>
-        <property name="javac.fork" value="${jdkBug6558476}"/>
-        <condition property="junit.available">
-            <or>
-                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
-                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
-            </or>
-        </condition>
-        <condition property="testng.available">
-            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
-        </condition>
-        <condition property="junit+testng.available">
-            <and>
-                <istrue value="${junit.available}"/>
-                <istrue value="${testng.available}"/>
-            </and>
-        </condition>
-        <condition else="testng" property="testng.mode" value="mixed">
-            <istrue value="${junit+testng.available}"/>
-        </condition>
-        <condition else="" property="testng.debug.mode" value="-mixed">
-            <istrue value="${junit+testng.available}"/>
-        </condition>
-    </target>
-    <target depends="init" name="-init-cos" unless="deploy.on.save">
-        <condition property="deploy.on.save" value="true">
-            <or>
-                <istrue value="${j2ee.deploy.on.save}"/>
-                <istrue value="${j2ee.compile.on.save}"/>
-            </or>
-        </condition>
-    </target>
-    <target name="-post-init">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
-        <fail unless="src.dir">Must set src.dir</fail>
-        <fail unless="test.src.dir">Must set test.src.dir</fail>
-        <fail unless="build.dir">Must set build.dir</fail>
-        <fail unless="build.web.dir">Must set build.web.dir</fail>
-        <fail unless="build.generated.dir">Must set build.generated.dir</fail>
-        <fail unless="dist.dir">Must set dist.dir</fail>
-        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
-        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
-        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
-        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
-        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
-        <fail unless="dist.war">Must set dist.war</fail>
-        <condition property="missing.j2ee.server.home">
-            <and>
-                <matches pattern="j2ee.server.home" string="${j2ee.platform.classpath}"/>
-                <not>
-                    <isset property="j2ee.server.home"/>
-                </not>
-            </and>
-        </condition>
-        <fail if="missing.j2ee.server.home">
-The Java EE server classpath is not correctly set up - server home directory is missing.
-Either open the project in the IDE and assign the server or setup the server classpath manually.
-For example like this:
-   ant -Dj2ee.server.home=&lt;app_server_installation_directory&gt;
-                </fail>
-        <fail unless="j2ee.platform.classpath">
-The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}.
-Either open the project in the IDE and assign the server or setup the server classpath manually.
-For example like this:
-   ant -Duser.properties.file=&lt;path_to_property_file&gt; (where you put the property "j2ee.platform.classpath" in a .properties file)
-or ant -Dj2ee.platform.classpath=&lt;server_classpath&gt; (where no properties file is used)
-                </fail>
-    </target>
-    <target name="-init-macrodef-property">
-        <macrodef name="property" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute name="name"/>
-            <attribute name="value"/>
-            <sequential>
-                <property name="@{name}" value="${@{value}}"/>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
-        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${src.dir}" name="srcdir"/>
-            <attribute default="${build.classes.dir}" name="destdir"/>
-            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
-            <attribute default="${javac.processorpath}" name="processorpath"/>
-            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="${javac.debug}" name="debug"/>
-            <attribute default="${empty.dir}" name="gensrcdir"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property location="${build.dir}/empty" name="empty.dir"/>
-                <mkdir dir="${empty.dir}"/>
-                <mkdir dir="@{apgeneratedsrcdir}"/>
-                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}">
-                    <src>
-                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
-                            <include name="*"/>
-                        </dirset>
-                    </src>
-                    <classpath>
-                        <path path="@{classpath}"/>
-                    </classpath>
-                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
-                    <compilerarg line="${javac.compilerargs}"/>
-                    <compilerarg value="-processorpath"/>
-                    <compilerarg path="@{processorpath}:${empty.dir}"/>
-                    <compilerarg line="${ap.processors.internal}"/>
-                    <compilerarg value="-s"/>
-                    <compilerarg path="@{apgeneratedsrcdir}"/>
-                    <compilerarg line="${ap.proc.none.internal}"/>
-                    <customize/>
-                </javac>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
-        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${src.dir}" name="srcdir"/>
-            <attribute default="${build.classes.dir}" name="destdir"/>
-            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
-            <attribute default="${javac.processorpath}" name="processorpath"/>
-            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="${javac.debug}" name="debug"/>
-            <attribute default="${empty.dir}" name="gensrcdir"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property location="${build.dir}/empty" name="empty.dir"/>
-                <mkdir dir="${empty.dir}"/>
-                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}">
-                    <src>
-                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
-                            <include name="*"/>
-                        </dirset>
-                    </src>
-                    <classpath>
-                        <path path="@{classpath}"/>
-                    </classpath>
-                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
-                    <compilerarg line="${javac.compilerargs}"/>
-                    <customize/>
-                </javac>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
-        <macrodef name="depend" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${src.dir}" name="srcdir"/>
-            <attribute default="${build.classes.dir}" name="destdir"/>
-            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
-            <sequential>
-                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
-                    <classpath>
-                        <path path="@{classpath}"/>
-                    </classpath>
-                </depend>
-            </sequential>
-        </macrodef>
-        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${build.classes.dir}" name="destdir"/>
-            <sequential>
-                <fail unless="javac.includes">Must set javac.includes</fail>
-                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
-                    <path>
-                        <filelist dir="@{destdir}" files="${javac.includes}"/>
-                    </path>
-                    <globmapper from="*.java" to="*.class"/>
-                </pathconvert>
-                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
-                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
-                <delete>
-                    <files includesfile="${javac.includesfile.binary}"/>
-                </delete>
-                <delete file="${javac.includesfile.binary}"/>
-            </sequential>
-        </macrodef>
-    </target>
-    <target if="${junit.available}" name="-init-macrodef-junit-init">
-        <condition else="false" property="nb.junit.batch" value="true">
-            <and>
-                <istrue value="${junit.available}"/>
-                <not>
-                    <isset property="test.method"/>
-                </not>
-            </and>
-        </condition>
-        <condition else="false" property="nb.junit.single" value="true">
-            <and>
-                <istrue value="${junit.available}"/>
-                <isset property="test.method"/>
-            </and>
-        </condition>
-    </target>
-    <target name="-init-test-properties">
-        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
-        <property name="test.binarytestincludes" value=""/>
-        <property name="test.binaryexcludes" value=""/>
-    </target>
-    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${java.io.tmpdir}">
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
-        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property name="run.jvmargs.ide" value=""/>
-                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
-                    <batchtest todir="${build.test.results.dir}">
-                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
-                            <filename name="${test.binarytestincludes}"/>
-                        </fileset>
-                    </batchtest>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <jvmarg line="${run.jvmargs.ide}"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
-    <target if="${testng.available}" name="-init-macrodef-testng">
-        <macrodef name="testng" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
-                    <isset property="test.method"/>
-                </condition>
-                <union id="test.set">
-                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
-                        <filename name="@{testincludes}"/>
-                    </fileset>
-                </union>
-                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
-                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="csip-wqm" testname="TestNG tests" workingDir="${basedir}">
-                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
-                    <propertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </propertyset>
-                    <customize/>
-                </testng>
-            </sequential>
-        </macrodef>
-    </target>
-    <target name="-init-macrodef-test-impl">
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element implicit="true" name="customize" optional="true"/>
-            <sequential>
-                <echo>No tests executed.</echo>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element implicit="true" name="customize" optional="true"/>
-            <sequential>
-                <webproject2:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize/>
-                </webproject2:junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
-        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element implicit="true" name="customize" optional="true"/>
-            <sequential>
-                <webproject2:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize/>
-                </webproject2:testng>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
-        <macrodef name="test" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <sequential>
-                <webproject2:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize>
-                        <classpath>
-                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
-                        </classpath>
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
-                        <jvmarg line="${runmain.jvmargs}"/>
-                    </customize>
-                </webproject2:test-impl>
-            </sequential>
-        </macrodef>
-    </target>
-    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${java.io.tmpdir}">
-                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
-        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <property name="run.jvmargs.ide" value=""/>
-                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
-                    <batchtest todir="${build.test.results.dir}">
-                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
-                            <filename name="@{testincludes}"/>
-                        </fileset>
-                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
-                            <filename name="${test.binarytestincludes}"/>
-                        </fileset>
-                    </batchtest>
-                    <syspropertyset>
-                        <propertyref prefix="test-sys-prop."/>
-                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <formatter type="brief" usefile="false"/>
-                    <formatter type="xml"/>
-                    <jvmarg value="-ea"/>
-                    <jvmarg line="${run.jvmargs.ide}"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
-                    <customize/>
-                </junit>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
-        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <element implicit="true" name="customize" optional="true"/>
-            <sequential>
-                <webproject2:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize/>
-                </webproject2:junit-debug>
-            </sequential>
-        </macrodef>
-    </target>
-    <target if="${testng.available}" name="-init-macrodef-testng-debug">
-        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${main.class}" name="testClass"/>
-            <attribute default="" name="testMethod"/>
-            <element name="customize2" optional="true"/>
-            <sequential>
-                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
-                    <isset property="test.method"/>
-                </condition>
-                <condition else="-suitename csip-wqm -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
-                    <matches pattern=".*\.xml" string="@{testClass}"/>
-                </condition>
-                <delete dir="${build.test.results.dir}" quiet="true"/>
-                <mkdir dir="${build.test.results.dir}"/>
-                <webproject1:debug args="${testng.cmd.args}" classname="org.testng.TestNG" classpath="${debug.test.classpath}:${j2ee.platform.embeddableejb.classpath}">
-                    <customize>
-                        <customize2/>
-                        <jvmarg value="-ea"/>
-                        <arg line="${testng.debug.mode}"/>
-                        <arg line="-d ${build.test.results.dir}"/>
-                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
-                    </customize>
-                </webproject1:debug>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
-        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${main.class}" name="testClass"/>
-            <attribute default="" name="testMethod"/>
-            <element implicit="true" name="customize2" optional="true"/>
-            <sequential>
-                <webproject2:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
-                    <customize2/>
-                </webproject2:testng-debug>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
-        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <attribute default="${main.class}" name="testClass"/>
-            <attribute default="" name="testMethod"/>
-            <sequential>
-                <webproject2:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
-                    <customize>
-                        <classpath>
-                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
-                        </classpath>
-                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
-                        <jvmarg line="${runmain.jvmargs}"/>
-                    </customize>
-                </webproject2:test-debug-impl>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
-        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
-            <attribute default="${includes}" name="includes"/>
-            <attribute default="${excludes}" name="excludes"/>
-            <attribute default="**" name="testincludes"/>
-            <attribute default="" name="testmethods"/>
-            <attribute default="${main.class}" name="testClass"/>
-            <attribute default="" name="testMethod"/>
-            <sequential>
-                <webproject2:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
-                    <customize2>
-                        <syspropertyset>
-                            <propertyref prefix="test-sys-prop."/>
-                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
-                        </syspropertyset>
-                    </customize2>
-                </webproject2:testng-debug-impl>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
-    <target name="-init-macrodef-java">
-        <macrodef name="java" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute default="${main.class}" name="classname"/>
-            <attribute default="${debug.classpath}" name="classpath"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <java classname="@{classname}" fork="true">
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
-                    <jvmarg line="${runmain.jvmargs}"/>
-                    <classpath>
-                        <path path="@{classpath}:${j2ee.platform.classpath}"/>
-                    </classpath>
-                    <syspropertyset>
-                        <propertyref prefix="run-sys-prop."/>
-                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <customize/>
-                </java>
-            </sequential>
-        </macrodef>
-    </target>
-    <target name="-init-macrodef-nbjsdebug">
-        <macrodef name="nbjsdebugstart" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute default="${client.url}" name="webUrl"/>
-            <sequential>
-                <nbjsdebugstart urlPart="${client.urlPart}" webUrl="@{webUrl}"/>
-            </sequential>
-        </macrodef>
-    </target>
-    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
-        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute default="${main.class}" name="name"/>
-            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
-            <sequential>
-                <nbjpdastart addressproperty="jpda.address" name="@{name}" transport="${debug-transport}">
-                    <classpath>
-                        <path path="@{classpath}"/>
-                    </classpath>
-                </nbjpdastart>
-            </sequential>
-        </macrodef>
-        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute default="${build.classes.dir}" name="dir"/>
-            <sequential>
-                <nbjpdareload>
-                    <fileset dir="@{dir}" includes="${fix.classes}">
-                        <include name="${fix.includes}*.class"/>
-                    </fileset>
-                </nbjpdareload>
-            </sequential>
-        </macrodef>
-        <macrodef name="nbjpdaappreloaded" uri="http://www.netbeans.org/ns/web-project/1">
-            <sequential>
-                <nbjpdaappreloaded/>
-            </sequential>
-        </macrodef>
-    </target>
-    <target name="-init-debug-args">
-        <property name="version-output" value="java version &quot;${ant.java.version}"/>
-        <condition property="have-jdk-older-than-1.4">
-            <or>
-                <contains string="${version-output}" substring="java version &quot;1.0"/>
-                <contains string="${version-output}" substring="java version &quot;1.1"/>
-                <contains string="${version-output}" substring="java version &quot;1.2"/>
-                <contains string="${version-output}" substring="java version &quot;1.3"/>
-            </or>
-        </condition>
-        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
-            <istrue value="${have-jdk-older-than-1.4}"/>
-        </condition>
-        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
-            <os family="windows"/>
-        </condition>
-        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
-            <isset property="debug.transport"/>
-        </condition>
-    </target>
-    <target depends="-init-debug-args" name="-init-macrodef-debug">
-        <macrodef name="debug" uri="http://www.netbeans.org/ns/web-project/1">
-            <attribute default="${main.class}" name="classname"/>
-            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
-            <attribute default="${application.args.param}" name="args"/>
-            <element name="customize" optional="true"/>
-            <sequential>
-                <java classname="@{classname}" fork="true">
-                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
-                    <jvmarg line="${debug-args-line}"/>
-                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
-                    <jvmarg line="${runmain.jvmargs}"/>
-                    <classpath>
-                        <path path="@{classpath}"/>
-                    </classpath>
-                    <syspropertyset>
-                        <propertyref prefix="run-sys-prop."/>
-                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
-                    </syspropertyset>
-                    <arg line="@{args}"/>
-                    <customize/>
-                </java>
-            </sequential>
-        </macrodef>
-    </target>
-    <target name="-init-taskdefs">
-        <fail unless="libs.CopyLibs.classpath">
-The libs.CopyLibs.classpath property is not set up.
-This property must point to 
-org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part
-of NetBeans IDE installation and is usually located at 
-&lt;netbeans_installation&gt;/java&lt;version&gt;/ant/extra folder.
-Either open the project in the IDE and make sure CopyLibs library
-exists or setup the property manually. For example like this:
- ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar
-                </fail>
-        <taskdef classpath="${libs.CopyLibs.classpath}" resource="org/netbeans/modules/java/j2seproject/copylibstask/antlib.xml"/>
-    </target>
-    <target name="-init-ap-cmdline-properties">
-        <property name="annotation.processing.enabled" value="true"/>
-        <property name="annotation.processing.processors.list" value=""/>
-        <property name="annotation.processing.run.all.processors" value="true"/>
-        <property name="javac.processorpath" value="${javac.classpath}"/>
-        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
-        <condition property="ap.supported.internal" value="true">
-            <not>
-                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
-            </not>
-        </condition>
-    </target>
-    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
-        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
-            <isfalse value="${annotation.processing.run.all.processors}"/>
-        </condition>
-        <condition else="" property="ap.proc.none.internal" value="-proc:none">
-            <isfalse value="${annotation.processing.enabled}"/>
-        </condition>
-    </target>
-    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
-        <property name="ap.cmd.line.internal" value=""/>
-    </target>
-    <!--
-                pre NB7.2 profiling section; consider it deprecated
-            -->
-    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
-    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="-profile-pre-init, init, -profile-post-init" if="profiler.info.jvmargs.agent" name="-profile-init-check">
-        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
-        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
-    </target>
-    <!--
-                end of pre NB7.2 profiling section
-            -->
-    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-java,-init-macrodef-nbjpda,-init-macrodef-nbjsdebug,-init-macrodef-debug,-init-taskdefs,-init-ap-cmdline" name="init"/>
-    <!--
-                COMPILATION SECTION
-            -->
-    <target depends="init" if="no.dist.ear.dir" name="deps-module-jar" unless="no.deps">
-        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="jar">
-            <property name="deploy.on.save" value="false"/>
-        </ant>
-    </target>
-    <target depends="init" if="dist.ear.dir" name="deps-ear-jar" unless="no.deps">
-        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="jar">
-            <property name="deploy.on.save" value="false"/>
-        </ant>
-    </target>
-    <target depends="init, deps-module-jar, deps-ear-jar" name="deps-jar" unless="no.deps"/>
-    <target depends="init,deps-jar,generate-rest-config" name="-pre-pre-compile">
-        <mkdir dir="${build.classes.dir}"/>
-    </target>
-    <target name="-pre-compile">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target name="-copy-webdir">
-        <copy todir="${build.web.dir}">
-            <fileset dir="${web.docbase.dir}" excludes="${build.web.excludes},${excludes}" includes="${includes}"/>
-        </copy>
-        <copy todir="${build.web.dir}/WEB-INF">
-            <fileset dir="${webinf.dir}" excludes="${build.web.excludes}"/>
-        </copy>
-    </target>
-    <target depends="init, deps-jar, -pre-pre-compile, -pre-compile, -copy-manifest, -copy-persistence-xml, -copy-webdir, library-inclusion-in-archive,library-inclusion-in-manifest" if="have.sources" name="-do-compile">
-        <webproject2:javac destdir="${build.classes.dir}" gensrcdir="${build.generated.sources.dir}"/>
-        <copy todir="${build.classes.dir}">
-            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-        </copy>
-    </target>
-    <target if="has.custom.manifest" name="-copy-manifest">
-        <mkdir dir="${build.meta.inf.dir}"/>
-        <copy todir="${build.meta.inf.dir}">
-            <fileset dir="${conf.dir}" includes="MANIFEST.MF"/>
-        </copy>
-    </target>
-    <target if="has.persistence.xml" name="-copy-persistence-xml">
-        <mkdir dir="${build.web.dir}/WEB-INF/classes/META-INF"/>
-        <copy todir="${build.web.dir}/WEB-INF/classes/META-INF">
-            <fileset dir="${persistence.xml.dir}" includes="persistence.xml orm.xml"/>
-        </copy>
-    </target>
-    <target name="-post-compile">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
-    <target name="-pre-compile-single">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
-        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
-        <webproject2:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}"/>
-        <copy todir="${build.classes.dir}">
-            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-        </copy>
-    </target>
-    <target name="-post-compile-single">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
-    <property name="jspc.schemas" value="/resources/schemas/"/>
-    <property name="jspc.dtds" value="/resources/dtds/"/>
-    <target depends="compile" description="Test compile JSP pages to expose compilation errors." if="do.compile.jsps" name="compile-jsps">
-        <mkdir dir="${build.generated.dir}/src"/>
-        <java classname="org.netbeans.modules.web.project.ant.JspC" failonerror="true" fork="true">
-            <arg value="-uriroot"/>
-            <arg file="${basedir}/${build.web.dir}"/>
-            <arg value="-d"/>
-            <arg file="${basedir}/${build.generated.dir}/src"/>
-            <arg value="-die1"/>
-            <arg value="-schemas ${jspc.schemas}"/>
-            <arg value="-dtds ${jspc.dtds}"/>
-            <arg value="-compilerSourceVM ${javac.source}"/>
-            <arg value="-compilerTargetVM ${javac.target}"/>
-            <arg value="-javaEncoding ${source.encoding}"/>
-            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
-            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
-        </java>
-        <mkdir dir="${build.generated.dir}/classes"/>
-        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src"/>
-    </target>
-    <target depends="compile" if="jsp.includes" name="-do-compile-single-jsp">
-        <fail unless="javac.jsp.includes">Must select some files in the IDE or set javac.jsp.includes</fail>
-        <mkdir dir="${build.generated.dir}/src"/>
-        <java classname="org.netbeans.modules.web.project.ant.JspCSingle" failonerror="true" fork="true">
-            <arg value="-uriroot"/>
-            <arg file="${basedir}/${build.web.dir}"/>
-            <arg value="-d"/>
-            <arg file="${basedir}/${build.generated.dir}/src"/>
-            <arg value="-die1"/>
-            <arg value="-schemas ${jspc.schemas}"/>
-            <arg value="-dtds ${jspc.dtds}"/>
-            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
-            <arg value="-jspc.files"/>
-            <arg path="${jsp.includes}"/>
-            <arg value="-compilerSourceVM ${javac.source}"/>
-            <arg value="-compilerTargetVM ${javac.target}"/>
-            <arg value="-javaEncoding ${source.encoding}"/>
-            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
-        </java>
-        <mkdir dir="${build.generated.dir}/classes"/>
-        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src">
-            <customize>
-                <patternset includes="${javac.jsp.includes}"/>
-            </customize>
-        </webproject2:javac>
-    </target>
-    <target name="compile-single-jsp">
-        <fail unless="jsp.includes">Must select a file in the IDE or set jsp.includes</fail>
-        <antcall target="-do-compile-single-jsp"/>
-    </target>
-    <!--
-                DIST BUILDING SECTION
-            -->
-    <target name="-pre-dist">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.without.custom.manifest" name="-do-dist-without-manifest">
-        <dirname file="${dist.war}" property="dist.jar.dir"/>
-        <mkdir dir="${dist.jar.dir}"/>
-        <jar compress="${jar.compress}" jarfile="${dist.war}">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
-        </jar>
-    </target>
-    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.with.custom.manifest" name="-do-dist-with-manifest">
-        <dirname file="${dist.war}" property="dist.jar.dir"/>
-        <mkdir dir="${dist.jar.dir}"/>
-        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
-        </jar>
-    </target>
-    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.without.custom.manifest" name="-do-tmp-dist-without-manifest">
-        <dirname file="${dist.war}" property="dist.jar.dir"/>
-        <mkdir dir="${dist.jar.dir}"/>
-        <jar compress="${jar.compress}" jarfile="${dist.war}">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
-        </jar>
-    </target>
-    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.with.custom.manifest" name="-do-tmp-dist-with-manifest">
-        <dirname file="${dist.war}" property="dist.jar.dir"/>
-        <mkdir dir="${dist.jar.dir}"/>
-        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
-        </jar>
-    </target>
-    <target depends="init,compile,compile-jsps,-pre-dist,-do-dist-with-manifest,-do-dist-without-manifest" name="do-dist"/>
-    <target depends="init" if="dist.ear.dir" name="library-inclusion-in-manifest">
-        <copyfiles files="${libs.PostgreSQLDriver.classpath}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
-        <copyfiles files="${reference.csip-core-1.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
-        <copyfiles files="${libs.CSIP-Jersey-2.16.classpath}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
-        <mkdir dir="${build.web.dir}/META-INF"/>
-        <manifest file="${build.web.dir}/META-INF/MANIFEST.MF" mode="update"/>
-    </target>
-    <target depends="init" name="library-inclusion-in-archive" unless="dist.ear.dir">
-        <copyfiles files="${libs.PostgreSQLDriver.classpath}" todir="${build.web.dir}/WEB-INF/lib"/>
-        <copyfiles files="${reference.csip-core-1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
-        <copyfiles files="${libs.CSIP-Jersey-2.16.classpath}" todir="${build.web.dir}/WEB-INF/lib"/>
-    </target>
-    <target depends="init" if="dist.ear.dir" name="-clean-webinf-lib">
-        <delete dir="${build.web.dir}/WEB-INF/lib"/>
-    </target>
-    <target depends="init,-clean-webinf-lib,compile,compile-jsps,-pre-dist,library-inclusion-in-manifest" if="do.tmp.war.package" name="do-ear-dist">
-        <dirname file="${dist.ear.war}" property="dist.jar.dir"/>
-        <mkdir dir="${dist.jar.dir}"/>
-        <jar compress="${jar.compress}" jarfile="${dist.ear.war}" manifest="${build.web.dir}/META-INF/MANIFEST.MF">
-            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
-        </jar>
-    </target>
-    <target name="-post-dist">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,-pre-dist,do-dist,-post-dist" description="Build distribution (WAR)." name="dist"/>
-    <target depends="init,-clean-webinf-lib,-init-cos,compile,-pre-dist,do-ear-dist,-post-dist" description="Build distribution (WAR) to be packaged into an EAR." name="dist-ear"/>
-    <!--
-                EXECUTION SECTION
-            -->
-    <target depends="run-deploy,run-display-browser" description="Deploy to server and show in browser." name="run"/>
-    <target name="-pre-run-deploy">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target name="-post-run-deploy">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target name="-pre-nbmodule-run-deploy">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -pre-run-deploy task instead. -->
-    </target>
-    <target name="-post-nbmodule-run-deploy">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -post-run-deploy task instead. -->
-    </target>
-    <target name="-run-deploy-am">
-        <!-- Task to deploy to the Access Manager runtime. -->
-    </target>
-    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest,-pre-run-deploy,-pre-nbmodule-run-deploy,-run-deploy-nb,-init-deploy-ant,-deploy-ant,-run-deploy-am,-post-nbmodule-run-deploy,-post-run-deploy,-do-update-breakpoints" name="run-deploy"/>
-    <target if="netbeans.home" name="-run-deploy-nb">
-        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="false" forceRedeploy="${forceRedeploy}"/>
-    </target>
-    <target name="-init-deploy-ant" unless="netbeans.home">
-        <property name="deploy.ant.archive" value="${dist.war}"/>
-        <property name="deploy.ant.docbase.dir" value="${web.docbase.dir}"/>
-        <property name="deploy.ant.resource.dir" value="${resource.dir}"/>
-        <property name="deploy.ant.enabled" value="true"/>
-    </target>
-    <target depends="dist,-run-undeploy-nb,-init-deploy-ant,-undeploy-ant" name="run-undeploy"/>
-    <target if="netbeans.home" name="-run-undeploy-nb">
-        <fail message="Undeploy is not supported from within the IDE"/>
-    </target>
-    <target depends="init,-pre-dist,dist,-post-dist" name="verify">
-        <nbverify file="${dist.war}"/>
-    </target>
-    <target depends="run-deploy,-init-display-browser,-display-browser-nb-old,-display-browser-nb,-display-browser-cl" name="run-display-browser"/>
-    <target if="do.display.browser" name="-init-display-browser">
-        <condition property="do.display.browser.nb.old">
-            <and>
-                <isset property="netbeans.home"/>
-                <not>
-                    <isset property="browser.context"/>
-                </not>
-            </and>
-        </condition>
-        <condition property="do.display.browser.nb">
-            <and>
-                <isset property="netbeans.home"/>
-                <isset property="browser.context"/>
-            </and>
-        </condition>
-        <condition property="do.display.browser.cl">
-            <isset property="deploy.ant.enabled"/>
-        </condition>
-    </target>
-    <target if="do.display.browser.nb.old" name="-display-browser-nb-old">
-        <nbbrowse url="${client.url}"/>
-    </target>
-    <target if="do.display.browser.nb" name="-display-browser-nb">
-        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
-    </target>
-    <target if="do.display.browser.cl" name="-get-browser" unless="browser">
-        <condition property="browser" value="rundll32">
-            <os family="windows"/>
-        </condition>
-        <condition else="" property="browser.args" value="url.dll,FileProtocolHandler">
-            <os family="windows"/>
-        </condition>
-        <condition property="browser" value="/usr/bin/open">
-            <os family="mac"/>
-        </condition>
-        <property environment="env"/>
-        <condition property="browser" value="${env.BROWSER}">
-            <isset property="env.BROWSER"/>
-        </condition>
-        <condition property="browser" value="/usr/bin/firefox">
-            <available file="/usr/bin/firefox"/>
-        </condition>
-        <condition property="browser" value="/usr/local/firefox/firefox">
-            <available file="/usr/local/firefox/firefox"/>
-        </condition>
-        <condition property="browser" value="/usr/bin/mozilla">
-            <available file="/usr/bin/mozilla"/>
-        </condition>
-        <condition property="browser" value="/usr/local/mozilla/mozilla">
-            <available file="/usr/local/mozilla/mozilla"/>
-        </condition>
-        <condition property="browser" value="/usr/sfw/lib/firefox/firefox">
-            <available file="/usr/sfw/lib/firefox/firefox"/>
-        </condition>
-        <condition property="browser" value="/opt/csw/bin/firefox">
-            <available file="/opt/csw/bin/firefox"/>
-        </condition>
-        <condition property="browser" value="/usr/sfw/lib/mozilla/mozilla">
-            <available file="/usr/sfw/lib/mozilla/mozilla"/>
-        </condition>
-        <condition property="browser" value="/opt/csw/bin/mozilla">
-            <available file="/opt/csw/bin/mozilla"/>
-        </condition>
-    </target>
-    <target depends="-get-browser" if="do.display.browser.cl" name="-display-browser-cl">
-        <fail unless="browser">
-                    Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable.
-                </fail>
-        <property name="browse.url" value="${deploy.ant.client.url}${client.urlPart}"/>
-        <echo>Launching ${browse.url}</echo>
-        <exec executable="${browser}" spawn="true">
-            <arg line="${browser.args} ${browse.url}"/>
-        </exec>
-    </target>
-    <target depends="init,-init-cos,compile-single" name="run-main">
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
-        <webproject1:java classname="${run.class}"/>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single" name="run-test-with-main">
-        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
-        <webproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
-    </target>
-    <target depends="init" if="netbeans.home" name="-do-update-breakpoints">
-        <webproject1:nbjpdaappreloaded/>
-    </target>
-    <!--
-                DEBUGGING SECTION
-            -->
-    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" description="Debug project in IDE." if="netbeans.home" name="debug">
-        <nbstartserver debugmode="true"/>
-        <antcall target="connect-debugger"/>
-        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="true" forceRedeploy="true"/>
-        <antcall target="debug-display-browser-old"/>
-        <antcall target="debug-display-browser"/>
-        <antcall target="connect-client-debugger"/>
-    </target>
-    <target if="do.debug.server" name="connect-debugger" unless="is.debugged">
-        <condition property="listeningcp" value="sourcepath">
-            <istrue value="${j2ee.compile.on.save}"/>
-        </condition>
-        <nbjpdaconnect address="${jpda.address}" host="${jpda.host}" listeningcp="${listeningcp}" name="${name}" transport="${jpda.transport}">
-            <classpath>
-                <path path="${debug.classpath}:${j2ee.platform.classpath}"/>
-            </classpath>
-            <sourcepath>
-                <path path="${web.docbase.dir}"/>
-            </sourcepath>
-        </nbjpdaconnect>
-    </target>
-    <target if="do.display.browser.debug.old" name="debug-display-browser-old">
-        <nbbrowse url="${client.url}"/>
-    </target>
-    <target if="do.display.browser.debug" name="debug-display-browser">
-        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
-    </target>
-    <target if="do.debug.client" name="connect-client-debugger">
-        <webproject1:nbjsdebugstart webUrl="${client.url}"/>
-    </target>
-    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
-        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
-        <webproject1:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
-    </target>
-    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
-    <target depends="init,compile,compile-jsps,-do-compile-single-jsp,debug" if="netbeans.home" name="debug-single"/>
-    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
-        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
-    </target>
-    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
-        <webproject1:nbjpdastart name="${debug.class}"/>
-    </target>
-    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
-        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
-        <webproject1:debug classname="${debug.class}"/>
-    </target>
-    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single-main"/>
-    <target depends="init" name="-pre-debug-fix">
-        <fail unless="fix.includes">Must set fix.includes</fail>
-        <property name="javac.includes" value="${fix.includes}.java"/>
-    </target>
-    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
-        <webproject1:nbjpdareload/>
-    </target>
-    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
-    <!--
-            =================
-            PROFILING SECTION
-            =================
-            -->
-    <!--
-                pre NB7.2 profiling section; consider it deprecated
-            -->
-    <target description="Profile a J2EE project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
-        <condition else="start-profiled-server" property="profiler.startserver.target" value="start-profiled-server-extraargs">
-            <isset property="profiler.info.jvmargs.extra"/>
-        </condition>
-        <antcall target="${profiler.startserver.target}"/>
-        <antcall target="run"/>
-        <antcall target="-profile-start-loadgen"/>
-    </target>
-    <target if="profiler.info.jvmargs.agent" name="start-profiled-server">
-        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
-            <jvmarg value="${profiler.info.jvmargs.agent}"/>
-            <jvmarg value="${profiler.j2ee.agentID}"/>
-        </nbstartprofiledserver>
-    </target>
-    <target if="profiler.info.jvmargs.agent" name="start-profiled-server-extraargs">
-        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
-            <jvmarg value="${profiler.info.jvmargs.extra}"/>
-            <jvmarg value="${profiler.info.jvmargs.agent}"/>
-            <jvmarg value="${profiler.j2ee.agentID}"/>
-        </nbstartprofiledserver>
-    </target>
-    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
-        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
-        <nbprofiledirect>
-            <classpath>
-                <path path="${run.test.classpath}"/>
-                <path path="${j2ee.platform.classpath}"/>
-            </classpath>
-        </nbprofiledirect>
-        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
-            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
-            <jvmarg value="${profiler.info.jvmargs.agent}"/>
-            <jvmarg line="${profiler.info.jvmargs}"/>
-            <test name="${profile.class}"/>
-            <classpath>
-                <path path="${run.test.classpath}"/>
-                <path path="${j2ee.platform.classpath}"/>
-            </classpath>
-            <syspropertyset>
-                <propertyref prefix="test-sys-prop."/>
-                <mapper from="test-sys-prop.*" to="*" type="glob"/>
-            </syspropertyset>
-            <formatter type="brief" usefile="false"/>
-            <formatter type="xml"/>
-        </junit>
-    </target>
-    <target if="netbeans.home" name="-profile-check">
-        <condition property="profiler.configured">
-            <or>
-                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
-                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
-            </or>
-        </condition>
-    </target>
-    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" name="-do-profile">
-        <startprofiler/>
-        <nbstartserver profilemode="true"/>
-        <nbdeploy clientUrlPart="${client.urlPart}" forceRedeploy="true" profilemode="true"/>
-        <antcall target="debug-display-browser-old"/>
-        <antcall target="debug-display-browser"/>
-        <antcall target="-profile-start-loadgen"/>
-    </target>
-    <target depends="-profile-check,-profile-pre72" description="Profile a J2EE project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
-        <antcall target="-do-profile"/>
-    </target>
-    <target depends="-profile-test-single-pre72" name="profile-test-single"/>
-    <target depends="-profile-check" if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs.agent">
-        <startprofiler/>
-        <antcall target="test-single"/>
-    </target>
-    <target if="profiler.loadgen.path" name="-profile-start-loadgen">
-        <loadgenstart path="${profiler.loadgen.path}"/>
-    </target>
-    <!--
-                JAVADOC SECTION
-            -->
-    <target depends="init" if="have.sources" name="javadoc-build">
-        <mkdir dir="${dist.javadoc.dir}"/>
-        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
-            <classpath>
-                <path path="${javac.classpath}:${j2ee.platform.classpath}"/>
-            </classpath>
-            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
-                <filename name="**/*.java"/>
-            </fileset>
-            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
-                <include name="**/*.java"/>
-            </fileset>
-        </javadoc>
-        <copy todir="${dist.javadoc.dir}">
-            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
-                <filename name="**/doc-files/**"/>
-            </fileset>
-            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
-                <include name="**/doc-files/**"/>
-            </fileset>
-        </copy>
-    </target>
-    <target depends="init,javadoc-build" if="netbeans.home" name="javadoc-browse" unless="no.javadoc.preview">
-        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
-    </target>
-    <target depends="init,javadoc-build,javadoc-browse" description="Build Javadoc." name="javadoc"/>
-    <!--
-                
-                TEST COMPILATION SECTION
-            -->
-    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
-        <mkdir dir="${build.test.classes.dir}"/>
-        <property name="j2ee.platform.embeddableejb.classpath" value=""/>
-    </target>
-    <target name="-pre-compile-test">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test" if="have.tests" name="-do-compile-test">
-        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
-        <copy todir="${build.test.classes.dir}">
-            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-        </copy>
-    </target>
-    <target name="-post-compile-test">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
-    <target name="-pre-compile-test-single">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
-        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
-        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" srcdir="${test.src.dir}"/>
-        <copy todir="${build.test.classes.dir}">
-            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
-        </copy>
-    </target>
-    <target name="-post-compile-test-single">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
-    <!--
-                
-                TEST EXECUTION SECTION
-            -->
-    <target depends="init" if="have.tests" name="-pre-test-run">
-        <mkdir dir="${build.test.results.dir}"/>
-    </target>
-    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
-        <webproject2:test includes="${includes}" testincludes="**/*Test.java"/>
-    </target>
-    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
-    </target>
-    <target depends="init" if="have.tests" name="test-report"/>
-    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
-    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
-    <target depends="init" if="have.tests" name="-pre-test-run-single">
-        <mkdir dir="${build.test.results.dir}"/>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
-        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
-        <webproject2:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
-        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
-        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
-        <webproject2:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
-        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
-    <!--
-                
-                TEST DEBUGGING SECTION
-            -->
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
-        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
-        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
-    </target>
-    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
-        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
-        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
-        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
-    </target>
-    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
-        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
-    </target>
-    <target depends="init,compile-test,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
-    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
-    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
-        <webproject1:nbjpdareload dir="${build.test.classes.dir}"/>
-    </target>
-    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
-    <!--
-                
-                CLEANUP SECTION
-            -->
-    <target depends="init" name="deps-clean" unless="no.deps">
-        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="clean"/>
-    </target>
-    <target depends="init" name="do-clean">
-        <condition property="build.dir.to.clean" value="${build.web.dir}">
-            <isset property="dist.ear.dir"/>
-        </condition>
-        <property name="build.dir.to.clean" value="${build.web.dir}"/>
-        <delete includeEmptyDirs="true" quiet="true">
-            <fileset dir="${build.dir.to.clean}/WEB-INF/lib"/>
-        </delete>
-        <delete dir="${build.dir}"/>
-        <available file="${build.dir.to.clean}/WEB-INF/lib" property="status.clean-failed" type="dir"/>
-        <delete dir="${dist.dir}"/>
-    </target>
-    <target depends="do-clean" if="status.clean-failed" name="check-clean">
-        <echo message="Warning: unable to delete some files in ${build.web.dir}/WEB-INF/lib - they are probably locked by the J2EE server. "/>
-        <echo level="info" message="To delete all files undeploy the module from Server Registry in Runtime tab and then use Clean again."/>
-    </target>
-    <target depends="init" if="netbeans.home" name="undeploy-clean">
-        <nbundeploy failOnError="false" startServer="false"/>
-    </target>
-    <target name="-post-clean">
-        <!-- Empty placeholder for easier customization. -->
-        <!-- You can override this target in the ../build.xml file. -->
-    </target>
-    <target depends="init,undeploy-clean,deps-clean,do-clean,check-clean,-post-clean" description="Clean build products." name="clean"/>
-    <target depends="clean" description="Clean build products." name="clean-ear"/>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+        *** GENERATED FROM project.xml - DO NOT EDIT  ***
+        ***         EDIT ../build.xml INSTEAD         ***
+
+        For the purpose of easier reading the script
+        is divided into following sections:
+        - initialization
+        - compilation
+        - dist
+        - execution
+        - debugging
+        - javadoc
+        - test compilation
+        - test execution
+        - test debugging
+        - cleanup
+
+        -->
+<project xmlns:webproject1="http://www.netbeans.org/ns/web-project/1" xmlns:webproject2="http://www.netbeans.org/ns/web-project/2" xmlns:webproject3="http://www.netbeans.org/ns/web-project/3" basedir=".." default="default" name="csip-wqm-impl">
+    <import file="rest-build.xml"/>
+    <import file="ant-deploy.xml"/>
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="dist,javadoc" description="Build whole project." name="default"/>
+    <!--
+                INITIALIZATION SECTION
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.4"/>
+        <property name="default.javac.target" value="1.4"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" if="dist.ear.dir" name="-do-ear-init"/>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <webproject1:property name="platform.home" value="platforms.${platform.active}.home"/>
+        <webproject1:property name="platform.bootcp" value="platforms.${platform.active}.bootclasspath"/>
+        <webproject1:property name="platform.compiler" value="platforms.${platform.active}.compile"/>
+        <webproject1:property name="platform.javac.tmp" value="platforms.${platform.active}.javac"/>
+        <condition property="platform.javac" value="${platform.home}/bin/javac">
+            <equals arg1="${platform.javac.tmp}" arg2="$${platforms.${platform.active}.javac}"/>
+        </condition>
+        <property name="platform.javac" value="${platform.javac.tmp}"/>
+        <webproject1:property name="platform.java.tmp" value="platforms.${platform.active}.java"/>
+        <condition property="platform.java" value="${platform.home}/bin/java">
+            <equals arg1="${platform.java.tmp}" arg2="$${platforms.${platform.active}.java}"/>
+        </condition>
+        <property name="platform.java" value="${platform.java.tmp}"/>
+        <webproject1:property name="platform.javadoc.tmp" value="platforms.${platform.active}.javadoc"/>
+        <condition property="platform.javadoc" value="${platform.home}/bin/javadoc">
+            <equals arg1="${platform.javadoc.tmp}" arg2="$${platforms.${platform.active}.javadoc}"/>
+        </condition>
+        <property name="platform.javadoc" value="${platform.javadoc.tmp}"/>
+        <fail unless="platform.home">Must set platform.home</fail>
+        <fail unless="platform.bootcp">Must set platform.bootcp</fail>
+        <fail unless="platform.java">Must set platform.java</fail>
+        <fail unless="platform.javac">Must set platform.javac</fail>
+        <fail if="platform.invalid">
+ The J2SE Platform is not correctly set up.
+ Your active platform is: ${platform.active}, but the corresponding property "platforms.${platform.active}.home" is not found in the project's properties files. 
+ Either open the project in the IDE and setup the Platform with the same name or add it manually.
+ For example like this:
+     ant -Duser.properties.file=&lt;path_to_property_file&gt; jar (where you put the property "platforms.${platform.active}.home" in a .properties file)
+  or ant -Dplatforms.${platform.active}.home=&lt;path_to_JDK_home&gt; jar (where no properties file is used) 
+  </fail>
+        <condition property="have.tests">
+            <or>
+                <available file="${test.src.dir}"/>
+            </or>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <isfalse value="${javadoc.preview}"/>
+        </condition>
+        <property name="javac.compilerargs" value=""/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <condition property="no.dist.ear.dir">
+            <not>
+                <isset property="dist.ear.dir"/>
+            </not>
+        </condition>
+        <property name="build.web.excludes" value="${build.classes.excludes}"/>
+        <condition property="do.compile.jsps">
+            <istrue value="${compile.jsps}"/>
+        </condition>
+        <condition property="do.debug.server">
+            <or>
+                <not>
+                    <isset property="debug.server"/>
+                </not>
+                <istrue value="${debug.server}"/>
+                <and>
+                    <not>
+                        <istrue value="${debug.server}"/>
+                    </not>
+                    <not>
+                        <istrue value="${debug.client}"/>
+                    </not>
+                </and>
+            </or>
+        </condition>
+        <condition property="do.debug.client">
+            <istrue value="${debug.client}"/>
+        </condition>
+        <condition property="do.display.browser">
+            <istrue value="${display.browser}"/>
+        </condition>
+        <condition property="do.display.browser.debug.old">
+            <and>
+                <isset property="do.display.browser"/>
+                <not>
+                    <isset property="do.debug.client"/>
+                </not>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.display.browser.debug">
+            <and>
+                <isset property="do.display.browser"/>
+                <not>
+                    <isset property="do.debug.client"/>
+                </not>
+                <isset property="browser.context"/>
+            </and>
+        </condition>
+        <available file="${conf.dir}/MANIFEST.MF" property="has.custom.manifest"/>
+        <available file="${persistence.xml.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="do.war.package.with.custom.manifest">
+            <isset property="has.custom.manifest"/>
+        </condition>
+        <condition property="do.war.package.without.custom.manifest">
+            <not>
+                <isset property="has.custom.manifest"/>
+            </not>
+        </condition>
+        <condition property="do.tmp.war.package.with.custom.manifest">
+            <and>
+                <isset property="has.custom.manifest"/>
+                <or>
+                    <isfalse value="${directory.deployment.supported}"/>
+                    <isset property="dist.ear.dir"/>
+                </or>
+            </and>
+        </condition>
+        <condition property="do.tmp.war.package.without.custom.manifest">
+            <and>
+                <not>
+                    <isset property="has.custom.manifest"/>
+                </not>
+                <or>
+                    <isfalse value="${directory.deployment.supported}"/>
+                    <isset property="dist.ear.dir"/>
+                </or>
+            </and>
+        </condition>
+        <condition property="do.tmp.war.package">
+            <or>
+                <isfalse value="${directory.deployment.supported}"/>
+                <isset property="dist.ear.dir"/>
+            </or>
+        </condition>
+        <property name="build.meta.inf.dir" value="${build.web.dir}/META-INF"/>
+        <condition else="" property="application.args.param" value="${application.args}">
+            <and>
+                <isset property="application.args"/>
+                <not>
+                    <equals arg1="${application.args}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="runmain.jvmargs" value=""/>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <length length="0" string="${endorsed.classpath}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+    </target>
+    <target depends="init" name="-init-cos" unless="deploy.on.save">
+        <condition property="deploy.on.save" value="true">
+            <or>
+                <istrue value="${j2ee.deploy.on.save}"/>
+                <istrue value="${j2ee.compile.on.save}"/>
+            </or>
+        </condition>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="test.src.dir">Must set test.src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="build.web.dir">Must set build.web.dir</fail>
+        <fail unless="build.generated.dir">Must set build.generated.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.war">Must set dist.war</fail>
+        <condition property="missing.j2ee.server.home">
+            <and>
+                <matches pattern="j2ee.server.home" string="${j2ee.platform.classpath}"/>
+                <not>
+                    <isset property="j2ee.server.home"/>
+                </not>
+            </and>
+        </condition>
+        <fail if="missing.j2ee.server.home">
+The Java EE server classpath is not correctly set up - server home directory is missing.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+   ant -Dj2ee.server.home=&lt;app_server_installation_directory&gt;
+                </fail>
+        <fail unless="j2ee.platform.classpath">
+The Java EE server classpath is not correctly set up. Your active server type is ${j2ee.server.type}.
+Either open the project in the IDE and assign the server or setup the server classpath manually.
+For example like this:
+   ant -Duser.properties.file=&lt;path_to_property_file&gt; (where you put the property "j2ee.platform.classpath" in a .properties file)
+or ant -Dj2ee.platform.classpath=&lt;server_classpath&gt; (where no properties file is used)
+                </fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" executable="${platform.javac}" fork="yes" includeantruntime="false" includes="@{includes}" source="${javac.source}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete file="${javac.includesfile.binary}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true" tempdir="${java.io.tmpdir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="run.jvmargs.ide" value=""/>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set">
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
+                        <filename name="@{testincludes}"/>
+                    </fileset>
+                </union>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" jvm="${platform.java}" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="csip-wqm" testname="TestNG tests" workingDir="${basedir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <webproject2:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${runmain.jvmargs}"/>
+                    </customize>
+                </webproject2:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true" tempdir="${java.io.tmpdir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="run.jvmargs.ide" value=""/>
+                <junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                            <filename name="@{testincludes}"/>
+                        </fileset>
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <webproject2:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </webproject2:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename csip-wqm -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <webproject1:debug args="${testng.cmd.args}" classname="org.testng.TestNG" classpath="${debug.test.classpath}:${j2ee.platform.embeddableejb.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                    </customize>
+                </webproject1:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <webproject2:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </webproject2:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <webproject2:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${runmain.jvmargs}"/>
+                    </customize>
+                </webproject2:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/web-project/2">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <webproject2:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </webproject2:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" fork="true" jvm="${platform.java}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${runmain.jvmargs}"/>
+                    <classpath>
+                        <path path="@{classpath}:${j2ee.platform.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-nbjsdebug">
+        <macrodef name="nbjsdebugstart" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${client.url}" name="webUrl"/>
+            <sequential>
+                <nbjsdebugstart urlPart="${client.urlPart}" webUrl="@{webUrl}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <bootclasspath>
+                        <path path="${platform.bootcp}"/>
+                    </bootclasspath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdaappreloaded" uri="http://www.netbeans.org/ns/web-project/1">
+            <sequential>
+                <nbjpdaappreloaded/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <exec executable="${platform.java}" outputproperty="version-output">
+            <arg value="-version"/>
+        </exec>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/web-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}:${j2ee.platform.classpath}" name="classpath"/>
+            <attribute default="${application.args.param}" name="args"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" fork="true" jvm="${platform.java}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg line="${runmain.jvmargs}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <arg line="@{args}"/>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-taskdefs">
+        <fail unless="libs.CopyLibs.classpath">
+The libs.CopyLibs.classpath property is not set up.
+This property must point to 
+org-netbeans-modules-java-j2seproject-copylibstask.jar file which is part
+of NetBeans IDE installation and is usually located at 
+&lt;netbeans_installation&gt;/java&lt;version&gt;/ant/extra folder.
+Either open the project in the IDE and make sure CopyLibs library
+exists or setup the property manually. For example like this:
+ ant -Dlibs.CopyLibs.classpath=a/path/to/org-netbeans-modules-java-j2seproject-copylibstask.jar
+                </fail>
+        <taskdef classpath="${libs.CopyLibs.classpath}" resource="org/netbeans/modules/java/j2seproject/copylibstask/antlib.xml"/>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-java,-init-macrodef-nbjpda,-init-macrodef-nbjsdebug,-init-macrodef-debug,-init-taskdefs,-init-ap-cmdline" name="init"/>
+    <!--
+                COMPILATION SECTION
+            -->
+    <target depends="init" if="no.dist.ear.dir" name="deps-module-jar" unless="no.deps">
+        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="jar">
+            <property name="deploy.on.save" value="false"/>
+        </ant>
+    </target>
+    <target depends="init" if="dist.ear.dir" name="deps-ear-jar" unless="no.deps">
+        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="jar">
+            <property name="deploy.on.save" value="false"/>
+        </ant>
+    </target>
+    <target depends="init, deps-module-jar, deps-ear-jar" name="deps-jar" unless="no.deps"/>
+    <target depends="init,deps-jar,generate-rest-config" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-copy-webdir">
+        <copy todir="${build.web.dir}">
+            <fileset dir="${web.docbase.dir}" excludes="${build.web.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+        <copy todir="${build.web.dir}/WEB-INF">
+            <fileset dir="${webinf.dir}" excludes="${build.web.excludes}"/>
+        </copy>
+    </target>
+    <target depends="init, deps-jar, -pre-pre-compile, -pre-compile, -copy-manifest, -copy-persistence-xml, -copy-webdir, library-inclusion-in-archive,library-inclusion-in-manifest" if="have.sources" name="-do-compile">
+        <webproject2:javac destdir="${build.classes.dir}" gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.custom.manifest" name="-copy-manifest">
+        <mkdir dir="${build.meta.inf.dir}"/>
+        <copy todir="${build.meta.inf.dir}">
+            <fileset dir="${conf.dir}" includes="MANIFEST.MF"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.web.dir}/WEB-INF/classes/META-INF"/>
+        <copy todir="${build.web.dir}/WEB-INF/classes/META-INF">
+            <fileset dir="${persistence.xml.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <webproject2:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <property name="jspc.schemas" value="/resources/schemas/"/>
+    <property name="jspc.dtds" value="/resources/dtds/"/>
+    <target depends="compile" description="Test compile JSP pages to expose compilation errors." if="do.compile.jsps" name="compile-jsps">
+        <mkdir dir="${build.generated.dir}/src"/>
+        <java classname="org.netbeans.modules.web.project.ant.JspC" failonerror="true" fork="true">
+            <arg value="-uriroot"/>
+            <arg file="${basedir}/${build.web.dir}"/>
+            <arg value="-d"/>
+            <arg file="${basedir}/${build.generated.dir}/src"/>
+            <arg value="-die1"/>
+            <arg value="-schemas ${jspc.schemas}"/>
+            <arg value="-dtds ${jspc.dtds}"/>
+            <arg value="-compilerSourceVM ${javac.source}"/>
+            <arg value="-compilerTargetVM ${javac.target}"/>
+            <arg value="-javaEncoding ${source.encoding}"/>
+            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
+            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
+        </java>
+        <mkdir dir="${build.generated.dir}/classes"/>
+        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src"/>
+    </target>
+    <target depends="compile" if="jsp.includes" name="-do-compile-single-jsp">
+        <fail unless="javac.jsp.includes">Must select some files in the IDE or set javac.jsp.includes</fail>
+        <mkdir dir="${build.generated.dir}/src"/>
+        <java classname="org.netbeans.modules.web.project.ant.JspCSingle" failonerror="true" fork="true">
+            <arg value="-uriroot"/>
+            <arg file="${basedir}/${build.web.dir}"/>
+            <arg value="-d"/>
+            <arg file="${basedir}/${build.generated.dir}/src"/>
+            <arg value="-die1"/>
+            <arg value="-schemas ${jspc.schemas}"/>
+            <arg value="-dtds ${jspc.dtds}"/>
+            <arg value="-sysClasspath ${libs.jsp-compilation-syscp.classpath}"/>
+            <arg value="-jspc.files"/>
+            <arg path="${jsp.includes}"/>
+            <arg value="-compilerSourceVM ${javac.source}"/>
+            <arg value="-compilerTargetVM ${javac.target}"/>
+            <arg value="-javaEncoding ${source.encoding}"/>
+            <classpath path="${java.home}/../lib/tools.jar:${libs.jsp-compiler.classpath}:${libs.jsp-compilation.classpath}"/>
+        </java>
+        <mkdir dir="${build.generated.dir}/classes"/>
+        <webproject2:javac classpath="${build.classes.dir}:${libs.jsp-compilation.classpath}:${javac.classpath}:${j2ee.platform.classpath}" destdir="${build.generated.dir}/classes" srcdir="${build.generated.dir}/src">
+            <customize>
+                <patternset includes="${javac.jsp.includes}"/>
+            </customize>
+        </webproject2:javac>
+    </target>
+    <target name="compile-single-jsp">
+        <fail unless="jsp.includes">Must select a file in the IDE or set jsp.includes</fail>
+        <antcall target="-do-compile-single-jsp"/>
+    </target>
+    <!--
+                DIST BUILDING SECTION
+            -->
+    <target name="-pre-dist">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.without.custom.manifest" name="-do-dist-without-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.war.package.with.custom.manifest" name="-do-dist-with-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.without.custom.manifest" name="-do-tmp-dist-without-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist" if="do.tmp.war.package.with.custom.manifest" name="-do-tmp-dist-with-manifest">
+        <dirname file="${dist.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.war}" manifest="${build.meta.inf.dir}/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target depends="init,compile,compile-jsps,-pre-dist,-do-dist-with-manifest,-do-dist-without-manifest" name="do-dist"/>
+    <target depends="init" if="dist.ear.dir" name="library-inclusion-in-manifest">
+        <copyfiles files="${libs.PostgreSQLDriver.classpath}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${reference.csip-core-1.jar}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
+        <copyfiles files="${libs.CSIP-Jersey-2.16.classpath}" iftldtodir="${build.web.dir}/WEB-INF" todir="${dist.ear.dir}/lib"/>
+        <mkdir dir="${build.web.dir}/META-INF"/>
+        <manifest file="${build.web.dir}/META-INF/MANIFEST.MF" mode="update"/>
+    </target>
+    <target depends="init" name="library-inclusion-in-archive" unless="dist.ear.dir">
+        <copyfiles files="${libs.PostgreSQLDriver.classpath}" todir="${build.web.dir}/WEB-INF/lib"/>
+        <copyfiles files="${reference.csip-core-1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
+        <copyfiles files="${libs.CSIP-Jersey-2.16.classpath}" todir="${build.web.dir}/WEB-INF/lib"/>
+    </target>
+    <target depends="init" if="dist.ear.dir" name="-clean-webinf-lib">
+        <delete dir="${build.web.dir}/WEB-INF/lib"/>
+    </target>
+    <target depends="init,-clean-webinf-lib,compile,compile-jsps,-pre-dist,library-inclusion-in-manifest" if="do.tmp.war.package" name="do-ear-dist">
+        <dirname file="${dist.ear.war}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+        <jar compress="${jar.compress}" jarfile="${dist.ear.war}" manifest="${build.web.dir}/META-INF/MANIFEST.MF">
+            <fileset dir="${build.web.dir}" excludes="WEB-INF/classes/.netbeans_*,${dist.archive.excludes}"/>
+        </jar>
+    </target>
+    <target name="-post-dist">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-dist,do-dist,-post-dist" description="Build distribution (WAR)." name="dist"/>
+    <target depends="init,-clean-webinf-lib,-init-cos,compile,-pre-dist,do-ear-dist,-post-dist" description="Build distribution (WAR) to be packaged into an EAR." name="dist-ear"/>
+    <!--
+                EXECUTION SECTION
+            -->
+    <target depends="run-deploy,run-display-browser" description="Deploy to server and show in browser." name="run"/>
+    <target name="-pre-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-post-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target name="-pre-nbmodule-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -pre-run-deploy task instead. -->
+    </target>
+    <target name="-post-nbmodule-run-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- This target can be overriden by NetBeans modules. Don't override it directly, use -post-run-deploy task instead. -->
+    </target>
+    <target name="-run-deploy-am">
+        <!-- Task to deploy to the Access Manager runtime. -->
+    </target>
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest,-pre-run-deploy,-pre-nbmodule-run-deploy,-run-deploy-nb,-init-deploy-ant,-deploy-ant,-run-deploy-am,-post-nbmodule-run-deploy,-post-run-deploy,-do-update-breakpoints" name="run-deploy"/>
+    <target if="netbeans.home" name="-run-deploy-nb">
+        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="false" forceRedeploy="${forceRedeploy}"/>
+    </target>
+    <target name="-init-deploy-ant" unless="netbeans.home">
+        <property name="deploy.ant.archive" value="${dist.war}"/>
+        <property name="deploy.ant.docbase.dir" value="${web.docbase.dir}"/>
+        <property name="deploy.ant.resource.dir" value="${resource.dir}"/>
+        <property name="deploy.ant.enabled" value="true"/>
+    </target>
+    <target depends="dist,-run-undeploy-nb,-init-deploy-ant,-undeploy-ant" name="run-undeploy"/>
+    <target if="netbeans.home" name="-run-undeploy-nb">
+        <fail message="Undeploy is not supported from within the IDE"/>
+    </target>
+    <target depends="init,-pre-dist,dist,-post-dist" name="verify">
+        <nbverify file="${dist.war}"/>
+    </target>
+    <target depends="run-deploy,-init-display-browser,-display-browser-nb-old,-display-browser-nb,-display-browser-cl" name="run-display-browser"/>
+    <target if="do.display.browser" name="-init-display-browser">
+        <condition property="do.display.browser.nb.old">
+            <and>
+                <isset property="netbeans.home"/>
+                <not>
+                    <isset property="browser.context"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.display.browser.nb">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="browser.context"/>
+            </and>
+        </condition>
+        <condition property="do.display.browser.cl">
+            <isset property="deploy.ant.enabled"/>
+        </condition>
+    </target>
+    <target if="do.display.browser.nb.old" name="-display-browser-nb-old">
+        <nbbrowse url="${client.url}"/>
+    </target>
+    <target if="do.display.browser.nb" name="-display-browser-nb">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
+    <target if="do.display.browser.cl" name="-get-browser" unless="browser">
+        <condition property="browser" value="rundll32">
+            <os family="windows"/>
+        </condition>
+        <condition else="" property="browser.args" value="url.dll,FileProtocolHandler">
+            <os family="windows"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/open">
+            <os family="mac"/>
+        </condition>
+        <property environment="env"/>
+        <condition property="browser" value="${env.BROWSER}">
+            <isset property="env.BROWSER"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/firefox">
+            <available file="/usr/bin/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/local/firefox/firefox">
+            <available file="/usr/local/firefox/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/bin/mozilla">
+            <available file="/usr/bin/mozilla"/>
+        </condition>
+        <condition property="browser" value="/usr/local/mozilla/mozilla">
+            <available file="/usr/local/mozilla/mozilla"/>
+        </condition>
+        <condition property="browser" value="/usr/sfw/lib/firefox/firefox">
+            <available file="/usr/sfw/lib/firefox/firefox"/>
+        </condition>
+        <condition property="browser" value="/opt/csw/bin/firefox">
+            <available file="/opt/csw/bin/firefox"/>
+        </condition>
+        <condition property="browser" value="/usr/sfw/lib/mozilla/mozilla">
+            <available file="/usr/sfw/lib/mozilla/mozilla"/>
+        </condition>
+        <condition property="browser" value="/opt/csw/bin/mozilla">
+            <available file="/opt/csw/bin/mozilla"/>
+        </condition>
+    </target>
+    <target depends="-get-browser" if="do.display.browser.cl" name="-display-browser-cl">
+        <fail unless="browser">
+                    Browser not found, cannot launch the deployed application. Try to set the BROWSER environment variable.
+                </fail>
+        <property name="browse.url" value="${deploy.ant.client.url}${client.urlPart}"/>
+        <echo>Launching ${browse.url}</echo>
+        <exec executable="${browser}" spawn="true">
+            <arg line="${browser.args} ${browse.url}"/>
+        </exec>
+    </target>
+    <target depends="init,-init-cos,compile-single" name="run-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <webproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <webproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-do-update-breakpoints">
+        <webproject1:nbjpdaappreloaded/>
+    </target>
+    <!--
+                DEBUGGING SECTION
+            -->
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" description="Debug project in IDE." if="netbeans.home" name="debug">
+        <nbstartserver debugmode="true"/>
+        <antcall target="connect-debugger"/>
+        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="true" forceRedeploy="true"/>
+        <antcall target="debug-display-browser-old"/>
+        <antcall target="debug-display-browser"/>
+        <antcall target="connect-client-debugger"/>
+    </target>
+    <target if="do.debug.server" name="connect-debugger" unless="is.debugged">
+        <condition property="listeningcp" value="sourcepath">
+            <istrue value="${j2ee.compile.on.save}"/>
+        </condition>
+        <nbjpdaconnect address="${jpda.address}" host="${jpda.host}" listeningcp="${listeningcp}" name="${name}" transport="${jpda.transport}">
+            <classpath>
+                <path path="${debug.classpath}:${j2ee.platform.classpath}"/>
+            </classpath>
+            <sourcepath>
+                <path path="${web.docbase.dir}"/>
+            </sourcepath>
+            <bootclasspath>
+                <path path="${platform.bootcp}"/>
+            </bootclasspath>
+        </nbjpdaconnect>
+    </target>
+    <target if="do.display.browser.debug.old" name="debug-display-browser-old">
+        <nbbrowse url="${client.url}"/>
+    </target>
+    <target if="do.display.browser.debug" name="debug-display-browser">
+        <nbbrowse context="${browser.context}" url="${client.url}" urlPath="${client.urlPart}"/>
+    </target>
+    <target if="do.debug.client" name="connect-client-debugger">
+        <webproject1:nbjsdebugstart webUrl="${client.url}"/>
+    </target>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <webproject1:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init,compile,compile-jsps,-do-compile-single-jsp,debug" if="netbeans.home" name="debug-single"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <webproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <webproject1:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <webproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+            =================
+            PROFILING SECTION
+            =================
+            -->
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target description="Profile a J2EE project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <condition else="start-profiled-server" property="profiler.startserver.target" value="start-profiled-server-extraargs">
+            <isset property="profiler.info.jvmargs.extra"/>
+        </condition>
+        <antcall target="${profiler.startserver.target}"/>
+        <antcall target="run"/>
+        <antcall target="-profile-start-loadgen"/>
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="start-profiled-server">
+        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg value="${profiler.j2ee.agentID}"/>
+        </nbstartprofiledserver>
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="start-profiled-server-extraargs">
+        <nbstartprofiledserver forceRestart="${profiler.j2ee.serverForceRestart}" javaPlatform="${profiler.info.javaPlatform}" startupTimeout="${profiler.j2ee.serverStartupTimeout}">
+            <jvmarg value="${profiler.info.jvmargs.extra}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg value="${profiler.j2ee.agentID}"/>
+        </nbstartprofiledserver>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+                <path path="${j2ee.platform.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+                <path path="${j2ee.platform.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="init,-init-cos,compile,compile-jsps,-do-compile-single-jsp,-pre-dist,-do-tmp-dist-with-manifest,-do-tmp-dist-without-manifest" name="-do-profile">
+        <startprofiler/>
+        <nbstartserver profilemode="true"/>
+        <nbdeploy clientUrlPart="${client.urlPart}" forceRedeploy="true" profilemode="true"/>
+        <antcall target="debug-display-browser-old"/>
+        <antcall target="debug-display-browser"/>
+        <antcall target="-profile-start-loadgen"/>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a J2EE project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <antcall target="-do-profile"/>
+    </target>
+    <target depends="-profile-test-single-pre72" name="profile-test-single"/>
+    <target depends="-profile-check" if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target if="profiler.loadgen.path" name="-profile-start-loadgen">
+        <loadgenstart path="${profiler.loadgen.path}"/>
+    </target>
+    <!--
+                JAVADOC SECTION
+            -->
+    <target depends="init" if="have.sources" name="javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" executable="${platform.javadoc}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}:${j2ee.platform.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+            </fileset>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,javadoc-build" if="netbeans.home" name="javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,javadoc-build,javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                
+                TEST COMPILATION SECTION
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+        <property name="j2ee.platform.embeddableejb.classpath" value=""/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test" if="have.tests" name="-do-compile-test">
+        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <webproject2:javac classpath="${javac.test.classpath}:${j2ee.platform.classpath}:${j2ee.platform.embeddableejb.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" srcdir="${test.src.dir}"/>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                
+                TEST EXECUTION SECTION
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <webproject2:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <webproject2:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <webproject2:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                
+                TEST DEBUGGING SECTION
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <webproject2:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <webproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <webproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                
+                CLEANUP SECTION
+            -->
+    <target depends="init" name="deps-clean" unless="no.deps">
+        <ant antfile="${project.csip-core-1}/build.xml" inheritall="false" target="clean"/>
+    </target>
+    <target depends="init" name="do-clean">
+        <condition property="build.dir.to.clean" value="${build.web.dir}">
+            <isset property="dist.ear.dir"/>
+        </condition>
+        <property name="build.dir.to.clean" value="${build.web.dir}"/>
+        <delete includeEmptyDirs="true" quiet="true">
+            <fileset dir="${build.dir.to.clean}/WEB-INF/lib"/>
+        </delete>
+        <delete dir="${build.dir}"/>
+        <available file="${build.dir.to.clean}/WEB-INF/lib" property="status.clean-failed" type="dir"/>
+        <delete dir="${dist.dir}"/>
+    </target>
+    <target depends="do-clean" if="status.clean-failed" name="check-clean">
+        <echo message="Warning: unable to delete some files in ${build.web.dir}/WEB-INF/lib - they are probably locked by the J2EE server. "/>
+        <echo level="info" message="To delete all files undeploy the module from Server Registry in Runtime tab and then use Clean again."/>
+    </target>
+    <target depends="init" if="netbeans.home" name="undeploy-clean">
+        <nbundeploy failOnError="false" startServer="false"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,undeploy-clean,deps-clean,do-clean,check-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target depends="clean" description="Clean build products." name="clean-ear"/>
+</project>

nbproject/genfiles.properties

@@ -1,25 +1,25 @@
-<<<<<<< local
-build.xml.data.CRC32=b029a393
-build.xml.script.CRC32=388e9258
-build.xml.stylesheet.CRC32=651128d4@1.65.1.1
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=a8f467a9
-nbproject/build-impl.xml.script.CRC32=fe296715
-nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1
-nbproject/rest-build.xml.data.CRC32=bff4a8fe
-nbproject/rest-build.xml.script.CRC32=4734534b
-nbproject/rest-build.xml.stylesheet.CRC32=5f13befe@1.21
-=======
-build.xml.data.CRC32=b029a393
-build.xml.script.CRC32=388e9258
-build.xml.stylesheet.CRC32=651128d4@1.65.1.1
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=4688688e
-nbproject/build-impl.xml.script.CRC32=0c674ee2
-nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1
-nbproject/rest-build.xml.data.CRC32=bff4a8fe
-nbproject/rest-build.xml.script.CRC32=4734534b
-nbproject/rest-build.xml.stylesheet.CRC32=5f13befe@1.21
->>>>>>> other
+<<<<<<< local
+build.xml.data.CRC32=b029a393
+build.xml.script.CRC32=388e9258
+build.xml.stylesheet.CRC32=651128d4@1.65.1.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=a8f467a9
+nbproject/build-impl.xml.script.CRC32=fe296715
+nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1
+nbproject/rest-build.xml.data.CRC32=bff4a8fe
+nbproject/rest-build.xml.script.CRC32=4734534b
+nbproject/rest-build.xml.stylesheet.CRC32=5f13befe@1.21
+=======
+build.xml.data.CRC32=b029a393
+build.xml.script.CRC32=388e9258
+build.xml.stylesheet.CRC32=651128d4@1.65.1.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=abb4a0bc
+nbproject/build-impl.xml.script.CRC32=7b15492b
+nbproject/build-impl.xml.stylesheet.CRC32=99ea4b56@1.68.1.1
+nbproject/rest-build.xml.data.CRC32=bff4a8fe
+nbproject/rest-build.xml.script.CRC32=4734534b
+nbproject/rest-build.xml.stylesheet.CRC32=5f13befe@1.21
+>>>>>>> other

nbproject/project.properties

@@ -1,192 +1,192 @@
-<<<<<<< local
-annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=true
-annotation.processing.processors.list=
-annotation.processing.run.all.processors=true
-annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
-auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
-auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
-auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
-auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
-auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
-auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
-auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs
-build.classes.dir=${build.web.dir}/WEB-INF/classes
-build.classes.excludes=**/*.java,**/*.form
-build.dir=build
-build.generated.dir=${build.dir}/generated
-build.generated.sources.dir=${build.dir}/generated-sources
-build.test.classes.dir=${build.dir}/test/classes
-build.test.results.dir=${build.dir}/test/results
-build.web.dir=${build.dir}/web
-build.web.excludes=${build.classes.excludes}
-client.urlPart=
-compile.jsps=false
-conf.dir=${source.root}/conf
-debug.classpath=${build.classes.dir}:${javac.classpath}
-debug.test.classpath=\
-    ${run.test.classpath}
-display.browser=false
-dist.dir=dist
-dist.ear.war=${dist.dir}/${war.ear.name}
-dist.javadoc.dir=${dist.dir}/javadoc
-dist.war=${dist.dir}/${war.name}
-endorsed.classpath=\
-    ${libs.javaee-endorsed-api-6.0.classpath}
-excludes=
-includes=**
-j2ee.compile.on.save=false
-j2ee.copy.static.files.on.save=false
-j2ee.deploy.on.save=false
-j2ee.platform=1.6-web
-j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-spdy.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
-j2ee.server.type=Tomcat
-jar.compress=false
-javac.classpath=\
-    ${libs.CSIP-Jersey-2.16.classpath}:\
-    ${libs.PostgreSQLDriver.classpath}:\
-    ${reference.csip-core-1.jar}
-# Space-separated list of extra javac options
-javac.compilerargs=
-javac.debug=true
-javac.deprecation=false
-javac.processorpath=\
-    ${javac.classpath}
-javac.source=1.7
-javac.target=1.7
-javac.test.classpath=\
-    ${javac.classpath}:\
-    ${build.classes.dir}:\
-    ${libs.junit_4.classpath}
-javac.test.processorpath=\
-    ${javac.test.classpath}
-javadoc.additionalparam=
-javadoc.author=false
-javadoc.encoding=${source.encoding}
-javadoc.noindex=false
-javadoc.nonavbar=false
-javadoc.notree=false
-javadoc.preview=true
-javadoc.private=false
-javadoc.splitindex=true
-javadoc.use=true
-javadoc.version=false
-javadoc.windowtitle=
-lib.dir=${web.docbase.dir}/WEB-INF/lib
-persistence.xml.dir=${conf.dir}
-platform.active=JDK_1.7
-project.csip-core-1=../csip-core
-reference.csip-core-1.jar=${project.csip-core-1}/dist/csip-core.jar
-resource.dir=setup
-rest.config.type=ide
-run.test.classpath=\
-    ${javac.test.classpath}:\
-    ${build.test.classes.dir}
-# Space-separated list of JVM arguments used when running a class with a main method or a unit test
-# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
-runmain.jvmargs=
-source.encoding=UTF-8
-source.root=src
-src.dir=${source.root}/java
-test.src.dir=test
-war.content.additional=
-war.ear.name=${war.name}
-war.name=csip-wqm.war
-web.docbase.dir=web
-webinf.dir=web/WEB-INF
-=======
-annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=true
-annotation.processing.processors.list=
-annotation.processing.run.all.processors=true
-annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
-auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
-auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
-auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
-auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
-auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
-auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
-auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs
-build.classes.dir=${build.web.dir}/WEB-INF/classes
-build.classes.excludes=**/*.java,**/*.form
-build.dir=build
-build.generated.dir=${build.dir}/generated
-build.generated.sources.dir=${build.dir}/generated-sources
-build.test.classes.dir=${build.dir}/test/classes
-build.test.results.dir=${build.dir}/test/results
-build.web.dir=${build.dir}/web
-build.web.excludes=${build.classes.excludes}
-client.urlPart=
-compile.jsps=false
-conf.dir=${source.root}/conf
-debug.classpath=${build.classes.dir}:${javac.classpath}
-debug.test.classpath=\
-    ${run.test.classpath}
-display.browser=false
-dist.dir=dist
-dist.ear.war=${dist.dir}/${war.ear.name}
-dist.javadoc.dir=${dist.dir}/javadoc
-dist.war=${dist.dir}/${war.name}
-endorsed.classpath=\
-    ${libs.javaee-endorsed-api-6.0.classpath}
-excludes=
-includes=**
-j2ee.compile.on.save=false
-j2ee.copy.static.files.on.save=false
-j2ee.deploy.on.save=false
-j2ee.platform=1.6-web
-j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-spdy.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
-j2ee.server.type=Tomcat
-jar.compress=false
-javac.classpath=\
-    ${libs.PostgreSQLDriver.classpath}:\
-    ${reference.csip-core-1.jar}:\
-    ${libs.CSIP-Jersey-2.16.classpath}
-# Space-separated list of extra javac options
-javac.compilerargs=
-javac.debug=true
-javac.deprecation=false
-javac.processorpath=\
-    ${javac.classpath}
-javac.source=1.8
-javac.target=1.8
-javac.test.classpath=\
-    ${javac.classpath}:\
-    ${build.classes.dir}:\
-    ${libs.junit_4.classpath}
-javac.test.processorpath=\
-    ${javac.test.classpath}
-javadoc.additionalparam=
-javadoc.author=false
-javadoc.encoding=${source.encoding}
-javadoc.noindex=false
-javadoc.nonavbar=false
-javadoc.notree=false
-javadoc.preview=true
-javadoc.private=false
-javadoc.splitindex=true
-javadoc.use=true
-javadoc.version=false
-javadoc.windowtitle=
-lib.dir=${web.docbase.dir}/WEB-INF/lib
-persistence.xml.dir=${conf.dir}
-platform.active=default_platform
-project.csip-core=../csip-core
-resource.dir=setup
-rest.config.type=ide
-run.test.classpath=\
-    ${javac.test.classpath}:\
-    ${build.test.classes.dir}
-# Space-separated list of JVM arguments used when running a class with a main method or a unit test
-# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
-runmain.jvmargs=
-source.encoding=UTF-8
-source.root=src
-src.dir=${source.root}/java
-test.src.dir=test
-war.content.additional=
-war.ear.name=${war.name}
-war.name=csip-wqm.war
-web.docbase.dir=web
-webinf.dir=web/WEB-INF
->>>>>>> other
+<<<<<<< local
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=true
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
+auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
+auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
+auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
+auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
+auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
+auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs
+build.classes.dir=${build.web.dir}/WEB-INF/classes
+build.classes.excludes=**/*.java,**/*.form
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+build.web.dir=${build.dir}/web
+build.web.excludes=${build.classes.excludes}
+client.urlPart=
+compile.jsps=false
+conf.dir=${source.root}/conf
+debug.classpath=${build.classes.dir}:${javac.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+display.browser=false
+dist.dir=dist
+dist.ear.war=${dist.dir}/${war.ear.name}
+dist.javadoc.dir=${dist.dir}/javadoc
+dist.war=${dist.dir}/${war.name}
+endorsed.classpath=\
+    ${libs.javaee-endorsed-api-6.0.classpath}
+excludes=
+includes=**
+j2ee.compile.on.save=false
+j2ee.copy.static.files.on.save=false
+j2ee.deploy.on.save=false
+j2ee.platform=1.6-web
+j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-spdy.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
+j2ee.server.type=Tomcat
+jar.compress=false
+javac.classpath=\
+    ${libs.CSIP-Jersey-2.16.classpath}:\
+    ${libs.PostgreSQLDriver.classpath}:\
+    ${reference.csip-core-1.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.debug=true
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.7
+javac.target=1.7
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}:\
+    ${libs.junit_4.classpath}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.preview=true
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+lib.dir=${web.docbase.dir}/WEB-INF/lib
+persistence.xml.dir=${conf.dir}
+platform.active=JDK_1.7
+project.csip-core-1=../csip-core
+reference.csip-core-1.jar=${project.csip-core-1}/dist/csip-core.jar
+resource.dir=setup
+rest.config.type=ide
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+# Space-separated list of JVM arguments used when running a class with a main method or a unit test
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
+runmain.jvmargs=
+source.encoding=UTF-8
+source.root=src
+src.dir=${source.root}/java
+test.src.dir=test
+war.content.additional=
+war.ear.name=${war.name}
+war.name=csip-wqm.war
+web.docbase.dir=web
+webinf.dir=web/WEB-INF
+=======
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=true
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
+auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
+auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
+auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
+auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
+auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
+auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs
+build.classes.dir=${build.web.dir}/WEB-INF/classes
+build.classes.excludes=**/*.java,**/*.form
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+build.web.dir=${build.dir}/web
+build.web.excludes=${build.classes.excludes}
+client.urlPart=
+compile.jsps=false
+conf.dir=${source.root}/conf
+debug.classpath=${build.classes.dir}:${javac.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+display.browser=false
+dist.dir=dist
+dist.ear.war=${dist.dir}/${war.ear.name}
+dist.javadoc.dir=${dist.dir}/javadoc
+dist.war=${dist.dir}/${war.name}
+endorsed.classpath=\
+    ${libs.javaee-endorsed-api-6.0.classpath}
+excludes=
+includes=**
+j2ee.compile.on.save=false
+j2ee.copy.static.files.on.save=false
+j2ee.deploy.on.save=false
+j2ee.platform=1.6-web
+j2ee.platform.classpath=${j2ee.server.home}/lib/annotations-api.jar:${j2ee.server.home}/lib/catalina-ant.jar:${j2ee.server.home}/lib/catalina-ha.jar:${j2ee.server.home}/lib/catalina-storeconfig.jar:${j2ee.server.home}/lib/catalina-tribes.jar:${j2ee.server.home}/lib/catalina.jar:${j2ee.server.home}/lib/ecj-4.4.jar:${j2ee.server.home}/lib/el-api.jar:${j2ee.server.home}/lib/jasper-el.jar:${j2ee.server.home}/lib/jasper.jar:${j2ee.server.home}/lib/jsp-api.jar:${j2ee.server.home}/lib/servlet-api.jar:${j2ee.server.home}/lib/tomcat-api.jar:${j2ee.server.home}/lib/tomcat-coyote.jar:${j2ee.server.home}/lib/tomcat-dbcp.jar:${j2ee.server.home}/lib/tomcat-i18n-es.jar:${j2ee.server.home}/lib/tomcat-i18n-fr.jar:${j2ee.server.home}/lib/tomcat-i18n-ja.jar:${j2ee.server.home}/lib/tomcat-jdbc.jar:${j2ee.server.home}/lib/tomcat-jni.jar:${j2ee.server.home}/lib/tomcat-spdy.jar:${j2ee.server.home}/lib/tomcat-util-scan.jar:${j2ee.server.home}/lib/tomcat-util.jar:${j2ee.server.home}/lib/tomcat-websocket.jar:${j2ee.server.home}/lib/websocket-api.jar
+j2ee.server.type=Tomcat
+jar.compress=false
+javac.classpath=\
+    ${libs.PostgreSQLDriver.classpath}:\
+    ${reference.csip-core-1.jar}:\
+    ${libs.CSIP-Jersey-2.16.classpath}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.debug=true
+javac.deprecation=false
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.7
+javac.target=1.7
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}:\
+    ${libs.junit_4.classpath}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.preview=true
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+lib.dir=${web.docbase.dir}/WEB-INF/lib
+persistence.xml.dir=${conf.dir}
+platform.active=JDK_1.7
+project.csip-core=../csip-core
+resource.dir=setup
+rest.config.type=ide
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+# Space-separated list of JVM arguments used when running a class with a main method or a unit test
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value):
+runmain.jvmargs=
+source.encoding=UTF-8
+source.root=src
+src.dir=${source.root}/java
+test.src.dir=test
+war.content.additional=
+war.ear.name=${war.name}
+war.name=csip-wqm.war
+web.docbase.dir=web
+webinf.dir=web/WEB-INF
+>>>>>>> other

nbproject/project.xml

@@ -1,46 +1,47 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.web.project</type>
-    <configuration>
-        <buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1">
-            <extension file="rest-build.xml" id="rest.4">
-                <dependency dependsOn="generate-rest-config" target="-pre-pre-compile"/>
-            </extension>
-        </buildExtensions>
-        <data xmlns="http://www.netbeans.org/ns/web-project/3">
-            <name>csip-wqm</name>
-            <minimum-ant-version>1.6.5</minimum-ant-version>
-            <web-module-libraries>
-                <library dirs="200">
-                    <file>${libs.PostgreSQLDriver.classpath}</file>
-                    <path-in-war>WEB-INF/lib</path-in-war>
-                </library>
-                <library dirs="200">
-                    <file>${reference.csip-core-1.jar}</file>
-                    <path-in-war>WEB-INF/lib</path-in-war>
-                </library>
-                <library dirs="200">
-                    <file>${libs.CSIP-Jersey-2.16.classpath}</file>
-                    <path-in-war>WEB-INF/lib</path-in-war>
-                </library>
-            </web-module-libraries>
-            <web-module-additional-libraries/>
-            <source-roots>
-                <root id="src.dir"/>
-            </source-roots>
-            <test-roots>
-                <root id="test.src.dir"/>
-            </test-roots>
-        </data>
-        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
-            <reference>
-                <foreign-project>csip-core-1</foreign-project>
-                <artifact-type>jar</artifact-type>
-                <script>build.xml</script>
-                <target>jar</target>
-                <clean-target>clean</clean-target>
-                <id>jar</id>
-            </reference>
-        </references>
-    </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.web.project</type>
+    <configuration>
+        <buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1">
+            <extension file="rest-build.xml" id="rest.4">
+                <dependency dependsOn="generate-rest-config" target="-pre-pre-compile"/>
+            </extension>
+        </buildExtensions>
+        <data xmlns="http://www.netbeans.org/ns/web-project/3">
+            <name>csip-wqm</name>
+            <minimum-ant-version>1.6.5</minimum-ant-version>
+            <explicit-platform explicit-source-supported="true"/>
+            <web-module-libraries>
+                <library dirs="200">
+                    <file>${libs.PostgreSQLDriver.classpath}</file>
+                    <path-in-war>WEB-INF/lib</path-in-war>
+                </library>
+                <library dirs="200">
+                    <file>${reference.csip-core-1.jar}</file>
+                    <path-in-war>WEB-INF/lib</path-in-war>
+                </library>
+                <library dirs="200">
+                    <file>${libs.CSIP-Jersey-2.16.classpath}</file>
+                    <path-in-war>WEB-INF/lib</path-in-war>
+                </library>
+            </web-module-libraries>
+            <web-module-additional-libraries/>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots>
+                <root id="test.src.dir"/>
+            </test-roots>
+        </data>
+        <references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
+            <reference>
+                <foreign-project>csip-core-1</foreign-project>
+                <artifact-type>jar</artifact-type>
+                <script>build.xml</script>
+                <target>jar</target>
+                <clean-target>clean</clean-target>
+                <id>jar</id>
+            </reference>
+        </references>
+    </configuration>
+</project>

src/java/m/wqm/ApplicationConfig.java

@@ -38,9 +38,9 @@
         resources.add(csip.ReportService.class);
         resources.add(m.wqm.NutrientSLP.V1_0.class);
         resources.add(m.wqm.nutappmgtscores.V1_0.class);
+        resources.add(m.wqm.nutrientslpsrp.V1_0.class);
         resources.add(m.wqm.nuttechscores.V1_0.class);
         resources.add(m.wqm.pesthazrating.V1_0.class);
-        resources.add(m.wqm.pesticide.attributes.V1_0.class);
         resources.add(m.wqm.pesticidesarp.V1_0.class);
         resources.add(m.wqm.pesticidessrp.V1_0.class);
         resources.add(m.wqm.pestipmscores.V1_0.class);

src/java/m/wqm/NutrientSLP/V1_0.java

@@ -1,10 +1,7 @@
-/*
- * 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.NutrientSLP;
+
 import csip.ModelDataService;
+import csip.ServiceException;
 import java.util.ArrayList;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
@@ -13,265 +10,215 @@
 import org.codehaus.jettison.json.JSONObject;
 import csip.utils.JSONUtils;
 import java.util.Map;
+import org.codehaus.jettison.json.JSONException;
 
 /**
  *
  * @ Srinivas
+ * @author Rumpal Sidhu
  */
-@Name("Nutrient.")
-@Description("Clculating Nutrient Soil Leaching Potential")
+@Name("WQM-05: Nutrient Soil Leaching Potential (NutrientSLP)")
+@Description("This service computes nutrient soil leaching potential for soil components in an area of analysis, and then computes nutrient soil leaching potential representing the area of analysis (AoA). The service primarily will consume data from the WQM-02 WQMSoilAttributes service to compute nutrient soil leaching potentials used later by the WQM-13 service to compute threshold treatment level scores.")
 @Path("m/nutrient_slp/1.0")
 
-public class V1_0 extends ModelDataService{
-    
-  //  String comp_nslp;
-    int comp_nslp_number;
-    String aoa_nslp;
-    String[] comp_nslp=new String[]{"","LOW","MODERATE","MODERATELY HIGH","HIGH"};
-    //JSONArray getArray
-    ArrayList<Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
-    ArrayList<Result1> result1=new ArrayList<>();  // store the result as objects
+public class V1_0 extends ModelDataService {
+
+    private final String[] nslpList = new String[]{"LOW", "MODERATE", "MODERATELY HIGH", "HIGH"};
+    //Request
+    private int aoaId;
+    private ArrayList<SoilComponent> soilComponentList;
+    //Result
+    private String aoaNslp;
+    private String error_msg;
+
     @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("soilcomponents");
-            for(int i=0;i<groups.length();i++)
-            {
+    protected void preProcess() throws Exception {
+        soilComponentList = new ArrayList<>();
+        this.error_msg = "";
+        try {
+            aoaId = getIntParam("AoAId");
+            JSONArray groups = getJSONArrayParam("soilcomponents");
+            for (int i = 0; i < groups.length(); i++) {
                 Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
+                SoilComponent input = new SoilComponent(
+                        JSONUtils.getStringParam(group, "cokey", "err"),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_area", 0),
+                        JSONUtils.getStringParam(group, "aoa_comp_hsg", "err"),
+                        JSONUtils.getStringParam(group, "aoa_comp_taxorder", "err"),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_kfact", 0),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_slope", 0),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_coarse_frag", 0),
+                        JSONUtils.getBooleanParam(group, "aoa_comp_drained", false),
+                        JSONUtils.getStringParam(group, "aoa_comp_wtbl", "err"),
+                        JSONUtils.getBooleanParam(group, "aoa_comp_hwt_lt_24", false));
+                soilComponentList.add(input);
+            }
+        } catch (ServiceException | JSONException ex) {
+            this.error_msg += "  " + ex.getMessage() + ". ";
+        }
+    }
 
-                
-                int AoAId = JSONUtils.getIntParam(group, "AoAId", 0);
-                String cokey=JSONUtils.getStringParam(group,"cokey","err");
-                double aoa_comp_area=JSONUtils.getDoubleParam(group,"aoa_comp_area",0);
-                String aoa_comp_hsg=JSONUtils.getStringParam(group,"aoa_comp_hsg","err");
-                String aoa_comp_taxorder=JSONUtils.getStringParam(group,"aoa_comp_taxorder","err");
-                double aoa_comp_kfact=JSONUtils.getDoubleParam(group,"aoa_comp_kfact",0);
-                double aoa_comp_slope=JSONUtils.getDoubleParam(group,"aoa_comp_slope",0);
-                int aoa_comp_coarse_frag=JSONUtils.getIntParam(group,"aoa_comp_coarse_frag",0);
-                boolean aoa_comp_drained=JSONUtils.getBooleanParam(group,"aoa_comp_drained",false);
-                Input input=new Input(AoAId,cokey,aoa_comp_area,aoa_comp_hsg,aoa_comp_taxorder,aoa_comp_kfact,aoa_comp_slope,aoa_comp_coarse_frag,aoa_comp_drained);
-        components.add(input);
+    @Override
+    protected String process() throws Exception {
+        try {
+            if (this.error_msg.isEmpty()) {
+                this.computeNSLP();
+            }
+            if (this.error_msg.isEmpty()) {
+                this.computeAoaNSLP();
+            }
+        } catch (Exception ex) {
+            LOG.info(ex.getMessage());
+            this.error_msg += ex.getMessage();
+        }
+        return (this.error_msg.isEmpty() ? EXEC_OK : this.error_msg);
+    }
+
+    @Override
+    protected void postProcess() throws Exception {
+        putResult("aoa_id", aoaId, "Area of analysis identifier");
+        putResult("aoa_nslp", aoaNslp, "Soil leaching potential of the area of analysis");
+        JSONArray resultArr = new JSONArray();
+        for (SoilComponent sc : soilComponentList) {
+            JSONArray array = new JSONArray();
+            array.put(JSONUtils.dataDesc("cokey", sc.getCokey(), "Soil component key"));
+            array.put(JSONUtils.dataDesc("comp_nslp", sc.getNslp(), "Soil leaching potential of the soil component"));
+            resultArr.put(JSONUtils.dataDesc("soil_component", array, "Soil Component"));
+        }
+        putResult("soil_components", resultArr, "List of Soil Components");
+    }
+
+    private void computeNSLP() {
+        int comp_nslp_number = -2;
+        for (SoilComponent ip : soilComponentList) {
+            if (ip.getTaxorder().equals("Histosols")) {
+                comp_nslp_number = 3;
+            } else if (ip.getWtbl().equals("Apparent") && ip.isHwt_lt_24()) {
+                comp_nslp_number = 3;
+            } else {
+                switch (ip.getHsg()) {
+                    case "A":
+                        comp_nslp_number = this.computeNSLPHsgA(ip);
+                        break;
+                    case "B":
+                        comp_nslp_number = this.computeNSLPHsgB(ip);
+                        break;
+                    case "C":
+                        comp_nslp_number = this.computeNSLPHsgC(ip);
+                        break;
+                    case "D":
+                        comp_nslp_number = this.computeNSLPHsgD(ip);
+                        break;
+                    case "A/D":
+                        if (ip.isDrained()) {
+                            comp_nslp_number = this.computeNSLPHsgA(ip);
+                        } else {
+                            comp_nslp_number = this.computeNSLPHsgD(ip);
+                        }
+                        break;
+                    case "B/D":
+                        if (ip.isDrained()) {
+                            comp_nslp_number = this.computeNSLPHsgB(ip);
+                        } else {
+                            comp_nslp_number = this.computeNSLPHsgD(ip);
+                        }
+                        break;
+                    case "C/D":
+                        if (ip.isDrained()) {
+                            comp_nslp_number = this.computeNSLPHsgC(ip);
+                        } else {
+                            comp_nslp_number = this.computeNSLPHsgD(ip);
+                        }
+                        break;
+                }
+            }
+            if (comp_nslp_number != -1 && comp_nslp_number != -2) {
+                ip.setNslpNumber(comp_nslp_number);
+                ip.setNslp(nslpList[comp_nslp_number]);
+            } else {
+                error_msg = "Error.";
             }
         }
+    }
 
-    @Override
-        protected String process() throws Exception
-        {
-        for (Input ip : components) {
-            if(ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                
-                comp_nslp_number=4;
+    private int computeNSLPHsgA(SoilComponent ip) {
+        int nslpNumber = -1;
+        if (ip.getSlope() > 12) {
+            if (ip.getCoarseFrag() > 10) {
+                nslpNumber = 3;
+            } else {
+                nslpNumber = 2;
             }
-            else if("A".equals(ip.aoa_comp_hsg)&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                if(ip.aoa_comp_slope>12)
-                {
-                    if(ip.aoa_comp_coarse_frag>10)
-                    {
-                        
-                        comp_nslp_number=4;
-                    }
-                    else
-                    {
-                        
-                        comp_nslp_number=3;
-                    }
-                }
-                else
-                {
-                    
-                    comp_nslp_number=4;
-                }
+        } else if (ip.getSlope() <= 12) {
+            nslpNumber = 3;
+        }
+        return nslpNumber;
+    }
+
+    private int computeNSLPHsgB(SoilComponent ip) {
+        int nslpNumber = -1;
+        if ((ip.getSlope() <= 12 && ip.getKfact() >= 0.24) || (ip.getSlope() > 12)) {
+            if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
+                nslpNumber = 2;
+            } else if (ip.getCoarseFrag() > 30) {
+                nslpNumber = 3;
+            } else {
+                nslpNumber = 1;
             }
-            else if("B".equals(ip.aoa_comp_hsg)&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                if(ip.aoa_comp_slope<=12 && ip.aoa_comp_kfact>=0.24 )
-                {
-                    if(ip.aoa_comp_coarse_frag>10 && ip.aoa_comp_coarse_frag<=30)
-                    {
-                        
-                        comp_nslp_number=3;
-                    }
-                    else if(ip.aoa_comp_coarse_frag>30)
-                    {
-                        
-                        comp_nslp_number=4;
-                    }
-                    else
-                    {
-                        
-                        comp_nslp_number=2;
-                    }
-                }
-                else if(ip.aoa_comp_slope>=3 && ip.aoa_comp_slope<=12 && ip.aoa_comp_kfact<0.24)
-                {
-                    if(ip.aoa_comp_coarse_frag>10)
-                    {
-                        
-                        comp_nslp_number=4;
-                    }
-                    else
-                    {
-                        
-                        comp_nslp_number=3;
-                    }
-                }
-                else
-                {
-                    
-                    comp_nslp_number=4;
-                }
-                
+        } else if (ip.getSlope() >= 3 && ip.getSlope() <= 12 && ip.getKfact() < 0.24) {
+            if (ip.getCoarseFrag() > 10) {
+                nslpNumber = 3;
+            } else {
+                nslpNumber = 2;
             }
-            else if(ip.aoa_comp_hsg.equals("C")&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                
-                comp_nslp_number=2;
-            }
-            else if(ip.aoa_comp_hsg.equals("D")&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                
-                comp_nslp_number=1;
-            }
-            else if("A/D".equals(ip.aoa_comp_hsg)&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                if(ip.aoa_comp_drained)
-                {
-                    if(ip.aoa_comp_slope>12)
-                    {
-                        if(ip.aoa_comp_coarse_frag>10)
-                        {
-                            
-                            comp_nslp_number=4;
-                        }
-                        else
-                        {
-                           
-                            comp_nslp_number=3;
-                        }
-                    }
-                    else
-                    {
-                        
-                        comp_nslp_number=4;
-                    }
-                }
-                else
-                {
-               
-                    comp_nslp_number=4;
-                }
-                
-            }
-            else if("B/D".equals(ip.aoa_comp_hsg)&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {
-                if(ip.aoa_comp_drained)
-                {
-                    if(ip.aoa_comp_slope<=12 && ip.aoa_comp_kfact>=0.24 )
-                    {
-                        if(ip.aoa_comp_coarse_frag>10 && ip.aoa_comp_coarse_frag<=30)
-                        {
-                          
-                            comp_nslp_number=3;
-                        }
-                        else if(ip.aoa_comp_coarse_frag>30)
-                        {
-                          
-                            comp_nslp_number=4;
-                        }
-                        else
-                        {
-                          
-                            comp_nslp_number=2;
-                        }
-                    }
-                    else if(ip.aoa_comp_slope>=3 && ip.aoa_comp_slope<=12 && ip.aoa_comp_kfact<0.24)
-                    {
-                        if(ip.aoa_comp_coarse_frag>10)
-                        {
-                          
-                            comp_nslp_number=4;
-                        }
-                        else
-                        {
-                          
-                            comp_nslp_number=3;
-                        }
-                    }
-                    else
-                    {
-                        
-                        comp_nslp_number=4;
-                    }
-                }
-                else
-                {
-                    
-                    comp_nslp_number=4;
-                }
-            }
-            else if(ip.aoa_comp_hsg.equals("C/D")&&!ip.aoa_comp_taxorder.equals("Histosols"))
-            {    
-                if(ip.aoa_comp_drained)
-                {
-                    
-                    comp_nslp_number=2;
-                }
-                else if(!ip.aoa_comp_drained)
-                {
-                    
-                    comp_nslp_number=4;
-                }
-            }
-            
-            Result1 result=new Result1(ip.AoAId,ip.cokey,ip.aoa_comp_area,comp_nslp[comp_nslp_number],comp_nslp_number);
-            result1.add(result);
+        } else if (ip.getSlope() < 3 && ip.getKfact() < 0.24) {
+            nslpNumber = 3;
         }
-        calAoANutSLP(result1);
-        return EXEC_OK;       
+        return nslpNumber;
     }
-        @Override
-        //writing the results back to JSON
-    protected void postProcess() throws Exception {
-        for(int i=0;i<result1.size();i++)
-        {
-            Result1 temp=result1.get(i);
-            putResult("AoAId",temp.AoAId,"Areao of analysis ID");
-            putResult("cokey",temp.cokey,"Soil Component Key");
-            putResult("aoa_comp_area",temp.aoa_comp_area,"Soil component area in the area of analysis");
-            putResult("comp_nslp",temp.comp_nslp,"Soil leaching potential of the soil component");
-            putResult("comp_nslp_number",temp.comp_nslp_number,"Number indicating #Soil leaching potential of the soil component");
-        }    
-        putResult("aoa_nslp",aoa_nslp,"Soil leaching potential of the area of analysis");
+
+    private int computeNSLPHsgC(SoilComponent ip) {
+        int nslpNumber;
+        if (ip.getCoarseFrag() > 30) {
+            nslpNumber = 3;
+        } else if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
+            nslpNumber = 2;
+        } else {
+            nslpNumber = 1;
+        }
+        return nslpNumber;
     }
-   // calculate the aoa_nslp 
-    void calAoANutSLP(ArrayList<Result1> source)
-    {
-        double cum_nslp_product=0;
-        double aoa_area=0;
-        
-        for(Result1 tmp:source)
-        {
-             cum_nslp_product+=(tmp.comp_nslp_number*tmp.aoa_comp_area);
-             aoa_area+=tmp.aoa_comp_area;
+
+    private int computeNSLPHsgD(SoilComponent ip) {
+        int nslpNumber;
+        if (ip.getCoarseFrag() > 30) {
+            nslpNumber = 2;
+        } else if (ip.getCoarseFrag() > 10 && ip.getCoarseFrag() <= 30) {
+            nslpNumber = 1;
+        } else {
+            nslpNumber = 0;
         }
-        double aoa_nslp_fract=cum_nslp_product/aoa_area;
-        if(aoa_nslp_fract<=1.50)
-        {
-               aoa_nslp="LOW"; 
+        return nslpNumber;
+    }
+
+    //Compute weighted average nutrient soil leaching potential for the AoA
+    private void computeAoaNSLP() {
+        double cumNslpProduct = 0;
+        double aoaArea = 0;
+
+        for (SoilComponent sc : soilComponentList) {
+            cumNslpProduct += (sc.getNslpNumber() * sc.getArea());
+            aoaArea += sc.getArea();
         }
-        else if(aoa_nslp_fract>1.50&&aoa_nslp_fract<=2.50)
-        {
-            aoa_nslp="MODERATE";
-        }
-        else if(aoa_nslp_fract>2.50&&aoa_nslp_fract<=3.50)
-        {
-            aoa_nslp="MODERATELY HIGH";
-        }
-        else
-        {
-            aoa_nslp="HIGH";
+        double aoaNslpFract = cumNslpProduct / aoaArea;
+        if (aoaNslpFract <= 0.50) {
+            aoaNslp = "LOW";
+        } else if (aoaNslpFract > 0.50 && aoaNslpFract <= 1.50) {
+            aoaNslp = "MODERATE";
+        } else if (aoaNslpFract > 1.50 && aoaNslpFract <= 2.50) {
+            aoaNslp = "MODERATELY HIGH";
+        } else {
+            aoaNslp = "HIGH";
         }
     }
 }

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

@@ -1,106 +1,434 @@
 {
- "metainfo": {
- },
- "parameter": [
-  {
-   "name": "soilcomponents",
-   "value": [
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"Areo Of Analysis Identifier"
-      
-     },
-     {
-      "name": "cokey",
-      "value": "11510284",
-      "Description":"#Soil component key (character)"
-     },
-     {
-      "name": "aoa_comp_area",
-      "value": 45.84,
-      "Description":"#Soil component area in the area of analysis (double)"
-     },
-     {
-      "name": "aoa_comp_hsg",
-      "value": "B",
-      "Description":"#Hydrologic soil group of the soil component (character)"
-     },
-     {
-      "name": "aoa_comp_taxorder",
-      "value": "Aridisols",
-      "Description":"#Taxonomic order of the soil component (character)"
-     },
-     {
-      "name": "aoa_comp_kfact",
-      "value": 0.24,
-      "Description":"#Representative K factor of the soil component (double)"
-     },
-     {
-      "name": "aoa_comp_slope",
-      "value": 8,
-      "Description":"#Representative slope of the soil component (double)"
-     },
-     {
-       "name":"aoa_comp_coarse_frag",
-       "value":3,
-       "Description":"#Representative coarse rock fragments of the soil component (integer)"
-     },
-     {
-         "name":"aoa_comp_drained",
-         "value":true,
-         "Description":"#Whether this soil component instance is drained (true/false)"
-     }
-    ],
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"Areo Of Analysis Identifier"
-     },
-     {
-      "name": "cokey",
-      "value": "11510290",
-      "Description":"#Soil component key (character)"
-     },
-     {
-      "name": "aoa_comp_area",
-      "value": 63.72,
-      "Description":"#Soil component area in the area of analysis (double)"
-     },
-     {
-      "name": "aoa_comp_hsg",
-      "value": "D",
-      "Description":"#Hydrologic soil group of the soil component (character)"
-     },
-     {
-      "name": "aoa_comp_taxorder",
-      "value": "Aridisols",
-      "Description":"#Taxonomic order of the soil component (character)"
-     },
-     {
-      "name": "aoa_comp_kfact",
-      "value": 0.37,
-      "Description":"#Representative K factor of the soil component (double)"
-     },
-     {
-      "name": "aoa_comp_slope",
-      "value": 12,
-      "Description":"#Representative slope of the soil component (double)"
-     },
-     {
-       "name":"aoa_comp_coarse_frag",
-       "value":6,
-       "Description":"#Representative coarse rock fragments of the soil component (integer)"
-     },
-     {
-         "name":"aoa_comp_drained",
-         "value":true,
-         "Description":"#Whether this soil component instance is drained (true/false)"
-     }
+    "metainfo": {
+    },
+    "parameter": [
+        {
+            "name": "AoAId",
+            "value": 1,
+            "Description": "Area of analysis identifier"
+        },
+        {
+            "name": "soilcomponents",
+            "value": [
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150284",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 45.84,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Aridisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.24,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 8,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 3.7,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": true,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150285",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 63.72,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "A",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.37,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 12,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 0,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": true,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Apparent",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150286",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 25.6,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "A/D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Spodosols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.21,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 15,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 12,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150287",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 33.5,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "C",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Inceptisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.42,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 16,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 6,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150288",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 10.77,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Histosols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.02,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 3,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 2,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Apparent",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150289",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 36.93,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B/D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Entisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.28,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 1,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 3,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Perched",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150290",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 44.33,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.32,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 14,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 7,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150291",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 21.76,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.48,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 5,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 5,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Perched",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ]
+            ]
+        }
     ]
-   ]
-  }
- ]
 }

src/java/m/wqm/nutappmgtscores/Crop.java

@@ -3,41 +3,114 @@
 /**
  *
  * @author RUMPAL SIDHU
+ * @author Shaun Case
  */
+import csip.utils.Dates;
+import csip.utils.JSONUtils;
+
 import java.util.Date;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
 
 public class Crop {
 
+    
+    
+    //  Begin Crop Class
+    public static final int N_APP_RATE_SCORE = 0;
+    public static final int P_APP_RATE_SCORE = 1;
+    public static final int N_APP_TIMING_SCORE = 0;
+    public static final int P_APP_TIMING_SCORE = 1;
+    
     private int mgtCropId;
-    private boolean lmod;
     private String cropPlantDate;
+    private Date plantDate;
     private double cropYield;
     private String cropYieldUnits;
-    private ArrayList<Nutrient> nutrientApplicationList;
-
-    public Crop(int mgtCropId, boolean lmod, String cropPlantDate, double cropYield,
-            String cropYieldUnits, ArrayList<Nutrient> nutrientApplicationList) {
+    private ArrayList<Crop.NutrientApplication> nutrientApplicationList;
+    private m.wqm.nutappmgtscores.Result calc_result;
+    private Statement statement;
+    private String cropType = "";
+    private String error_msg = "";
+    private Boolean multipleNutrientApplication = false;
+    private int n_app_timing_score = 100;
+    private int p_app_timing_score = 100;
+    private int app_method_score = 0;
+    private int[] appRateScore = new int[2];
+    private int[] appNutrientTimingScore = new int[2];
+    private String pSoilTestResult = "None";
+  
+    public Crop(int mgtCropId,String cropPlantDate, double cropYield,
+                String cropYieldUnits, JSONArray applicationList, String pSoilTestResult, Statement statement){
         this.mgtCropId = mgtCropId;
-        this.lmod = lmod;
         this.cropPlantDate = cropPlantDate;
         this.cropYield = cropYield;
         this.cropYieldUnits = cropYieldUnits;
-        this.nutrientApplicationList = nutrientApplicationList;
+        this.statement = statement;
+        this.pSoilTestResult = pSoilTestResult;
+     
+        nutrientApplicationList = new ArrayList<Crop.NutrientApplication>();
+        
+        try{
+            plantDate = getCropPlantDate();
+            if ( null != applicationList ){                           
+                for (int j = 0; j < applicationList.length(); j++) {
+                    Map<String, JSONObject> application = JSONUtils.preprocess(applicationList.getJSONArray(j));
+                    nutrientApplicationList.add(new Crop.NutrientApplication(JSONUtils.getStringParam(application, "nutrient_application_date", "err"), JSONUtils.getStringParam(application, "incorporated", ""), JSONUtils.getJSONArrayParam(application, "application")));              
+                }            
+            }
+        }
+        catch( Exception ex){
+           error_msg += "Cannot process list of applied nutrients.  " + ex.getMessage(); 
+        }
+
+        multipleNutrientApplication = (nutrientApplicationList.size() > 1);           
+        this.appRateScore[N_APP_RATE_SCORE] = this.appRateScore[P_APP_RATE_SCORE] = -1;
+        this.appNutrientTimingScore[N_APP_TIMING_SCORE] = this.appNutrientTimingScore[P_APP_TIMING_SCORE] = -1;
     }
 
-    //Getter methods
+    //Get methods
     public int getMgtCropId() {
         return this.mgtCropId;
     }
 
-    public boolean getLmod() {
-        return this.lmod;
+    public String getErrorMsg(){
+        for ( Crop.NutrientApplication nutrientApplied: this.nutrientApplicationList ){
+            error_msg += nutrientApplied.getErrorMsg();
+        }
+        return error_msg;
     }
-
-    public Date getCropPlantDate() throws Exception {
+    
+    public String getCropType(){
+        if ( (cropType.isEmpty()) && (error_msg.isEmpty()) ){
+            ResultSet resultSet;                   
+            String query = "SELECT wqm_crop_type FROM wqm_crops WHERE wqm_crop_id=" + mgtCropId + " AND wqm_crop_units='" + cropYieldUnits + "';";
+            try{
+                resultSet = statement.executeQuery(query);
+                if (!resultSet.first()){
+                    error_msg += "That crop, " + mgtCropId + ", and crop yield units, "+ cropYieldUnits + ", was not found in the database";
+                }
+                else{                        
+                    cropType = resultSet.getString("wqm_crop_type");   
+                }
+            }
+            catch( SQLException ex ) {
+                error_msg += ex.getMessage();
+            }
+        }
+        return cropType;
+    }
+    public final Date getCropPlantDate() throws Exception {
         String[] parse = this.cropPlantDate.split("-");
         Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]),
                 Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2]));
@@ -55,4 +128,337 @@
     public ArrayList getNutrientApplicationList() {
         return this.nutrientApplicationList;
     }
+    
+    public int[] getNutrientApplicationRateScores(){
+        if ( ( appRateScore[N_APP_RATE_SCORE] <0 ) || ( appRateScore[P_APP_RATE_SCORE] <0 ) ) {
+            try{
+                if ( nutrientApplicationList.isEmpty() ){
+                    ResultSet resultSet;                   
+
+                    appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;            
+                    String queryNitrogen = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='Nitrogen' AND app_mgt_kind='Rate' AND app_mgt_factor='none';";
+                    String queryPhosporous = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='Phosphorus' AND app_mgt_kind='Rate' AND app_mgt_factor='none' AND soil_test_result='" + pSoilTestResult + "';";
+
+                    resultSet = statement.executeQuery(queryNitrogen);
+                    if ( resultSet.first() ) {
+                        appRateScore[N_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score");
+                    }
+
+                    resultSet = statement.executeQuery(queryPhosporous);
+                    if ( resultSet.first() ) {
+                        appRateScore[P_APP_RATE_SCORE] = resultSet.getInt("app_mgt_score");  
+                    }  
+                }
+                else{
+                    ResultSet resultSet;
+                    String query;
+                    
+                    double nrate = 0.0;
+                    double prate = 0.0;
+
+                    double wqm_crop_pct_dmat = 0.0;
+                    double wqm_pct_nitrogen = 0.0;
+                    double wqm_pct_phosphorus = 0.0;
+                    double wqm_crop_yield = 0.0;
+                                        
+                    int ncrop_app_rate_score = 0;
+                    int pcrop_app_rate_score = 0;                       
+                    
+                    for (Crop.NutrientApplication nutrient : nutrientApplicationList) {
+                        ArrayList<Crop.NutrientApplication.Nutrient> nutrientAppliedList = nutrient.getNutrientList();
+                        for (Crop.NutrientApplication.Nutrient nApplied : nutrientAppliedList) {
+                            switch(nApplied.getNutrientApplied()){  //Note:  This switch requires JDK 1.7 or above
+                                case "Nitrogen":
+                                    nrate += nApplied.getApplicationRate();
+                                    break;
+                                case "Phosphorus":
+                                    prate += nApplied.getApplicationRate();
+                                    break;                                                                                                 
+                            }
+                        }
+                    }
+                    
+                    query = "SELECT wqm_crop_pct_dmat, wqm_pct_nitrogen, wqm_pct_phosphorus, wqm_crop_yield FROM wqm_crops WHERE wqm_crop_id=" + mgtCropId + ";";
+                    resultSet = statement.executeQuery(query);
+                    if (resultSet.first()) {
+                        wqm_crop_pct_dmat = resultSet.getDouble("wqm_crop_pct_dmat");
+                        wqm_pct_nitrogen = resultSet.getDouble("wqm_pct_nitrogen");
+                        wqm_pct_phosphorus = resultSet.getDouble("wqm_pct_phosphorus");
+                        wqm_crop_yield = resultSet.getDouble("wqm_crop_yield");
+                        
+                        //  Added wqm_crop_yield to the calc per bug #462839
+                        double n_growout = cropYield * wqm_crop_yield * wqm_crop_pct_dmat * wqm_pct_nitrogen;
+                        double p_growout = cropYield * wqm_crop_yield * wqm_crop_pct_dmat * wqm_pct_phosphorus;
+
+                        double n_remove_ratio = nrate / n_growout;
+                        double p_remove_ratio = prate / p_growout;      
+
+                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor=";
+
+                        switch( cropType ){
+                            case "Small Grain":  //Note the case conflicts here...
+                                query += "'small grain'";
+                                break;
+
+                            default:  
+                                query += "'other'";
+                        }   
+                        query += " AND remove_ratio_1 <= " + n_remove_ratio + "AND remove_ratio_2 > " + n_remove_ratio + ";";
+                        
+                        resultSet = statement.executeQuery(query);
+                        if (resultSet.first()) {
+                            ncrop_app_rate_score = resultSet.getInt("app_mgt_score");
+                        }
+                        else{
+                            appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
+                        }
+                            
+                        pcrop_app_rate_score = -1;
+                        //#Compute P application management rate scores based on removal ratio and soil test result
+                        switch (pSoilTestResult){
+                            case "High":
+                               if (p_remove_ratio >= 1.2) {
+                                    pcrop_app_rate_score = 0;
+                                }
+                                break;
+                            case "Medium": case "Low":
+                                if (p_remove_ratio >= 1.6) {
+                                    pcrop_app_rate_score = 0;
+                                }
+                                break;
+                            case "None":
+                                if (p_remove_ratio >= 1.2) {
+                                    pcrop_app_rate_score = 0;
+                                }
+                                break;                                                                                                                                                                                     
+                        }
+
+                        if ( pcrop_app_rate_score == -1 ){
+                            query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='Phosphorus' AND app_mgt_kind='Rate' AND app_mgt_factor='app' AND soil_test_result='" + pSoilTestResult +"' AND remove_ratio_1 <= " + p_remove_ratio + " AND remove_ratio_2 > " + p_remove_ratio + ";";
+                            resultSet = statement.executeQuery(query);
+                            if (resultSet.first()) {
+                                 pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
+                             }                                   
+                        }
+
+                        if (pcrop_app_rate_score != -1){
+                        //#Update N and P application management rate scores for the AoA
+                        appRateScore[N_APP_RATE_SCORE] = ncrop_app_rate_score;
+                        appRateScore[P_APP_RATE_SCORE] = pcrop_app_rate_score;                                                                                                
+                        }
+                        else{//We have a problem...no validity in any following computations if we proceed since the last query failed to find any data.  What would you like to do?
+                            appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
+                        }                                                                                                                                                                                                                                                                                                                                                                              
+                    }
+                    else{ //We have a problem...no validity in any following computations if we proceed.  What would you like to do?
+                        appRateScore[N_APP_RATE_SCORE] = appRateScore[P_APP_RATE_SCORE] = 0;
+                    }                                                       
+                }
+            }
+            catch (SQLException ex) {
+                error_msg += ex.getMessage();
+            }                   
+        }
+       
+        return this.appRateScore;
+    }
+    
+    public int[] getNutrientApplicationTimingScores(){
+        if ( ( appNutrientTimingScore[N_APP_TIMING_SCORE]  <0 ) || ( appNutrientTimingScore[P_APP_TIMING_SCORE]  <0 ) ) {
+            int tempNScore = 100;
+            int tempPScore = 100;
+            
+            for ( Crop.NutrientApplication nutrientApplication : this.nutrientApplicationList ){
+                //  Call each application compare its results to the last and adjust main score if necessary.
+                int[] tempAppTimingScores = nutrientApplication.getNutrientTimingScores( this.multipleNutrientApplication );
+                
+                if ( tempAppTimingScores[N_APP_TIMING_SCORE] < tempNScore ) {
+                    tempNScore = tempAppTimingScores[N_APP_TIMING_SCORE];
+                }
+                
+                if ( tempAppTimingScores[P_APP_TIMING_SCORE] < tempPScore ) {
+                    tempPScore = tempAppTimingScores[P_APP_TIMING_SCORE];                               
+                }                               
+            }
+            
+            appNutrientTimingScore[P_APP_TIMING_SCORE] = tempPScore;
+            appNutrientTimingScore[N_APP_TIMING_SCORE] = tempNScore;
+        }
+                
+        return this.appNutrientTimingScore;                        
+    }
+            
+    public Boolean allNutrientsIncorporated(){
+        Boolean ret_val = true;
+        for( Crop.NutrientApplication nutrientApplication : this.nutrientApplicationList ){
+            if ( !nutrientApplication.allNutrientsIncorporated() ){
+                ret_val = false;
+                break;
+            }
+        }
+        
+        return ret_val;
+    }
+    
+    public String processCropData(){
+        String ret_val = "";
+        
+        return ret_val;
+    }
+    
+    public Boolean validate(){          
+        for( Crop.NutrientApplication tNutrientApplication : nutrientApplicationList ) {
+            if (!tNutrientApplication.validate()) {
+                error_msg += "; " + tNutrientApplication.getErrorMsg();                
+            }
+        }                
+
+        
+        return ( error_msg.isEmpty() );
+    }
+
+    //  Inner Classes
+    class NutrientApplication {
+
+        class Nutrient {
+
+            private String error_msg = "";
+            private final String nutrientApplied;
+            private final double applicationRate;
+
+            Nutrient(String nutrientApplied, double applicationRate) {
+                this.nutrientApplied = nutrientApplied;
+                this.applicationRate = applicationRate;
+                
+                if ( !nutrientApplied.equals("Nitrogen") && !nutrientApplied.equals("Phosphorus") ) {
+                    this.error_msg += "Invalid input data.  Bad nutrient name";
+                }
+            }
+
+            //Get Methods
+            public String getNutrientApplied() {
+                return this.nutrientApplied;
+            }
+
+            public double getApplicationRate() {
+                return this.applicationRate;
+            }
+
+            public String getErrorMsg(){
+                return this.error_msg;
+            }
+
+            public Boolean validate(){
+                return (this.error_msg.isEmpty());
+            }
+        }
+        private String error_msg = "";
+        private String applicationDate;
+        private boolean incorporated;
+        private ArrayList<Crop.NutrientApplication.Nutrient> nutrientList;
+        private int appMethodScore = 0;
+        private int[] nutrientTimingScores = new int[2];
+
+        NutrientApplication(String applicationDate, String incorporated, JSONArray applications) {
+            this.applicationDate = applicationDate;
+            nutrientTimingScores[N_APP_TIMING_SCORE] = nutrientTimingScores[P_APP_TIMING_SCORE] = -1;
+            if (( !"true".equalsIgnoreCase(incorporated) ) && ( !"false".equalsIgnoreCase(incorporated) )) {
+                this.error_msg += "Invalid incorporation value for nutrient application " + applicationDate;
+            } else {
+                this.incorporated = Boolean.parseBoolean(incorporated);
+                nutrientList = new ArrayList<>();
+                try {
+                    for (int k = 0; k < applications.length(); k++) {
+                        Map<String, JSONObject> nutrient = JSONUtils.preprocess(applications.getJSONArray(k));
+                        nutrientList.add(new Crop.NutrientApplication.Nutrient(JSONUtils.getStringParam(nutrient, "nutrient_applied", "err"), JSONUtils.getDoubleParam(nutrient, "application_rate", 0)));
+                    }
+                } catch (JSONException ex) {
+                    this.error_msg += "Cannot process applied nutrient list.  " + ex.getMessage();
+                }
+            }
+        }
+
+        //Get Methods
+        public Date getApplicationDate() throws Exception {
+            String[] parse = this.applicationDate.split("-");
+            //Some say should set to use UTC first...do we wanna do that?
+            Calendar date = new GregorianCalendar(Integer.parseInt(parse[0]),
+                    Integer.parseInt(parse[1]) - 1, Integer.parseInt(parse[2]));
+            return date.getTime();
+        }
+        
+        public boolean isIncorporated() {
+            return this.incorporated;
+        }
+        
+        public ArrayList getNutrientList() {
+            return this.nutrientList;
+        }
+
+        public String getErrorMsg(){
+            for (Crop.NutrientApplication.Nutrient nutrient : this.nutrientList ){
+                this.error_msg += nutrient.getErrorMsg();
+            }
+            return this.error_msg;
+        }
+
+        public Boolean validate() {
+            for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) {
+                if (!nutrient.validate()) {
+                    this.error_msg += "; " + nutrient.getErrorMsg();
+                }
+            }
+            return (this.error_msg.isEmpty());
+        }
+
+        public int[] getNutrientTimingScores(Boolean split) {
+            if (( nutrientTimingScores[N_APP_TIMING_SCORE] < 0 ) || ( nutrientTimingScores[P_APP_TIMING_SCORE] < 0 )) {
+                int tempNScore = 100;
+                int tempPScore = 100;
+                ResultSet resultSet;
+                for (Crop.NutrientApplication.Nutrient nutrient : nutrientList) {
+                    int app_timing_score;
+                    try {
+                        long app_day_diff = Dates.diffInMillis( getCropPlantDate(), getApplicationDate() );
+                        app_day_diff = TimeUnit.MILLISECONDS.toDays(app_day_diff);
+                        String query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='";
+                        query += nutrient.getNutrientApplied() + "' ";
+                        query += "AND app_mgt_kind='Timing' AND app_mgt_factor='" + (split? "split":"nosplit") + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
+                        resultSet = statement.executeQuery(query);
+                        if ( !resultSet.first() ) {
+                            app_timing_score = -1;
+                        }
+                        else {
+                            app_timing_score = resultSet.getInt("app_mgt_score");
+                        }
+                        switch (nutrient.getNutrientApplied()) {
+                            case "Nitrogen":
+                                if (app_timing_score < tempNScore) {
+                                    tempNScore = app_timing_score;
+                                }
+                                break;
+                            case "Phosphorus":
+                                if (app_timing_score < tempPScore) {
+                                    tempPScore = app_timing_score;
+                                }
+                                break;
+                            default:
+                                this.error_msg += "Invalid nutrient name specified";
+                        }
+                    }catch (Exception ex){
+                        this.error_msg += "Cannot calculate nutrient application timing scores: " + ex.getMessage();
+                    }
+                    if ( this.error_msg.isEmpty() ){
+                        nutrientTimingScores[N_APP_TIMING_SCORE] = tempNScore;
+                        nutrientTimingScores[P_APP_TIMING_SCORE] = tempPScore;
+                    }
+                }
+            }
+            return nutrientTimingScores;
+        }
+
+        public Boolean allNutrientsIncorporated(){
+            return this.incorporated;
+        }
+    }
 }

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

@@ -3,7 +3,10 @@
 /**
  *
  * @author RUMPAL SIDHU
+ * @author Shaun Case
+ * 
  */
+ 
 import csip.ModelDataService;
 import csip.utils.JSONUtils;
 import csip.utils.Dates;
@@ -21,357 +24,155 @@
 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")
-@Description("Nutrient Application Management Scores")
+@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.")
 @Path("m/nutappmgtscores/1.0")
 @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 = "postgres";
-    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;
-
+    
+    //private class variables for this service
+    private int AoAId = 0;
+    private String p_soil_test_result = "err";
+    private ArrayList<Crop> cropList;   
+    private String error_msg = "";
+    private Connection conn = null;
+    private Statement statement = null;    
+    
     @Override
     protected void preProcess() throws Exception {
-        input = new ArrayList<>();
-        int AoAId = getIntParam("aoa_id", 0);
-        String p_soil_test_result = getStringParam("p_soil_test_result", "err");
-        ArrayList<Crop> cropList = new ArrayList<>();
-        JSONArray cropIds = getJSONArrayParam("cropIds");
-        for (int i = 0; i < cropIds.length(); i++) {
-            Map<String, JSONObject> mgtCropId = JSONUtils.preprocess(cropIds.getJSONArray(i));
+        try{
+            conn = wqm.utils.WQMTools.getConnection( "wqm", LOG );
+            statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+        }
+        catch( SQLException ex ) {
 
-            int cropId = JSONUtils.getIntParam(mgtCropId, "mgt_crop_id", 0);
-            boolean lmod = JSONUtils.getBooleanParam(mgtCropId, "from_lmod", false);
-            String cropPlantDate = JSONUtils.getStringParam(mgtCropId, "crop_plant_date", "err");
-            double cropYield = JSONUtils.getDoubleParam(mgtCropId, "crop_yield", 0);
-            String cropYieldUnits = JSONUtils.getStringParam(mgtCropId, "crop_yield_units", "err");
-            ArrayList<Nutrient> nutrientApplicationList = new ArrayList<>();
-            JSONArray applicationList = JSONUtils.getJSONArrayParam(mgtCropId, "applicationList");
-            for (int j = 0; j < applicationList.length(); j++) {
-                Map<String, JSONObject> application = JSONUtils.preprocess(applicationList.getJSONArray(j));
-                String nutrient_application_date = JSONUtils.getStringParam(application, "nutrient_application_date", "err");
-                boolean incorporated = JSONUtils.getBooleanParam(application, "incorporated", false);
-                ArrayList<NutrientApplied> nutrientAppliedList = new ArrayList<>();
-                JSONArray applicate = JSONUtils.getJSONArrayParam(application, "application");
-                for (int k = 0; k < applicate.length(); k++) {
-                    Map<String, JSONObject> a = JSONUtils.preprocess(applicate.getJSONArray(k));
-                    String nutrient_applied = JSONUtils.getStringParam(a, "nutrient_applied", "err");
-                    double application_rate = JSONUtils.getDoubleParam(a, "application_rate", 0);
-                    nutrientAppliedList.add(new NutrientApplied(nutrient_applied, application_rate));
-                }
-                nutrientApplicationList.add(new Nutrient(nutrient_application_date, incorporated, nutrientAppliedList));
-            }
-            cropList.add(new Crop(cropId, lmod, cropPlantDate, cropYield, cropYieldUnits, nutrientApplicationList));
+                LOG.info("Did not open database for WQM-16.");
+                LOG.info(ex.getMessage());      
+                this.error_msg = "Could not open database for WQM-16.  " + ex.getMessage();
+            }                                         
+
+        if (error_msg.isEmpty()){
+            AoAId = getIntParam("aoa_id", 0);
+            p_soil_test_result = getStringParam("p_soil_test_result", "err");
+            cropList = new ArrayList<>();
+
+            JSONArray cropIds = getJSONArrayParam("cropIds");
+            for (int i = 0; i < cropIds.length(); i++) {
+                JSONArray applicationList = null;
+                Map<String, JSONObject> mgtCropId = JSONUtils.preprocess(cropIds.getJSONArray(i));
+                
+                if ( JSONUtils.checkKeyExistsB( mgtCropId, "applicationList") )
+                    applicationList = JSONUtils.getJSONArrayParam(mgtCropId, "applicationList");
+                
+                cropList.add( new Crop(JSONUtils.getIntParam(mgtCropId, "mgt_crop_id", 0), JSONUtils.getStringParam(mgtCropId, "crop_plant_date", "err"), 
+                            JSONUtils.getDoubleParam(mgtCropId, "crop_yield", 0), JSONUtils.getStringParam(mgtCropId, "crop_yield_units", "err"), 
+                            applicationList, p_soil_test_result, statement));
+            }            
+            
+            ValidateInput();
         }
-        input.add(new m.wqm.nutappmgtscores.Input(AoAId, cropList, p_soil_test_result));
     }
 
     @Override
-    protected String process() throws Exception {
-        result = new ArrayList<>();
-        Connection conn = null;
-        Statement statement = null;
+    protected String process() throws Exception {        
+        String ret_val = EXEC_OK;
+        int n_app_timing_score = 100;
+        int p_app_timing_score = 100;
+        int app_method_score = -1;
+        int n_app_rate_score = 0;
+        int p_app_rate_score = 0;
+        int this_crop_id = 0;
         String query;
         ResultSet resultSet;
+        
+        if ( !error_msg.isEmpty()){
+            ret_val = error_msg;
+        }
+        else{
+            result = new ArrayList<>();
 
-        try {
-            Class.forName(CLASS_NAME);
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
-            conn.setAutoCommit(false);
-            statement = conn.createStatement();
-            for (Input ip : input) {
-                int n_app_timing_score = 100;
-                int p_app_timing_score = 100;
-                int app_method_score = 0;
-                int n_app_rate_score = 0;
-                int p_app_rate_score = 0;
-                int this_crop_id = 0;
-                ArrayList<Crop> cropList = ip.getCropList();
+            try {
                 for (Crop crop : cropList) {
-                    ArrayList<Nutrient> nutrientApplicationList = crop.getNutrientApplicationList();
-                    //#If request payload crop is an LMOD vegetation, then convert it to a wqm_crop using the link table
-                    if (crop.getLmod()) {
-                        query = "SELECT wqm_crop_id FROM wqm_lmod_crop_link WHERE lmod_crop_id=" + crop.getMgtCropId() + ";";
-                        resultSet = statement.executeQuery(query);
-                        while (resultSet.next()) {
-                            this_crop_id = resultSet.getInt("wqm_crop_id");
-                        }
-                    } else {
-                        this_crop_id = crop.getMgtCropId();
+                    
+                    String crop_type = crop.getCropType();
+//////TODO:  Remember to check for errors from the classes....   ///////                    
+                    if ( !crop_type.isEmpty() ){                                               
+                         //#Update N and P application management rate scores for each crop
+                        int[] app_rate_scores = crop.getNutrientApplicationRateScores();
+                        if ( !(error_msg = crop.getErrorMsg()).isEmpty() )
+                            break;
+                        
+                        //Cummulative sum of N and P application management scores over all crops for the AoA
+                        n_app_rate_score += app_rate_scores[Crop.N_APP_RATE_SCORE];
+                        p_app_rate_score += app_rate_scores[Crop.P_APP_RATE_SCORE];
+                                                
+                        
+                        //#Compute N and P application timing scores for the crop and update timing scores for the AoA
+                        int [] app_time_scores = crop.getNutrientApplicationTimingScores();
+                        if ( !(error_msg = crop.getErrorMsg()).isEmpty() )
+                            break;                        
+
+                        //  There is a problem with the logic of the specification here...It does not take into account the actual timing of applications when
+                        //  there are mulitple crops and multiple years invovled....these final values are probably not correct.  The "-1" below is placed here
+                        //  in an attempt to fix the missing database values problem that also exists with this logic at the nutrient level.
+                        if (( app_time_scores[Crop.N_APP_TIMING_SCORE] < n_app_timing_score ) || (n_app_timing_score == -1))
+                            n_app_timing_score = app_time_scores[Crop.N_APP_TIMING_SCORE];
+                        
+                        if (( app_time_scores[Crop.P_APP_TIMING_SCORE] < p_app_timing_score ) || (p_app_timing_score == -1))
+                            p_app_timing_score = app_time_scores[Crop.P_APP_TIMING_SCORE];
+                        
+                        //#If any nutrient application for any crop is not incorporated, the method score for the AoA is zero
+                        if ( !crop.allNutrientsIncorporated() ){
+                            app_method_score = 0;
+                        }                          
+                        if ( !(error_msg = crop.getErrorMsg()).isEmpty() )
+                            break;                        
                     }
-
-                    //#Determine crop type of the crop
-                    query = "SELECT wqm_crop_type FROM wqm_crops WHERE wqm_crop_id=" + this_crop_id + ";";
-                    resultSet = statement.executeQuery(query);
-                    String crop_type = "err";
-                    while (resultSet.next()) {
-                        crop_type = resultSet.getString("wqm_crop_type");
-                    }
-
-                    //#Determine whether split nutrient applications or not
-                    int app_count = 0;
-                    String app_type;
-                    //For each nutrient_application_date in the crop period
-                    //for (Nutrient i : nutrientApplication) {
-                    //    app_count = app_count + 1;
-                    //}
-                    app_count = nutrientApplicationList.size();
-                    if (app_count == 1) {
-                        app_type = "nosplit";
-                    } else {
-                        app_type = "split";
-                    }
-                    //If no nutrient_application_date (no nutrient applications for the crop)
-                    int ncrop_app_rate_score = 0;
-                    int pcrop_app_rate_score = 0;
-                    if (nutrientApplicationList.isEmpty()) {
-                        //#Compute score for not fertilizing.
-                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "None" + "';";
-                        resultSet = statement.executeQuery(query);
-                        while (resultSet.next()) {
-                            n_app_rate_score = resultSet.getInt("app_mgt_score");
-                        }
-                        switch (ip.getPSoilTestResult()) {
-                            case "High": {
-                                query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "None" + "' AND soil_test_result='" + "High" + "';";
-                                resultSet = statement.executeQuery(query);
-                                while (resultSet.next()) {
-                                    p_app_rate_score = resultSet.getInt("app_mgt_score");
-                                }
-                                break;
-                            }
-                            case "Medium": {
-                                query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "None" + "' AND soil_test_result='" + "Medium" + "';";
-                                resultSet = statement.executeQuery(query);
-                                while (resultSet.next()) {
-                                    p_app_rate_score = resultSet.getInt("app_mgt_score");
-                                }
-                                break;
-                            }
-                            case "None": {
-                                query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "None" + "' AND soil_test_result='" + "None" + "';";
-                                resultSet = statement.executeQuery(query);
-                                while (resultSet.next()) {
-                                    p_app_rate_score = resultSet.getInt("app_mgt_score");
-                                }
-                            }
-                        }
-                    } else { //Else #Compute N and P removal ratios
-                        double nrate = 0.0;
-                        double prate = 0.0;
-                        for (Nutrient nutrient : nutrientApplicationList) {
-                            ArrayList<NutrientApplied> nutrientAppliedList = nutrient.getNutrientAppliedList();
-                            for (NutrientApplied nApplied : nutrientAppliedList) {
-                                if (nApplied.getNutrientApplied().equals("Nitrogen")) {
-                                    nrate = nrate + nApplied.getApplicationRate();
-                                } else {
-                                    prate = prate + nApplied.getApplicationRate();
-                                }
-                            }
-                        }
-                        double wqm_crop_pct_dmat = 0.0;
-                        double wqm_pct_nitrogen = 0.0;
-                        double wqm_pct_phosphorus = 0.0;
-                        query = "SELECT wqm_crop_pct_dmat, wqm_pct_nitrogen, wqm_pct_phosphorus FROM wqm_crops WHERE wqm_crop_id=" + this_crop_id + ";";
-                        resultSet = statement.executeQuery(query);
-                        while (resultSet.next()) {
-                            wqm_crop_pct_dmat = resultSet.getDouble("wqm_crop_pct_dmat");
-                            wqm_pct_nitrogen = resultSet.getDouble("wqm_pct_nitrogen");
-                            wqm_pct_phosphorus = resultSet.getDouble("wqm_pct_phosphorus");
-                        }
-
-                        double n_growout = crop.getCropYield() * wqm_crop_pct_dmat * wqm_pct_nitrogen;
-                        double p_growout = crop.getCropYield() * wqm_crop_pct_dmat * wqm_pct_phosphorus;
-
-                        double n_remove_ratio = nrate / n_growout;
-                        double p_remove_ratio = prate / p_growout;
-
-                        //#Compute N application management rate score based on removal ratio and whether small grain or not
-                        if (crop_type.equals("small grain")) {
-                            query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "small grain" + "' AND remove_ratio_1 <= " + n_remove_ratio + "AND remove_ratio_2 > " + n_remove_ratio + ";";
-                            resultSet = statement.executeQuery(query);
-                            while (resultSet.next()) {
-                                ncrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                            }
-                        } else {
-                            query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "other" + "' AND remove_ratio_1 <= " + n_remove_ratio + "AND remove_ratio_2 > " + n_remove_ratio + ";";
-                            resultSet = statement.executeQuery(query);
-                            while (resultSet.next()) {
-                                ncrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                            }
-                        }
-
-                        //#Compute P application management rate scores based on removal ratio and soil test result
-                        switch (ip.getPSoilTestResult()) {
-                            case "High": {
-                                if (p_remove_ratio >= 1.2) {
-                                    pcrop_app_rate_score = 0;
-                                } else {
-                                    query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "app" + "' AND soil_test_result'=" + "High" + "'AND remove_ratio_1 <= " + p_remove_ratio + "AND remove_ratio_2 > " + p_remove_ratio + ";";
-                                    resultSet = statement.executeQuery(query);
-                                    while (resultSet.next()) {
-                                        pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                                    }
-                                }
-                                break;
-                            }
-                            case "Medium": {
-                                if (p_remove_ratio >= 1.6) {
-                                    pcrop_app_rate_score = 0;
-                                } else {
-                                    query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "app" + "' AND soil_test_result'=" + "Medium" + "'AND remove_ratio_1 <= " + p_remove_ratio + "AND remove_ratio_2 > " + p_remove_ratio + ";";
-                                    resultSet = statement.executeQuery(query);
-                                    while (resultSet.next()) {
-                                        pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                                    }
-                                }
-                                break;
-                            }
-                            case "Low": {
-                                if (p_remove_ratio >= 1.6) {
-                                    pcrop_app_rate_score = 0;
-                                } else {
-                                    query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "app" + "' AND soil_test_result'=" + "Low" + "'AND remove_ratio_1 <= " + p_remove_ratio + "AND remove_ratio_2 > " + p_remove_ratio + ";";
-                                    resultSet = statement.executeQuery(query);
-                                    while (resultSet.next()) {
-                                        pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                                    }
-                                }
-                                break;
-                            }
-                            case "None": {
-                                if (p_remove_ratio >= 1.2) {
-                                    pcrop_app_rate_score = 0;
-                                } else {
-                                    query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Rate" + "' AND app_mgt_factor='" + "app" + "' AND soil_test_result'=" + "None" + "'AND remove_ratio_1 <= " + p_remove_ratio + "AND remove_ratio_2 > " + p_remove_ratio + ";";
-                                    resultSet = statement.executeQuery(query);
-                                    while (resultSet.next()) {
-                                        pcrop_app_rate_score = resultSet.getInt("app_mgt_score");
-                                    }
-                                }
-                                break;
-                            }
-                        }
-                        //#Update N and P application management rate scores for the AoA
-                        n_app_rate_score = n_app_rate_score + ncrop_app_rate_score;
-                        p_app_rate_score = p_app_rate_score + pcrop_app_rate_score;
-                    }
-                    //#Compute N and P application timing scores for the crop and update timin scores for the AoA
-                    int ncrop_app_timing_score = 0;
-                    int pcrop_app_timing_score = 0;
-                    for (Nutrient nutrient : nutrientApplicationList) {
-                        long app_day_diff = Dates.diffInMillis(crop.getCropPlantDate(), nutrient.getApplicationDate());
-                        app_day_diff = TimeUnit.MICROSECONDS.convert(app_day_diff, TimeUnit.DAYS);
-                        ArrayList<NutrientApplied> nutrientAppliedList = nutrient.getNutrientAppliedList();
-                        for (NutrientApplied nApplied : nutrientAppliedList) {
-                            switch (nApplied.getNutrientApplied()) {
-                                case "Nitrogen": {
-                                    if (app_type.equals("split")) {
-                                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Timing" + "' AND app_mgt_factor='" + "split" + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
-                                        resultSet = statement.executeQuery(query);
-                                        while (resultSet.next()) {
-                                            ncrop_app_timing_score = resultSet.getInt("app_mgt_score");
-                                            //Doubt
-                                            if (resultSet.wasNull()) {
-                                                n_app_timing_score = 0;
-                                            } else if (ncrop_app_timing_score < n_app_timing_score) {
-                                                n_app_timing_score = ncrop_app_timing_score;
-                                            }
-                                        }
-
-                                    } else {
-                                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Nitrogen" + "' AND app_mgt_kind='" + "Timing" + "' AND app_mgt_factor='" + "nosplit" + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
-                                        resultSet = statement.executeQuery(query);
-                                        while (resultSet.next()) {
-                                            ncrop_app_timing_score = resultSet.getInt("app_mgt_score");
-                                            //Doubt
-                                            if (resultSet.wasNull()) {
-                                                n_app_timing_score = 0;
-                                            } else if (ncrop_app_timing_score < n_app_timing_score) {
-                                                n_app_timing_score = ncrop_app_timing_score;
-                                            }
-                                        }
-                                    }
-                                    break;
-                                }
-                                case "Phosphorus": {
-                                    if (app_type.equals("split")) {
-                                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Timing" + "' AND app_mgt_factor='" + "split" + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
-                                        resultSet = statement.executeQuery(query);
-                                        while (resultSet.next()) {
-                                            pcrop_app_timing_score = resultSet.getInt("app_mgt_score");
-                                            //Doubt
-                                            if (resultSet.wasNull()) {
-                                                p_app_timing_score = 0;
-                                            } else if (pcrop_app_timing_score < p_app_timing_score) {
-                                                p_app_timing_score = ncrop_app_timing_score;
-                                            }
-                                        }
-                                    } else {
-                                        query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE nutrient='" + "Phosphorus" + "' AND app_mgt_kind='" + "Timing" + "' AND app_mgt_factor='" + "nosplit" + "'AND days_fr_plant_1 <= " + app_day_diff + "AND days_fr_plant_2 > " + app_day_diff + ";";
-                                        resultSet = statement.executeQuery(query);
-                                        while (resultSet.next()) {
-                                            pcrop_app_timing_score = resultSet.getInt("app_mgt_score");
-                                            //Doubt
-                                            if (resultSet.wasNull()) {
-                                                p_app_timing_score = 0;
-                                            } else if (pcrop_app_timing_score < p_app_timing_score) {
-                                                p_app_timing_score = pcrop_app_timing_score;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    for (Nutrient nutrient : nutrientApplicationList) {
-                        //#If any nutrient application for any crop is not incorporated, the method score for the AoA is zero
-                        if (!nutrient.isIncorporated()) {
-                            app_method_score = 0;
-                            break;
-                        } else if (nutrient.isIncorporated()) { //#If all nutrient applications for all crops are incorporated, the method score for incorporation applies to the AoA
-                            query = "SELECT app_mgt_score FROM wqm_nutrient_application_mgt_scores WHERE app_mgt_kind='" + "Method" + "' AND app_mgt_factor='" + "incorporate" + "';";
-                            resultSet = statement.executeQuery(query);
-                            while (resultSet.next()) {
-                                app_method_score = resultSet.getInt("app_mgt_score");
-                            }
-                        }
+                    else{
+                        ret_val = error_msg = "Cannot get crop_type. " + crop.getErrorMsg();
                     }
                 }
+                
+                //  If all crops' nutrients were incorporated this value will still be -1
+                if ( app_method_score == -1 ){
+                    query = "SELECT app_mgt_score from wqm_nutrient_application_mgt_scores WHERE app_mgt_kind='Method' AND app_mgt_factor='incorporate';";
+                    resultSet = statement.executeQuery(query);
+                    if ( resultSet.first() ){
+                        app_method_score = resultSet.getInt("app_mgt_score");
+                    }                                                                
+                }
+                
                 //#Compute application management scores for nitrogen in groundwater, nitrogen in surface water, and phosphorus in surface water
                 int nleach_app_mgt_score = n_app_rate_score + n_app_timing_score + app_method_score;
                 int nsurf_app_mgt_score = n_app_rate_score + n_app_timing_score + app_method_score;
                 int psurf_app_mgt_score = p_app_rate_score + p_app_timing_score + app_method_score;
-                m.wqm.nutappmgtscores.Result result1 = new m.wqm.nutappmgtscores.Result(ip.getAoAId(), nleach_app_mgt_score, nsurf_app_mgt_score, psurf_app_mgt_score, n_app_rate_score, n_app_timing_score, p_app_rate_score, p_app_timing_score, app_method_score);
-                result.add(result1);
+                m.wqm.nutappmgtscores.Result result1 = new m.wqm.nutappmgtscores.Result(AoAId, nleach_app_mgt_score, nsurf_app_mgt_score, psurf_app_mgt_score, n_app_rate_score, n_app_timing_score, p_app_rate_score, p_app_timing_score, app_method_score);
+                result.add(result1);                    
+                
+                conn.close();
+            } catch (SQLException se) {
+                    LOG.info("Did not open database for WQM-16!");
+                    LOG.info(se.getMessage());
+                    ret_val += se.getMessage();                    
+                }catch (Exception ex ){
+                    ret_val += ex.getMessage();
+            } finally {
+                if (statement != null) {
+                    statement.close();
+                }
+                if (conn != null) {
+                    conn.close();
+                }
             }
-            conn.close();
-        } catch (SQLException se) {
-            LOG.info("Did not open database for WQM-16!");
-            LOG.info(se.getMessage());
-        } finally {
-            if (statement != null) {
-                statement.close();
-            }
-            if (conn != null) {
-                conn.close();
-            }
-        }
-        return EXEC_OK;
+        }       
+        return (error_msg.isEmpty()? EXEC_OK:error_msg);
     }
 
     @Override
@@ -393,4 +194,12 @@
         }
         putResult("Result", resultArr);
     }
+    
+    private boolean ValidateInput(){
+        for( Crop tCrop : cropList )
+            if ( !tCrop.validate() )
+                error_msg += "; " + tCrop.getErrorMsg();
+      
+      return (error_msg.isEmpty());    
+    }
 }

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

@@ -23,11 +23,6 @@
                         "value": 121
                     },
                     {
-                        "name": "from_lmod",
-                        "value": false,
-                        "Description": "LMOD Source Indicator, True means the source of the mgt_crop_id is from LMOD"
-                    },
-                    {
                         "name": "crop_plant_date",
                         "value": "2015-09-10",
                         "Description": "Crop Planting Date (Year-Month-Day), null if fallow “crop” period"
@@ -122,11 +117,6 @@
                         "value": 89
                     },
                     {
-                        "name": "from_lmod",
-                        "value": false,
-                        "Description": "LMOD Source Indicator, True means the source of the mgt_crop_id is from LMOD"
-                    },
-                    {
                         "name": "crop_plant_date",
                         "value": "2017-05-25",
                         "Description": "Crop Planting Date (Year-Month-Day), null if fallow “crop” period"

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

@@ -18,22 +18,11 @@
 import java.sql.*;
 import java.util.concurrent.*;
 
-@Name("WQM-14:(NutTechScores)")
-@Description("Nutrient Technique Scores")
+@Name("WQM-14: Nutrient Technique Scores (NutTechScores)")
+@Description("This service computes scores for techniques applied to mitigate nitrogen leaching, nitrogen runoff, and phosphorus runoff loss potential")
 @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 = "postgres";
-    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;
@@ -60,8 +49,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();
 
@@ -195,7 +183,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/pesthazrating/V1_0.java

@@ -6,199 +6,238 @@
 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("(PestHazRating)")
-@Description("Pesticide Hazard Ratings for an Area of Analysis")
+@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.")
 @Path("m/pest_hazrating/1.0")
 
 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/postgres", "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)
             {
@@ -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/pesticide/attributes/V1_0.java

@@ -13,10 +13,11 @@
  *
  * @author od
  */
-@Name("Pest Attributes")
-@Description("Pest Attributes")
-@Path("m/wqm/pestattr/1.0")
-@Polling(first = 10000, next = 2000)
+//@Name("Pest Attributes")
+//@Description("Pest Attributes")
+//@Path("m/wqm/pestattr/1.0")
+//@Polling(first = 10000, next = 2000)
+
 public class V1_0 extends csip.ModelDataService {
 
         double a;

src/java/m/wqm/pesticidesarp/V1_0.java

@@ -16,8 +16,8 @@
  * @ Srinivas
  * @ update Rumpal Sidhu
  */
-@Name("WQM-9:Pesticide Soil Adsorbed Runoff Potential (PesticideSARP)")
-@Description("Calculating Pesticide Soil Adsorbed Runoff Potential")
+@Name("WQM-09: Pesticide Soil Adsorbed Runoff Potential (PesticideSARP)")
+@Description("This service computes pesticide soil adsorbed runoff potential for soil components in an area of analysis, and then computes soil adsorbed runoff potential representing the area of analysis. The service primarily will consume data from the WQM-2 WQMSoilAttributes service to compute pesticide soil adsorbed runoff potentials used later by the WQM-13 to compute threshold treatment level scores.")
 @Path("m/pesticide_sarp/1.0")
 
 public class V1_0 extends ModelDataService {

src/java/m/wqm/pesticidessrp/V1_0.java

@@ -20,8 +20,8 @@
  *
  * @ Srinivas
  */
-@Name("Pesticide Soil Solution Runoff Potential (PesticideSSRP)")
-@Description("Computation of Pesticide Soil Solution Runoff Potential for a Soil Component")
+@Name("WQM-08: Pesticide Soil Solution Runoff Potential (PesticideSSRP)")
+@Description("This service computes pesticide soil solution runoff potential for soil components in an area of analysis, and computes soil solution runoff potential representing the area of analysis (AoA). The service primarily will consume data from the WQM-2 WQMSoilAttributes service to compute soil solution runoff potential used later by the WQM-13 service to compute WQM threshold treatment level scores.")
 @Path("m/pesticide_ssrp/1.0")
 
 public class V1_0 extends ModelDataService{

src/java/m/wqm/pestipmscores/V1_0.java

@@ -20,8 +20,8 @@
  *
  * @author dhawal
  */
-@Name("Integrated Pest Management Mitigation Scores (PestIPMScores)")
-@Description("Getting mitigation score for pest management")
+@Name("WQM-17: Integrated Pest Management Mitigation Scores (PestIPMScores)")
+@Description("This service computes scores for the level of integrated pest management (IPM) to be applied to mitigate pesticide leaching, solution runoff, adsorbed runoff, and drift hazard potential.")
 //change
 @Path("m/pesticide_ipm_score/1.0")
 
@@ -60,7 +60,7 @@
             Connection conn = null;
             Statement statement = null;
             Class.forName("org.postgresql.Driver");
-            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/WQM Data Mart 20150324", "postgres", "postgresql");
+            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/wqm", "postgres", "admin");
             conn.setAutoCommit(false);
             statement = conn.createStatement();
             

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

@@ -18,31 +18,40 @@
 /**
  *
  * @ Srinivas
- * @ Update Rumpal Sidhu
+ * @ author Rumpal Sidhu
  */
-@Name("WQM-4")
-@Description("Pesticide Attributes (WQMPestAttr)")
+@Name("WQM-04: Pesticide Attributes and Loss Potentials (WQMPestLossPot)")
+@Description("The service consumes a request payload of one or more pesticide application operations from a farm crop rotation for an area of analysis, get attributes from the WQM pesticide table for each instance of pesticide active ingredient applied. The pesticide active ingredient attributes will be used later in WQM to compute hazard ratings. The service computes loss potentials for pesticide leaching, solution runoff, and adsorbed runoff also to be used later for computing soil/pesticide interaction ratings.")
 @Path("m/pestlosspot/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 = "postgres";
+    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 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/pestlosspot/V1_0.json

@@ -25,7 +25,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {
@@ -59,7 +59,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {
@@ -93,7 +93,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {
@@ -126,7 +126,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {
@@ -160,7 +160,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {
@@ -194,7 +194,7 @@
                     },
                     {
                         "name": "app_rate",
-                        "value": "Starndard Rate",
+                        "value": "Standard",
                         "Description": "Pesticide application rate"
                     },
                     {

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

@@ -1,144 +1,349 @@
+package m.wqm.pestpractscores;
 /*
  * 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.pestpractscores;
 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 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;
-import csip.utils.JSONUtils;
-import java.util.Map;
-import java.sql.*;
+
 
 /**
  *
  * @author dhawal
+ * @author Shaun Case
  */
-@Name("Integrated Pest Mitigation Practice Scores (PestPractScores)")
-@Description("Compile WQM pesticide-related concern mitigation scores")
-//change
+
+@Name("WQM-19: Pesticide Mitigation Practice Scores (PestPractScores)")
+@Description("This service computes scores for conservation practices applied to mitigate pesticide leaching, solution runoff, adsorbed runoff, and drift.")
 @Path("m/pesticide_practice_score/1.0")
 
 public class V1_0 extends ModelDataService{
     
-    int AoAId=0;
-    int pleach_practice_score=0;
-    int psolsurf_practice_score=0;
-    int padsurf_practice_score=0;
-    int pdrift_practice_score=0;
+    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;
+        
+        try{
+            AoAId = getIntParam("AoAId");
+            pestComponents =  getJSONArrayParam("pestcomponents");
+            
+            pestPractScores = new V1_0.PestPractScores( AoAId, pestComponents );            
+        }
+        catch (ServiceException ex ){
+            this.error_msg = ex.getMessage();
+        }
+    }
+        
+    @Override
+    protected String process() throws Exception
+    {
+        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 );       
+    }
     
     
-    //JSONArray getArray
-    ArrayList<m.wqm.pestpractscores.Input> components=new ArrayList<>(); // store the set of all input soilcomponents as objects
-    ArrayList<m.wqm.pestpractscores.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 {
-        JSONArray groups = getJSONArrayParam("pestcomponents");
-        System.out.println("Entry into ModelDataService");
-            for(int i=0;i<groups.length();i++)
-            {
-                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
-             
-                int AoAId = JSONUtils.getIntParam(group, "AoAId", 0);
-                int plan_ipm_practice = JSONUtils.getIntParam(group, "plan_ipm_practice", 0);
-                String plan_ipm_variant=JSONUtils.getStringParam(group,"plan_pract_variant","err");
-
-                m.wqm.pestpractscores.Input input=new m.wqm.pestpractscores.Input(AoAId,plan_ipm_practice,plan_ipm_variant);
-                //System.out.println(input.plan_ipm_level);
-                components.add(input);
+    @Override    
+    protected void postProcess() throws Exception {
+        if ( pestPractScores.getErrorMsg().isEmpty() && this.error_msg.isEmpty() ){
+            V1_0.Result result = pestPractScores.getResults();
+            if ( result != null ) {
+                result.putResults();
             }
-            System.out.println(components);
+        }
+    }
+    
+    class PestPractScores {        
+        private String error_msg = "";
+        private int AoAId;
+        private int pleach_practice_score;
+        private int psolsurf_practice_score;
+        private int padsurf_practice_score;
+        private int pdrift_practice_score;
+        private ArrayList<ipmData> ipmList;
+        private Result results = null;
+        Connection conn = null;
+        Statement statement = null;
+        
+        PestPractScores( int AoAId, JSONArray ipms ){
+            this.pleach_practice_score = this.psolsurf_practice_score = this.padsurf_practice_score = this.pdrift_practice_score = 0;
+            this.error_msg = "";
+            this.ipmList = new ArrayList<>();
+            this.results = null;
+            
+            this.AoAId = AoAId;
+            
+            if ( null != ipms ){
+                try{
+                    for (int i = 0; i < ipms.length(); i++) {
+                        Map<String, JSONObject> ipmsData = JSONUtils.preprocess(ipms.getJSONArray(i));
+                        
+                        ipmList.add( new ipmData( JSONUtils.getIntParam(ipmsData, "plan_ipm_practice", -1 ), 
+                                                  JSONUtils.getStringParam(ipmsData, "plan_pract_variant", "err") ) );                                
+                    }   
+                }
+                catch( JSONException ex){
+                    this.error_msg = " Cannot read IPM input variables:  " + ex.getMessage() + "  ";
+                }
+            }
+            else{
+                this.error_msg = "No input variables:  Missing plan_ipm_practice list. ";
+            }                                       
         }
         
-    @Override
-        protected String process() throws Exception
+        String getErrorMsg(){
+            return this.error_msg;
+        }
+        
+        Result getResults(){
+            return this.results;            
+        }
+        
+        boolean computeScores() throws Exception {
+            boolean ret_val = false;
+            
+            if (  ( this.error_msg.isEmpty() ) && ( (null != this.ipmList) && (!this.ipmList.isEmpty()) ) ){
+                //Compute values here.
+                try{ 
+                    this.conn = wqm.utils.WQMTools.getConnection( "wqm", LOG );
+                    this.statement = this.conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);                   
+                }
+                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() ){                
+                    this.pleach_practice_score = this.psolsurf_practice_score = this.padsurf_practice_score = this.pdrift_practice_score = 0;
+                    for ( ipmData ipm : this.ipmList ){
+                        this.pleach_practice_score += getPlPractScore( ipm );
+                        this.psolsurf_practice_score += getPsPractScore( ipm );
+                        this.padsurf_practice_score += getPaPractScore( ipm );
+                        this.pdrift_practice_score += getPdPractScore( ipm );
+                        if ( !this.error_msg.isEmpty() ) {
+                            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;                
+        }
+        
+        private int getPlPractScore( ipmData ipm ){
+            int ret_val = 0;
+            String query;
+            
+            if ( this.error_msg.isEmpty() ){
+                try{
+                    String variant = ipm.getVariant();
+                    query = "SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='" + ipm.getIpm() + "' AND wqm_concern='Pesticide Leaching'" ;  
+                    
+                    if ( variant != null && !variant.isEmpty() ){ 
+                        query += " AND practice_variant='" + variant + "'";
+                    }
+        
+                    ResultSet result = statement.executeQuery( query );
+
+                    if ( result.first() ){                   
+                       ret_val = result.getInt("ipm_practice_score");
+                    }
+                    else{
+                        //  Assume "0" when database query fails...
+                        //this.error_msg += " Cannot compute pl_pract_score:  database query result was empty. ";
+                    }                        
+                }
+                catch (SQLException ex ){
+                    this.error_msg += " Cannot compute pl_pract_score:  " + ex.getMessage() + " ";
+                }
+            }
+            
+            return ret_val;
+        }
+        
+        private int getPsPractScore( ipmData ipm ){
+            int ret_val = 0;
+            String query;
+            
+            if ( this.error_msg.isEmpty() ){
+                try{
+                    String variant = ipm.getVariant();
+                    query = "SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='" + ipm.getIpm() + "' AND wqm_concern='Pesticide Solution Runoff'" ;  
+                    
+                    if ( variant != null && !variant.isEmpty() ){ 
+                        query += " AND practice_variant='" + variant + "'";
+                    }
+        
+                    ResultSet result = statement.executeQuery( query );
+
+                    if ( result.first() ){                   
+                       ret_val = result.getInt("ipm_practice_score");
+                    }
+                    else{                        
+                        //this.error_msg += " Cannot compute ps_pract_score:  database query result was empty. ";
+                    }                        
+                }
+                catch (SQLException ex ){
+                    this.error_msg += " Cannot compute ps_pract_score:  " + ex.getMessage() + " ";
+                }
+            }
+            
+            return ret_val;           
+        }
+        
+        private int getPaPractScore( ipmData ipm ){
+            int ret_val = 0;
+            String query;
+            
+            if ( this.error_msg.isEmpty() ){
+                try{
+                    String variant = ipm.getVariant();
+                    query = "SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='" + ipm.getIpm() + "' AND wqm_concern='Pesticide Adsorbed Runoff'" ;  
+                    
+                    if ( variant != null && !variant.isEmpty() ){ 
+                        query += " AND practice_variant='" + variant + "'";
+                    }
+        
+                    ResultSet result = statement.executeQuery( query );
+
+                    if ( result.first() ){                   
+                       ret_val = result.getInt("ipm_practice_score");
+                    }
+                    else{
+                        //this.error_msg += " Cannot compute pa_pract_score:  database query result was empty. ";
+                    }                        
+                }
+                catch (SQLException ex ){
+                    this.error_msg += " Cannot compute pa_pract_score:  " + ex.getMessage() + " ";
+                }
+            }
+            
+            return ret_val;            
+        }
+        
+        private int getPdPractScore( ipmData ipm ){
+            int ret_val = 0;
+            String query;
+            
+            if ( this.error_msg.isEmpty() ){
+                try{
+                    String variant = ipm.getVariant();
+                    query = "SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='" + ipm.getIpm() + "' AND wqm_concern='Pesticide Drift'" ;  
+                    
+                    if ( variant != null && !variant.isEmpty() ){ 
+                        query += " AND practice_variant='" + variant + "'";
+                    }
+        
+                    ResultSet result = statement.executeQuery( query );
+
+                    if ( result.first() ){                   
+                       ret_val = result.getInt("ipm_practice_score");
+                    }
+                    else{
+                        //this.error_msg += " Cannot compute pd_pract_score for practice_id=" + ipm.getIpm() + ":  database query result was empty. ";
+                    }                        
+                }
+                catch (SQLException ex ){
+                    this.error_msg += " Cannot compute pd_pract_score:  " + ex.getMessage() + " ";
+                }
+            }
+            
+            return ret_val;            
+        }  
+        
+        class ipmData{
+            int ipm = 0;
+            String variant = "";
+            
+            ipmData( int plan_ipm_practice, String plan_pract_variant ){
+                this.ipm = plan_ipm_practice;
+                this.variant = plan_pract_variant;
+            }
+            
+            public int getIpm(){
+                return this.ipm;
+            }
+            
+            public String getVariant(){
+                return this.variant;
+            }
+        }        
+    }
+
+     class Result {
+        int AoAId;
+        int pleach_practice_score;
+        int psolsurf_practice_score;
+        int padsurf_practice_score;
+        int pdrift_practice_score;
+
+         Result(int AoAId,int pleach_practice_score,int psolsurf_practice_score,int padsurf_practice_score,int pdrift_practice_score)
         {
-            Connection conn = null;
-            Statement statement = null;
-            Class.forName("org.postgresql.Driver");
-            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/WQM Data Mart 20150324", "postgres", "postgresql");
-            conn.setAutoCommit(false);
-            statement = conn.createStatement();
+            this.AoAId=AoAId;
+            this.pleach_practice_score=pleach_practice_score;
+            this.psolsurf_practice_score=psolsurf_practice_score;
+            this.padsurf_practice_score=padsurf_practice_score;
+            this.pdrift_practice_score=pdrift_practice_score;
+        }
+        
+        void putResults(){
+            putResult("AoAId",this.AoAId,"Area of Analysis ID");
+            putResult("pleach_practice_score",this.pleach_practice_score,"pleach_practice_score");
+            putResult("psolsurf_practice_score",this.psolsurf_practice_score,"psolsurf_practice_score");
+            putResult("padsurf_practice_score",this.padsurf_practice_score,"padsurf_practice_score");
+            putResult("pdrift_practice_score",this.pdrift_practice_score,"pdrift_practice_score");            
             
-        for (m.wqm.pestpractscores.Input ip : components) {
-             
-             int pleach_practice_score=0;
-             int psolsurf_practice_score=0;
-             int padsurf_practice_score=0;
-             int pdrift_practice_score=0;
-             String query;
-             query="SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='"+ip.plan_ipm_practice+"' AND wqm_concern='Pesticide Leaching'" ;  
-             if (ip.plan_pract_variant!=null && !ip.plan_pract_variant.isEmpty()){ 
-                query=query.concat(" AND practice_variant='"+ip.plan_pract_variant+"'");}
-             //System.out.println(ip.plan_pract_variant);
-             //System.out.println(ip.AoAId);
-             ResultSet results = statement.executeQuery(query);
-
-                while (results.next())
-                {
-                   int pract_score =results.getInt("ipm_practice_score");
-                   pleach_practice_score=pleach_practice_score +pract_score ;
-                }
-             query="SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='"+ip.plan_ipm_practice+"' AND wqm_concern='Pesticide Solution Runoff'" ;
-             if (ip.plan_pract_variant!=null && !ip.plan_pract_variant.isEmpty()){
-                query=query.concat(" AND practice_variant='"+ip.plan_pract_variant+"'");}
-             //System.out.println(query);
-                results = statement.executeQuery(query);
-             
-                while (results.next())
-                {
-                   int pract_score =results.getInt("ipm_practice_score");
-                   psolsurf_practice_score  =psolsurf_practice_score +pract_score ;
-                }
-             query="SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='"+ip.plan_ipm_practice+"' AND wqm_concern='Pesticide Adsorbed Runoff'" ;
-             if (ip.plan_pract_variant!=null && !ip.plan_pract_variant.isEmpty()){
-                query=query.concat(" AND practice_variant='"+ip.plan_pract_variant+"'");}
-             //System.out.println(query);
-                results = statement.executeQuery(query);
-
-                while (results.next())
-                {
-                   int pract_score=results.getInt("ipm_practice_score");
-                   padsurf_practice_score =padsurf_practice_score +pract_score;
-                }
-            query="SELECT ipm_practice_score FROM wqm_ipm_practice_scores WHERE practice_id='"+ip.plan_ipm_practice+"' AND wqm_concern='Pesticide Drift'" ;
-            if (ip.plan_pract_variant!=null && !ip.plan_pract_variant.isEmpty()){
-                query=query.concat(" AND practice_variant='"+ip.plan_pract_variant+"'");}
-            //System.out.println(query);
-                results = statement.executeQuery(query);
-
-                while (results.next())
-                {
-                   int practice_score =results.getInt("ipm_practice_score");
-                   pdrift_practice_score =pdrift_practice_score +practice_score ;
-                }
+        }
+    } 
+    
             
-            Result1 result=new Result1(ip.AoAId,pleach_practice_score,psolsurf_practice_score,padsurf_practice_score,pdrift_practice_score);
-            result1.add(result);
-        }
-
-            return EXEC_OK;       
-    }
-        @Override
-        //writing the results back to JSON
-    protected void postProcess() throws Exception {
-        for(int i=0;i<result1.size();i++)
-        {
-            
-            Result1 temp=result1.get(i);
-            putResult("AoAId",temp.AoAId,"Area of Analysis ID");
-            putResult("pleach_practice_score",temp.pleach_practice_score,"pleach_practice_score");
-            putResult("psolsurf_practice_score",temp.psolsurf_practice_score,"psolsurf_practice_score");
-            putResult("padsurf_practice_score",temp.padsurf_practice_score,"padsurf_practice_score");
-            putResult("pdrift_practice_score",temp.pdrift_practice_score,"pdrift_practice_score");
-        }    
-        //putResult("aoa_sarp",aoa_sarp,"Pesticide Soil Adsorbed Runoff Potential of AoA");
-    }
 }

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

@@ -2,91 +2,73 @@
  "metainfo": {
  },
  "parameter": [
-  {
-   "name": "pestcomponents",
-   "value": [
-    [
      {
       "name": "AoAId",
       "value": 1,
       "Description":"Area of Analysis Identifier"
       
      },
-     {
-      "name": "plan_ipm_practice",
-      "value": 12,
-      "Description":"Integrated Pest Management Conservation practice"
-      
-     },
-     {
-      "name": "plan_pract_variant",
-      "value": "",
-      "Description":"Variation of IPM Conservation practice"
-      
-     }
-    ],
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"AoA Identifier"
-      
-     },
-     {
-      "name": "plan_ipm_practice",
-      "value": 20,
-      "Description":"Integrated Pest Management Conservation practice"
-      
-     },
-     {
-      "name": "plan_pract_variant",
-      "value": "Weed Suppression",
-      "Description":"Variation of IPM Conservation practice"
-      
-     }
-    ],
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"AoA Identifier"
-      
-     },
-     {
-      "name": "plan_ipm_practice",
-      "value": 80,
-      "Description":"Integrated Pest Management Conservation practice"
-      
-     },
-     {
-      "name": "plan_pract_variant",
-      "value": "Natural Materials",
-      "Description":"Variation of IPM Conservation practice"
-      
-     }
-    ],
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"AoA Identifier"
-      
-     },
-     {
-      "name": "plan_ipm_practice",
-      "value": 66,
-      "Description":"Integrated Pest Management Conservation practice"
-      
-     },
-     {
-      "name": "plan_pract_variant",
-      "value": "",
-      "Description":"Variation of IPM Conservation practice"
-      
-     }
-    ]
-   ]
-  }
+     {        
+        "name": "pestcomponents",
+        "value": [
+            [
+                {
+                 "name": "plan_ipm_practice",
+                 "value": 12,
+                 "Description":"Integrated Pest Management Conservation practice"
+
+                },
+                {
+                 "name": "plan_pract_variant",
+                 "value": "",
+                 "Description":"Variation of IPM Conservation practice"
+
+                }
+            ],
+            [
+                {
+                 "name": "plan_ipm_practice",
+                 "value": 20,
+                 "Description":"Integrated Pest Management Conservation practice"
+
+                },
+                {
+                 "name": "plan_pract_variant",
+                 "value": "Weed Suppression",
+                 "Description":"Variation of IPM Conservation practice"
+
+                }
+            ],
+            [     
+                {
+                 "name": "plan_ipm_practice",
+                 "value": 80,
+                 "Description":"Integrated Pest Management Conservation practice"
+
+                },
+                {
+                 "name": "plan_pract_variant",
+                 "value": "Natural Materials",
+                 "Description":"Variation of IPM Conservation practice"
+
+                }
+            ],
+            [
+                {
+                 "name": "plan_ipm_practice",
+                 "value": 66,
+                 "Description":"Integrated Pest Management Conservation practice"
+
+                },
+                {
+                 "name": "plan_pract_variant",
+                 "value": "",
+                 "Description":"Variation of IPM Conservation practice"
+
+                }
+            ]
+        ]
+    }
  ]
 }
 

src/java/m/wqm/pesttechnscores/V1_0.java

@@ -18,8 +18,8 @@
 import java.sql.*;
 import java.util.concurrent.*;
 
-@Name("(pesttechnscores)")
-@Description("Pesticide Mitigation Technique Scores")
+@Name("WQM-18: Pesticide Mitigation Technique Scores (PestTechnScores)")
+@Description("This services computes scores for applying pesticide management techniques to mitigate hazard potentials for leaching, solution runoff, adsorbed runoff, and drift.")
 @Path("m/pest_techn_scores/1.0")
 
 public class V1_0 extends ModelDataService
@@ -52,7 +52,7 @@
             Connection conn = null;
             Statement statement = null;
             Class.forName("org.postgresql.Driver");
-            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/WQM Data Mart 20150324", "postgres", "postgresql");
+            conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/wqm", "postgres", "admin");
             conn.setAutoCommit(false);
             statement = conn.createStatement();
             

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")
-@Description("R Factor for an Area of Analysis")
+@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 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/scorebar/V1_0.java

@@ -15,8 +15,8 @@
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONObject;
 
-@Name("WQM-20")
-@Description("Threshold and Mitigation Scores for WQM Scorebar")
+@Name("WQM-20: Threshold and Mitigation Scores for WQM Scorebar (WQMScorebar)")
+@Description("This service computes and compiles mitigation and threshold scores for each WQM sediment, nutrient, and pesticide-related resource concern: nitrogen leaching, nitrogen runoff, phosphorus runoff, sediment runoff, pesticide leaching (human), pesticide leaching (fish), pesticide solution runoff (human), pesticide solution runoff (fish), pesticide adsorbed runoff (human), pesticide adsorbed runoff (fish), pesticide drift (human), and pesticide drift (fish).")
 @Path("m/wqmscorebar/1.0")
 @Polling(first = 10000, next = 2000)
 
@@ -79,7 +79,7 @@
     protected String process() throws Exception {
         result = new ArrayList<>();
 
-        components.stream().map((ip) -> {
+        for (Input ip : components) {
             //Nitrogen in Ground Water mitigation and threshold scores
             int bar_nleach_mit_score = ip.nleach_techn_score + ip.nleach_pract_score + ip.nleach_app_mgt_score;
             int bar_nleach_threshold = ip.aoa_nleach_threshold;
@@ -117,10 +117,8 @@
             int bar_pdrift_fish_mit_score = ip.pdrift_ipm_score + ip.pdrift_technique_score + ip.pdrift_practice_score;
             int bar_pdrift_fish_threshold = ip.aoa_psorun_matcfish_threshold;
             Result result1 = new Result(ip.AoAId, bar_nleach_mit_score, bar_nleach_threshold, bar_nsurf_mit_score, bar_nsurf_threshold, bar_psurf_mit_score, bar_psurf_threshold, bar_ssurf_mit_score, bar_ssurf_threshold, bar_pleach_human_mit_score, bar_pleach_human_threshold, bar_pleach_fish_mit_score, bar_pleach_fish_threshold, bar_psorun_human_mit_score, bar_psorun_human_threshold, bar_psorun_fish_mit_score, bar_psorun_fish_threshold, bar_padrun_human_mit_score, bar_padrun_human_threshold, bar_padrun_fish_mit_score, bar_padrun_fish_threshold, bar_pdrift_human_mit_score, bar_pdrift_human_threshold, bar_pdrift_fish_mit_score, bar_pdrift_fish_threshold);
-            return result1;
-        }).forEach((result1) -> {
             result.add(result1);
-        });
+        }
         return EXEC_OK;
     }
 
@@ -160,4 +158,4 @@
         putResult("operation", resultArr);
     }
 
-}
\ No newline at end of file
+}

src/java/m/wqm/scpestslp/V1_0.java

@@ -1,127 +1,390 @@
+/*
+ * 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.scpestslp;
 
 import csip.ModelDataService;
+import csip.ServiceException;
+import csip.utils.JSONUtils;
 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;
 
 /**
  *
- * @ Srinivas
- * @ Update Rumpal Sidhu
+ * @author Srinivas
+ * @author Rumpal Sidhu
+ * @author Shaun Case
  */
-@Name("WQM-7:Pesticide Soil Leaching Potential (PesticideSLP)")
-@Description("Calculating Pesticide Soil Leaching Potential")
+@Name("WQM-07: Pesticide Soil Leaching Potential (PesticideSLP)")
+@Description("This service computes pesticide soil leaching potential for soil components in an area of analysis, and then computes pesticide soil leaching potential representing the area of analysis. The service primarily will consume data from the WQM-2 WQMSoilAttributes service to compute soil pesticide leaching potential used later by the WQM-13 service to compute threshold treatment level scores.")
 @Path("m/pesticide_slp/1.0")
 
 public class V1_0 extends ModelDataService {
-
-    String comp_pslp[] = new String[]{"", "VERY LOW", "LOW", "INTERMEDIATE", "HIGH"};
-    int comp_pslp_number;
-    String aoa_pslp;
-
-    //request
-    ArrayList<Input> components; // store the set of all input soilcomponents as objects
-    //response
-    ArrayList<Result1> result1;  // store the result as objects
+    private static final int VERY_LOW = 1;
+    private static final int LOW = 2;
+    private static final int INTERMEDIATE = 3;
+    private static final int HIGH = 4;
+    private final String comp_pslp_string[] = {"", "VERY LOW", "LOW", "INTERMEDIATE", "HIGH" };
+    
+    private int comp_pslp_number;
+    private String aoa_pslp;
+    private ArrayList<V1_0.AoA> AoAs;
+    private String error_msg;
+    
+    // request payload
+    // Store all of the input data by AoA
+    private V1_0.Input inputData; 
+    
+    // response payload
+    // Storeage the results
+    private V1_0.Result result; 
 
     @Override
     // reading the inputs from the json file into input object and placing it in the arraylist
     protected void preProcess() throws Exception {
-        components = new ArrayList<>();
-        JSONArray groups = getJSONArrayParam("soilcomponents");
-        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 cokey = JSONUtils.getStringParam(group, "cokey", "err");
-            double aoa_comp_area = JSONUtils.getDoubleParam(group, "aoa_comp_area", 0);
-            String aoa_comp_hsg = JSONUtils.getStringParam(group, "aoa_comp_hsg", "err");
-            double aoa_comp_kfact = JSONUtils.getDoubleParam(group, "aoa_comp_kfact", 0);
-            double aoa_comp_om = JSONUtils.getDoubleParam(group, "aoa_comp_om", 0);
-            int aoa_comp_hzdepth = JSONUtils.getIntParam(group, "aoa_comp_hzdepth", 0);
-            boolean aoa_comp_cracksgr24 = JSONUtils.getBooleanParam(group, "aoa_comp_cracksgr24", false);
-            boolean aoa_comp_hwt_lt_24 = JSONUtils.getBooleanParam(group, "aoa_comp_hwt_lt_24", false);
-            Input input = new Input(AoAId, cokey, aoa_comp_area, aoa_comp_hsg, aoa_comp_kfact, aoa_comp_om, aoa_comp_hzdepth, aoa_comp_cracksgr24, aoa_comp_hwt_lt_24);
-            components.add(input);
-        }
+        comp_pslp_number = 0;
+        aoa_pslp = "";
+        error_msg = "";
+        result = null;
+        
+        AoAs = new ArrayList<>();
+        inputData = new V1_0.Input( AoAs );
+  
+        if ( inputData.getError() ){
+            this.error_msg = inputData.getErrorMsg();
+        }                
     }
 
     @Override
-    protected String process() throws Exception {
-        result1 = new ArrayList<>();
-        for (Input ip : components) {
-            if (ip.aoa_comp_hwt_lt_24) {
-                comp_pslp_number = 4;
-            } else if (((ip.aoa_comp_hsg.equals("A") || ip.aoa_comp_hsg.equals("A\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om <= 30))
-                    || ((ip.aoa_comp_hsg.equals("B") || ip.aoa_comp_hsg.equals("B\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om <= 9) && ip.aoa_comp_kfact <= 0.48)
-                    || ((ip.aoa_comp_hsg.equals("B") || ip.aoa_comp_hsg.equals("B\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om <= 15) && ip.aoa_comp_kfact <= 0.26)) {
-                comp_pslp_number = 4;
-            } else if (((ip.aoa_comp_hsg.equals("B") || ip.aoa_comp_hsg.equals("B\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om >= 35) && ip.aoa_comp_kfact >= 0.40)
-                    || ((ip.aoa_comp_hsg.equals("B") || ip.aoa_comp_hsg.equals("B\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om >= 45) && ip.aoa_comp_kfact >= 0.20)
-                    || ((ip.aoa_comp_hsg.equals("C") || ip.aoa_comp_hsg.equals("C\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om <= 10) && ip.aoa_comp_kfact <= 0.28)
-                    || ((ip.aoa_comp_hsg.equals("C") || ip.aoa_comp_hsg.equals("C\\/D")) && (ip.aoa_comp_hzdepth * ip.aoa_comp_om >= 10))) {
-                if (!ip.aoa_comp_cracksgr24) {
-                    comp_pslp_number = 2;
-                } else {
-                    comp_pslp_number = 3;
-                }
-            } else if (ip.aoa_comp_hsg.equals("D")) {
-                if (!ip.aoa_comp_cracksgr24) {
-                    comp_pslp_number = 1;
-                } else {
-                    comp_pslp_number = 2;
-                }
-            } else {
-                if (!ip.aoa_comp_cracksgr24) {
-                    comp_pslp_number = 3;
-                } else {
-                    comp_pslp_number = 4;
+    protected String process() throws Exception {       
+        if ( this.error_msg.isEmpty() ){
+            for ( V1_0.AoA AoA : this.AoAs ){
+                if ( !AoA.process() ){
+                    this.error_msg += AoA.getErrorMsg();
+                    break;
                 }
             }
-            Result1 result = new Result1(ip.AoAId, ip.cokey, ip.aoa_comp_area, comp_pslp[comp_pslp_number], comp_pslp_number);
-            result1.add(result);
+            if ( this.error_msg.isEmpty() ){
+                result = new V1_0.Result( AoAs );
+            }
         }
-        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 {
-        for (int i = 0; i < result1.size(); i++) {
-            Result1 temp = result1.get(i);
-            putResult("AoAId", temp.AoAId, "Area of Analysis ID");
-            putResult("cokey", temp.cokey, "cokey");
-            putResult("aoa_comp_area", temp.aoa_comp_area, "Area of the soil component in the AoA");
-            putResult("comp_pslp", temp.comp_pslp, "Pesticide soil leaching potential representing the soil component");
-            putResult("comp_pslp_number", temp.comp_pslp_number, "Integer Representinf Pesticide Soil Leaching Potential");
-        }
-        putResult("aoa_pslp", aoa_pslp, "Pesticide soil leaching potential representing the AoA");
-    }
-
-    // calculate the aoa_nslp
-    void calAoANutSLP(ArrayList<Result1> source) {
-        double cum_pslp_product = 0;
-        double aoa_area = 0;
-
-        for (Result1 tmp : source) {
-            cum_pslp_product += (tmp.comp_pslp_number * tmp.aoa_comp_area);
-            aoa_area += tmp.aoa_comp_area;
-        }
-        double aoa_pslp_fract = cum_pslp_product / aoa_area;
-        if (aoa_pslp_fract <= 1.50) {
-            aoa_pslp = "VERY LOW";
-        } else if (aoa_pslp_fract > 1.50 && aoa_pslp_fract <= 2.50) {
-            aoa_pslp = "LOW";
-        } else if (aoa_pslp_fract > 2.50 && aoa_pslp_fract <= 3.50) {
-            aoa_pslp = "INTERMEDIATE";
-        } else {
-            aoa_pslp = "HIGH";
+    protected void postProcess() throws Exception { 
+        if ( null != result ){
+            result.putResults();
         }
     }
+    
+    class AoA{
+        private ArrayList<V1_0.AoA.SoilComponent> soilComponents;
+        private final int AoAId;
+        private String error_msg;
+        private double cum_pslp_product;
+        private double aoa_area;     
+        private String aoa_pslp;
+            
+        AoA( int AoAId, JSONArray components ){
+            this.cum_pslp_product = 0;
+            this.aoa_area = 0; 
+            this.AoAId = AoAId;
+            this.error_msg = "";
+            this.aoa_pslp = "NONE";
+            
+            this.soilComponents = new ArrayList<>();
+            
+            if ( AoAId == -1 ){
+                this.error_msg = " Invalid AoA Identifier. ";
+            }
+            else{            
+                try{
+                    if ( ( null != components ) &&( components.length() > 0) ){
+                        for (int j = 0; j < components.length(); j++ ){
+                            Map<String, JSONObject> cokey = JSONUtils.preprocess(components.getJSONArray(j)); 
+                            V1_0.AoA.SoilComponent tSC = new V1_0.AoA.SoilComponent(AoAId, JSONUtils.getStringParam(cokey, "cokey", "err"),
+                                                                            JSONUtils.getStringParam(cokey, "compname", " "), JSONUtils.getDoubleParam(cokey, "aoa_comp_area", 0.0),
+                                                                            JSONUtils.getStringParam(cokey, "aoa_comp_hsg", "err"), JSONUtils.getDoubleParam(cokey, "aoa_comp_kfact", 0.0), 
+                                                                            JSONUtils.getDoubleParam(cokey, "aoa_comp_om", 0.0), JSONUtils.getIntParam(cokey, "aoa_comp_hzdepth", 0),
+                                                                            JSONUtils.getBooleanParam(cokey, "aoa_comp_cracksgr24", false), JSONUtils.getBooleanParam(cokey, "aoa_comp_hwt_lt_24", false)
+                                                                           );
+                            if (!tSC.getError()){
+                                if ( !this.soilComponents.add( tSC ) ){
+                                    //Shouldn't ever happen, but just in case...
+                                    this.error_msg += "Internal error, could not add this component to the list." ;
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                //Most likely an input validation error here, caught by the subclass
+                                this.error_msg += tSC.getErrorMsg();
+                                break;
+                            }
+                        }// End for loop of components for this AoA
+                    }
+                    else{
+                        //This component was empty or the JSON failed to create an item.
+                            this.error_msg += " This AoA's component is empty or missing, cannot proceed.";
+                    }  
+                }
+                catch ( Exception ex ){
+                    this.error_msg += " " + ex.getMessage();
+                } 
+            }
+        }
+        
+        public Boolean process(){
+            Boolean ret_val = true;
+            
+            for (V1_0.AoA.SoilComponent component : this.soilComponents){
+                if ( !component.process() ){
+                    this.error_msg += " " + component.getErrorMsg();
+                    break;
+                }                
+
+                this.cum_pslp_product += ( component.getCompPslpNumber() * component.getAoaCompArea() );
+                this.aoa_area += component.getAoaCompArea();
+            }
+        
+            if ( this.error_msg.isEmpty() ){
+                double aoa_pslp_fract = ( this.cum_pslp_product / this.aoa_area );
+
+                if (aoa_pslp_fract <= 1.50) {
+                    this.aoa_pslp = "VERY LOW";
+                } 
+                else if (aoa_pslp_fract > 1.50 && aoa_pslp_fract <= 2.50) {
+                    this.aoa_pslp = "LOW";
+                } 
+                else if (aoa_pslp_fract > 2.50 && aoa_pslp_fract <= 3.50) {
+                    this.aoa_pslp = "INTERMEDIATE";
+                } 
+                else {
+                    this.aoa_pslp = "HIGH";
+                }
+            }
+
+            return ret_val;
+        }
+        
+        public JSONArray putResults(){
+            JSONArray AoAData;
+            JSONArray components;
+            
+            AoAData = new JSONArray();
+            try{
+                AoAData.put( JSONUtils.dataDesc("AoAId", this.AoAId, "Area of Analysis Identifier") );
+                AoAData.put( JSONUtils.dataDesc("aoa_pslp", this.aoa_pslp, "Pesticide soil leaching potential representing the AoA") );
+
+                components = new JSONArray();
+                for ( V1_0.AoA.SoilComponent component : this.soilComponents ){
+                    components.put( component.putResults() );
+                    if ( component.getError() ){
+                        this.error_msg += " " + component.getErrorMsg();
+                        break;
+                    }                    
+                }
+
+                AoAData.put( JSONUtils.dataDesc( "componentlist", components, "List of soil components" ) );
+            }
+            catch( JSONException ex ){
+                this.error_msg += " " + ex.getMessage();                
+            }
+            
+            return AoAData;
+        }
+        
+        
+        public Boolean getError(){return ( !this.error_msg.isEmpty());}
+        public String getErrorMsg(){ return this.error_msg;}
+        public String getAoAPslp(){ return this.aoa_pslp;}
+        public int getAoAId(){return this.AoAId;}
+                
+    
+        class SoilComponent{   
+            private final int AoAId;
+            private final String cokey;
+            private final String compname;
+            private String comp_pslp;
+            private int comp_pslp_number;
+            private final double aoa_comp_area;
+            private final String aoa_comp_hsg;
+            private final double aoa_comp_kfact;
+            private final double aoa_comp_om;
+            private final int aoa_comp_hzdepth;
+            private final boolean aoa_comp_cracksgr24;
+            private final boolean aoa_comp_hwt_lt_24;   
+            private String error_msg;
+
+            SoilComponent( int AoAId, String cokey, String compname, double aoa_comp_area, String aoa_comp_hsg, double aoa_comp_kfact, double aoa_comp_om, int aoa_comp_hzdepth, boolean aoa_comp_cracksgr24, boolean aoa_comp_hwt_lt_24 ){
+                this.AoAId = AoAId;
+                this.cokey = cokey;
+                this.compname = compname;
+                this.aoa_comp_area = aoa_comp_area;
+                this.aoa_comp_hsg = aoa_comp_hsg;
+                this.aoa_comp_kfact = aoa_comp_kfact;
+                this.aoa_comp_om = aoa_comp_om;
+                this.aoa_comp_hzdepth = aoa_comp_hzdepth;
+                this.aoa_comp_cracksgr24 = aoa_comp_cracksgr24;
+                this.aoa_comp_hwt_lt_24 = aoa_comp_hwt_lt_24;                     
+
+                this.error_msg = "";
+                this.comp_pslp = "";
+                this.comp_pslp_number = 0;      
+                
+                if ( cokey.equals("err") || aoa_comp_hsg.equals("err") || (AoAId == -1) ){
+                    this.error_msg += " Invalid input data for this soil component.";
+                }                                
+            }
+
+            public int getAoAId(){return this.AoAId;}
+            public String getCokey(){return this.cokey;}
+            public String getCompname(){return this.compname;}
+            public String getCompPslp(){return this.comp_pslp;};
+            public int getCompPslpNumber(){return this.comp_pslp_number;}
+            public double getAoaCompArea(){return this.aoa_comp_area;}   
+            public Boolean getError(){ return ( !this.error_msg.isEmpty() );}
+            public String getErrorMsg(){return (this.error_msg);}
+
+            public boolean process(){
+                boolean ret_val = true;
+
+                if (this.aoa_comp_hwt_lt_24) {
+                    this.comp_pslp_number = V1_0.HIGH;
+                } else if ( ( (this.aoa_comp_hsg.equals("A") || this.aoa_comp_hsg.equals("A/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) <= 30) ) ||
+                            ( (this.aoa_comp_hsg.equals("B") || this.aoa_comp_hsg.equals("B/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) <= 9) && (this.aoa_comp_kfact <= 0.48) ) ||
+                            ( (this.aoa_comp_hsg.equals("B") || this.aoa_comp_hsg.equals("B/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) <= 15) && (this.aoa_comp_kfact <= 0.26) ) 
+                          ) {
+                    this.comp_pslp_number = V1_0.HIGH;
+                } else if ( ( (this.aoa_comp_hsg.equals("B") || this.aoa_comp_hsg.equals("B/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) >= 35) && this.aoa_comp_kfact >= 0.40) ||
+                            ( (this.aoa_comp_hsg.equals("B") || this.aoa_comp_hsg.equals("B/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) >= 45) && this.aoa_comp_kfact >= 0.20) ||
+                            ( (this.aoa_comp_hsg.equals("C") || this.aoa_comp_hsg.equals("C/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) <= 10) && this.aoa_comp_kfact <= 0.28) ||
+                            ( (this.aoa_comp_hsg.equals("C") || this.aoa_comp_hsg.equals("C/D")) && ( (this.aoa_comp_hzdepth * this.aoa_comp_om) >= 10) )
+                          ) {
+                    if (!this.aoa_comp_cracksgr24) {
+                        this.comp_pslp_number = V1_0.LOW;
+                    } else {
+                        this.comp_pslp_number = V1_0.INTERMEDIATE;
+                    }
+                } else if (this.aoa_comp_hsg.equals("D")) {
+                    if (!this.aoa_comp_cracksgr24) {
+                        this.comp_pslp_number = V1_0.VERY_LOW;
+                    } else {
+                        this.comp_pslp_number = V1_0.LOW;
+                    }
+                } else {
+                    if (!this.aoa_comp_cracksgr24) {
+                        this.comp_pslp_number = V1_0.INTERMEDIATE;
+                    } else {
+                        this.comp_pslp_number = V1_0.HIGH;
+                    }     
+                }
+                
+                this.comp_pslp = comp_pslp_string[this.comp_pslp_number];
+
+                return ret_val;
+            }
+            
+            public JSONArray putResults(){
+                JSONArray componentData;
+                componentData = new JSONArray();
+                
+                try{
+                    componentData.put( JSONUtils.dataDesc("cokey", this.cokey, "Soil component key") );
+                    componentData.put( JSONUtils.dataDesc("compname", this.compname, "Soil component name") );
+                    componentData.put( JSONUtils.dataDesc("comp_pslp", this.comp_pslp, "Pesticide soil leaching potential representing the soil component") );
+                }
+                catch( JSONException ex ){
+                    this.error_msg += " " + ex.getMessage();
+                }
+                
+                return componentData;            
+            }            
+        }        
+    }
+    
+    public class Input {
+        private String error_msg;
+        private JSONArray AoAList;
+             
+        Input( ArrayList<V1_0.AoA> AoAs ){
+            this.error_msg = "";
+            
+            try{
+                AoAList = getJSONArrayParam("AoAList");
+                if ( null != AoAList ){
+                    for( int i = 0; i < AoAList.length(); i++ ){
+                        Map<String, JSONObject> componentGroup = JSONUtils.preprocess(AoAList.getJSONArray(i));
+                        
+                        int AoAId = JSONUtils.getIntParam(componentGroup, "AoAId", -1);
+                        
+                        if ( AoAId != -1 ){
+                            JSONArray components = JSONUtils.getJSONArrayParam(componentGroup, "componentlist");
+                            V1_0.AoA AoA = new V1_0.AoA(AoAId, components);
+                            if ( AoA.getError() ){
+                                this.error_msg += " " + AoA.getErrorMsg();
+                                break;
+                            }
+                            else{
+                                AoAs.add( AoA );
+                            }
+                        }
+                        else{
+                            this.error_msg += " The AoAId is not valid or is missing, cannot proceed";
+                            break;
+                        }                                                    
+                    }//  End for loop of AoA's
+                }                   
+                else{
+                    this.error_msg += " There were no AoA's found in the input payload.  Cannot proceed.";
+                }
+            }
+            catch( ServiceException | JSONException ex ){
+                this.error_msg += " " + ex.getMessage();
+            }            
+        }
+        
+        public String getErrorMsg(){return this.error_msg;}
+        public Boolean getError(){return ( !this.error_msg.isEmpty());}
+    }   
+    
+    public class Result {
+        JSONArray AoAList;
+        
+        Result( ArrayList<V1_0.AoA> AoAs ) throws Exception{
+            if ( !AoAs.isEmpty() ){                
+                AoAList = new JSONArray();
+                for( V1_0.AoA AoA : AoAs ){                                        
+                    AoAList.put( AoA.putResults() );                                        
+                    if ( AoA.getError() ){
+                        AoAList.put( JSONUtils.dataDesc("Error:", AoA.getErrorMsg(),"Error message returned while trying to build result output" ) );
+                        break;
+                    }
+                }
+            }
+            else{
+                AoAList = null;
+            }
+        }
+
+        public void putResults(){
+            if ( null != AoAList ){                
+                putResult( "AoAList", AoAList );
+            }
+        }
+    }
+    
+    
 }

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

@@ -3,250 +3,480 @@
     },
     "parameter": [
         {
-            "name": "soilcomponents",
-            "value": [
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1
-                    },
-                    {
-                        "name": "cokey",
-                        "value": "11510284"
-                    },
-                    {
-                        "name": "aoa_comp_area",
-                        "value": 45.84,
-                        "description": "Area of the soil component in the AoA"
+        "name": "AoAList",
+        "value": [
+            [                
+                {
+                    "name": "AoAId",
+                    "value": 1
+                },
+                {
+                    "name": "componentlist",
+                    "value": [
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510284"
+                            },
+                            {
+                                "name": "compname",
+                                "value": "Berrend",
+                                "description": "Soil Component Name"
+                            },                              
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 45.84,
+                                "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "A",
+                                "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.24,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 2.3,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 14,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510285"
+                            },
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 25.84,
+                                "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "B",
+                                "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 2.3,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 20,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510286"
+                            },
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 15.84,
+                                "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "A/D",
+                                "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 1.3,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 45,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }
+                        ],
+                        [
+                            {
+                                "name": "AoAId",
+                                "value": 1
+                            },
+                            {
+                                "name": "cokey",
+                                "value": "11510287"
+                            },
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 55.84,
+                                "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "B/D",
+                                "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 3.3,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 64,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": false,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510288"
+                            },
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 45.84,
+                                "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "C/D",
+                                "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.24,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 4,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 14,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": false,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": true,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }
+                        ]
+                    ]
+                }
+            ],
+            [
+                {
+                    "name": "AoAId",
+                    "value": 2
+                },
+                {
+                    "name": "componentlist",
+                    "value": [
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510284",
+                                "description": "Soil Component Key"
+                            },
+                            {
+                                "name": "compname",
+                                "value": "Berrend",
+                                "description": "Soil Component Name"
+                            },                    
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 45.84,
+                                "description": "Area of the soil component in the AoA"
 
-                    },
-                    {
-                        "name": "aoa_comp_hsg",
-                        "value": "A",
-                        "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "A",
+                                "description": "Hydrologic soil group of the soil component"
 
-                    },
-                    {
-                        "name": "aoa_comp_kfact",
-                        "value": 0.24,
-                        "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
-                    },
-                    {
-                        "name": "aoa_comp_om",
-                        "value": 2.30,
-                        "description": "#Organic matter content of the horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_hzdepth",
-                        "value": 14,
-                        "unit": "inches",
-                        "description": "#Thickness of horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_cracksgr24",
-                        "value": true,
-                        "description": "#Whether the soil has surface connected macropores to 24 inches"
-                    },
-                    {
-                        "name": "aoa_comp_hwt_lt_24",
-                        "value": false,
-                        "description": "#Whether the soil has a water table less than 24 inches from the surface"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1
-                    },
-                    {
-                        "name": "cokey",
-                        "value": "11510284"
-                    },
-                    {
-                        "name": "aoa_comp_area",
-                        "value": 25.84,
-                        "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.24,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 2.30,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 14,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }                                
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510285",
+                                "description": "Soil Component Key"
+                            },                               
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 25.84,
+                                "description": "Area of the soil component in the AoA"
 
-                    },
-                    {
-                        "name": "aoa_comp_hsg",
-                        "value": "B",
-                        "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "B",
+                                "description": "Hydrologic soil group of the soil component"
 
-                    },
-                    {
-                        "name": "aoa_comp_kfact",
-                        "value": 0.34,
-                        "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
-                    },
-                    {
-                        "name": "aoa_comp_om",
-                        "value": 2.30,
-                        "description": "#Organic matter content of the horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_hzdepth",
-                        "value": 20,
-                        "unit": "inches",
-                        "description": "#Thickness of horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_cracksgr24",
-                        "value": true,
-                        "description": "#Whether the soil has surface connected macropores to 24 inches"
-                    },
-                    {
-                        "name": "aoa_comp_hwt_lt_24",
-                        "value": false,
-                        "description": "#Whether the soil has a water table less than 24 inches from the surface"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1
-                    },
-                    {
-                        "name": "cokey",
-                        "value": "11510284"
-                    },
-                    {
-                        "name": "aoa_comp_area",
-                        "value": 15.84,
-                        "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 2.30,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 20,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }                                
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510286",
+                                "description": "Soil Component Key"
+                            },                                
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 15.84,
+                                "description": "Area of the soil component in the AoA"
 
-                    },
-                    {
-                        "name": "aoa_comp_hsg",
-                        "value": "A/D",
-                        "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "A/D",
+                                "description": "Hydrologic soil group of the soil component"
 
-                    },
-                    {
-                        "name": "aoa_comp_kfact",
-                        "value": 0.34,
-                        "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
-                    },
-                    {
-                        "name": "aoa_comp_om",
-                        "value": 1.30,
-                        "description": "#Organic matter content of the horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_hzdepth",
-                        "value": 45,
-                        "unit": "inches",
-                        "description": "#Thickness of horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_cracksgr24",
-                        "value": true,
-                        "description": "#Whether the soil has surface connected macropores to 24 inches"
-                    },
-                    {
-                        "name": "aoa_comp_hwt_lt_24",
-                        "value": false,
-                        "description": "#Whether the soil has a water table less than 24 inches from the surface"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1
-                    },
-                    {
-                        "name": "cokey",
-                        "value": "11510284"
-                    },
-                    {
-                        "name": "aoa_comp_area",
-                        "value": 55.84,
-                        "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 1.30,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 45,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": true,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }                                
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510287",
+                                "description": "Soil Component Key"
+                            },                               
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 55.84,
+                                "description": "Area of the soil component in the AoA"
 
-                    },
-                    {
-                        "name": "aoa_comp_hsg",
-                        "value": "B/D",
-                        "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "B/D",
+                                "description": "Hydrologic soil group of the soil component"
 
-                    },
-                    {
-                        "name": "aoa_comp_kfact",
-                        "value": 0.34,
-                        "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
-                    },
-                    {
-                        "name": "aoa_comp_om",
-                        "value": 3.30,
-                        "description": "#Organic matter content of the horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_hzdepth",
-                        "value": 64,
-                        "unit": "inches",
-                        "description": "#Thickness of horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_cracksgr24",
-                        "value": false,
-                        "description": "#Whether the soil has surface connected macropores to 24 inches"
-                    },
-                    {
-                        "name": "aoa_comp_hwt_lt_24",
-                        "value": false,
-                        "description": "#Whether the soil has a water table less than 24 inches from the surface"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1
-                    },
-                    {
-                        "name": "cokey",
-                        "value": "11510284"
-                    },
-                    {
-                        "name": "aoa_comp_area",
-                        "value": 45.84,
-                        "description": "Area of the soil component in the AoA"
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.34,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 3.30,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 64,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": false,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": false,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }                                
+                        ],
+                        [
+                            {
+                                "name": "cokey",
+                                "value": "11510288",
+                                "description": "Soil Component Key"
+                            },                            
+                            {
+                                "name": "aoa_comp_area",
+                                "value": 45.84,
+                                "description": "Area of the soil component in the AoA"
 
-                    },
-                    {
-                        "name": "aoa_comp_hsg",
-                        "value": "C/D",
-                        "description": "Hydrologic soil group of the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hsg",
+                                "value": "C/D",
+                                "description": "Hydrologic soil group of the soil component"
 
-                    },
-                    {
-                        "name": "aoa_comp_kfact",
-                        "value": 0.24,
-                        "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
-                    },
-                    {
-                        "name": "aoa_comp_om",
-                        "value": 4.00,
-                        "description": "#Organic matter content of the horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_hzdepth",
-                        "value": 14,
-                        "unit": "inches",
-                        "description": "#Thickness of horizon representing the soil component"
-                    },
-                    {
-                        "name": "aoa_comp_cracksgr24",
-                        "value": false,
-                        "description": "#Whether the soil has surface connected macropores to 24 inches"
-                    },
-                    {
-                        "name": "aoa_comp_hwt_lt_24",
-                        "value": true,
-                        "description": "#Whether the soil has a water table less than 24 inches from the surface"
-                    }
-                ]
-
+                            },
+                            {
+                                "name": "aoa_comp_kfact",
+                                "value": 0.24,
+                                "description": "#K factor of the horizon representing the soil component; usually the surface horizon"
+                            },
+                            {
+                                "name": "aoa_comp_om",
+                                "value": 4.00,
+                                "description": "#Organic matter content of the horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_hzdepth",
+                                "value": 14,
+                                "unit": "inches",
+                                "description": "#Thickness of horizon representing the soil component"
+                            },
+                            {
+                                "name": "aoa_comp_cracksgr24",
+                                "value": false,
+                                "description": "#Whether the soil has surface connected macropores to 24 inches"
+                            },
+                            {
+                                "name": "aoa_comp_hwt_lt_24",
+                                "value": true,
+                                "description": "#Whether the soil has a water table less than 24 inches from the surface"
+                            }                                                                                                                             
+                        ]
+                    ]
+                }                    
             ]
-        }
-    ]
+        ]
+    }
+]        
 }

src/java/m/wqm/scsednutsrp/V1_0.java

@@ -1,11 +1,7 @@
-/*
- * 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.scsednutsrp;
 
 import csip.ModelDataService;
+import csip.ServiceException;
 import java.util.ArrayList;
 import javax.ws.rs.Path;
 import oms3.annotations.Description;
@@ -14,182 +10,204 @@
 import org.codehaus.jettison.json.JSONObject;
 import csip.utils.JSONUtils;
 import java.util.Map;
+import org.codehaus.jettison.json.JSONException;
 
 /**
  *
  * @author Srinivas
+ * @author Rumpal Sidhu
  */
-@Name("Sediment and Nutrient Soil Runoff Potential (SedNutSRP)")
-@Description("Computation of Sediment and Nutrient Runoff Potential for a Soil Component")
+@Name("WQM-06: Sediment and Nutrient Soil Runoff Potential (SedNutSRP)")
+@Description("This service computes sediment and nutrient soil runoff potential for soil components in an area of analysis, and then compute soil runoff potential representing the area of analysis. The service primarily will consume data from the WQM-2 soil attributes service to compute soil runoff potential values for subsequent use by WQM-13 to compute threshold treatment level scores.")
 @Path("m/scsednut_srp/1.0")
 public class V1_0 extends ModelDataService {
 
-    
-    String comp_srp;
-    int comp_srp_number;
-    String aoa_srp;
-
-    //JSONArray getArray
-    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[] srp = new String[]{"", "LOW", "MODERATE", "MODERATELY HIGH", "HIGH"};
+    private final String[] srpList = new String[]{"LOW", "MODERATE", "MODERATELY HIGH", "HIGH"};
+    //Request
+    private int aoaId;
+    private ArrayList<SoilComponent> soilComponentList;
+    //Result
+    private String aoaSrp;
+    private String error_msg;
 
     @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("soilcomponents");
-        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 cokey = JSONUtils.getStringParam(group, "cokey", "err");
-            double aoa_comp_area = JSONUtils.getDoubleParam(group, "aoa_comp_area", 0);
-            String aoa_comp_hsg = JSONUtils.getStringParam(group, "aoa_comp_hsg", "err");
-            double aoa_comp_kfact = JSONUtils.getDoubleParam(group, "aoa_comp_kfact", 0);
-            double aoa_comp_slope = JSONUtils.getDoubleParam(group, "aoa_comp_slope", 0);
-            boolean aoa_comp_drained = JSONUtils.getBooleanParam(group, "aoa_comp_drained", false);
-            Input input = new Input(AoAId, cokey, aoa_comp_area, aoa_comp_hsg, aoa_comp_kfact, aoa_comp_slope, aoa_comp_drained);
-            components.add(input);
+        soilComponentList = new ArrayList<>();
+        this.error_msg = "";
+        try {
+            aoaId = getIntParam("AoAId");
+            JSONArray groups = getJSONArrayParam("soilcomponents");
+            for (int i = 0; i < groups.length(); i++) {
+                Map<String, JSONObject> group = JSONUtils.preprocess(groups.getJSONArray(i));
+                SoilComponent input = new SoilComponent(
+                        JSONUtils.getStringParam(group, "cokey", "err"),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_area", 0),
+                        JSONUtils.getStringParam(group, "aoa_comp_hsg", "err"),
+                        JSONUtils.getStringParam(group, "aoa_comp_taxorder", "err"),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_kfact", 0),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_slope", 0),
+                        JSONUtils.getDoubleParam(group, "aoa_comp_coarse_frag", 0),
+                        JSONUtils.getBooleanParam(group, "aoa_comp_drained", false),
+                        JSONUtils.getStringParam(group, "aoa_comp_wtbl", "err"),
+                        JSONUtils.getBooleanParam(group, "aoa_comp_hwt_lt_24", false));
+                soilComponentList.add(input);
+            }
+        } catch (ServiceException | JSONException ex) {
+            this.error_msg += "  " + ex.getMessage() + ". ";
         }
     }
 
+    @Override
+    protected String process() throws Exception {
+        try {
+            if (this.error_msg.isEmpty()) {
+                this.computeSedNutSRP();
+            }
+            if (this.error_msg.isEmpty()) {
+                this.computeAoaSrp();
+            }
+        } catch (Exception ex) {
+            LOG.info(ex.getMessage());
+            this.error_msg += ex.getMessage();
+        }
+        return (this.error_msg.isEmpty() ? EXEC_OK : this.error_msg);
+    }
 
     @Override
-    protected String process() throws Exception {
-        for (Input ip : components) {
-            if ("A".equals(ip.aoa_comp_hsg)) {
-                comp_srp_number = 1;
-            } else if ("B".equals(ip.aoa_comp_hsg)) {
-                if (ip.aoa_comp_slope < 4) {
-                    comp_srp_number = 1;
-                } else if (ip.aoa_comp_slope >= 4 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact < 0.32) {
-                    comp_srp_number = 2;
-                } else if (ip.aoa_comp_slope >= 4 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact >= 0.32) {
-                    comp_srp_number = 3;
-                } else if (ip.aoa_comp_slope > 6) {
-                    comp_srp_number = 4;
-                }
-            } else if (ip.aoa_comp_hsg.equals("C")) {
-                if (ip.aoa_comp_slope < 2) {
-                    comp_srp_number = 1;
-                } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact < 0.28) {
-                    comp_srp_number = 2;
-                } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact >= 0.28) {
-                    comp_srp_number = 3;
-                } else if (ip.aoa_comp_slope > 6) {
-                    comp_srp_number = 4;
-                }
-            } else if (ip.aoa_comp_hsg.equals("D")) {
-                if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact < 0.28) {
-                    comp_srp_number = 1;
-                } else if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact >= 0.28) {
-                    comp_srp_number = 2;
-                } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 4) {
-                    comp_srp_number = 3;
-                } else if (ip.aoa_comp_slope > 4) {
-                    comp_srp_number = 4;
-                }
-            } else if (ip.aoa_comp_hsg.equals("A/D")) {
-                if (ip.aoa_comp_drained) {
-                    comp_srp_number = 1;
-                } else if (!ip.aoa_comp_drained) {
-                    if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact < 0.28) {
-                        comp_srp_number = 1;
-                    } else if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact >= 0.28) {
-                        comp_srp_number = 2;
-                    } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 4) {
-                        comp_srp_number = 3;
-                    } else if (ip.aoa_comp_slope > 4) {
-                        comp_srp_number = 4;
-                    }
-                }
-            } else if (ip.aoa_comp_hsg.equals("B/D")) {
-                if (ip.aoa_comp_drained) {
-                    if (ip.aoa_comp_slope < 4) {
-                        comp_srp_number = 1;
-                    } else if (ip.aoa_comp_slope >= 4 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact < 0.32) {
-                        comp_srp_number = 2;
-                    } else if (ip.aoa_comp_slope >= 4 && ip.aoa_comp_slope <= 6 &&ip.aoa_comp_kfact >= 0.32) {
-                        comp_srp_number = 3;
-                    } else if (ip.aoa_comp_slope > 6) {
-                        comp_srp_number = 4;
-                    }
-                } else if (!ip.aoa_comp_drained) {
-                    if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact < 0.28) {
-                        comp_srp_number = 1;
-                    } else if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact >= 0.28) {
-                        comp_srp_number = 2;
-                    } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 4) {
-                        comp_srp_number = 3;
-                    } else if (ip.aoa_comp_slope > 4) {
-                        comp_srp_number = 4;
-                    }
-                }
-            } else if (ip.aoa_comp_hsg.equals("C/D")) {
-                if (ip.aoa_comp_drained) {
-                    if (ip.aoa_comp_slope < 2) {
-                        comp_srp_number = 1;
-                    } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 6 &&ip.aoa_comp_kfact < 0.28) {
-                        comp_srp_number = 2;
-                    } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 6 && ip.aoa_comp_kfact >= 0.28) {
-                        comp_srp_number = 3;
-                    } else if (ip.aoa_comp_slope > 6) {
-                        comp_srp_number = 4;
-                    }
-                } else if (!ip.aoa_comp_drained) {
-                    if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact < 0.28) {
-                        comp_srp_number = 1;
-                    } else if (ip.aoa_comp_slope < 2 && ip.aoa_comp_kfact >= 0.28) {
-                        comp_srp_number = 2;
-                    } else if (ip.aoa_comp_slope >= 2 && ip.aoa_comp_slope <= 4) {
-                        comp_srp_number = 3;
-                    } else if (ip.aoa_comp_slope > 4) {
-                        comp_srp_number = 4;
-                    }
-                }
-            }
-            Result1 result = new Result1(ip.AoAId, ip.cokey, ip.aoa_comp_area, srp[comp_srp_number], comp_srp_number);
-            result1.add(result);
+    protected void postProcess() throws Exception {
+        putResult("aoa_id", aoaId, "Area of analysis identifier");
+        putResult("aoa_srp", aoaSrp, "Soil runoff potential for the area of analysis");
+        JSONArray resultArr = new JSONArray();
+        for (SoilComponent sc : soilComponentList) {
+            JSONArray array = new JSONArray();
+            array.put(JSONUtils.dataDesc("cokey", sc.getCokey(), "Soil component key"));
+            array.put(JSONUtils.dataDesc("comp_srp", sc.getSrp(), "Soil runoff potential for soil component"));
+            resultArr.put(JSONUtils.dataDesc("soil_component", array, "Soil Component"));
         }
-        calAoANutSLP(result1);
-        return EXEC_OK;
+        putResult("soil_components", resultArr, "List of Soil Components");
     }
 
-    
-
-
-    @Override
-    //writing the results back to JSON
-    protected void postProcess() throws Exception {
-        for (int i = 0; i < result1.size(); i++) {
-            Result1 temp = result1.get(i);
-            putResult("AoAId", temp.AoAId,"Area of Analysis Id");
-            putResult("cokey", temp.cokey,"Key value of the soil component");
-            putResult("aoa_comp_area", temp.aoa_comp_area,"Area of the soil component");
-//            putResult("comp_srp", srp[temp.comp_srp]);
-            putResult("comp_srp", srp[temp.comp_srp_number],"Soil component Soil Runoff potential");
-            putResult("comp_srp_number", temp.comp_srp_number,"Number representing the soil component soil runoff potential");
+    //Compute sediment and nutrient soil runoff potential for each soil component in the AoA
+    private void computeSedNutSRP() {
+        int comp_srp_number = -2;
+        for (SoilComponent ip : soilComponentList) {
+            switch (ip.getHsg()) {
+                case "A":
+                    comp_srp_number = 0;
+                    break;
+                case "B":
+                    comp_srp_number = this.computeSRPHsgB(ip);
+                    break;
+                case "C":
+                    comp_srp_number = this.computeSRPHsgC(ip);
+                    break;
+                case "D":
+                    if (ip.getWtbl().equals("Perched")
+                            || ip.getWtbl().equals("Apparent") && ip.isHwt_lt_24()) {
+                        comp_srp_number = 3;
+                    } else if (ip.getSlope() < 2 && ip.getKfact() < 0.28) {
+                        comp_srp_number = 0;
+                    } else if (ip.getSlope() < 2 && ip.getKfact() >= 0.28) {
+                        comp_srp_number = 1;
+                    } else if (ip.getSlope() >= 2 && ip.getSlope() <= 4) {
+                        comp_srp_number = 2;
+                    } else if (ip.getSlope() > 4) {
+                        comp_srp_number = 3;
+                    }
+                    break;
+                case "A/D":
+                    if (ip.isDrained()) {
+                        comp_srp_number = 0;
+                    } else {
+                        comp_srp_number = this.computeSRPHsgD(ip);
+                    }
+                    break;
+                case "B/D":
+                    if (ip.isDrained()) {
+                        comp_srp_number = this.computeSRPHsgB(ip);
+                    } else {
+                        comp_srp_number = this.computeSRPHsgD(ip);
+                    }
+                    break;
+                case "C/D":
+                    if (ip.isDrained()) {
+                        comp_srp_number = this.computeSRPHsgC(ip);
+                    } else {
+                        comp_srp_number = this.computeSRPHsgD(ip);
+                    }
+                    break;
+            }
+            if (comp_srp_number != -1 && comp_srp_number != -2) {
+                ip.setSrpNumber(comp_srp_number);
+                ip.setSrp(srpList[comp_srp_number]);
+            } else {
+                error_msg = "Error.";
+            }
         }
-        putResult("aoa_srp", aoa_srp,"Area of analysis soil runoff potential");
     }
 
+    public int computeSRPHsgB(SoilComponent ip) {
+        int srp_number = -1;
+        if (ip.getSlope() < 4) {
+            srp_number = 0;
+        } else if (ip.getSlope() >= 4 && ip.getSlope() <= 6 && ip.getKfact() < 0.32) {
+            srp_number = 1;
+        } else if (ip.getSlope() >= 4 && ip.getSlope() <= 6 && ip.getKfact() >= 0.32) {
+            srp_number = 2;
+        } else if (ip.getSlope() > 6) {
+            srp_number = 3;
+        }
+        return srp_number;
+    }
 
-    // calculate the aoa_nslp 
-    void calAoANutSLP(ArrayList<Result1> source) {
-        double cum_nslp_product = 0;
-        double aoa_area = 0;
-        for (Result1 tmp : source) {
-            cum_nslp_product += (tmp.comp_srp_number * tmp.aoa_comp_area);
-            aoa_area += tmp.aoa_comp_area;
+    public int computeSRPHsgC(SoilComponent ip) {
+        int srp_number = -1;
+        if (ip.getSlope() < 2) {
+            srp_number = 0;
+        } else if (ip.getSlope() >= 2 && ip.getSlope() <= 6 && ip.getKfact() < 0.28) {
+            srp_number = 1;
+        } else if (ip.getSlope() >= 2 && ip.getSlope() <= 6 && ip.getKfact() >= 0.28) {
+            srp_number = 2;
+        } else if (ip.getSlope() > 6) {
+            srp_number = 3;
         }
-        double aoa_nslp_fract = cum_nslp_product / aoa_area;
-        if (aoa_nslp_fract <= 1.50) {
-            aoa_srp = "LOW";
-        } else if (aoa_nslp_fract > 1.50 && aoa_nslp_fract <= 2.50) {
-            aoa_srp = "MODERATE";
-        } else if (aoa_nslp_fract > 2.50 && aoa_nslp_fract <= 3.50) {
-            aoa_srp = "MODERATELY HIGH";
+        return srp_number;
+    }
+
+    public int computeSRPHsgD(SoilComponent ip) {
+        int srp_number = -1;
+        if (ip.getSlope() < 2 && ip.getKfact() < 0.28) {
+            srp_number = 0;
+        } else if (ip.getSlope() < 2 && ip.getKfact() >= 0.28) {
+            srp_number = 1;
+        } else if (ip.getSlope() >= 2 && ip.getSlope() <= 4) {
+            srp_number = 2;
+        } else if ((ip.getSlope() > 4) || (ip.getWtbl().equals("Perched")
+                || ip.getWtbl().equals("Apparent") && ip.isHwt_lt_24())) {
+            srp_number = 3;
+        }
+        return srp_number;
+    }
+
+    //Compute weighted average nutrient soil leaching potential for the AoA
+    void computeAoaSrp() {
+        double srpProduct = 0;
+        double aoaArea = 0;
+        for (SoilComponent sc : soilComponentList) {
+            srpProduct += (sc.getSrpNumber() * sc.getArea());
+            aoaArea += sc.getArea();
+        }
+        double aoaSrpFract = srpProduct / aoaArea;
+
+        if (aoaSrpFract <= 0.50) {
+            aoaSrp = "LOW";
+        } else if (aoaSrpFract > 0.50 && aoaSrpFract <= 1.50) {
+            aoaSrp = "MODERATE";
+        } else if (aoaSrpFract > 1.50 && aoaSrpFract <= 2.50) {
+            aoaSrp = "MODERATELY HIGH";
         } else {
-            aoa_srp = "HIGH";
+            aoaSrp = "HIGH";
         }
     }
+
 }

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

@@ -1,87 +1,434 @@
 {
- "metainfo": {
- },
- "parameter": [
-  {
-   "name": "soilcomponents",
-   "value": [
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"Area of analysis identifier"
-     },
-     {
-      "name": "cokey",
-      "value": "11510284",
-      "Description":"#Soil component key"
-     },
-     {
-      "name": "aoa_comp_area",
-      "value": 45.84,
-      "Description":"#Soil component area in the area of analysis (double)"
-     },
-     {
-      "name": "aoa_comp_hsg",
-      "value": "B",
-      "Description":"#Hydrologic soil group of the soil component"
-     },
-     {
-      "name": "aoa_comp_kfact",
-      "value": 0.24,
-      "Description":"#Representative K factor of the soil component (double)"
-     },
-     {
-      "name": "aoa_comp_slope",
-      "value": 8,
-      "Description":"#Representative slope of the soil component (double)"
-     },
-     {
-         "name":"aoa_comp_drained",
-         "value":true,
-          "Description":"Whether the soil component is drained or not"
-     }
-    ],
-    [
-     {
-      "name": "AoAId",
-      "value": 1,
-      "Description":"Area of analysis identifier"
-     },
-     {
-      "name": "cokey",
-      "value": "11510290",
-      "Description":"#Soil component key"
-     },
-     {
-      "name": "aoa_comp_area",
-      "value": 63.72,
-      "Description":"#Soil component area in the area of analysis (double)"
-     },
-     {
-      "name": "aoa_comp_hsg",
-      "value": "D",
-      "Description":"#Hydrologic soil group of the soil component"
-     },
-     
-     {
-      "name": "aoa_comp_kfact",
-      "value": 0.37,
-      "Description":"#Representative K factor of the soil component (double)"
-     },
-     {
-      "name": "aoa_comp_slope",
-      "value": 12,
-      "Description":"#Representative slope of the soil component (double)"
-     },
-     
-     {
-         "name":"aoa_comp_drained",
-         "value":true,
-          "Description":"Whether the soil component is drained or not"
-     }
+    "metainfo": {
+    },
+    "parameter": [
+        {
+            "name": "AoAId",
+            "value": 1,
+            "Description": "Area of analysis identifier"
+        },
+        {
+            "name": "soilcomponents",
+            "value": [
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150284",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 45.84,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Aridisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.24,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 8,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 3.7,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": true,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150285",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 63.72,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "A",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.37,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 12,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 0,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": true,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Apparent",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150286",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 25.6,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "A/D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Spodosols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.21,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 15,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 12,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150287",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 33.5,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "C",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Inceptisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.42,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 16,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 6,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150288",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 10.77,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Histosols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.02,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 3,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 2,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Apparent",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150289",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 36.93,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B/D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Entisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.28,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 1,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 3,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Perched",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150290",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 44.33,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "D",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.32,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 14,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 7,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "None",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": false,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ],
+                [
+                    {
+                        "name": "cokey",
+                        "value": "11150291",
+                        "Description": "Soil component key"
+                    },
+                    {
+                        "name": "aoa_comp_area",
+                        "value": 21.76,
+                        "Description": "Soil component area in the area of analysis"
+                    },
+                    {
+                        "name": "aoa_comp_hsg",
+                        "value": "B",
+                        "Description": "Hydrologic soil group of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_taxorder",
+                        "value": "Mollisols",
+                        "Description": "Taxonomic order of the soil component "
+                    },
+                    {
+                        "name": "aoa_comp_kfact",
+                        "value": 0.48,
+                        "Description": "Representative K factor of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_slope",
+                        "value": 5,
+                        "Description": "Representative slope of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_coarse_frag",
+                        "value": 5,
+                        "Description": "Representative coarse rock fragments of the soil component"
+                    },
+                    {
+                        "name": "aoa_comp_drained",
+                        "value": false,
+                        "Description": "Whether this soil component instance is drained"
+                    },
+                    {
+                        "name": "aoa_comp_wtbl",
+                        "value": "Perched",
+                        "Description": "Kind of water table"
+                    },
+                    {
+                        "name": "aoa_comp_hwt_lt_24",
+                        "value": true,
+                        "Description": "High water table within 24 inches of soil surface"
+                    }
+                ]
+            ]
+        }
     ]
-   ]
-  }
- ]
 }

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("SedNutPractScores")
-@Description("Sediment Nutrient Practice Scores")
+@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 Data Mart 20150324", "postgres", "postgresql");
-            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

@@ -1,168 +1,488 @@
 package m.wqm.soilpestlosspot;
 
+
+import csip.ModelDataService;
+import csip.ServiceException;
+import csip.annotations.Polling;
+import csip.utils.JSONUtils;
+import java.sql.Connection;
+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;
+import java.util.Collections;
+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;
+
 /**
  *
  * @author RUMPAL SIDHU
+ * @author Shaun Case
  */
-import csip.ModelDataService;
-import csip.annotations.Polling;
-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 javax.ws.rs.Path;
-import oms3.annotations.Name;
-import oms3.annotations.Description;
-import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONObject;
 
-@Name("WQM-10")
-@Description("Soil/Pesticide Interaction Loss Potentials")
+@Name("WQM-10: Soil Pesticide Interaction Loss Potentials (SoilPestLossPot)")
+@Description("This service computes soil pesticide interaction loss potentials for leaching, solution runoff, and adsorbed runoff.")
 @Path("m/soilpestlosspot/1.0")
 @Polling(first = 10000, next = 2000)
 
 public class V1_0 extends ModelDataService {
 
-    //SQL params names here for quick modification
+    //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 = "postgres";
+    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 Statement statement;
+    private Connection conn;
+    private AoA aoa;
+    private String error_msg;
+    
 
-    //Request
-    private ArrayList<Input> components;
     //Response
     private ArrayList<Result> result;
 
     @Override
     protected void preProcess() throws Exception {
-        components = new ArrayList<>();
-        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);
-            int operation_id = JSONUtils.getIntParam(group, "operation_id", 0);
-            String op_pesticide_id = JSONUtils.getStringParam(group, "op_pesticide_id", "err");
-            String ai_plp = JSONUtils.getStringParam(group, "ai_plp", "err");
-            String ai_psrp = JSONUtils.getStringParam(group, "ai_psrp", "err");
-            String ai_parp = JSONUtils.getStringParam(group, "ai_parp", "err");
-            String aoa_pslp = JSONUtils.getStringParam(group, "aoa_pslp", "err");
-            String aoa_ssrp = JSONUtils.getStringParam(group, "aoa_ssrp", "err");
-            String aoa_sarp = JSONUtils.getStringParam(group, "aoa_sarp", "err");
-            String aoa_rain_prob = JSONUtils.getStringParam(group, "aoa_rain_prob", "err");
-            Input input = new Input(AoAId, operation_id, op_pesticide_id, ai_plp, ai_psrp, ai_parp, aoa_pslp, aoa_ssrp, aoa_sarp, aoa_rain_prob);
-            components.add(input);
+        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.
+        //  For some of these calls, default strings can be applied if the data is not found, however, in most cases
+        //  one should not proceed with a calculation if some data or parameters are missing.
+        try{ 
+            aoa = new AoA(  getStringParam("AoAId"),getStringParam("aoa_pslp"),getStringParam("aoa_ssrp"),
+                            getStringParam("aoa_sarp"),getStringParam("aoa_rain_prob"), getJSONArrayParam("operationlist") );
+            error_msg = aoa.getErrorMsg();        
+        }
+        catch (ServiceException ex) {
+            error_msg += "  " + ex.getMessage() + ". ";
         }
     }
 
     @Override
     protected String process() throws Exception {
-        result = new ArrayList();
-        Connection conn = null;
-        Statement statement = null;
-        String query;
         ResultSet resultSet;
         try {
-            Class.forName(CLASS_NAME);
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
+            conn = wqm.utils.WQMTools.getConnection("wqm", LOG );
             conn.setAutoCommit(false);
-            statement = conn.createStatement();
+            statement = conn.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY);            
+            if (error_msg.isEmpty() ){
+                if ( aoa.calculate() ) {
+                    result = aoa.getResults();
+                } else {
+                    error_msg = aoa.getErrorMsg();
+                }
+            }           
+        } 
+        catch (ServiceException | SQLException ex) {            
+            LOG.info(ex.getMessage());
+            error_msg += ex.getMessage();
+        } 
+        finally{
+            if ( this.statement != null ){
+                this.statement.close();
+                this.statement = null;
+            }
 
-            for (Input ip : components) {
-
-                query = "SELECT wqm_ilp FROM wqm_soil_pest_interaction_leaching WHERE wqm_plp='" + ip.getAi_plp() + "' AND wqm_slp='" + ip.getAoa_pslp() + "';";
-                resultSet = statement.executeQuery(query);
-                String op_pest_ilp = "err";
-                while (resultSet.next()) {
-                    op_pest_ilp = resultSet.getString("wqm_ilp");
-                }
-                if (ip.getAoa_rain_prob().equals("LOW")) {
-                    switch (op_pest_ilp) {
-                        case "HIGH":
-                            op_pest_ilp = "INTERMEDIATE";
-                            break;
-                        case "INTERMEDIATE":
-                            op_pest_ilp = "LOW";
-                            break;
-                        case "LOW":
-                            op_pest_ilp = "VERY LOW";
-                            break;
-                    }
-                }
-
-                query = "SELECT wqm_isrp FROM wqm_soil_pest_interaction_solution_runoff WHERE wqm_psrp='" + ip.getAi_psrp() + "' AND wqm_ssrp ='" + ip.getAoa_ssrp() + "';";
-                resultSet = statement.executeQuery(query);
-                String op_pest_isrp = "err";
-                while (resultSet.next()) {
-                    op_pest_isrp = resultSet.getString("wqm_isrp");
-                }
-                if (ip.getAoa_rain_prob().equals("LOW")) {
-                    switch (op_pest_isrp) {
-                        case "HIGH":
-                            op_pest_isrp = "INTERMEDIATE";
-                            break;
-                        case "INTERMEDIATE":
-                            op_pest_isrp = "LOW";
-                            break;
-                    }
-                }
-
-                query = "SELECT wqm_iarp FROM wqm_soil_pest_interaction_adsorbed_runoff WHERE wqm_parp='" + ip.getAi_parp() + "' AND wqm_sarp='" + ip.getAoa_sarp() + "';";
-                resultSet = statement.executeQuery(query);
-                String op_pest_iarp = "err";
-                while (resultSet.next()) {
-                    op_pest_iarp = resultSet.getString("wqm_iarp");
-                }
-                if (ip.getAoa_rain_prob().equals("LOW")) {
-                    switch (op_pest_iarp) {
-                        case "HIGH":
-                            op_pest_iarp = "INTERMEDIATE";
-                            break;
-                        case "INTERMEDIATE":
-                            op_pest_iarp = "LOW";
-                            break;
-                    }
-                }
-
-                Result result1 = new Result(ip.getAoaId(), ip.getOperationId(), ip.getPesticideId(), op_pest_ilp, op_pest_isrp, op_pest_iarp);
-                result.add(result1);
-            }
-        } catch (SQLException se) {
-            LOG.info("Did not open database for WQM-10!");
-            LOG.info(se.getMessage());
-        } finally {
-            if (statement != null) {
-                statement.close();
-            }
-            if (conn != null) {
-                conn.close();
+            if ( this.conn != null ){
+                this.conn.close();
+                this.conn = null;
             }
         }
-        return EXEC_OK;
+        
+        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 );
     }
 
     @Override
     //writing the results back to JSON
     protected void postProcess() throws Exception {
         JSONArray resultArr = new JSONArray();
-        for (Result rs1 : result) {
+
+        if (result != null){            
+            String currentOperationId = "";
+            Collections.sort( result ); 
+            
+            //Put out the AoA top line
+            putResult( "AoAId", result.get(0).getAoaId(), "Area of Analysis Identifier");
             JSONArray tmpArr = new JSONArray();
-            tmpArr.put(JSONUtils.dataDesc("AoAId", rs1.getAoaId(), "Area of Analysis Identifier"));
-            tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.getOperationId(), "Pesticide Application Operation Identifier"));
-            tmpArr.put(JSONUtils.dataDesc("op_pesticide_id", rs1.getOpPesticideId(), "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"));
-            tmpArr.put(JSONUtils.dataDesc("op_pest_ilp", rs1.getOpPestIlp(), "Operation Soil Pesticide Interaction Leaching Potential"));
-            tmpArr.put(JSONUtils.dataDesc("op_pest_isrp", rs1.getOpPestIsrp(), "Operation Soil Pesticide Interaction Solution Runoff Potential"));
-            tmpArr.put(JSONUtils.dataDesc("op_pest_iarp", rs1.getOpPestIarp(), "Operation Soil Pesticide Interaction Adsorbed Runoff Potential"));
-            resultArr.put(JSONUtils.dataDesc("pesticide summary", tmpArr, "Pest"));
+            JSONArray tmpArr2 = new JSONArray();
+            for (Result rs1 : result) {
+                if ( !rs1.getOperationId().equals(currentOperationId) ) {
+                    if ( !currentOperationId.isEmpty() ){
+                        currentOperationId = rs1.getOperationId();                                        
+                        //resultArr.put(JSONUtils.dataDesc("operation summary", tmpArr2, "Summary of this operation"));
+                        tmpArr.put( JSONUtils.dataDesc("pesticideList", tmpArr2, null) ); 
+
+                        tmpArr2 = new JSONArray();                     
+                        tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.getOperationId(), "Pesticide Application Operation Identifier"));
+                    }
+                    else {
+                        tmpArr2 = new JSONArray();
+                        currentOperationId = rs1.getOperationId();  
+                        tmpArr.put(JSONUtils.dataDesc("operation_id", rs1.getOperationId(), "Pesticide Application Operation Identifier"));                        
+                    }
+                }
+                 
+                JSONArray tmpArr3 = new JSONArray();                    
+                tmpArr3.put(JSONUtils.dataDesc("op_pesticide_id", rs1.getOpPesticideId(), "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"));
+                tmpArr3.put(JSONUtils.dataDesc("op_pest_ilp", rs1.getOpPestIlp(), "Operation Soil Pesticide Interaction Leaching Potential"));
+                tmpArr3.put(JSONUtils.dataDesc("op_pest_isrp", rs1.getOpPestIsrp(), "Operation Soil Pesticide Interaction Solution Runoff Potential"));
+                tmpArr3.put(JSONUtils.dataDesc("op_pest_iarp", rs1.getOpPestIarp(), "Operation Soil Pesticide Interaction Adsorbed Runoff Potential"));
+                
+                tmpArr2.put( tmpArr3 );
+            }
+            
+            tmpArr.put( JSONUtils.dataDesc("pesticideList", tmpArr2, "List of Pesticides") );
+            resultArr.put( tmpArr  );
+            putResult("operationList", resultArr);
         }
-        putResult("operation", resultArr);
     }
-}
+    
+    class AoA{
+        private final String AoAId;
+        private final String aoa_pslp;
+        private final String aoa_ssrp;
+        private final String aoa_sarp;
+        private final String aoa_rain_prob;
+        private ArrayList<pesticideOperation> pesticideOperationList;
+        private String error_msg;
+        ArrayList<Result> results;
+
+        AoA(String AoAId, String aoa_pslp, String aoa_ssrp, String aoa_sarp, String aoa_rain_prob, JSONArray operationList) {
+            error_msg = "";
+            this.AoAId = AoAId;
+            this.aoa_pslp = aoa_pslp;
+            this.aoa_ssrp = aoa_ssrp;
+            this.aoa_sarp = aoa_sarp;
+            this.aoa_rain_prob = aoa_rain_prob;            
+            pesticideOperationList = new ArrayList<>();
+            
+            //  Create pesticide operation list here...
+            try{
+                for (int i = 0; i < operationList.length(); i++) {
+                    Map<String, JSONObject> operation = JSONUtils.preprocess(operationList.getJSONArray(i));  
+                    
+                    pesticideOperationList.add( new pesticideOperation( JSONUtils.getStringParam(operation, "operation_id", "err"),this, JSONUtils.getJSONArrayParam(operation, "pesticidelist") ) );                    
+                }
+            }
+            catch( JSONException ex){
+                this.error_msg += ex.getMessage();                
+            }            
+        }
+
+        //Get Methods
+        public String getAoaId() {
+            return this.AoAId;
+        }
+
+        public String getAoa_pslp() {
+            return this.aoa_pslp;
+        }
+
+        public String getAoa_ssrp() {
+            return this.aoa_ssrp;
+        }
+
+        public String getAoa_sarp() {
+            return this.aoa_sarp;
+        }
+
+        public String getAoa_rain_prob() {
+            return this.aoa_rain_prob;
+        }
+        
+        public String getErrorMsg(){
+            return this.error_msg;
+        }
+                
+        
+        public Boolean calculate(){
+            Boolean ret_val = true;
+            
+            for( pesticideOperation pesticides : pesticideOperationList ){
+                if ( !pesticides.calculate() ){
+                    ret_val = false;
+                    this.error_msg = pesticides.getError();
+                    break;
+                }
+            }
+            
+            return ret_val;
+        }
+        
+        public ArrayList<Result> getResults(){
+            this.results = new ArrayList<>();
+            
+            for( pesticideOperation pOperation : pesticideOperationList ){
+                this.results = pOperation.getResult( this.results );
+            }
+                
+            return this.results;
+        }
+    }
+    
+    class pesticideOperation {
+        private final String operation_id;
+        private final AoA aoa;
+        private ArrayList<pesticide> pesticideList;
+        private String error_msg = "";
+        
+        pesticideOperation( String operation_id, AoA aoa, JSONArray pesticides ) {
+            this.operation_id = operation_id;
+            this.aoa = aoa;
+            pesticideList = new ArrayList<>();
+            
+            try{     
+            
+                for (int i = 0; i < pesticides.length(); i++) {
+                    Map<String, JSONObject> pesticidesData = JSONUtils.preprocess(pesticides.getJSONArray(i));
+                    pesticideList.add( new pesticide(   JSONUtils.getStringParam(pesticidesData, "op_pesticide_id", "err"), 
+                                                        JSONUtils.getStringParam(pesticidesData, "ai_plp", "err"),
+                                                        JSONUtils.getStringParam(pesticidesData, "ai_psrp", "err"),
+                                                        JSONUtils.getStringParam(pesticidesData, "ai_parp", "err") ) );                                
+                }
+            }
+            catch( JSONException ex ){
+                this.error_msg = ex.getMessage();
+            }
+        }
+        
+        String getError(){
+            return this.error_msg;
+        }
+        
+        Boolean calculate(){
+            Boolean ret_val = true;
+            
+            for ( pesticide pst: pesticideList ){
+                String tResult = pst.getILP() + " " + pst.getISRP() +  " " + pst.getIARP();
+                if ( ( tResult.contains("ERROR") ) || (tResult.contains("err")) ){
+                    ret_val = false;
+                    this.error_msg += "  For operation: " + this.operation_id + ", " + pst.getErrorMsg();
+                    break;
+                }  
+            }
+            
+            return ret_val;
+        }
+        
+        ArrayList<Result> getResult( ArrayList<Result> results ){
+            
+            for( pesticideOperation.pesticide pesticide : this.pesticideList ){
+                results.add( pesticide.getResult() );
+            }
+            
+            return results;
+        }
+        
+        class pesticide{
+            private final String op_pesticide_id;
+            private final String ai_plp;
+            private final String ai_psrp;
+            private final String ai_parp;
+            private String error_msg = "";
+            private String op_pest_ilp = "ERROR";
+            private String op_pest_isrp = "ERROR";            
+            private String op_pest_iarp = "ERROR";
+
+            
+            pesticide(String op_pesticide_id, String ai_plp, String ai_psrp, String ai_parp){
+                  this.op_pesticide_id = ("err".equals(op_pesticide_id)? (this.error_msg="Pesticide Id invalid or missing"):op_pesticide_id);
+                  this.ai_plp = ("err".equals(ai_plp)? (this.error_msg="Active Ingredient Pesticide Leaching Potential invalid or missing"):ai_plp);
+                  this.ai_psrp = ("err".equals(ai_psrp)? (this.error_msg="Active Ingredient Pesticide Solution Runoff Potential invalid or missing"):ai_psrp);
+                  this.ai_parp = ("err".equals(ai_parp)? (this.error_msg="Active Ingredient Pesticide Adsorbed Runoff Potential invalid or missing"):ai_parp);                                                          
+            }
+            
+            String getILP(){
+                if ("ERROR".equals(op_pest_ilp) ){
+                //Calculate it
+                    ResultSet resultSet;
+                    String query = "SELECT wqm_ilp FROM wqm_soil_pest_interaction_leaching WHERE wqm_plp='" + ai_plp + "' AND wqm_slp='" + aoa.getAoa_pslp() + "';";
+                    try{
+                        resultSet = statement.executeQuery(query);
+                        if ( resultSet.first() ) {
+                            op_pest_ilp = resultSet.getString("wqm_ilp");
+                        }
+                        else {
+                            this.error_msg += "For pesticide: " + this.op_pesticide_id + ", Cannot find that ai_plp and aoa_pslp combination in the database.";
+                        }
+                        
+                        if ( "LOW".equals(aoa.getAoa_rain_prob()) ) {
+                            switch (op_pest_ilp) {
+                                case "HIGH":
+                                    op_pest_ilp = "INTERMEDIATE";
+                                    break;
+                                case "INTERMEDIATE":
+                                    op_pest_ilp = "LOW";
+                                    break;
+                                case "LOW":
+                                    op_pest_ilp = "VERY LOW";
+                                    break;
+                            }
+                        }                                                
+                    }
+                    catch( SQLException se ){
+                        this.error_msg += se.getMessage();                        
+                    }
+                }
+                
+                return op_pest_ilp;
+            }
+            
+            String getISRP(){
+                if ("ERROR".equals(op_pest_isrp) ){
+                //Calculate it
+                    ResultSet resultSet;
+                    String query = "SELECT wqm_isrp FROM wqm_soil_pest_interaction_solution_runoff WHERE wqm_psrp='" + ai_psrp + "' AND wqm_ssrp ='" + aoa.getAoa_ssrp() + "';";
+                    try{
+                        resultSet = statement.executeQuery(query);
+                        op_pest_isrp = "err";
+                        if  (resultSet.first()) {
+                            op_pest_isrp = resultSet.getString("wqm_isrp");
+                        }
+                        else {
+                            this.error_msg += "For pesticide: " + this.op_pesticide_id + ", Cannot find that ai_psrp and aoa_ssrp combination in the database.";
+                        }                        
+                        
+                        if ( "LOW".equals(aoa.getAoa_rain_prob()) ) {
+                            switch (op_pest_isrp) {
+                                case "HIGH":
+                                    op_pest_isrp = "INTERMEDIATE";
+                                    break;
+                                case "INTERMEDIATE":
+                                    op_pest_isrp = "LOW";
+                                    break;
+                                                                        
+                                /*case "LOW":
+                                    op_pest_isrp = "LOW";
+                                    break;\
+                                */
+                            }
+                        }
+                    }
+                    catch( SQLException se ){
+                        this.error_msg += se.getMessage();
+                    }
+                   
+                }
+                                
+                return op_pest_isrp;
+            }
+            
+            String getIARP(){
+                if ("ERROR".equals(op_pest_iarp) ){
+                //Calculate it
+                    ResultSet resultSet;
+                    String query = "SELECT wqm_iarp FROM wqm_soil_pest_interaction_adsorbed_runoff WHERE wqm_parp='" + ai_parp + "' AND wqm_sarp='" + aoa.getAoa_sarp() + "';";
+                    try{
+                        resultSet = statement.executeQuery(query);
+                        op_pest_iarp = "err";
+                        if ( resultSet.first() ) {
+                            op_pest_iarp = resultSet.getString("wqm_iarp");
+                        }
+                        else {
+                            this.error_msg += "For pesticide: " + this.op_pesticide_id + ", Cannot find that ai_parp and aoa_sarp combination in the database.";
+                        }
+                        
+                        if ( "LOW".equals( aoa.getAoa_rain_prob() )) {
+                            switch (op_pest_iarp) {
+                                case "HIGH":
+                                    op_pest_iarp = "INTERMEDIATE";
+                                    break;
+                                case "INTERMEDIATE":
+                                    op_pest_iarp = "LOW";
+                                    break;
+                                    
+                                /*case "LOW":
+                                    op_pest_iarp = "VERY LOW";
+                                    break;                                    
+                                */
+                            }
+                        }
+                    }
+                    catch( SQLException Se ){
+                        this.error_msg += Se.getMessage();
+                    }
+                }
+                                
+                return op_pest_iarp;
+            }
+            
+            String getErrorMsg(){
+                return this.error_msg;
+            }
+                    
+            Result getResult(){
+                Result result = new Result( aoa.getAoaId(), operation_id, op_pesticide_id, op_pest_ilp, op_pest_isrp, op_pest_iarp );
+                return result;            
+            }            
+        }                
+    }
+    class Result implements Comparable<Result>{
+
+           private final String AoAId;
+           private final String operation_id;
+           private final String op_pesticide_id;
+           private final String op_pest_ilp;
+           private final String op_pest_isrp;
+           private final String op_pest_iarp;
+
+           Result(String AoAId, String operation_id, String op_pesticide_id, String op_pest_ilp, String op_pest_isrp, String op_pest_iarp) {
+               this.AoAId = AoAId;
+               this.operation_id = operation_id;
+               this.op_pesticide_id = op_pesticide_id;
+               this.op_pest_ilp = op_pest_ilp;
+               this.op_pest_isrp = op_pest_isrp;
+               this.op_pest_iarp = op_pest_iarp;
+           }
+
+           public String getAoaId() {
+               return this.AoAId;
+           }
+
+           public String getOperationId() {
+               return this.operation_id;
+           }
+
+           public String getOpPesticideId() {
+               return this.op_pesticide_id;
+           }
+
+           public String getOpPestIlp() {
+               return this.op_pest_ilp;
+           }
+
+           public String getOpPestIsrp() {
+               return this.op_pest_isrp;
+           }
+
+           public String getOpPestIarp() {
+               return this.op_pest_iarp;
+           }
+
+           @Override
+           public int compareTo( Result rs ){           
+               return this.getOperationId().compareTo(rs.getOperationId());
+           }        
+    }              
+}  
+

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

@@ -1,320 +1,201 @@
 {
     "metainfo": {
     },
-    "parameter": [
+    "parameter": [        
         {
-            "name": "components",
-            "value": [
+            "name": "AoAId",
+            "value": 1,
+            "Description": "Area of analysis identifier"
+        },
+        {
+            "name": "aoa_pslp",
+            "value": "LOW",
+            "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
+        },
+        {
+            "name": "aoa_ssrp",
+            "value": "HIGH",
+            "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
+        },
+        {
+            "name": "aoa_sarp",
+            "value": "LOW",
+            "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
+        },        
+        {
+            "name": "aoa_rain_prob",
+            "value": "HIGH",
+            "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
+        },
+        {
+            "name": "operationlist",
+            "value":[
                 [
-                    {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
+                    {                    
                         "name": "operation_id",
                         "value": 1,
                         "Description": "Pesticide Application Operation Identifier"
                     },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "101101",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "LOW",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "INTERMEDIATE",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
+                    {    
+                        "name": "pesticidelist",
+                        "value": [
+                            [
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "101101",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "LOW",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "INTERMEDIATE",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }                   
+                            ],
+                            [
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "101702",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "INTERMEDIATE",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "LOW",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }
+                            ] 
+                        ]        
                     }
                 ],
                 [
                     {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
-                        "name": "operation_id",
-                        "value": 1,
-                        "Description": "Pesticide Application Operation Identifier"
-                    },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "101702",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "INTERMEDIATE",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "LOW",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
                         "name": "operation_id",
                         "value": 2,
                         "Description": "Pesticide Application Operation Identifier"
                     },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "102301",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
+                    {    
+                        "name": "pesticidelist",
+                        "value": [
+                            [                    
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "102301",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }
+                            ],
+                            [
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "101101",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "LOW",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "INTERMEDIATE",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }
+                            ]
+                        ]
                     }
                 ],
                 [
                     {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
-                        "name": "operation_id",
-                        "value": 2,
-                        "Description": "Pesticide Application Operation Identifier"
-                    },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "101101",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "LOW",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "INTERMEDIATE",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
                         "name": "operation_id",
                         "value": 3,
                         "Description": "Pesticide Application Operation Identifier"
                     },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "102301",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "INTERMEDIATE",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
-                    }
-                ],
-                [
-                    {
-                        "name": "AoAId",
-                        "value": 1,
-                        "Description": "Area of analysis identifier"
-                    },
-                    {
-                        "name": "operation_id",
-                        "value": 3,
-                        "Description": "Pesticide Application Operation Identifier"
-                    },
-                    {
-                        "name": "op_pesticide_id",
-                        "value": "101101",
-                        "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
-                    },
-                    {
-                        "name": "ai_plp",
-                        "value": "HIGH",
-                        "Description": "Active Ingredient Pesticide Leaching Potential"
-                    },
-                    {
-                        "name": "ai_psrp",
-                        "value": "LOW",
-                        "Description": "Active Ingredient Pesticide Solution Runoff Potential"
-                    },
-                    {
-                        "name": "ai_parp",
-                        "value": "INTERMEDIATE",
-                        "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
-                    },
-                    {
-                        "name": "aoa_pslp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Leaching Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_ssrp",
-                        "value": "HIGH",
-                        "Description": "Soil Pesticide Solution Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_sarp",
-                        "value": "LOW",
-                        "Description": "Soil Pesticide Adsorbed Runoff Potential for the Area of Analysis"
-                    },
-                    {
-                        "name": "aoa_rain_prob",
-                        "value": "HIGH",
-                        "Description": "Probability Rain Impacts Pesticide Soil Interaction Rating"
+                    {    
+                        "name": "pesticidelist",
+                        "value": [
+                            [                            
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "102301",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "INTERMEDIATE",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }
+                            ],
+                            [
+                                {
+                                    "name": "op_pesticide_id",
+                                    "value": "101101",
+                                    "Description": "Pesticide identifier, EPA Pesticide Chemical Code (PC_CODE)"
+                                },
+                                {
+                                    "name": "ai_plp",
+                                    "value": "HIGH",
+                                    "Description": "Active Ingredient Pesticide Leaching Potential"
+                                },
+                                {
+                                    "name": "ai_psrp",
+                                    "value": "LOW",
+                                    "Description": "Active Ingredient Pesticide Solution Runoff Potential"
+                                },
+                                {
+                                    "name": "ai_parp",
+                                    "value": "INTERMEDIATE",
+                                    "Description": "Active Ingredient Pesticide Adsorbed Runoff Potential"
+                                }
+                            ]
+                        ]
                     }
                 ]
             ]

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

@@ -1,63 +1,84 @@
 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")
-@Description("Computation of  WQM Concern Treatment Level Threshold Scores for an Area of Analysis")
+@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.")
 @Path("m/thresholdscores/1.0")
 
 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/postgres", "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,6 +3,7 @@
 /**
  *
  * @author RUMPAL SIDHU
+ * @author Shaun Case
  */
 import oms3.annotations.*;
 import csip.ModelDataService;
@@ -10,179 +11,783 @@
 import csip.utils.JSONUtils;
 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;
 import java.util.ArrayList;
+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.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
 
-@Name("WQM 2:")
-@Description("Soil Component Attributes")
+/**
+ *
+ * @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 = JDBC_TYPE + HOST + ":" + PORT + "/" + 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";        
 
     //Request
-    private int aoaId;
-    private String aoaGeometry;
+    private String aoaId;
+    private JSONObject aoaGeometry;
 
     //Response
-    private ArrayList<Component> componentList;
+    private ArrayList<V1_0.Component> componentList;
+    private HashMap<String, V1_0.Component> componentMap;
 
+    private String error_msg = "";
+    private Connection conn = null;
+    private Statement statement = null; 
+    private V1_0.ServiceCall intersectCall = null;
+    
     @Override
     protected void preProcess() throws Exception {
-        aoaId = getIntParam("AoAId");
-        aoaGeometry = getJSONParam("aoa_geometry").toString();
+        this.error_msg = "";
+        
+        JSONArray request = getRequest().optJSONArray("parameter");
+        
+        if ( JSONUtils.checkKeyExistsB( JSONUtils.preprocess(request), "AoAId") ){
+            this.aoaId = getStringParam("AoAId");
+            //Get the entire aoa_geometry group as it matches the input payload for the ServiceCall class
+            this.aoaGeometry = getJSONParam("aoa_geometry");
+            this.intersectCall = new ServiceCall( this.SSURGO_INTERSECT_URI );            
+            
+            try {
+                this.conn = wqm.utils.WQMTools.getConnection( "ssurgo", LOG );
+                this.statement = this.conn.createStatement();
+
+            } catch (SQLException se) {
+                LOG.info("Did not open database for WQM-02");
+                LOG.info(se.getMessage());
+                this.error_msg = "Could not open the database connection required. ";
+            }                                     
+        }
+        else{
+            //  No valid input stream for this service
+            this.error_msg = "No valid input parameters were found.  Check your input JSON.";
+        }                 
     }
 
     @Override
-    protected String process() throws Exception {
-        Connection conn = null;
-        Statement statement = null;
-        ResultSet resultSet;
-        String query;
-        componentList = new ArrayList();
+    protected String process() throws Exception {       
+        if ( ( null != this.intersectCall ) && ( !this.intersectCall.getError() ) ){
+            HashMap<String, Double> aoa_mukeyList;               
+            aoa_mukeyList = this.intersectCall.intersect( this.aoaGeometry );
+            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 = "(";
 
-        HashMap<String, Double> aoa_mukeyList = new ServiceCall().intersect(aoaGeometry);
+                    Set keys = aoa_mukeyList.keySet();                                                
+                    Iterator ite = keys.iterator();
 
-        try {
-            Class.forName(CLASS_NAME);
-            conn = DriverManager.getConnection(CONNECTION, USER, PASS);
-            conn.setAutoCommit(false);
-            statement = conn.createStatement();
+                    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='";
 
-            Set keys = aoa_mukeyList.keySet();
-            Iterator ite = keys.iterator();
-            while (ite.hasNext()) {
-                String mukey = ite.next().toString();
-                double aoaArea = (Double) 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;";
-                resultSet = 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"));
-                    componentList.add(component);
-                }
-            }
+                    while (ite.hasNext()) {
+                        if ( mapCount > 0 ){
+                            query += " OR ssurgo.component.mukey='" + ite.next().toString() + "' ";
+                        }
+                        else{
+                            query += ite.next().toString() + "' ";
+                        }   
 
-            //For each soil component (cokey) in the AoA
-            for (Component component : 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"));
-                }
+                        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() ){
+                        V1_0.Component tComponent;
+                        V1_0.Component component;
 
-                //#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 = 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();
+                        String mukey = resultSet.getString( "mukey");                 
+                        String cokey = resultSet.getString("cokey");  
+                        String chkey = resultSet.getString("chkey"); 
 
-                    if (!kwfact_b || !kffact_b) {
-                        if (!kffact_b) {
-                            aoa_comp_kfact = kffact;
-                        } else {
-                            aoa_comp_kfact = kwfact;
+                        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 );
                         }
 
-                        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 = statement.executeQuery(query2);
-                        while (resultSet2.next()) {
-                            component.setCoarseFrag(resultSet2.getInt("fragvol_r"));
+                        //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() + "'";
+                            }                        
+                        }                                        
+                    }                
 
-                        check = true;
-                        break;
+                    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") );
+                        }                                                    
                     }
-                }
-
-                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 = 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 = statement.executeQuery(query2);
-                        while (resultSet2.next()) {
-                            component.setCoarseFrag(resultSet2.getInt("fragvol_r"));
-                        }
-                        break;
-                    }
-                }
+                } // Actual Intersect Call failed.
+                else{
+                    this.error_msg += " Could not intersect polygons. ";
+                }    
             }
-
-        } catch (SQLException se) {
-            LOG.info("Did not open database for GRAS-16f!");
-            LOG.info(se.getMessage());
-        } finally {
-            if (statement != null) {
-                statement.close();
+            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();                
             }
-            if (conn != null) {
-                conn.close();
-            }
+            this.conn.close();                
         }
-        return EXEC_OK;
+        return ( !this.error_msg.isEmpty()? this.error_msg : EXEC_OK );
     }
 
     @Override
     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
+
+    /**
+     *
+     */
+            
+
+    public class ServiceCall {
+
+        private HashMap<String, Double> aoa_mukeyList;
+        private final String URI;
+        private final csip.Client newClient;
+        private String error_msg;    
+
+        ServiceCall( String URI ){
+            this.URI = URI;
+            this.error_msg = "";
+            this.aoa_mukeyList = new HashMap();
+            this.newClient = new csip.Client();   
+            if ( this.URI.isEmpty() ){
+                this.error_msg = "SSURGO mapunit Intersect URI is empty.";
+            }
+        }
+
+        /*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{            
+                    JSONObject result;
+                    result = this.newClient.doPOST( this.URI, this.createRequest( aoaGeometry ) );                 
+                    if  (( null == result ) || ( result.length() <= 0 ) ){
+                        this.error_msg += " No data was returned from " + URI + " for this request. "; 
+                    }
+                    else{
+                        //Process result information
+                        JSONArray intersectResult = result.optJSONArray("result");
+                        
+                        if  (intersectResult.length() > 0 ){
+                            HashMap<String, Double> tempMap = new HashMap<>();                
+                            String mukey;
+                            double aoaArea;
+                            ArrayList<String> keys = new ArrayList<String>();
+                            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 = 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);
+                                }
+                            }  
+
+                            Collections.sort(keys);
+                            for (String i : keys) {
+                                this.aoa_mukeyList.put(i, tempMap.get(i));
+                            }                               
+                        }
+                        else{
+                            //  Check this:  Is this an error or does it just mean that no intersects are found??
+                            this.error_msg += " No returned data was found in the result section from the SSURGO mapunit polygon intersect call. ";
+                        }                                         
+                    }
+                }
+                catch (Exception ex) {
+                    this.error_msg += " Cannot make a connection to that location: " + URI + ".  " + ex.getMessage();
+                }               
+            }
+
+            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 headerArray;
+           JSONObject metainfo;
+
+           metainfo = new JSONObject();
+           ret_val = new JSONObject();
+           headerArray = new JSONArray();       
+
+           metainfo.put( "MultipartRequest", "mapunit intersect request WQM-02");
+           metainfo.put( "OriginalSource", getRequestHost() );
+           metainfo.put( "OriginalRequest", getRequestURL() );
+           metainfo.put( "OriginalSUID", getSUID() );
+           ret_val.put("metainfo", metainfo );                     
+
+           headerArray.put(JSONUtils.dataDesc( "AoAI", aoaGeometry, null ) );
+
+           ret_val.put( "parameter", headerArray);           
+
+           return ret_val;          
+        }                        
+    }
+
+    /**
+     *
+     */
+    public class Component {
+
+        private String cokey; //Soil Component Key
+        private String name; //Soil Component Name
+        private double area; //Soil Component Area (Acres) in the Area of Analysis
+        private String hsg; //Hydrologic Soil Group of the Soil Component
+        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 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;
+
+        /**
+         *
+         * @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 );                                   
+        }
+
+        //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;
+        }
+
+        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;
+        }
+
+        /**
+         *
+         * @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

@@ -26,36 +26,41 @@
  * @author Sandeep
  */
 
-@Name("WQM-1")
-@Description("Water Quality Sensitivity Rating")
+@Name("WQM-01: Water Quality Sensitivity Rating (WQSR)")
+@Description("This service intersects area of analysis (AoA) geometry with the NRCS Water Quality Sensitivity Rating (WQSR) spatial layer and computes a sensitivity rating and treatment level required for mitigating nutrient and pesticide loss potentials and hazards.")
 @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();
          
@@ -139,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: 0.1.23 c6fa25b6a133 2015-07-28 $"
-}
+
+  "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: ${out} $"
+}