tds.student.sql.repository.ResponseRepository.java Source code

Java tutorial

Introduction

Here is the source code for tds.student.sql.repository.ResponseRepository.java

Source

/*******************************************************************************
 * Educational Online Test Delivery System 
 * Copyright (c) 2014 American Institutes for Research
 *     
 * Distributed under the AIR Open Source License, Version 1.0 
 * See accompanying file AIR-License-1_0.txt or at
 * http://www.smarterapp.org/documents/American_Institutes_for_Research_Open_Source_Software_License.pdf
 ******************************************************************************/
package tds.student.sql.repository;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import tds.dll.api.ICommonDLL;
import tds.dll.api.IStudentDLL;
import tds.student.performance.services.StudentInsertItemsService;
import tds.student.sql.abstractions.IResponseRepository;
import tds.student.sql.data.AdaptiveGroup;
import tds.student.sql.data.AdaptiveItem;
import tds.student.sql.data.IItemResponseUpdate;
import tds.student.sql.data.OpportunityInstance;
import tds.student.sql.data.OpportunityItem;
import tds.student.sql.data.OpportunityItem.OpportunityItems;
import AIR.Common.Configuration.AppSettings;
import AIR.Common.DB.AbstractDAO;
import AIR.Common.DB.SQLConnection;
import AIR.Common.DB.results.DbResultRecord;
import AIR.Common.DB.results.MultiDataResultSet;
import AIR.Common.DB.results.SingleDataResultSet;
import AIR.Common.TDSLogger.ITDSLogger;
import TDS.Shared.Data.ReturnStatus;
import TDS.Shared.Exceptions.ReturnStatusException;

/**
 * @author temp_rreddy
 * 
 */
@Component
@Scope("prototype")
public class ResponseRepository extends AbstractDAO implements IResponseRepository {
    private static final Logger _logger = LoggerFactory.getLogger(SessionRepository.class);

    private static final Float MS_TO_SECS_DIVISOR = 1000F;

    @Autowired
    private ICommonDLL _commonDll = null;
    @Autowired
    private IStudentDLL _studentDll = null;
    @Autowired
    private ITDSLogger _tdsLogger;

    @Autowired
    private StudentInsertItemsService studentInsertItemsService;

    public ResponseRepository() {
        super();
    }

    public void setiCommonDLL(ICommonDLL _dll) {
        _commonDll = _dll;
    }

    public void setiStudentDLL(IStudentDLL _dll) {
        _studentDll = _dll;
    }

