/**
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* The Original Code is OpenELIS code.
*
* Copyright (C) The Minnesota Department of Health. All Rights Reserved.
*
* Contributor(s): CIRG, University of Washington, Seattle WA.
*/
package us.mn.state.health.lims.common.provider.query;
import org.apache.commons.validator.GenericValidator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import us.mn.state.health.lims.analysis.dao.AnalysisDAO;
import us.mn.state.health.lims.analysis.daoimpl.AnalysisDAOImpl;
import us.mn.state.health.lims.analysis.valueholder.Analysis;
import us.mn.state.health.lims.common.services.TestService;
import us.mn.state.health.lims.common.servlet.validation.AjaxServlet;
import us.mn.state.health.lims.dictionary.daoimpl.DictionaryDAOImpl;
import us.mn.state.health.lims.dictionary.valueholder.Dictionary;
import us.mn.state.health.lims.result.dao.ResultDAO;
import us.mn.state.health.lims.result.daoimpl.ResultDAOImpl;
import us.mn.state.health.lims.result.valueholder.Result;
import us.mn.state.health.lims.sample.daoimpl.SampleDAOImpl;
import us.mn.state.health.lims.sample.valueholder.Sample;
import us.mn.state.health.lims.test.valueholder.Test;
import us.mn.state.health.lims.testreflex.action.util.TestReflexUtil;
import us.mn.state.health.lims.testreflex.dao.TestReflexDAO;
import us.mn.state.health.lims.testreflex.daoimpl.TestReflexDAOImpl;
import us.mn.state.health.lims.testreflex.valueholder.TestReflex;
import us.mn.state.health.lims.testresult.dao.TestResultDAO;
import us.mn.state.health.lims.testresult.daoimpl.TestResultDAOImpl;
import us.mn.state.health.lims.testresult.valueholder.TestResult;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.util.*;
public class TestReflexUserChoiceProvider extends BaseQueryProvider {
private static final String ID_SEPERATOR = ",";
protected AjaxServlet ajaxServlet = null;
private static final AnalysisDAO ANALYSIS_DAO = new AnalysisDAOImpl();
private static final TestReflexDAO TEST_REFLEX_DAO = new TestReflexDAOImpl();
private static final TestResultDAO TEST_RESULT_DAO = new TestResultDAOImpl();
private static final ResultDAO RESULT_DAO = new ResultDAOImpl();
@Override
public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String resultIds = request.getParameter("resultIds");
String analysisIds = request.getParameter("analysisIds");
String testIds = request.getParameter("testIds");
String rowIndex = request.getParameter("rowIndex");
String accessionNumber = request.getParameter("accessionNumber");
String jResult;
JSONObject jsonResult =new JSONObject();
String jString;
if (GenericValidator.isBlankOrNull(resultIds) ||
GenericValidator.isBlankOrNull(testIds) ||
GenericValidator.isBlankOrNull(rowIndex) ||
(GenericValidator.isBlankOrNull(analysisIds) && GenericValidator.isBlankOrNull(accessionNumber))) {
jResult = INVALID;
jString = "Internal error, please contact Admin and file bug report";
} else {
jResult = createJsonTestReflex( resultIds, analysisIds, testIds, accessionNumber, rowIndex, jsonResult );
StringWriter out = new StringWriter();
try{
jsonResult.writeJSONString( out );
jString = out.toString();
}catch( IOException e ){
e.printStackTrace();
jResult = INVALID;
jString = "Internal error, please contact Admin and file bug report";
}
}
ajaxServlet.sendData(jString, jResult, request, response);
}
private String createJsonTestReflex( String resultIds, String analysisIds, String testIds, String accessionNumber, String rowIndex, JSONObject jsonResult ){
TestReflexUtil reflexUtil = new TestReflexUtil();
String[] resultIdSeries = resultIds.split(ID_SEPERATOR);
/*
* Here's the deal. If the UC test reflex has both an add_test_id and a
* scriptlet_id then we are done. If it has only one Then we need to
* look for the other
*/
ArrayList<TestReflex> selectableReflexes = new ArrayList<TestReflex>( );
HashSet<String> reflexTriggers = new HashSet<String>( );
HashSet<String> reflexTriggerIds = new HashSet<String>( );
// Both test given results on client
if (resultIdSeries.length > 1) {
/* String[] testIdSeries = testIds.split(ID_SEPERATOR);
List<TestReflex> testReflexesForResultOne = reflexUtil.getTestReflexsForDictioanryResultTestId(resultIdSeries[0],
testIdSeries[0], true);
if (!testReflexesForResultOne.isEmpty()) {
List<TestReflex> sibTestReflexList = reflexUtil.getTestReflexsForDictioanryResultTestId(resultIdSeries[1],
testIdSeries[1], true);
boolean allChoicesFound = false;
for (TestReflex reflexFromResultOne : testReflexesForResultOne) {
for (TestReflex sibReflex : sibTestReflexList) {
if (areSibs(reflexFromResultOne, sibReflex)
&& TestReflexUtil.isUserChoiceReflex( reflexFromResultOne )) {
if (reflexFromResultOne.getActionScriptlet() != null) {
testReflexOne = reflexFromResultOne;
allChoicesFound = true;
break;
} else if (testReflexOne == null) {
testReflexOne = reflexFromResultOne;
} else {
testReflexTwo = reflexFromResultOne;
allChoicesFound = true;
break;
}
}
if (allChoicesFound) {
break;
}
}
}
}
*/ // One test given results on client, the other is in the DB
} else {
// for each reflex we are going to try and find a sibling reflex
// which is currently satisfied
// get their common sample
Sample sample = getSampleForKnownTest(analysisIds, accessionNumber, ANALYSIS_DAO );
Dictionary dictionaryResult = new DictionaryDAOImpl().getDictionaryById( resultIds );
List<Analysis> analysisList = ANALYSIS_DAO.getAnalysesBySampleId( sample.getId() );
List<TestReflex> candidateReflexList = reflexUtil.getTestReflexsForDictioanryResultTestId(resultIds, testIds, true);
for (TestReflex candidateReflex : candidateReflexList) {
if (TestReflexUtil.isUserChoiceReflex( candidateReflex )) {
if (GenericValidator.isBlankOrNull( candidateReflex.getSiblingReflexId() )) {
selectableReflexes.add( candidateReflex );
reflexTriggers.add( TestService.getUserLocalizedTestName( candidateReflex.getTest() ) + ":" + dictionaryResult.getDictEntry() );
// reflexTriggerIds.add( candidateReflex.getTest().getId() );
} else {
// find if the sibling reflex is satisfied
TestReflex sibTestReflex = new TestReflex();
sibTestReflex.setId(candidateReflex.getSiblingReflexId() );
TEST_REFLEX_DAO.getData( sibTestReflex );
TestResult sibTestResult = new TestResult();
sibTestResult.setId(sibTestReflex.getTestResultId());
TEST_RESULT_DAO.getData( sibTestResult );
for (Analysis analysis : analysisList) {
List<Result> resultList = RESULT_DAO.getResultsByAnalysis( analysis );
Test test = analysis.getTest();
for (Result result : resultList) {
TestResult testResult = TEST_RESULT_DAO.getTestResultsByTestAndDictonaryResult( test.getId(),
result.getValue() );
if (testResult != null && testResult.getId().equals(sibTestReflex.getTestResultId())) {
selectableReflexes.add(candidateReflex);
reflexTriggers.add( TestService.getUserLocalizedTestName( candidateReflex.getTest() ) + ":" + dictionaryResult.getDictEntry() );
// reflexTriggerIds.add( candidateReflex.getTest().getId() );
}
}
}
}
}
}
}
if ( selectableReflexes.size() > 1) {
jsonResult.put( "rowIndex", rowIndex );
createTriggerList( reflexTriggers, resultIds, jsonResult);
createChoiceElement(selectableReflexes, jsonResult);
createPlaceholderForSelectedReflexes(jsonResult) ;
return VALID;
}
return INVALID;
}
private void createPlaceholderForSelectedReflexes( JSONObject jsonResult ){
jsonResult.put( "selected", new JSONArray());
}
private void createTriggerList( HashSet<String> reflexTriggers, String reflexTriggerIds, JSONObject jsonResult ){
StringBuilder triggers = new StringBuilder( );
for( String trigger : reflexTriggers){
triggers.append( trigger );
triggers.append( "," );
}
jsonResult.put( "triggers", triggers.deleteCharAt( triggers.length() -1 ).toString() );
triggers = new StringBuilder( );
String[] sortedTriggerIds = reflexTriggerIds.split( "," );
Arrays.sort( sortedTriggerIds);
for( String trigger : sortedTriggerIds){
triggers.append( trigger.trim() );
triggers.append( "_" );
}
jsonResult.put( "triggerIds", triggers.deleteCharAt( triggers.length() -1 ).toString() );
}
private Sample getSampleForKnownTest(String analysisIds, String accessionNumber, AnalysisDAO analysisDAO) {
//We use the analysisId for logbook results and accessionNumber for analysis results, we should accessionNumber for both.
if( GenericValidator.isBlankOrNull(analysisIds)){
return new SampleDAOImpl().getSampleByAccessionNumber(accessionNumber);
}else{
Analysis knownAnalysis = new Analysis();
knownAnalysis.setId(analysisIds);
analysisDAO.getData(knownAnalysis);
return knownAnalysis.getSampleItem().getSample();
}
}
private boolean areSibs(TestReflex testReflex, TestReflex sibTestReflex) {
return !GenericValidator.isBlankOrNull(testReflex.getSiblingReflexId())
&& !GenericValidator.isBlankOrNull(sibTestReflex.getSiblingReflexId())
&& testReflex.getSiblingReflexId().equals(sibTestReflex.getId())
&& sibTestReflex.getSiblingReflexId().equals(testReflex.getId());
}
private void createChoiceElement(List<TestReflex> reflexList, JSONObject jsonResult) {
JSONArray jsonArray = new JSONArray();
for(TestReflex reflex : reflexList){
if( reflex.getActionScriptlet() != null){
JSONObject selectionObject = new JSONObject();
selectionObject.put( "name", TestReflexUtil.makeReflexScriptName( reflex ) );
selectionObject.put( "value", TestReflexUtil.makeReflexScriptValue( reflex ));
jsonArray.add( selectionObject );
}
if(reflex.getAddedTest() != null){
JSONObject selectionObject = new JSONObject();
selectionObject.put( "name", TestReflexUtil.makeReflexTestName( reflex ) );
selectionObject.put( "value", TestReflexUtil.makeReflexTestValue( reflex ));
jsonArray.add( selectionObject );
}
}
jsonResult.put( "selections", jsonArray );
}
@Override
public void setServlet(AjaxServlet as) {
this.ajaxServlet = as;
}
@Override
public AjaxServlet getServlet() {
return this.ajaxServlet;
}
}