    public OpportunityItems insertItems(OpportunityInstance oppInstance, AdaptiveGroup adaptiveGroup, boolean isMsb)
            throws ReturnStatusException {
        // create item keys delimited string
        OpportunityItems opportunityItems = new OpportunityItem().new OpportunityItems();

        String itemKeys = getItemKeys(adaptiveGroup.getItems());
        //    String itemKeys = null;
        try (SQLConnection connection = getSQLConnection()) {

            // Original call to insert items.
            // MultiDataResultSet resultSets = _studentDll.T_InsertItems_SP (connection, oppInstance.getKey (), oppInstance.getSessionKey (), oppInstance.getBrowserKey (), adaptiveGroup.getSegmentPosition (),
            //    adaptiveGroup.getSegmentID (), adaptiveGroup.getPage (), adaptiveGroup.getGroupID (), itemKeys, '|', new Integer (adaptiveGroup.getNumItemsRequired ()), new Float (0), new Integer (0),
            //    false);

            // New insert items method to improve performance.  See comments in module for further details.
            MultiDataResultSet resultSets = studentInsertItemsService.insertItems(connection, oppInstance.getKey(),
                    oppInstance.getSessionKey(), oppInstance.getBrowserKey(), adaptiveGroup.getSegmentPosition(),
                    adaptiveGroup.getSegmentID(), adaptiveGroup.getPage(), adaptiveGroup.getGroupID(), itemKeys,
                    '|', adaptiveGroup.getNumItemsRequired(), 0f, isMsb);

            Iterator<SingleDataResultSet> results = resultSets.getResultSets();
            // first expected result set

            SingleDataResultSet firstResultSet = results.next();
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);

            ReturnStatus status = ReturnStatus.parse(firstResultSet);
            opportunityItems.setReturnStatus(status);
            DbResultRecord record = firstResultSet.getRecords().next();
            if (!record.hasColumn("dateCreated"))
                return opportunityItems;

            String dateCreated = record.<String>get("dateCreated");

            if (!results.hasNext()) {
                _tdsLogger.sqlWarn("Item positions were not returned.", "insertItems");
                return opportunityItems;
            } else {
                SingleDataResultSet res = results.next();
                Iterator<DbResultRecord> records = res.getRecords();

                while (records.hasNext()) {
                    record = records.next();
                    OpportunityItem oppItem = new OpportunityItem();
                    String itemID = record.<String>get("bankitemkey");
                    // get data from SP
                    oppItem.setBankKey(record.<Long>get("bankkey"));
                    oppItem.setItemKey(record.<Long>get("itemkey"));
                    oppItem.setPage(record.<Integer>get("page"));
                    oppItem.setPosition(record.<Integer>get("position"));
                    oppItem.setFormat(record.<String>get("format"));
                    oppItem.setDateCreated(dateCreated);

                    AdaptiveItem adaptiveItem = (AdaptiveItem) CollectionUtils.find(adaptiveGroup.getItems(),
                            new MyPredicate(itemID));
                    //          {
                    //            @Override
                    //            public boolean evaluate (Object object) {
                    //              if (((AdaptiveItem) object).getItemID ().equals (itemID))
                    //                return true;
                    //              return false;
                    //            }
                    //          });
                    // find matching adaptive item
                    // AdaptiveItem adaptiveItem = adaptiveGroup.getItems ().Find(ai =>
                    // ai.ItemID == itemID);
                    // check if item was found
                    if (adaptiveItem == null) {
                        _logger.error("itemID:: " + itemID);
                        _logger.error("adaptiveGroup.getItems ():: " + adaptiveGroup.getItems());
                        String error = "T_InsertItems: The item key  %1$s was returned but was not found in [%2$s].";
                        throw new ReturnStatusException(String.format(error, itemID, adaptiveGroup.getItems()));
                    }
                    // get data from adaptive algorithm
                    oppItem.setGroupID(adaptiveGroup.getGroupID());
                    oppItem.setSegment(adaptiveGroup.getSegmentPosition());
                    oppItem.setSegmentID(adaptiveGroup.getSegmentID());
                    oppItem.setIsRequired(adaptiveItem.isRequired());
                    //oppItem.setIsFieldTest (adaptiveItem.isFieldTest ());
                    oppItem.setGroupItemsRequired(adaptiveGroup.getNumItemsRequired());

                    // manually set data
                    oppItem.setIsVisible(true);
                    oppItem.setIsSelected(false);
                    oppItem.setIsValid(false);
                    oppItem.setMarkForReview(false);
                    oppItem.setSequence(0);
                    oppItem.setStimulusFile(null);
                    oppItem.setItemFile(null);

                    // DEBUG: Check if items should all be marked as not required

                    if (_logger.isDebugEnabled()) {
                        boolean itemsNeverRequired = AppSettings.getBoolean("debug.itemsNeverRequired").getValue();
                        if (itemsNeverRequired) {
                            oppItem.setIsRequired(false);
                            oppItem.setGroupItemsRequired(0);
                        }
                    }
                    opportunityItems.add(oppItem);
                }
            }
        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return opportunityItems;
    }

    private String getItemKeys(List<AdaptiveItem> itemList) {
        String itemKeys = null;
        if (itemList != null) {
            StringBuilder sb = new StringBuilder();
            for (AdaptiveItem item : itemList) {
                sb.append(item.getItemID()).append("|");
            }
            if (!sb.toString().isEmpty()) {
                itemKeys = sb.substring(0, sb.length() - 1);
            }
        }
        return itemKeys;
    }

    public ReturnStatus updateScoredResponse(OpportunityInstance oppInstance, IItemResponseUpdate responseUpdate,
            int score, String scoreStatus, String scoreRationale, long scoreLatency, Float itemDuration)
            throws ReturnStatusException {
        ReturnStatus returnStatus = null;

        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_UpdateScoredResponse_SP(connection,
                    oppInstance.getKey(), oppInstance.getSessionKey(), oppInstance.getBrowserKey(),
                    responseUpdate.getItemID(), responseUpdate.getPage(), responseUpdate.getPosition(),
                    responseUpdate.getDateCreated(), responseUpdate.getSequence(), score, responseUpdate.getValue(),
                    responseUpdate.getIsSelected(), responseUpdate.getIsValid(), (int) scoreLatency, scoreStatus,
                    scoreRationale, itemDuration / MS_TO_SECS_DIVISOR);
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);
            Iterator<DbResultRecord> records = firstResultSet.getRecords();
            if (records.hasNext()) {
                DbResultRecord record = records.next();
                returnStatus = ReturnStatus.parse(record);
                if (record.hasColumn("scoremark")) {
                    responseUpdate.setScoreMark(record.<UUID>get("scoremark"));
                }
            }
        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }

        return returnStatus;
    }

    public OpportunityItems getOpportunityItems(UUID oppKey) throws ReturnStatusException {
        OpportunityItems opportunityItems = null;

        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_GetOpportunityItems_SP(connection, oppKey);

            opportunityItems = readOpportunityItems(firstResultSet, false);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return opportunityItems;
    }

    public OpportunityItems getOpportunityItemsWithValidation(OpportunityInstance oppInstance)
            throws ReturnStatusException {
        OpportunityItems opportunityItems = null;

        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_GetOpportunityItemsWithValidation_SP(connection,
                    oppInstance.getKey(), oppInstance.getSessionKey(), oppInstance.getBrowserKey());
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);

            ReturnStatus status = ReturnStatus.parse(firstResultSet);
            if (status != null && status.getStatus() != null && !status.getStatus().isEmpty())
                throw new ReturnStatusException(status);

            opportunityItems = readOpportunityItems(firstResultSet, false);
            //opportunityItems.setReturnStatus (status);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return opportunityItems;
    }

    public OpportunityItems getItemGroup(OpportunityInstance oppInstance, int pageNumber, String groupID,
            String dateCreated, boolean validateAccess) throws ReturnStatusException {
        OpportunityItems opportunityItems = null;
        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_GetItemGroup_SP(connection, oppInstance.getKey(),
                    pageNumber, groupID, dateCreated, oppInstance.getSessionKey(), oppInstance.getBrowserKey(),
                    validateAccess);
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);

            opportunityItems = readOpportunityItems(firstResultSet, true);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return opportunityItems;
    }

    protected OpportunityItems readOpportunityItems(SingleDataResultSet resultSet, boolean parseContent) {
        OpportunityItems responseCollection = new OpportunityItem().new OpportunityItems();

        Iterator<DbResultRecord> records = resultSet.getRecords();
        while (records.hasNext()) {
            DbResultRecord reader = records.next();
            OpportunityItem response = new OpportunityItem();

            response.setBankKey(reader.<Long>get("ItemBank"));
            response.setItemKey(reader.<Long>get("Item"));
            response.setPosition(reader.<Integer>get("position"));
            response.setPage(reader.<Integer>get("page"));
            response.setGroupID(reader.<String>get("GroupID"));
            response.setSegment(reader.<Integer>get("segment"));
            response.setSegmentID(reader.<String>get("SegmentID"));

            response.setSequence(reader.<Integer>get("ResponseSequence"));
            response.setDateCreated(reader.<String>get("dateCreated"));
            response.setFormat(reader.<String>get("Format").toUpperCase());

            if (reader.get("isVisible") != null) {
                response.setIsVisible(Boolean.parseBoolean(reader.get("isVisible").toString()));
            }

            //response.setScore (reader.<Integer> get ("Score"));
            response.setMarkForReview(reader.<Boolean>get("Mark"));

            response.setGroupItemsRequired(reader.<Integer>get("GroupItemsRequired"));
            if (reader.get("IsRequired") != null) {
                response.setIsRequired(Boolean.parseBoolean(reader.get("IsRequired").toString()));
            }

            response.setIsSelected(reader.<Boolean>get("IsSelected"));
            //response.setIsFieldTest (reader.<Boolean> get ("IsFieldTest"));
            response.setIsValid(reader.<Boolean>get("IsValid"));

            // check if we are parsing the content info (for T_GetItemGroup)
            if (parseContent) {
                response.setValue((reader.<String>get("Response") == null) ? null : reader.<String>get("Response"));

                // check if there is item path (this should always exist)
                if (reader.<String>get("itemFile") != null)
                    response.setItemFile(reader.<String>get("itemFile"));

                // check if there is stimulus path (optional)
                if (reader.<String>get("stimulusFile") != null)
                    response.setStimulusFile(reader.<String>get("stimulusFile"));

                // check if this item is printable
                Long printable = null;
                try { //TODO: jmambo determine cause of change in data type from Long to Integer
                    printable = reader.<Long>get("IsPrintable");
                } catch (Exception ex) {
                    printable = new Long(reader.<Integer>get("IsPrintable"));
                }
                response.setIsPrintable(printable == 1);
            }

            // DEBUG: Check if items should all be marked as not required and always
            // visible
            // #if (DEBUG)
            if (_logger.isDebugEnabled()) {
                boolean itemsNeverRequired = AppSettings.getBoolean("debug.itemsNeverRequired").getValue();
                if (itemsNeverRequired) {
                    response.setIsRequired(false);
                    response.setGroupItemsRequired(0);
                }
                boolean itemsAlwaysVisible = AppSettings.getBoolean("debug.itemsAlwaysVisible").getValue();
                if (itemsAlwaysVisible) {
                    response.setIsVisible(true);
                }
            }
            // #endif

            responseCollection.add(response);
        }
        return responseCollection;
    }

    public List<OpportunityItem> getItemGroup(OpportunityInstance oppInstance, int pageNumber)
            throws ReturnStatusException {
        try {
            return getItemGroup(oppInstance, pageNumber, null, null, false);
        } catch (ReturnStatusException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
    }

    public ReturnStatus setItemMarkForReview(OpportunityInstance oppInstance, int position, boolean mark)
            throws ReturnStatusException {
        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_SetItemMark_SP(connection, oppInstance.getKey(),
                    oppInstance.getSessionKey(), oppInstance.getBrowserKey(), position, mark);
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return null;
    }

    public void recordComment(UUID sessionKey, long testeeKey, UUID oppKey, int position, String comment)
            throws ReturnStatusException {

        try (SQLConnection connection = getSQLConnection()) {
            _studentDll.T_RecordComment_SP(connection, sessionKey, testeeKey, comment, null, oppKey, position);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }

    }

    public boolean isTestComplete(UUID oppKey) throws ReturnStatusException {
        boolean isComplete = false;

        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_IsTestComplete_SP(connection, oppKey);
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);
            Iterator<DbResultRecord> records = firstResultSet.getRecords();

            if (records.hasNext()) {
                DbResultRecord record = records.next();
                isComplete = record.<Boolean>get("IsComplete");
            }
        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        return isComplete;
    }

    public ReturnStatus removeResponse(OpportunityInstance oppInstance, int position, String itemID,
            String dateCreated) throws ReturnStatusException {

        ReturnStatus returnStatus = new ReturnStatus("success");
        try (SQLConnection connection = getSQLConnection()) {
            SingleDataResultSet firstResultSet = _studentDll.T_RemoveResponse_SP(connection, oppInstance.getKey(),
                    itemID, position, dateCreated, oppInstance.getSessionKey(), oppInstance.getBrowserKey());
            ReturnStatusException.getInstanceIfAvailable(firstResultSet);

        } catch (SQLException e) {
            _logger.error(e.getMessage());
            throw new ReturnStatusException(e);
        }
        // SP returns nothing on SUCCESS.
        return returnStatus;
    }

    public class MyPredicate implements Predicate {

        private String theItemId;

        public MyPredicate(String theItemId) {
            super();
            this.theItemId = theItemId;
        }

        public boolean evaluate(Object object) {
            if (((AdaptiveItem) object).getItemID().equals(theItemId))
                return true;
            return false;
        }
    }
}