Search in sources :

Example 1 with ResponseOptionBean

use of org.akaza.openclinica.bean.submit.ResponseOptionBean in project OpenClinica by OpenClinica.

the class ScoreCalculator method redoCalculations.

/**
     * Re-do calculations if funcs include changed item(s) and funcs are not
     * included in the current section. If calculation can not sucessfully redo,
     * old value will be erased and "<erased>" will be saved in database. <br>
     * The parameter 'itemdata' might be overwritten.
     * 
     * @param itemGroupSizes
     * @param items
     * @param itemdata
     * @param oldItemdata
     * @param updatedData
     * @param sectionId
     * @return ArrayList<String> which records left_item_text of items who
     *         failed to be updated into database.
     */
public ArrayList<String> redoCalculations(HashMap<String, ItemBean> items, HashMap<String, String> itemdata, TreeSet<String> changedItems, HashMap<Integer, TreeSet<Integer>> itemOrdinals, int sectionId) {
    ArrayList<String> updateFailedItems = new ArrayList<String>();
    if (itemdata == null) {
        logger.error("In ScoreCalculator redoCalculations(), itemdata is empty!");
        errors.add("In ScoreCalculator redoCalculations(), 'itemdata' map is empty!");
        return updateFailedItems;
    }
    if (changedItems == null) {
        logger.error("In ScoreCalculator redoCalculations(), 'changeItems' set is empty!");
        errors.add("In ScoreCalculator redoCalculations(), 'changeItems' set is empty!");
        return updateFailedItems;
    }
    ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO(sm.getDataSource());
    ItemDAO idao = new ItemDAO(sm.getDataSource());
    ItemDataDAO iddao = new ItemDataDAO(sm.getDataSource());
    NumberFormat nf = NumberFormat.getInstance();
    Parser parser = new Parser(items, itemdata);
    try {
        // for calculation type
        List<ItemFormMetadataBean> derivedItemList = ifmdao.findAllByCRFVersionIdAndResponseTypeId(ecb.getCRFVersionId(), ResponseType.CALCULATION.getId());
        if (derivedItemList.size() > 0) {
            Collections.sort(derivedItemList);
            for (ItemFormMetadataBean ifmb : derivedItemList) {
                if (ifmb.getSectionId() != sectionId) {
                    ItemBean ib = (ItemBean) idao.findByPK(ifmb.getItemId());
                    ResponseOptionBean rob = (ResponseOptionBean) ifmb.getResponseSet().getOptions().get(0);
                    int groupsize = 1;
                    if (itemOrdinals.containsKey(ib.getId())) {
                        groupsize = itemOrdinals.get(ib.getId()).size();
                    }
                    String value = "";
                    ArrayList<ScoreToken> parsedExp = new ArrayList<ScoreToken>();
                    for (int i = 0; i < groupsize; ++i) {
                        ItemDataBean idb = iddao.findByItemIdAndEventCRFIdAndOrdinal(ifmb.getItemId(), ecb.getId(), i + 1);
                        // is there any changed item
                        Parser p = new Parser(items, itemdata);
                        parsedExp = parser.parseScoreTokens(rob.getValue());
                        if (p.isChanged(changedItems, parsedExp)) {
                            StringBuffer err = new StringBuffer();
                            parsedExp = parser.assignVariables(parsedExp, i + 1);
                            // before, set "<erased>"
                            if (parser.getErrors().length() > 0) {
                                err.append(parser.getErrors());
                                if (idb.isActive()) {
                                    idb.setValue("<erased>");
                                    idb.setStatus(Status.UNAVAILABLE);
                                    idb = (ItemDataBean) iddao.update(idb);
                                    if (!idb.isActive()) {
                                        String key = i + 1 > 1 ? ifmb.getLeftItemText() + "_" + (i + 1) : ifmb.getLeftItemText();
                                        updateFailedItems.add(key);
                                    }
                                }
                                parser.setErrors(new StringBuffer());
                            } else // otherwise do calculation
                            {
                                try {
                                    value = ScoreUtil.eval(parsedExp);
                                } catch (ScoreException se) {
                                    logger.error(se.getMessage());
                                }
                                String exp = rob.getValue();
                                exp = exp.replace("##", ",");
                                if (writeToDB(ib, ifmb, idb, exp, value, err)) {
                                    changedItems.add(ib.getName());
                                    itemdata.put(ib.getId() + "_" + (i + 1), idb.getValue());
                                } else {
                                    String key = i + 1 > 1 ? ifmb.getLeftItemText() + "_" + (i + 1) : ifmb.getLeftItemText();
                                    updateFailedItems.add(key);
                                }
                            }
                            if (err.length() > 0) {
                                String key = i + 1 > 1 ? ifmb.getLeftItemText() + "_" + (i + 1) : ifmb.getLeftItemText();
                                errors.add("Item " + key + " contains calculation errors: " + err.toString());
                            }
                        }
                    }
                }
            }
        }
        List<ItemFormMetadataBean> itemList = ifmdao.findAllByCRFVersionIdAndResponseTypeId(ecb.getCRFVersionId(), ResponseType.GROUP_CALCULATION.getId());
        if (itemList.size() > 0) {
            Collections.sort(itemList);
            for (ItemFormMetadataBean ifmb : itemList) {
                if (ifmb.getSectionId() != sectionId) {
                    ItemBean ib = (ItemBean) idao.findByPK(ifmb.getItemId());
                    ResponseOptionBean rob = (ResponseOptionBean) ifmb.getResponseSet().getOptions().get(0);
                    String value = "";
                    Parser p = new Parser(items, itemdata);
                    ArrayList<ScoreToken> parsedExp = parser.parseScoreTokens(rob.getValue());
                    if (p.isChanged(changedItems, parsedExp)) {
                        StringBuffer err = new StringBuffer();
                        parser.setErrors(err);
                        parsedExp = parser.assignVariables(parsedExp, itemOrdinals);
                        ItemDataBean idb = iddao.findByItemIdAndEventCRFIdAndOrdinal(ifmb.getItemId(), ecb.getId(), 1);
                        if (parser.getErrors().length() > 0) {
                            err.append(parser.getErrors());
                            if (idb.isActive()) {
                                idb.setValue("<erased>");
                                idb.setStatus(Status.UNAVAILABLE);
                                idb = (ItemDataBean) iddao.update(idb);
                                if (!idb.isActive()) {
                                    updateFailedItems.add(ifmb.getLeftItemText());
                                }
                            }
                        } else {
                            try {
                                value = ScoreUtil.eval(parsedExp);
                            } catch (ScoreException se) {
                                logger.error(se.getMessage());
                            }
                            String exp = rob.getValue();
                            exp = exp.replace("##", ",");
                            if (writeToDB(ib, ifmb, idb, exp, value, err)) {
                                changedItems.add(ib.getName());
                                itemdata.put(ib.getId() + "_" + idb.getOrdinal(), idb.getValue());
                            } else {
                                updateFailedItems.add(ifmb.getLeftItemText());
                            }
                        }
                        if (err.length() > 0) {
                            errors.add("Item " + ifmb.getLeftItemText() + " contains calculation errors: " + err.toString());
                        }
                    }
                }
            }
        }
    } catch (OpenClinicaException e) {
        logger.error(e.getMessage());
    }
    return updateFailedItems;
}
Also used : DisplayItemBean(org.akaza.openclinica.bean.submit.DisplayItemBean) ItemBean(org.akaza.openclinica.bean.submit.ItemBean) ItemDAO(org.akaza.openclinica.dao.submit.ItemDAO) ArrayList(java.util.ArrayList) ResponseOptionBean(org.akaza.openclinica.bean.submit.ResponseOptionBean) OpenClinicaException(org.akaza.openclinica.exception.OpenClinicaException) ItemDataDAO(org.akaza.openclinica.dao.submit.ItemDataDAO) ScoreException(org.akaza.openclinica.exception.ScoreException) ItemDataBean(org.akaza.openclinica.bean.submit.ItemDataBean) ItemFormMetadataDAO(org.akaza.openclinica.dao.submit.ItemFormMetadataDAO) ItemFormMetadataBean(org.akaza.openclinica.bean.submit.ItemFormMetadataBean) NumberFormat(java.text.NumberFormat)

Example 2 with ResponseOptionBean

use of org.akaza.openclinica.bean.submit.ResponseOptionBean in project OpenClinica by OpenClinica.

the class CreateCRFVersionServlet method hasDifferentOption.

/**
     * When the version is added, for each non-new item OpenClinica should check the RESPONSE_OPTIONS_TEXT, and
     * RESPONSE_VALUES used for the item in other versions of the CRF.
     * 
     * For a given RESPONSE_VALUES code, the associated RESPONSE_OPTIONS_TEXT string is different than in a previous
     * version
     * 
     * For a given RESPONSE_OPTIONS_TEXT string, the associated RESPONSE_VALUES code is different than in a previous
     * version
     * 
     * @param oldRes
     * @param newRes
     * @return The original option
     */
public ResponseOptionBean hasDifferentOption(ResponseSetBean oldRes, ResponseSetBean newRes) {
    ArrayList oldOptions = oldRes.getOptions();
    ArrayList newOptions = newRes.getOptions();
    if (oldOptions.size() != newOptions.size()) {
        // if the sizes are different, means the options don't match
        return null;
    } else {
        for (int i = 0; i < oldOptions.size(); i++) {
            // from database
            ResponseOptionBean rob = (ResponseOptionBean) oldOptions.get(i);
            String text = rob.getText();
            String value = rob.getValue();
            for (int j = i; j < newOptions.size(); j++) {
                // from
                // spreadsheet
                ResponseOptionBean rob1 = (ResponseOptionBean) newOptions.get(j);
                // changed by jxu on 08-29-06, to fix the problem of cannot
                // recognize
                // the same responses
                String text1 = restoreQuotes(rob1.getText());
                String value1 = restoreQuotes(rob1.getValue());
                if (StringUtil.isBlank(text1) && StringUtil.isBlank(value1)) {
                    // ignore the checking for the repeated ones
                    break;
                }
                if (text1.equalsIgnoreCase(text) && !value1.equals(value)) {
                    logger.debug("different response value:" + value1 + "|" + value);
                    return rob;
                } else if (!text1.equalsIgnoreCase(text) && value1.equals(value)) {
                    logger.debug("different response text:" + text1 + "|" + text);
                    return rob;
                }
                break;
            }
        }
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) ResponseOptionBean(org.akaza.openclinica.bean.submit.ResponseOptionBean)

Example 3 with ResponseOptionBean

use of org.akaza.openclinica.bean.submit.ResponseOptionBean in project OpenClinica by OpenClinica.

the class DataEntryServlet method populateNotesWithDBNoteCounts.

/*
     * change to explicitly re-set the section bean after reviewing the disc note counts, tbh 01/2010
     */
protected DisplaySectionBean populateNotesWithDBNoteCounts(FormDiscrepancyNotes discNotes, DisplaySectionBean section, HttpServletRequest request) {
    DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
    // ArrayList items = section.getItems();
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);
    ArrayList<DiscrepancyNoteBean> ecNotes = dndao.findEventCRFDNotesFromEventCRF(ecb);
    ArrayList<DiscrepancyNoteBean> existingNameNotes = new ArrayList(), nameNotes = new ArrayList();
    ArrayList<DiscrepancyNoteBean> existingIntrvDateNotes = new ArrayList(), dateNotes = new ArrayList();
    long t = System.currentTimeMillis();
    logMe("Method:populateNotesWithDBNoteCounts" + t);
    int intNew = 0, intRes = 0, intUpdated = 0, intClosed = 0, intNA = 0;
    int dateNew = 0, dateRes = 0, dateUpdated = 0, dateClosed = 0, dateNA = 0;
    boolean hasMoreThreads = false;
    for (int i = 0; i < ecNotes.size(); i++) {
        DiscrepancyNoteBean dn = ecNotes.get(i);
        if (INTERVIEWER_NAME.equalsIgnoreCase(dn.getColumn())) {
            discNotes.setNumExistingFieldNotes(INPUT_INTERVIEWER, 1);
            request.setAttribute("hasNameNote", "yes");
            request.setAttribute(INTERVIEWER_NAME_NOTE, dn);
            if (dn.getParentDnId() == 0)
                existingNameNotes.add(dn);
        }
        if (DATE_INTERVIEWED.equalsIgnoreCase(dn.getColumn())) {
            discNotes.setNumExistingFieldNotes(INPUT_INTERVIEW_DATE, 1);
            request.setAttribute("hasDateNote", "yes");
            request.setAttribute(INTERVIEWER_DATE_NOTE, dn);
            if (dn.getParentDnId() == 0)
                existingIntrvDateNotes.add(dn);
        }
    }
    logMe("Method:populateNotesWithDBNoteCounts before calling setToolTipEventNotes" + System.currentTimeMillis() + "time took:" + (System.currentTimeMillis() - t));
    setToolTipEventNotes(request);
    request.setAttribute("nameNoteResStatus", getDiscrepancyNoteResolutionStatus(existingNameNotes));
    request.setAttribute("IntrvDateNoteResStatus", getDiscrepancyNoteResolutionStatus(existingIntrvDateNotes));
    request.setAttribute("existingNameNotes", existingNameNotes);
    request.setAttribute("existingIntrvDateNotes", existingIntrvDateNotes);
    List<DisplayItemWithGroupBean> allItems = section.getDisplayItemGroups();
    LOGGER.debug("start to populate notes: " + section.getDisplayItemGroups().size());
    this.output(allItems);
    logMe("Looping through allItems time:" + System.currentTimeMillis() + "time took from the begining" + (System.currentTimeMillis() - t));
    for (int k = 0; k < allItems.size(); k++) {
        DisplayItemWithGroupBean itemWithGroup = allItems.get(k);
        if (itemWithGroup.isInGroup()) {
            LOGGER.debug("group item DNote...");
            List<DisplayItemGroupBean> digbs = itemWithGroup.getItemGroups();
            LOGGER.trace("digbs size: " + digbs.size());
            for (int i = 0; i < digbs.size(); i++) {
                DisplayItemGroupBean displayGroup = digbs.get(i);
                List<DisplayItemBean> items = displayGroup.getItems();
                for (int j = 0; j < items.size(); j++) {
                    DisplayItemBean dib = items.get(j);
                    int itemDataId = dib.getData().getId();
                    int numNotes = dndao.findNumExistingNotesForItem(itemDataId);
                    int numNotes1 = dndao.findNumOfActiveExistingNotesForItemData(itemDataId);
                    int ordinal = this.getManualRows(digbs);
                    String inputName = getGroupItemInputName(displayGroup, displayGroup.getFormInputOrdinal(), dib);
                    if (!displayGroup.isAuto()) {
                        inputName = getGroupItemManualInputName(displayGroup, i, dib);
                    }
                    discNotes.setNumExistingFieldNotes(inputName, numNotes1);
                    ArrayList notes = discNotes.getNotes(inputName);
                    // + notes2.size());
                    dib.setNumDiscrepancyNotes(numNotes + notes.size());
                    dib.setDiscrepancyNoteStatus(getDiscrepancyNoteResolutionStatus(itemDataId, notes));
                    dib = setTotals(dib, itemDataId, notes, ecb.getId());
                    LOGGER.debug("dib note size:" + dib.getNumDiscrepancyNotes() + " " + dib.getData().getId() + " " + inputName);
                    items.set(j, dib);
                }
                displayGroup.setItems(items);
                digbs.set(i, displayGroup);
            }
            itemWithGroup.setItemGroups(digbs);
        } else {
            LOGGER.trace("single item db note");
            DisplayItemBean dib = itemWithGroup.getSingleItem();
            try {
                ResponseOptionBean rob = (ResponseOptionBean) dib.getMetadata().getResponseSet().getOptions().get(0);
                LOGGER.trace("test print of options for coding: " + rob.getValue());
            } catch (NullPointerException e) {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            }
            int itemDataId = dib.getData().getId();
            int itemId = dib.getItem().getId();
            int numNotes = dndao.findNumExistingNotesForItem(itemDataId);
            int numNotes1 = dndao.findNumOfActiveExistingNotesForItemData(itemDataId);
            String inputFieldName = "input" + itemId;
            discNotes.setNumExistingFieldNotes(inputFieldName, numNotes1);
            dib.setNumDiscrepancyNotes(numNotes + discNotes.getNotes(inputFieldName).size());
            dib.setDiscrepancyNoteStatus(getDiscrepancyNoteResolutionStatus(itemDataId, discNotes.getNotes(inputFieldName)));
            dib = setTotals(dib, itemDataId, discNotes.getNotes(inputFieldName), ecb.getId());
            ArrayList childItems = dib.getChildren();
            for (int j = 0; j < childItems.size(); j++) {
                DisplayItemBean child = (DisplayItemBean) childItems.get(j);
                int childItemDataId = child.getData().getId();
                int childItemId = child.getItem().getId();
                int childNumNotes = dndao.findNumExistingNotesForItem(childItemDataId);
                String childInputFieldName = "input" + childItemId;
                LOGGER.debug("*** setting " + childInputFieldName);
                discNotes.setNumExistingFieldNotes(childInputFieldName, childNumNotes);
                child.setNumDiscrepancyNotes(childNumNotes + discNotes.getNotes(childInputFieldName).size());
                child.setDiscrepancyNoteStatus(getDiscrepancyNoteResolutionStatus(childItemDataId, discNotes.getNotes(childInputFieldName)));
                child = setTotals(child, childItemDataId, discNotes.getNotes(childInputFieldName), ecb.getId());
                childItems.set(j, child);
            }
            dib.setChildren(childItems);
            itemWithGroup.setSingleItem(runDynamicsItemCheck(dib, null, request));
        }
        // missing piece of the puzzle - reset the itemgroup into all items?
        allItems.set(k, itemWithGroup);
    }
    section.setDisplayItemGroups(allItems);
    return section;
}
Also used : DisplayItemGroupBean(org.akaza.openclinica.bean.submit.DisplayItemGroupBean) DiscrepancyNoteDAO(org.akaza.openclinica.dao.managestudy.DiscrepancyNoteDAO) DisplayItemWithGroupBean(org.akaza.openclinica.bean.submit.DisplayItemWithGroupBean) ArrayList(java.util.ArrayList) ResponseOptionBean(org.akaza.openclinica.bean.submit.ResponseOptionBean) EventCRFBean(org.akaza.openclinica.bean.submit.EventCRFBean) DiscrepancyNoteBean(org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean) DisplayItemBean(org.akaza.openclinica.bean.submit.DisplayItemBean)

Example 4 with ResponseOptionBean

use of org.akaza.openclinica.bean.submit.ResponseOptionBean in project OpenClinica by OpenClinica.

the class DataEntryServlet method processRequest.

@Override
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //JN:The following were the the global variables, moved as local.
    locale = LocaleResolver.getLocale(request);
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);
    SectionBean sb = (SectionBean) request.getAttribute(SECTION_BEAN);
    ItemDataDAO iddao = new ItemDataDAO(getDataSource(), locale);
    HttpSession session = request.getSession();
    StudyBean currentStudy = (StudyBean) session.getAttribute("study");
    StudyUserRoleBean currentRole = (StudyUserRoleBean) session.getAttribute("userRole");
    SectionDAO sdao = new SectionDAO(getDataSource());
    /**
         * Determines whether the form was submitted. Calculated once in processRequest. The reason we don't use the normal means to determine if the form was
         * submitted (ie FormProcessor.isSubmitted) is because when we use forwardPage, Java confuses the inputs from the just-processed form with the inputs for
         * the forwarded-to page. This is a problem since frequently we're forwarding from one (submitted) section to the next (unsubmitted) section. If we use the
         * normal means, Java will always think that the unsubmitted section is, in fact, submitted. This member is guaranteed to be calculated before
         * shouldLoadDBValues() is called.
         */
    boolean isSubmitted = false;
    boolean hasGroup = false;
    EventCRFDAO ecdao = null;
    FormProcessor fp = new FormProcessor(request);
    logMe("Enterting DataEntry Servlet" + System.currentTimeMillis());
    EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
    FormDiscrepancyNotes discNotes;
    panel.setStudyInfoShown(false);
    String age = "";
    UserAccountBean ub = (UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
    String instantAtt = CV_INSTANT_META + ecb.getCRFVersionId();
    //for 11958: repeating groups rows appear if validation returns to the same section
    int isFirstTimeOnSection = fp.getInt("isFirstTimeOnSection");
    request.setAttribute("isFirstTimeOnSection", isFirstTimeOnSection + "");
    if (getCrfLocker().isLocked(ecb.getId())) {
        int userId = getCrfLocker().getLockOwner(ecb.getId());
        UserAccountDAO udao = new UserAccountDAO(getDataSource());
        UserAccountBean ubean = (UserAccountBean) udao.findByPK(userId);
        if (ubean.getId() != ub.getId()) {
            addPageMessage(resword.getString("CRF_unavailable") + " " + ubean.getName() + " " + resword.getString("Currently_entering_data") + " " + resword.getString("Leave_the_CRF"), request);
            forwardPage(Page.LIST_STUDY_SUBJECTS_SERVLET, request, response);
        }
    } else {
        getCrfLocker().lock(ecb.getId(), ub.getId());
    }
    if (!ecb.isActive()) {
        throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception.getString("event_not_exists"));
    }
    logMe("Enterting DataEntry Get the status/number of item discrepancy notes" + System.currentTimeMillis());
    // Get the status/number of item discrepancy notes
    DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
    ArrayList<DiscrepancyNoteBean> allNotes = new ArrayList<DiscrepancyNoteBean>();
    List<DiscrepancyNoteBean> eventCrfNotes = new ArrayList<DiscrepancyNoteBean>();
    List<DiscrepancyNoteThread> noteThreads = new ArrayList<DiscrepancyNoteThread>();
    // BWP: this try block is not necessary try {
    dndao = new DiscrepancyNoteDAO(getDataSource());
    allNotes = dndao.findAllTopNotesByEventCRF(ecb.getId());
    eventCrfNotes = dndao.findOnlyParentEventCRFDNotesFromEventCRF(ecb);
    if (!eventCrfNotes.isEmpty()) {
        allNotes.addAll(eventCrfNotes);
    }
    logMe("Entering DataEntry Create disc note threads out of the various notes" + System.currentTimeMillis());
    // Create disc note threads out of the various notes
    DiscrepancyNoteUtil dNoteUtil = new DiscrepancyNoteUtil();
    noteThreads = dNoteUtil.createThreadsOfParents(allNotes, getDataSource(), currentStudy, null, -1, true);
    // variables that provide values for the CRF discrepancy note header
    int updatedNum = 0;
    int openNum = 0;
    int closedNum = 0;
    int resolvedNum = 0;
    int notAppNum = 0;
    DiscrepancyNoteBean tempBean;
    for (DiscrepancyNoteThread dnThread : noteThreads) {
        /*
             * 3014: do not count parent beans, only the last child disc note of the thread.
             */
        tempBean = dnThread.getLinkedNoteList().getLast();
        if (tempBean != null) {
            if (ResolutionStatus.UPDATED.equals(tempBean.getResStatus())) {
                updatedNum++;
            } else if (ResolutionStatus.OPEN.equals(tempBean.getResStatus())) {
                openNum++;
            } else if (ResolutionStatus.CLOSED.equals(tempBean.getResStatus())) {
                // if (dn.getParentDnId() > 0){
                closedNum++;
            // }
            } else if (ResolutionStatus.RESOLVED.equals(tempBean.getResStatus())) {
                // if (dn.getParentDnId() > 0){
                resolvedNum++;
            // }
            } else if (ResolutionStatus.NOT_APPLICABLE.equals(tempBean.getResStatus())) {
                notAppNum++;
            }
        }
    }
    logMe("Entering DataEntry Create disc note threads out of the various notes DONE" + System.currentTimeMillis());
    request.setAttribute("updatedNum", updatedNum + "");
    request.setAttribute("openNum", openNum + "");
    request.setAttribute("closedNum", closedNum + "");
    request.setAttribute("resolvedNum", resolvedNum + "");
    request.setAttribute("notAppNum", notAppNum + "");
    String fromViewNotes = fp.getString("fromViewNotes");
    if (fromViewNotes != null && "1".equals(fromViewNotes)) {
        request.setAttribute("fromViewNotes", fromViewNotes);
    }
    logMe("Entering Create studySubjDao.. ++++stuff" + System.currentTimeMillis());
    StudySubjectDAO ssdao = new StudySubjectDAO(getDataSource());
    StudySubjectBean ssb = (StudySubjectBean) ssdao.findByPK(ecb.getStudySubjectId());
    // YW 11-07-2007, data entry could not be performed if its study subject
    // has been removed.
    // Notice: ViewSectionDataEntryServelet, ViewSectionDataEntryPreview,
    // PrintCRFServlet and PrintDataEntryServlet, have theirs own
    // processRequest
    Status s = ssb.getStatus();
    if ("removed".equalsIgnoreCase(s.getName()) || "auto-removed".equalsIgnoreCase(s.getName())) {
        addPageMessage(respage.getString("you_may_not_perform_data_entry_on_a_CRF") + respage.getString("study_subject_has_been_deleted"), request);
        request.setAttribute("id", new Integer(ecb.getStudySubjectId()).toString());
        session.removeAttribute(instantAtt);
        forwardPage(Page.VIEW_STUDY_SUBJECT_SERVLET, request, response);
    }
    // YW >>
    HashMap<String, String> newUploadedFiles = (HashMap<String, String>) session.getAttribute("newUploadedFiles");
    if (newUploadedFiles == null) {
        newUploadedFiles = new HashMap<String, String>();
    }
    request.setAttribute("newUploadedFiles", newUploadedFiles);
    if (!fp.getString("exitTo").equals("")) {
        request.setAttribute("exitTo", fp.getString("exitTo"));
    }
    //some EVENT CRF CHECK
    logMe("Entering some EVENT CRF CHECK" + System.currentTimeMillis());
    if (!fp.getString(GO_EXIT).equals("")) {
        session.removeAttribute(GROUP_HAS_DATA);
        session.removeAttribute("to_create_crf");
        session.removeAttribute("mayProcessUploading");
        //Removing the user and EventCRF from the locked CRF List
        if (getCrfLocker().isLocked(ecb.getId()) && getCrfLocker().getLockOwner(ecb.getId()) == ub.getId())
            getCrfLocker().unlock(ecb.getId());
        if (newUploadedFiles.size() > 0) {
            if (this.unloadFiles(newUploadedFiles)) {
            } else {
                String missed = "";
                Iterator iter = newUploadedFiles.keySet().iterator();
                while (iter.hasNext()) {
                    missed += " " + newUploadedFiles.get(iter.next());
                }
                addPageMessage(respage.getString("uploaded_files_not_deleted_or_not_exist") + ": " + missed, request);
            }
        }
        session.removeAttribute("newUploadedFiles");
        addPageMessage(respage.getString("exit_without_saving"), request);
        // another servlet
        if (fromViewNotes != null && "1".equals(fromViewNotes)) {
            String viewNotesURL = (String) session.getAttribute("viewNotesURL");
            if (viewNotesURL != null && viewNotesURL.length() > 0) {
                response.sendRedirect(response.encodeRedirectURL(viewNotesURL));
            }
            return;
        }
        String fromResolvingNotes = fp.getString("fromResolvingNotes", true);
        String winLocation = (String) session.getAttribute(ViewNotesServlet.WIN_LOCATION);
        session.removeAttribute(instantAtt);
        if (!StringUtil.isBlank(fromResolvingNotes) && !StringUtil.isBlank(winLocation)) {
            response.sendRedirect(response.encodeRedirectURL(winLocation));
        } else {
            if (!fp.getString("exitTo").equals("")) {
                response.sendRedirect(response.encodeRedirectURL(fp.getString("exitTo")));
            } else
                response.sendRedirect(response.encodeRedirectURL("ListStudySubjects"));
        }
        // forwardPage(Page.SUBMIT_DATA_SERVLET);
        return;
    }
    logMe("Entering some EVENT CRF CHECK DONE" + System.currentTimeMillis());
    // checks if the section has items in item group
    // for repeating items
    // hasGroup = getInputBeans();
    hasGroup = checkGroups(fp, ecb);
    Boolean b = (Boolean) request.getAttribute(INPUT_IGNORE_PARAMETERS);
    isSubmitted = fp.isSubmitted() && b == null;
    // variable is used for fetching any null values like "not applicable"
    int eventDefinitionCRFId = 0;
    if (fp != null) {
        eventDefinitionCRFId = fp.getInt("eventDefinitionCRFId");
    }
    StudyBean study = (StudyBean) session.getAttribute("study");
    // constructs the list of items used on UI
    // tbh>>
    // logger.trace("trying event def crf id: "+eventDefinitionCRFId);
    logMe("Entering some EVENT DEF CRF CHECK " + System.currentTimeMillis());
    if (eventDefinitionCRFId <= 0) {
        // TODO we have to get that id before we can continue
        EventDefinitionCRFBean edcBean = edcdao.findByStudyEventIdAndCRFVersionId(study, ecb.getStudyEventId(), ecb.getCRFVersionId());
        eventDefinitionCRFId = edcBean.getId();
    }
    logMe("Entering some EVENT DEF CRF CHECK DONE " + System.currentTimeMillis());
    logMe("Entering some Study EVENT DEF CRF CHECK  " + System.currentTimeMillis());
    StudyEventDAO seDao = new StudyEventDAO(getDataSource());
    EventDefinitionCRFBean edcBean = (EventDefinitionCRFBean) edcdao.findByPK(eventDefinitionCRFId);
    EventDefinitionCRFBean edcb = (EventDefinitionCRFBean) edcdao.findByPK(eventDefinitionCRFId);
    //JN:Putting the event_def_crf_bean in the request attribute.
    request.setAttribute(EVENT_DEF_CRF_BEAN, edcb);
    StudyEventBean studyEventBean = (StudyEventBean) seDao.findByPK(ecb.getStudyEventId());
    edcBean.setId(eventDefinitionCRFId);
    StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(getDataSource());
    StudyEventDefinitionBean studyEventDefinition = (StudyEventDefinitionBean) seddao.findByPK(edcBean.getStudyEventDefinitionId());
    CRFVersionDAO cvdao = new CRFVersionDAO(getDataSource());
    CRFVersionBean crfVersionBean = (CRFVersionBean) cvdao.findByPK(ecb.getCRFVersionId());
    Phase phase2 = Phase.INITIAL_DATA_ENTRY;
    if (getServletPage(request).startsWith(Page.DOUBLE_DATA_ENTRY_SERVLET.getFileName())) {
        phase2 = Phase.DOUBLE_DATA_ENTRY;
    } else if (getServletPage(request).startsWith(Page.ADMIN_EDIT_SERVLET.getFileName())) {
        phase2 = Phase.ADMIN_EDITING;
    }
    logMe("Entering ruleSets::: CreateAndInitializeRuleSet:::" + Thread.currentThread());
    logMe("Entering ruleSets::: CreateAndInitializeRuleSet:::" + Thread.currentThread() + "currentStudy?" + currentStudy + "studyEventDefinition" + studyEventDefinition + "crfVersionBean" + crfVersionBean + "studyEventBean" + studyEventBean + "ecb" + ecb);
    //  List<RuleSetBean> ruleSets = createAndInitializeRuleSet(currentStudy, studyEventDefinition, crfVersionBean, studyEventBean, ecb, true, request, response);
    // boolean shouldRunRules = getRuleSetService(request).shouldRunRulesForRuleSets(ruleSets, phase2);
    logMe("Entering getDisplayBean:::::Thread::::" + Thread.currentThread());
    DisplaySectionBean section = getDisplayBean(hasGroup, false, request, isSubmitted);
    //hasSCDItem has been initialized in getDisplayBean() which is online above
    VariableSubstitutionHelper.replaceVariables(section, study, ssb, studyEventDefinition, studyEventBean, dataSource);
    if (section.getSection().hasSCDItem()) {
        SimpleConditionalDisplayService cds0 = (SimpleConditionalDisplayService) SpringServletAccess.getApplicationContext(getServletContext()).getBean("simpleConditionalDisplayService");
        section = cds0.initConditionalDisplays(section);
    }
    logMe("Entering  Find out the id of the section's first field " + System.currentTimeMillis());
    // 2790: Find out the id of the section's first field
    String firstFieldId = getSectionFirstFieldId(section.getSection().getId());
    request.setAttribute("formFirstField", firstFieldId);
    // logger.trace("now trying event def crf id: "+eventDefinitionCRFId);
    // above is necessary to give us null values during DDE
    // ironically, this only covers vertical null value result sets
    // horizontal ones are covered in FormBeanUtil, tbh 112007
    logMe("Entering  displayItemWithGroups " + System.currentTimeMillis());
    //@pgawade 30-May-2012 Fix for issue 13963 - added an extra parameter 'isSubmitted' to method createItemWithGroups
    List<DisplayItemWithGroupBean> displayItemWithGroups = createItemWithGroups(section, hasGroup, eventDefinitionCRFId, request, isSubmitted);
    logMe("Entering  displayItemWithGroups end " + System.currentTimeMillis());
    this.getItemMetadataService().updateGroupDynamicsInSection(displayItemWithGroups, section.getSection().getId(), ecb);
    section.setDisplayItemGroups(displayItemWithGroups);
    DisplayTableOfContentsBean toc = TableOfContentsServlet.getDisplayBeanWithShownSections(getDataSource(), (DisplayTableOfContentsBean) request.getAttribute(TOC_DISPLAY), (DynamicsMetadataService) SpringServletAccess.getApplicationContext(getServletContext()).getBean("dynamicsMetadataService"));
    request.setAttribute(TOC_DISPLAY, toc);
    LinkedList<Integer> sectionIdsInToc = TableOfContentsServlet.sectionIdsInToc(toc);
    // why do we get previousSec and nextSec here, rather than in
    // getDisplayBeans?
    // so that we can use them in forwarding the user to the previous/next
    // section
    // if the validation was successful
    logMe("Entering  displayItemWithGroups sdao.findPrevious  " + System.currentTimeMillis());
    int sIndex = TableOfContentsServlet.sectionIndexInToc(section.getSection(), toc, sectionIdsInToc);
    SectionBean previousSec = this.prevSection(section.getSection(), ecb, toc, sIndex);
    logMe("Entering  displayItemWithGroups sdao.findPrevious  end " + System.currentTimeMillis());
    SectionBean nextSec = this.nextSection(section.getSection(), ecb, toc, sIndex);
    section.setFirstSection(!previousSec.isActive());
    section.setLastSection(!nextSec.isActive());
    // this is for generating side info panel
    // and the information panel under the Title
    SubjectDAO subjectDao = new SubjectDAO(getDataSource());
    StudyDAO studydao = new StudyDAO(getDataSource());
    SubjectBean subject = (SubjectBean) subjectDao.findByPK(ssb.getSubjectId());
    // Get the study then the parent study
    logMe("Entering  Get the study then the parent study   " + System.currentTimeMillis());
    if (study.getParentStudyId() > 0) {
        // this is a site,find parent
        StudyBean parentStudy = (StudyBean) studydao.findByPK(study.getParentStudyId());
        request.setAttribute("studyTitle", parentStudy.getName());
        request.setAttribute("siteTitle", study.getName());
    } else {
        request.setAttribute("studyTitle", study.getName());
    }
    logMe("Entering  Get the study then the parent study end  " + System.currentTimeMillis());
    // Let us process the age
    if (currentStudy.getStudyParameterConfig().getCollectDob().equals("1")) {
        // YW 11-16-2007 erollment-date is used for calculating age.
        Date enrollmentDate = ssb.getEnrollmentDate();
        age = Utils.getInstacne().processAge(enrollmentDate, subject.getDateOfBirth());
    }
    //ArrayList beans = ViewStudySubjectServlet.getDisplayStudyEventsForStudySubject(ssb, getDataSource(), ub, currentRole);
    request.setAttribute("studySubject", ssb);
    request.setAttribute("subject", subject);
    //request.setAttribute("beans", beans);
    request.setAttribute("eventCRF", ecb);
    request.setAttribute("age", age);
    request.setAttribute("decryptedPassword", ((SecurityManager) SpringServletAccess.getApplicationContext(getServletContext()).getBean("securityManager")).encrytPassword("root", getUserDetails()));
    // set up interviewer name and date
    fp.addPresetValue(INPUT_INTERVIEWER, ecb.getInterviewerName());
    if (ecb.getDateInterviewed() != null) {
        DateFormat local_df = new SimpleDateFormat(resformat.getString("date_format_string"), ResourceBundleProvider.getLocale());
        String idateFormatted = local_df.format(ecb.getDateInterviewed());
        fp.addPresetValue(INPUT_INTERVIEW_DATE, idateFormatted);
    } else {
        fp.addPresetValue(INPUT_INTERVIEW_DATE, "");
    }
    setPresetValues(fp.getPresetValues(), request);
    logMe("Entering Checks !submitted  " + System.currentTimeMillis());
    if (!isSubmitted) {
        // TODO: prevent data enterer from seeing results of first round of
        // data
        // entry, if this is second round
        // FLAG--SLOW HERE WHEN LOADING
        logMe("Entering Checks !submitted entered  " + System.currentTimeMillis());
        long t = System.currentTimeMillis();
        request.setAttribute(BEAN_DISPLAY, section);
        request.setAttribute(BEAN_ANNOTATIONS, getEventCRFAnnotations(request));
        session.setAttribute("shouldRunValidation", null);
        session.setAttribute("rulesErrors", null);
        session.setAttribute(DataEntryServlet.NOTE_SUBMITTED, null);
        discNotes = new FormDiscrepancyNotes();
        //            discNotes = (FormDiscrepancyNotes) session.getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
        //            if (discNotes == null) {
        //                discNotes = new FormDiscrepancyNotes();
        //            }
        // << tbh 01/2010
        section = populateNotesWithDBNoteCounts(discNotes, section, request);
        populateInstantOnChange(request.getSession(), ecb, section);
        LOGGER.debug("+++ just ran populateNotes, printing field notes: " + discNotes.getFieldNotes().toString());
        LOGGER.debug("found disc notes: " + discNotes.getNumExistingFieldNotes().toString());
        session.setAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME, discNotes);
        if (section.getSection().hasSCDItem()) {
            section = SCDItemDisplayInfo.generateSCDDisplayInfo(section, this.getServletPage(request).equals(Page.INITIAL_DATA_ENTRY) || this.getServletPage(request).equals(Page.ADMIN_EDIT_SERVLET) && !this.isAdminForcedReasonForChange(request));
        }
        int keyId = ecb.getId();
        session.removeAttribute(DoubleDataEntryServlet.COUNT_VALIDATE + keyId);
        setUpPanel(section);
        if (newUploadedFiles.size() > 0) {
            if (this.unloadFiles(newUploadedFiles)) {
            } else {
                String missed = "";
                Iterator iter = newUploadedFiles.keySet().iterator();
                while (iter.hasNext()) {
                    missed += " " + newUploadedFiles.get(iter.next());
                }
                addPageMessage(respage.getString("uploaded_files_not_deleted_or_not_exist") + ": " + missed, request);
            }
        }
        logMe("Entering Checks !submitted entered end forwarding page " + System.currentTimeMillis());
        logMe("Time Took for this block" + (System.currentTimeMillis() - t));
        forwardPage(getJSPPage(), request, response);
        return;
    } else {
        logMe("Entering Checks !submitted not entered  " + System.currentTimeMillis());
        //
        // VALIDATION / LOADING DATA
        //
        // If validation is required for this round, we will go through
        // each item and add an appropriate validation to the Validator
        //
        // Otherwise, we will just load the data into the DisplayItemBean
        // so that we can write to the database later.
        //
        // Validation is required if two conditions are met:
        // 1. The user clicked a "Save" button, not a "Confirm" button
        // 2. In this type of data entry servlet, when the user clicks
        // a Save button, the inputs are validated
        //
        boolean validate = fp.getBoolean(INPUT_CHECK_INPUTS) && validateInputOnFirstRound();
        // did the user click a "Save" button?
        // is validation required in this type of servlet when the user
        // clicks
        // "Save"?
        // We can conclude that the user is trying to save data; therefore,
        // set a request
        // attribute indicating that default values for items shouldn't be
        // displayed
        // in the application UI that will subsequently be displayed
        // TODO: find a better, less random place for this
        // session.setAttribute(HAS_DATA_FLAG, true);
        // section.setCheckInputs(fp.getBoolean(INPUT_CHECK_INPUTS));
        errors = new HashMap();
        // ArrayList items = section.getItems();
        discNotes = (FormDiscrepancyNotes) session.getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
        if (discNotes == null) {
            discNotes = new FormDiscrepancyNotes();
        }
        // populateNotesWithDBNoteCounts(discNotes, section);
        // all items- inlcude items in item groups and other single items
        List<DisplayItemWithGroupBean> allItems = section.getDisplayItemGroups();
        String attachedFilePath = Utils.getAttachedFilePath(currentStudy);
        DiscrepancyValidator v = new DiscrepancyValidator(request, discNotes);
        RuleValidator ruleValidator = new RuleValidator(request);
        LOGGER.debug("SZE 1  :: " + allItems.size());
        logMe("Looping inside !submitted  " + System.currentTimeMillis());
        for (int i = 0; i < allItems.size(); i++) {
            LOGGER.trace("===itering through items: " + i);
            DisplayItemWithGroupBean diwg = allItems.get(i);
            if (diwg.isInGroup()) {
                // for the items in groups
                DisplayItemGroupBean dgb = diwg.getItemGroup();
                List<DisplayItemGroupBean> dbGroups = diwg.getDbItemGroups();
                //dbGroups = diwg.getItemGroups();
                List<DisplayItemGroupBean> formGroups = new ArrayList<DisplayItemGroupBean>();
                LOGGER.debug("got db item group size " + dbGroups.size());
                if (validate) {
                    // int manualGroups = getManualRows(dbGroups2);
                    // logger.debug("+++ found manual rows from db group 2: " + manualGroups);
                    LOGGER.debug("===IF VALIDATE NOT A SINGLE ITEM: got to this part in the validation loop: " + dgb.getGroupMetaBean().getName());
                    // TODO next marker tbh 112007
                    // formGroups = validateDisplayItemGroupBean(v,
                    // dgb,dbGroups, formGroups,
                    // ruleValidator,groupOrdinalPLusItemOid);
                    formGroups = validateDisplayItemGroupBean(v, dgb, dbGroups, formGroups, request, response);
                    LOGGER.debug("form group size after validation " + formGroups.size());
                } else {
                    LOGGER.debug("+++ELSE NOT A SINGLE ITEM: got to this part in the validation loop: " + dgb.getGroupMetaBean().getName());
                    formGroups = loadFormValueForItemGroup(dgb, dbGroups, formGroups, eventDefinitionCRFId, request);
                    LOGGER.debug("form group size without validation " + formGroups.size());
                }
                diwg.setItemGroup(dgb);
                diwg.setItemGroups(formGroups);
                allItems.set(i, diwg);
            } else {
                // other single items
                DisplayItemBean dib = diwg.getSingleItem();
                // dib = (DisplayItemBean) allItems.get(i);
                if (validate) {
                    // generate input name here?
                    // DisplayItemGroupBean dgb = diwg.getItemGroup();
                    String itemName = getInputName(dib);
                    // no Item group for single item, so just use blank
                    // string as parameter for inputName
                    // this
                    dib = validateDisplayItemBean(v, dib, "", request);
                    // should be
                    // used,
                    // otherwise,
                    // DDE not
                    // working-jxu
                    LOGGER.debug("&&& found name: " + itemName);
                    LOGGER.debug("input VALIDATE " + itemName + ": " + fp.getString(itemName));
                    // dib.loadFormValue(fp.getString(itemName));
                    LOGGER.debug("input " + itemName + " has a response set of " + dib.getMetadata().getResponseSet().getOptions().size() + " options");
                } else {
                    String itemName = getInputName(dib);
                    LOGGER.debug("input NONVALIDATE " + itemName + ": " + fp.getString(itemName));
                    // dib.loadFormValue(itemName);
                    dib = loadFormValue(dib, request);
                // String itemName = getInputName(dib);
                // dib = loadFormValue(itemName);
                }
                ArrayList children = dib.getChildren();
                for (int j = 0; j < children.size(); j++) {
                    DisplayItemBean child = (DisplayItemBean) children.get(j);
                    // DisplayItemGroupBean dgb = diwg.getItemGroup();
                    String itemName = getInputName(child);
                    child.loadFormValue(fp.getString(itemName));
                    if (validate) {
                        // child = validateDisplayItemBean(v, child,
                        // itemName, ruleValidator, groupOrdinalPLusItemOid,
                        // false);
                        child = validateDisplayItemBean(v, child, itemName, request);
                    // was null changed value 092007 tbh
                    } else {
                        // child.loadFormValue(itemName);
                        child = loadFormValue(child, request);
                    }
                    LOGGER.debug("Checking child value for " + itemName + ": " + child.getData().getValue());
                    children.set(j, child);
                }
                dib.setChildren(children);
                diwg.setSingleItem(runDynamicsItemCheck(dib, null, request));
                // logger.trace("just set single item on line 447:
                // "+dib.getData().getValue());
                // items.set(i, dib);
                LOGGER.debug(" I : " + i);
                allItems.set(i, diwg);
            }
        }
        logMe("Loop ended  " + System.currentTimeMillis());
        //JN: This is the list that contains all the scd-shown items.
        List<ItemBean> itemBeansWithSCDShown = new ArrayList<ItemBean>();
        if (validate && section.getSection().hasSCDItem()) {
            logMe(" Validate and Loop  " + System.currentTimeMillis());
            for (int i = 0; i < allItems.size(); ++i) {
                DisplayItemBean dib = allItems.get(i).getSingleItem();
                ItemFormMetadataBean ifmb = dib.getMetadata();
                if (ifmb.getParentId() == 0) {
                    if (dib.getScdData().getScdSetsForControl().size() > 0) {
                        //for control item
                        //dib has to loadFormValue first. Here loadFormValue has been done in validateDisplayItemBean(v, dib, "")
                        section.setShowSCDItemIds(SimpleConditionalDisplayService.conditionalDisplayToBeShown(dib, section.getShowSCDItemIds()));
                    }
                    if (dib.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId() > 0) {
                        //for scd item
                        //a control item is always before its scd item
                        dib.setIsSCDtoBeShown(section.getShowSCDItemIds().contains(dib.getMetadata().getItemId()));
                        if (dib.getIsSCDtoBeShown())
                            itemBeansWithSCDShown.add(dib.getItem());
                        validateSCDItemBean(v, dib);
                    }
                    ArrayList<DisplayItemBean> children = dib.getChildren();
                    for (int j = 0; j < children.size(); j++) {
                        DisplayItemBean child = children.get(j);
                        if (child.getScdData().getScdSetsForControl().size() > 0) {
                            //for control item
                            //dib has to loadFormValue first. Here loadFormValue has been done in validateDisplayItemBean(v, dib, "")
                            section.setShowSCDItemIds(SimpleConditionalDisplayService.conditionalDisplayToBeShown(child, section.getShowSCDItemIds()));
                        }
                        if (child.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId() > 0) {
                            //for scd item
                            //a control item is always before its scd item
                            child.setIsSCDtoBeShown(section.getShowSCDItemIds().contains(child.getMetadata().getItemId()));
                            if (child.getIsSCDtoBeShown())
                                itemBeansWithSCDShown.add(dib.getItem());
                            validateSCDItemBean(v, child);
                        }
                    }
                }
            }
            logMe(" Validate and Loop end  " + System.currentTimeMillis());
        }
        logMe(" Validate and Loop end  " + System.currentTimeMillis());
        //JN:calling again here, for the items with simple conditional display and rules.
        List<RuleSetBean> ruleSets = createAndInitializeRuleSet(currentStudy, studyEventDefinition, crfVersionBean, studyEventBean, ecb, true, request, response, itemBeansWithSCDShown);
        boolean shouldRunRules = getRuleSetService(request).shouldRunRulesForRuleSets(ruleSets, phase2);
        // this.getItemMetadataService().resetItemCounter();
        HashMap<String, ArrayList<String>> groupOrdinalPLusItemOid = null;
        groupOrdinalPLusItemOid = runRules(allItems, ruleSets, true, shouldRunRules, MessageType.ERROR, phase2, ecb, request);
        logMe("allItems  Loop begin  " + System.currentTimeMillis());
        for (int i = 0; i < allItems.size(); i++) {
            DisplayItemWithGroupBean diwg = allItems.get(i);
            if (diwg.isInGroup()) {
                // for the items in groups
                DisplayItemGroupBean dgb = diwg.getItemGroup();
                List<DisplayItemGroupBean> dbGroups = diwg.getDbItemGroups();
                //dbGroups = diwg.getItemGroups();
                // tbh 01/2010 change the group list?
                List<DisplayItemGroupBean> formGroups = new ArrayList<DisplayItemGroupBean>();
                // items again?
                if (validate) {
                    // int manualGroups = getManualRows(dbGroups2);
                    // logger.debug("+++ found manual rows for db group2: " + manualGroups);
                    formGroups = validateDisplayItemGroupBean(v, dgb, dbGroups, formGroups, ruleValidator, groupOrdinalPLusItemOid, request, response);
                    // formGroups = validateDisplayItemGroupBean(v, dgb,
                    // dbGroups, formGroups);
                    LOGGER.debug("*** form group size after validation " + formGroups.size());
                }
                diwg.setItemGroup(dgb);
                diwg.setItemGroups(formGroups);
                allItems.set(i, diwg);
            } else {
                // other single items
                DisplayItemBean dib = diwg.getSingleItem();
                // dib = (DisplayItemBean) allItems.get(i);
                if (validate) {
                    String itemName = getInputName(dib);
                    //
                    dib = validateDisplayItemBean(v, dib, "", ruleValidator, groupOrdinalPLusItemOid, false, null, request);
                // / dib = validateDisplayItemBean(v, dib, "");// this
                }
                ArrayList children = dib.getChildren();
                for (int j = 0; j < children.size(); j++) {
                    DisplayItemBean child = (DisplayItemBean) children.get(j);
                    // DisplayItemGroupBean dgb = diwg.getItemGroup();
                    String itemName = getInputName(child);
                    child.loadFormValue(fp.getString(itemName));
                    if (validate) {
                        child = validateDisplayItemBean(v, child, "", ruleValidator, groupOrdinalPLusItemOid, false, null, request);
                    // child = validateDisplayItemBean(v, child,
                    // itemName);
                    }
                    children.set(j, child);
                    LOGGER.debug(" J (children): " + j);
                }
                dib.setChildren(children);
                diwg.setSingleItem(runDynamicsItemCheck(dib, null, request));
                LOGGER.debug(" I : " + i);
                allItems.set(i, diwg);
            }
        }
        logMe("allItems  Loop end  " + System.currentTimeMillis());
        // YW, 2-1-2008 <<
        // A map from item name to item bean object.
        HashMap<String, ItemBean> scoreItems = new HashMap<String, ItemBean>();
        HashMap<String, String> scoreItemdata = new HashMap<String, String>();
        HashMap<String, ItemDataBean> oldItemdata = prepareSectionItemdataObject(sb.getId(), request);
        // hold all item names of changed ItemBean in current section
        TreeSet<String> changedItems = new TreeSet<String>();
        // holds complete disply item beans for checking against 'request
        // for change' restriction
        ArrayList<DisplayItemBean> changedItemsList = new ArrayList<DisplayItemBean>();
        // key is repeating item name, value is its display item group bean
        HashMap<String, DisplayItemGroupBean> changedItemsMap = new HashMap<String, DisplayItemGroupBean>();
        // key is itemid, value is set of itemdata-ordinal
        HashMap<Integer, TreeSet<Integer>> itemOrdinals = prepareItemdataOrdinals(request);
        // prepare item data for scoring
        updateDataOrdinals(allItems);
        section.setDisplayItemGroups(allItems);
        scoreItems = prepareScoreItems(request);
        scoreItemdata = prepareScoreItemdata(request);
        logMe("allItems 2 Loop begin  " + System.currentTimeMillis());
        for (int i = 0; i < allItems.size(); i++) {
            DisplayItemWithGroupBean diwb = allItems.get(i);
            if (diwb.isInGroup()) {
                // for the items in groups
                DisplayItemGroupBean digb = diwb.getItemGroup();
                List<DisplayItemGroupBean> dbGroups = diwb.getDbItemGroups();
                for (int j = 0; j < dbGroups.size(); j++) {
                    DisplayItemGroupBean displayGroup = dbGroups.get(j);
                    List<DisplayItemBean> items = displayGroup.getItems();
                    if ("remove".equalsIgnoreCase(displayGroup.getEditFlag())) {
                        for (DisplayItemBean displayItem : items) {
                            if (displayItem.getMetadata().isShowItem() && digb.getGroupMetaBean().isShowGroup()) {
                                int itemId = displayItem.getItem().getId();
                                int ordinal = displayItem.getData().getOrdinal();
                                if (itemOrdinals.containsKey(itemId)) {
                                    itemOrdinals.get(itemId).remove(ordinal);
                                }
                                if (scoreItemdata.containsKey(itemId + "_" + ordinal)) {
                                    scoreItemdata.remove(itemId + "_" + ordinal);
                                }
                                changedItems.add(displayItem.getItem().getName());
                                changedItemsList.add(displayItem);
                                String formName = displayItem.getItem().getName();
                                // logger.debug("SET: formName:" + formName);
                                if (displayGroup.isAuto()) {
                                    formName = getGroupItemInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                    LOGGER.debug("GET: changed formName to " + formName);
                                } else {
                                    formName = getGroupItemManualInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                    LOGGER.debug("GET-MANUAL: changed formName to " + formName);
                                }
                                changedItemsMap.put(formName, displayGroup);
                                LOGGER.debug("adding to changed items map: " + formName);
                            }
                        }
                    }
                }
                List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
                int groupsize = dgbs.size();
                HashMap<Integer, Integer> maxOrdinals = new HashMap<Integer, Integer>();
                boolean first = true;
                for (int j = 0; j < dgbs.size(); j++) {
                    DisplayItemGroupBean displayGroup = dgbs.get(j);
                    List<DisplayItemBean> items = displayGroup.getItems();
                    boolean isAdd = "add".equalsIgnoreCase(displayGroup.getEditFlag()) ? true : false;
                    for (DisplayItemBean displayItem : items) {
                        ItemBean ib = displayItem.getItem();
                        String itemName = ib.getName();
                        int itemId = ib.getId();
                        if (first) {
                            maxOrdinals.put(itemId, iddao.getMaxOrdinalForGroup(ecb, sb, displayGroup.getItemGroupBean()));
                        }
                        ItemDataBean idb = displayItem.getData();
                        String value = idb.getValue();
                        scoreItems.put(itemName, ib);
                        int ordinal = displayItem.getData().getOrdinal();
                        if (isAdd && scoreItemdata.containsKey(itemId + "_" + ordinal)) {
                            int formMax = 1;
                            if (maxOrdinals.containsKey(itemId)) {
                                formMax = maxOrdinals.get(itemId);
                            }
                            int dbMax = iddao.getMaxOrdinalForGroup(ecb, sb, displayGroup.getItemGroupBean());
                            ordinal = ordinal >= dbMax ? formMax + 1 : ordinal;
                            maxOrdinals.put(itemId, ordinal);
                            displayItem.getData().setOrdinal(ordinal);
                            scoreItemdata.put(itemId + "_" + ordinal, value);
                        } else {
                            scoreItemdata.put(itemId + "_" + ordinal, value);
                        }
                        if (itemOrdinals.containsKey(itemId)) {
                            itemOrdinals.get(itemId).add(ordinal);
                        } else {
                            TreeSet<Integer> ordinalSet = new TreeSet<Integer>();
                            ordinalSet.add(ordinal);
                            itemOrdinals.put(itemId, ordinalSet);
                        }
                        if (isChanged(displayItem, oldItemdata, attachedFilePath)) {
                            changedItems.add(itemName);
                            changedItemsList.add(displayItem);
                            String formName = displayItem.getItem().getName();
                            // logger.debug("SET: formName:" + formName);
                            if (displayGroup.isAuto()) {
                                formName = getGroupItemInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                LOGGER.debug("RESET: formName group-item-input:" + formName);
                            } else {
                                formName = getGroupItemManualInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                LOGGER.debug("RESET: formName group-item-input-manual:" + formName);
                            }
                            changedItemsMap.put(formName, displayGroup);
                            LOGGER.debug("adding to changed items map: " + formName);
                        }
                    }
                    first = false;
                }
            } else {
                DisplayItemBean dib = diwb.getSingleItem();
                ItemBean ib = dib.getItem();
                ItemDataBean idb = dib.getData();
                int itemId = ib.getId();
                String itemName = ib.getName();
                String value = idb.getValue();
                scoreItems.put(itemName, ib);
                // for items which are not in any group, their ordinal is
                // set as 1
                TreeSet<Integer> ordinalset = new TreeSet<Integer>();
                ordinalset.add(1);
                itemOrdinals.put(itemId, ordinalset);
                scoreItemdata.put(itemId + "_" + 1, value);
                if (isChanged(idb, oldItemdata, dib, attachedFilePath)) {
                    changedItems.add(itemName);
                    changedItemsList.add(dib);
                // changedItemsMap.put(dib.getItem().getName(), new
                // DisplayItemGroupBean());
                }
                ArrayList children = dib.getChildren();
                for (int j = 0; j < children.size(); j++) {
                    DisplayItemBean child = (DisplayItemBean) children.get(j);
                    ItemBean cib = child.getItem();
                    scoreItems.put(cib.getName(), cib);
                    TreeSet<Integer> cordinalset = new TreeSet<Integer>();
                    cordinalset.add(1);
                    itemOrdinals.put(itemId, cordinalset);
                    scoreItemdata.put(cib.getId() + "_" + 1, child.getData().getValue());
                    if (isChanged(child.getData(), oldItemdata, child, attachedFilePath)) {
                        changedItems.add(itemName);
                        changedItemsList.add(child);
                    // changedItemsMap.put(itemName, new
                    // DisplayItemGroupBean());
                    }
                }
            }
        }
        logMe("allItems 2 Loop end  " + System.currentTimeMillis());
        // do calculation for 'calculation' and 'group-calculation' type
        // items
        // and write the result in DisplayItemBean's ItemDateBean - data
        ScoreItemValidator sv = new ScoreItemValidator(request, discNotes);
        // *** doing calc here, load it where? ***
        SessionManager sm = (SessionManager) request.getSession().getAttribute("sm");
        ScoreCalculator sc = new ScoreCalculator(sm, ecb, ub);
        logMe("allItems 3 Loop begin  " + System.currentTimeMillis());
        for (int i = 0; i < allItems.size(); i++) {
            DisplayItemWithGroupBean diwb = allItems.get(i);
            if (diwb.isInGroup()) {
                List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
                for (int j = 0; j < dgbs.size(); j++) {
                    DisplayItemGroupBean displayGroup = dgbs.get(j);
                    List<DisplayItemBean> items = displayGroup.getItems();
                    for (DisplayItemBean displayItem : items) {
                        ItemFormMetadataBean ifmb = displayItem.getMetadata();
                        int responseTypeId = ifmb.getResponseSet().getResponseTypeId();
                        if (responseTypeId == 8 || responseTypeId == 9) {
                            StringBuffer err = new StringBuffer();
                            ResponseOptionBean robBean = (ResponseOptionBean) ifmb.getResponseSet().getOptions().get(0);
                            String value = "";
                            String inputName = "";
                            // getFormInputOrdinal() here, tbh 06/2009
                            if (displayGroup.isAuto()) {
                                inputName = getGroupItemInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                LOGGER.debug("returning input name: " + inputName);
                            } else {
                                inputName = getGroupItemManualInputName(displayGroup, displayGroup.getFormInputOrdinal(), displayItem);
                                LOGGER.debug("returning input name: " + inputName);
                            }
                            if (robBean.getValue().startsWith("func: getexternalvalue") || robBean.getValue().startsWith("func: getExternalValue")) {
                                value = fp.getString(inputName);
                                LOGGER.debug("*** just set " + fp.getString(inputName) + " for line 815 " + displayItem.getItem().getName() + " with input name " + inputName);
                            } else {
                                value = sc.doCalculation(displayItem, scoreItems, scoreItemdata, itemOrdinals, err, displayItem.getData().getOrdinal());
                            }
                            displayItem.loadFormValue(value);
                            if (isChanged(displayItem, oldItemdata, attachedFilePath)) {
                                changedItems.add(displayItem.getItem().getName());
                                changedItemsList.add(displayItem);
                            }
                            request.setAttribute(inputName, value);
                            if (validate) {
                                displayItem = validateCalcTypeDisplayItemBean(sv, displayItem, inputName, request);
                                if (err.length() > 0) {
                                    Validation validation = new Validation(Validator.CALCULATION_FAILED);
                                    validation.setErrorMessage(err.toString());
                                    sv.addValidation(inputName, validation);
                                }
                            }
                        }
                    }
                }
            } else {
                DisplayItemBean dib = diwb.getSingleItem();
                ItemFormMetadataBean ifmb = dib.getMetadata();
                int responseTypeId = ifmb.getResponseSet().getResponseTypeId();
                if (responseTypeId == 8 || responseTypeId == 9) {
                    StringBuffer err = new StringBuffer();
                    ResponseOptionBean robBean = (ResponseOptionBean) ifmb.getResponseSet().getOptions().get(0);
                    String value = "";
                    if (robBean.getValue().startsWith("func: getexternalvalue") || robBean.getValue().startsWith("func: getExternalValue")) {
                        String itemName = getInputName(dib);
                        value = fp.getString(itemName);
                        LOGGER.debug("just set " + fp.getString(itemName) + " for " + dib.getItem().getName());
                        LOGGER.debug("found in fp: " + fp.getString(dib.getItem().getName()));
                    // logger.debug("scoreitemdata: " +
                    // scoreItemdata.toString());
                    } else {
                        value = sc.doCalculation(dib, scoreItems, scoreItemdata, itemOrdinals, err, 1);
                    }
                    dib.loadFormValue(value);
                    if (isChanged(dib.getData(), oldItemdata, dib, attachedFilePath)) {
                        changedItems.add(dib.getItem().getName());
                        changedItemsList.add(dib);
                    // changedItemsMap.put(dib.getItem().getName(), new
                    // DisplayItemGroupBean());
                    }
                    String inputName = getInputName(dib);
                    request.setAttribute(inputName, value);
                    if (validate) {
                        dib = validateCalcTypeDisplayItemBean(sv, dib, "", request);
                        if (err.length() > 0) {
                            Validation validation = new Validation(Validator.CALCULATION_FAILED);
                            validation.setErrorMessage(err.toString());
                            sv.addValidation(inputName, validation);
                        }
                    }
                }
                ArrayList children = dib.getChildren();
                for (int j = 0; j < children.size(); j++) {
                    DisplayItemBean child = (DisplayItemBean) children.get(j);
                    ItemFormMetadataBean cifmb = child.getMetadata();
                    int resTypeId = cifmb.getResponseSet().getResponseTypeId();
                    if (resTypeId == 8 || resTypeId == 9) {
                        StringBuffer cerr = new StringBuffer();
                        child.getDbData().setValue(child.getData().getValue());
                        ResponseOptionBean crobBean = (ResponseOptionBean) cifmb.getResponseSet().getOptions().get(0);
                        String cvalue = "";
                        if (crobBean.getValue().startsWith("func: getexternalvalue") || crobBean.getValue().startsWith("func: getExternalValue")) {
                            String itemName = getInputName(child);
                            cvalue = fp.getString(itemName);
                            LOGGER.debug("just set " + fp.getString(itemName) + " for " + child.getItem().getName());
                        } else {
                            cvalue = sc.doCalculation(child, scoreItems, scoreItemdata, itemOrdinals, cerr, 1);
                        }
                        child.loadFormValue(cvalue);
                        if (isChanged(child.getData(), oldItemdata, child, attachedFilePath)) {
                            changedItems.add(child.getItem().getName());
                            changedItemsList.add(child);
                        // changedItemsMap.put(child.getItem().getName(),
                        // new DisplayItemGroupBean());
                        }
                        String cinputName = getInputName(child);
                        request.setAttribute(cinputName, cvalue);
                        if (validate) {
                            child = validateCalcTypeDisplayItemBean(sv, child, "", request);
                            if (cerr.length() > 0) {
                                Validation cvalidation = new Validation(Validator.CALCULATION_FAILED);
                                cvalidation.setErrorMessage(cerr.toString());
                                sv.addValidation(cinputName, cvalidation);
                            }
                        }
                    }
                    children.set(j, child);
                }
            }
        }
        logMe("allItems 3 Loop end  " + System.currentTimeMillis());
        // YW >>
        // we have to do this since we loaded all the form values into the
        // display
        // item beans above
        // section.setItems(items);
        // setting this AFTER we populate notes - will that make a difference?
        section.setDisplayItemGroups(allItems);
        // logger.debug("+++ try to populate notes");
        section = populateNotesWithDBNoteCounts(discNotes, section, request);
        populateInstantOnChange(request.getSession(), ecb, section);
        if (currentStudy.getStudyParameterConfig().getInterviewerNameRequired().equals("yes")) {
            v.addValidation(INPUT_INTERVIEWER, Validator.NO_BLANKS);
        }
        if (currentStudy.getStudyParameterConfig().getInterviewDateRequired().equals("yes")) {
            v.addValidation(INPUT_INTERVIEW_DATE, Validator.NO_BLANKS);
        }
        if (!StringUtil.isBlank(fp.getString(INPUT_INTERVIEW_DATE))) {
            v.addValidation(INPUT_INTERVIEW_DATE, Validator.IS_A_DATE);
            v.alwaysExecuteLastValidation(INPUT_INTERVIEW_DATE);
        }
        if (section.getSection().hasSCDItem()) {
            section = SCDItemDisplayInfo.generateSCDDisplayInfo(section, this.getServletPage(request).equals(Page.INITIAL_DATA_ENTRY) || this.getServletPage(request).equals(Page.ADMIN_EDIT_SERVLET) && !this.isAdminForcedReasonForChange(request));
        }
        // logger.debug("about to validate: " + v.getKeySet());
        errors = v.validate();
        // tbh >>
        if (this.isAdminForcedReasonForChange(request) && this.isAdministrativeEditing() && errors.isEmpty()) {
            // "You have changed data after this CRF was marked complete. "
            // +
            // "You must provide a Reason For Change discrepancy note for this item before you can save this updated information."
            String error = respage.getString("reason_for_change_error");
            // "Please enter a reason for change discrepancy note before saving."
            // ;
            int nonforcedChanges = 0;
            // items map
            if (changedItemsList.size() > 0) {
                LOGGER.debug("found admin force reason for change: changed items " + changedItems.toString() + " and changed items list: " + changedItemsList.toString() + " changed items map: " + changedItemsMap.toString());
                logMe("DisplayItemBean  Loop begin  " + System.currentTimeMillis());
                for (DisplayItemBean displayItem : changedItemsList) {
                    String formName = getInputName(displayItem);
                    ItemDataBean idb = displayItem.getData();
                    ItemBean item_bean = displayItem.getItem();
                    ItemFormMetadataBean ifmb = displayItem.getMetadata();
                    LOGGER.debug("-- found group label " + ifmb.getGroupLabel());
                    if (!ifmb.getGroupLabel().equalsIgnoreCase("Ungrouped") && !ifmb.getGroupLabel().equalsIgnoreCase("")) {
                        // << tbh 11/2009 sometimes the group label is blank instead of ungrouped???
                        Iterator iter = changedItemsMap.entrySet().iterator();
                        while (iter.hasNext()) {
                            Map.Entry<String, DisplayItemGroupBean> pairs = (Map.Entry) iter.next();
                            String formName2 = pairs.getKey();
                            DisplayItemGroupBean dgb = pairs.getValue();
                            // logger.debug("found auto: " +
                            // dgb.isAuto());
                            String testFormName = "";
                            if (dgb.isAuto()) {
                                // testFormName = getGroupItemInputName(dgb, dgb.getFormInputOrdinal(), getManualRows(dgbs), displayItem);
                                testFormName = getGroupItemInputName(dgb, dgb.getFormInputOrdinal(), displayItem);
                            } else {
                                testFormName = getGroupItemManualInputName(dgb, dgb.getFormInputOrdinal(), displayItem);
                            }
                            LOGGER.debug("found test form name: " + testFormName);
                            // if our test is the same with both the display
                            // item and the display group ...
                            // logger.debug("comparing " +
                            // testFormName + " and " + formName2);
                            int existingNotes = dndao.findNumExistingNotesForItem(idb.getId());
                            if (testFormName.equals(formName2)) {
                                formName = formName2;
                                this.setReasonForChangeError(ecb, item_bean, idb, formName, error, request);
                                changedItemsMap.remove(formName2);
                                LOGGER.debug("form name changed: " + formName);
                                break;
                            // .., send it as the form name
                            }
                        // ... otherwise, don't touch it
                        // how to tell vs. manual and just plain input?
                        }
                    } else {
                        this.setReasonForChangeError(ecb, item_bean, idb, formName, error, request);
                        LOGGER.debug("form name added: " + formName);
                    }
                }
                logMe("DisplayItemBean  Loop end  " + System.currentTimeMillis());
            }
            if (nonforcedChanges > 0) {
            // do smething here?
            }
        }
        LOGGER.debug("errors here: " + errors.toString());
        // <<
        logMe("error check  Loop begin  " + System.currentTimeMillis());
        if (errors.isEmpty() && shouldRunRules) {
            LOGGER.debug("Errors was empty");
            if (session.getAttribute("rulesErrors") != null) {
                // rules have already generated errors, Let's compare old
                // error list with new
                // error list, if lists not same show errors.
                HashMap h = ruleValidator.validate();
                Set<String> a = (Set<String>) session.getAttribute("rulesErrors");
                Set<String> ba = h.keySet();
                Boolean showErrors = false;
                for (Object key : ba) {
                    if (!a.contains(key)) {
                        showErrors = true;
                    }
                }
                if (showErrors) {
                    errors = h;
                    if (errors.size() > 0) {
                        session.setAttribute("shouldRunValidation", "1");
                        session.setAttribute("rulesErrors", errors.keySet());
                    } else {
                        session.setAttribute("shouldRunValidation", null);
                        session.setAttribute("rulesErrors", null);
                    }
                } else {
                    session.setAttribute("shouldRunValidation", null);
                    session.setAttribute("rulesErrors", null);
                }
            } else if (session.getAttribute("shouldRunValidation") != null && session.getAttribute("shouldRunValidation").toString().equals("1")) {
                session.setAttribute("shouldRunValidation", null);
                session.setAttribute("rulesErrors", null);
            } else {
                errors = ruleValidator.validate();
                if (errors.size() > 0) {
                    session.setAttribute("shouldRunValidation", "1");
                    session.setAttribute("rulesErrors", errors.keySet());
                }
            }
        }
        if (!errors.isEmpty()) {
            LOGGER.debug("threw an error with data entry...");
            // copying below three lines, tbh 03/2010
            String[] textFields = { INPUT_INTERVIEWER, INPUT_INTERVIEW_DATE };
            fp.setCurrentStringValuesAsPreset(textFields);
            setPresetValues(fp.getPresetValues(), request);
            // YW, 2-4-2008 <<
            logMe("!errors if  Loop begin  " + System.currentTimeMillis());
            HashMap<String, ArrayList<String>> siErrors = sv.validate();
            if (siErrors != null && !siErrors.isEmpty()) {
                Iterator iter = siErrors.keySet().iterator();
                while (iter.hasNext()) {
                    String fieldName = iter.next().toString();
                    errors.put(fieldName, siErrors.get(fieldName));
                }
            }
            // we should 'shift' the names here, tbh 02/2010
            // need: total number of rows, manual rows, all row names
            // plus: error names
            Iterator iter2 = errors.keySet().iterator();
            while (iter2.hasNext()) {
                String fieldName = iter2.next().toString();
                LOGGER.debug("found error " + fieldName);
            }
            //                for (int i = 0; i < allItems.size(); i++) {
            //                    DisplayItemWithGroupBean diwb = allItems.get(i);
            //
            //                    if (diwb.isInGroup()) {
            //                        List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
            //                        logger.debug("found manual rows " + getManualRows(dgbs) + " and total rows " + dgbs.size() + " from ordinal " + diwb.getOrdinal());
            //                    }
            //                }
            errors = reshuffleErrorGroupNamesKK(errors, allItems, request);
            reshuffleReasonForChangeHashAndDiscrepancyNotes(allItems, request, ecb);
            // reset manual rows, so that we can catch errors correctly
            // but it needs to be set per block of repeating items?  what if there are two or more?
            /*
                int manualRows = 0; // getManualRows(formGroups);
                for (int i = 0; i < allItems.size(); i++) {
                    DisplayItemWithGroupBean diwb = allItems.get(i);

                    if (diwb.isInGroup()) {
                        List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
                        manualRows = getManualRows(dgbs);
                    }
                }
                */
            //request.setAttribute("manualRows", new Integer(manualRows));
            Iterator iter3 = errors.keySet().iterator();
            while (iter3.hasNext()) {
                String fieldName = iter3.next().toString();
                LOGGER.debug("found error after shuffle " + fieldName);
            }
            //Mantis Issue: 8116. Parsist the markComplete chebox on error
            request.setAttribute("markComplete", fp.getString(INPUT_MARK_COMPLETE));
            // << tbh, 02/2010
            // YW >>
            // copied
            request.setAttribute(BEAN_DISPLAY, section);
            request.setAttribute(BEAN_ANNOTATIONS, fp.getString(INPUT_ANNOTATIONS));
            setInputMessages(errors, request);
            addPageMessage(respage.getString("errors_in_submission_see_below"), request);
            request.setAttribute("hasError", "true");
            // addPageMessage("To override these errors and keep the data as
            // you
            // entered it, click one of the \"Confirm\" buttons. ");
            // if (section.isCheckInputs()) {
            // addPageMessage("Please notice that you must enter data for
            // the
            // <b>required</b> entries.");
            // }
            // we do not save any DNs if we get here, so we have to set it back into session...
            session.setAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME, discNotes);
            // << tbh 01/2010
            setUpPanel(section);
            forwardPage(getJSPPage(), request, response);
        } else {
            //reshuffleReasonForChangeHashAndDiscrepancyNotes( allItems, request, ecb);
            LOGGER.debug("Do we hit this in save ?????");
            logMe("Do we hit this in save ????  " + System.currentTimeMillis());
            boolean success = true;
            boolean temp = true;
            // save interviewer name and date into DB
            ecb.setInterviewerName(fp.getString(INPUT_INTERVIEWER));
            if (!StringUtil.isBlank(fp.getString(INPUT_INTERVIEW_DATE))) {
                ecb.setDateInterviewed(fp.getDate(INPUT_INTERVIEW_DATE));
            } else {
                ecb.setDateInterviewed(null);
            }
            if (ecdao == null) {
                ecdao = new EventCRFDAO(getDataSource());
            }
            // set validator id for DDE
            DataEntryStage stage = ecb.getStage();
            if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE) || stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY)) {
                ecb.setValidatorId(ub.getId());
            }
            // for Administrative editing
            if (studyEventBean.getSubjectEventStatus().equals(SubjectEventStatus.SIGNED) && changedItemsList.size() > 0) {
                studyEventBean.setSubjectEventStatus(SubjectEventStatus.COMPLETED);
                studyEventBean.setUpdater(ub);
                studyEventBean.setUpdatedDate(new Date());
                seDao.update(studyEventBean);
            }
            // If the Study Subject's Satus is signed and we save a section
            // , change status to available
            LOGGER.debug("Status of Study Subject {}", ssb.getStatus().getName());
            if (ssb.getStatus() == Status.SIGNED && changedItemsList.size() > 0) {
                LOGGER.debug("Status of Study Subject is Signed we are updating");
                StudySubjectDAO studySubjectDao = new StudySubjectDAO(getDataSource());
                ssb.setStatus(Status.AVAILABLE);
                ssb.setUpdater(ub);
                ssb.setUpdatedDate(new Date());
                studySubjectDao.update(ssb);
            }
            if (ecb.isSdvStatus() && changedItemsList.size() > 0) {
                LOGGER.debug("Status of Study Subject is SDV we are updating");
                StudySubjectDAO studySubjectDao = new StudySubjectDAO(getDataSource());
                ssb.setStatus(Status.AVAILABLE);
                ssb.setUpdater(ub);
                ssb.setUpdatedDate(new Date());
                studySubjectDao.update(ssb);
                ecb.setSdvStatus(false);
                ecb.setSdvUpdateId(ub.getId());
            }
            ecb = (EventCRFBean) ecdao.update(ecb);
            // save discrepancy notes into DB
            FormDiscrepancyNotes fdn = (FormDiscrepancyNotes) session.getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
            dndao = new DiscrepancyNoteDAO(getDataSource());
            AddNewSubjectServlet.saveFieldNotes(INPUT_INTERVIEWER, fdn, dndao, ecb.getId(), "EventCRF", currentStudy);
            AddNewSubjectServlet.saveFieldNotes(INPUT_INTERVIEW_DATE, fdn, dndao, ecb.getId(), "EventCRF", currentStudy);
            // items = section.getItems();
            allItems = section.getDisplayItemGroups();
            int nextOrdinal = 0;
            LOGGER.debug("all items before saving into DB" + allItems.size());
            this.output(allItems);
            //TODO:Seems longer here, check this
            logMe("DisplayItemWithGroupBean allitems4 " + System.currentTimeMillis());
            for (int i = 0; i < allItems.size(); i++) {
                DisplayItemWithGroupBean diwb = allItems.get(i);
                // from executing writeToDB.
                if (diwb.isInGroup()) {
                    List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
                    // using the above gets us the correct number of manual groups, tbh 01/2010
                    List<DisplayItemGroupBean> dbGroups = diwb.getDbItemGroups();
                    LOGGER.debug("item group size: " + dgbs.size());
                    LOGGER.debug("item db-group size: " + dbGroups.size());
                    for (int j = 0; j < dgbs.size(); j++) {
                        DisplayItemGroupBean displayGroup = dgbs.get(j);
                        List<DisplayItemBean> items = displayGroup.getItems();
                        // this ordinal will only useful to create a new
                        // item data
                        // update an item data won't touch its ordinal
                        //  int nextOrdinal = iddao.getMaxOrdinalForGroup(ecb, sb, displayGroup.getItemGroupBean()) + 1;
                        // Determine if any items in this group have data.  If so we need to undelete and previously deleted items.
                        boolean undelete = false;
                        for (DisplayItemBean displayItem : items) {
                            String currItemVal = displayItem.getData().getValue();
                            if (currItemVal != null && !currItemVal.equals("")) {
                                undelete = true;
                                break;
                            }
                        }
                        for (DisplayItemBean displayItem : items) {
                            String fileName = this.addAttachedFilePath(displayItem, attachedFilePath);
                            boolean writeDN = true;
                            displayItem.setEditFlag(displayGroup.getEditFlag());
                            LOGGER.debug("group item value: " + displayItem.getData().getValue());
                            //                if ("add".equalsIgnoreCase(displayItem.getEditFlag()) && fileName.length() > 0 && !newUploadedFiles.containsKey(fileName)) {
                            //                    displayItem.getData().setValue("");
                            //               }
                            //15350, this particular logic, takes into consideration that a DN is created properly as long as the item data record exists and it fails to get created when it doesnt.
                            //so, we are expanding the logic from writeToDb method to avoid creating duplicate records.
                            writeDN = writeDN(displayItem);
                            //pulling from dataset instead of database and correcting the flawed logic of using the database ordinals as max ordinal...
                            nextOrdinal = displayItem.getData().getOrdinal();
                            temp = writeToDB(displayItem, iddao, nextOrdinal, request);
                            LOGGER.debug("just executed writeToDB - 1");
                            LOGGER.debug("next ordinal: " + nextOrdinal);
                            // Undelete item if any item in the repeating group has data.
                            if (undelete && displayItem.getDbData() != null && displayItem.getDbData().isDeleted()) {
                                iddao.undelete(displayItem.getDbData().getId(), ub.getId());
                            }
                            if (temp && newUploadedFiles.containsKey(fileName)) {
                                newUploadedFiles.remove(fileName);
                            }
                            // maybe put ordinal in the place of j? maybe subtract max rows from next ordinal if j is gt
                            // next ordinal?
                            String inputName = getGroupItemInputName(displayGroup, j, displayItem);
                            // String inputName2 = getGroupItemManualInputName(displayGroup, j, displayItem);
                            if (!displayGroup.isAuto()) {
                                LOGGER.trace("not auto");
                                inputName = this.getGroupItemManualInputName(displayGroup, j, displayItem);
                            }
                            //htaycher last DN is not stored for new rows
                            //                                if (j == dgbs.size() - 1) {
                            //                                    // LAST ONE
                            //                                    logger.trace("last one");
                            //                                    int ordinal = j - this.getManualRows(dgbs);
                            //                                    logger.debug("+++ found manual rows from line 1326: " + ordinal);
                            //                                    inputName = getGroupItemInputName(displayGroup, ordinal, displayItem);
                            //                                }
                            // logger.trace("&&& we get previous looking at input name: " + inputName + " " + inputName2);
                            LOGGER.trace("&&& we get previous looking at input name: " + inputName);
                            // input name 2 removed from below
                            inputName = displayItem.getFieldName();
                            if (writeDN) {
                                AddNewSubjectServlet.saveFieldNotes(inputName, fdn, dndao, displayItem.getData().getId(), "itemData", currentStudy, ecb.getId());
                            }
                            success = success && temp;
                        }
                    }
                    for (int j = 0; j < dbGroups.size(); j++) {
                        DisplayItemGroupBean displayGroup = dbGroups.get(j);
                        //JN: Since remove button is gone, the following code can be commented out, however it needs to be tested? Can be tackled when handling discrepancy note w/repeating groups issues.
                        if ("remove".equalsIgnoreCase(displayGroup.getEditFlag())) {
                            List<DisplayItemBean> items = displayGroup.getItems();
                            for (DisplayItemBean displayItem : items) {
                                String fileName = this.addAttachedFilePath(displayItem, attachedFilePath);
                                displayItem.setEditFlag(displayGroup.getEditFlag());
                                LOGGER.debug("group item value: " + displayItem.getData().getValue());
                                //               if ("add".equalsIgnoreCase(displayItem.getEditFlag()) && fileName.length() > 0 && !newUploadedFiles.containsKey(fileName)) {
                                //                   displayItem.getData().setValue("");
                                //               }
                                temp = writeToDB(displayItem, iddao, 0, request);
                                LOGGER.debug("just executed writeToDB - 2");
                                if (temp && newUploadedFiles.containsKey(fileName)) {
                                    newUploadedFiles.remove(fileName);
                                }
                                // just use 0 here since update doesn't
                                // touch ordinal
                                success = success && temp;
                            }
                        }
                    }
                } else {
                    DisplayItemBean dib = diwb.getSingleItem();
                    // TODO work on this line
                    //  this.addAttachedFilePath(dib, attachedFilePath);
                    String fileName = addAttachedFilePath(dib, attachedFilePath);
                    boolean writeDN = writeDN(dib);
                    temp = writeToDB(dib, iddao, 1, request);
                    LOGGER.debug("just executed writeToDB - 3");
                    if (temp && (newUploadedFiles.containsKey(dib.getItem().getId() + "") || newUploadedFiles.containsKey(fileName))) {
                        // so newUploadedFiles will contain only failed file
                        // items;
                        newUploadedFiles.remove(dib.getItem().getId() + "");
                        newUploadedFiles.remove(fileName);
                    }
                    String inputName = getInputName(dib);
                    LOGGER.trace("3 - found input name: " + inputName);
                    if (writeDN)
                        AddNewSubjectServlet.saveFieldNotes(inputName, fdn, dndao, dib.getData().getId(), "itemData", currentStudy, ecb.getId());
                    success = success && temp;
                    ArrayList childItems = dib.getChildren();
                    for (int j = 0; j < childItems.size(); j++) {
                        DisplayItemBean child = (DisplayItemBean) childItems.get(j);
                        this.addAttachedFilePath(child, attachedFilePath);
                        writeDN = writeDN(child);
                        temp = writeToDB(child, iddao, 1, request);
                        LOGGER.debug("just executed writeToDB - 4");
                        if (temp && newUploadedFiles.containsKey(child.getItem().getId() + "")) {
                            // so newUploadedFiles will contain only failed
                            // file items;
                            newUploadedFiles.remove(child.getItem().getId() + "");
                        }
                        inputName = getInputName(child);
                        if (writeDN)
                            AddNewSubjectServlet.saveFieldNotes(inputName, fdn, dndao, child.getData().getId(), "itemData", currentStudy, ecb.getId());
                        success = success && temp;
                    }
                }
            }
            logMe("DisplayItemWithGroupBean allitems4 end " + System.currentTimeMillis());
            LOGGER.debug("running rules: " + phase2.name());
            List<Integer> prevShownDynItemDataIds = shouldRunRules ? this.getItemMetadataService().getDynamicsItemFormMetadataDao().findShowItemDataIdsInSection(section.getSection().getId(), ecb.getCRFVersionId(), ecb.getId()) : new ArrayList<Integer>();
            logMe("DisplayItemWithGroupBean dryrun  start" + System.currentTimeMillis());
            HashMap<String, ArrayList<String>> rulesPostDryRun = runRules(allItems, ruleSets, false, shouldRunRules, MessageType.WARNING, phase2, ecb, request);
            HashMap<String, ArrayList<String>> errorsPostDryRun = new HashMap<String, ArrayList<String>>();
            // additional step needed, run rules and see if any items are 'shown' AFTER saving data
            logMe("DisplayItemWithGroupBean dryrun  end" + System.currentTimeMillis());
            boolean inSameSection = false;
            logMe("DisplayItemWithGroupBean allitems4 " + System.currentTimeMillis());
            if (!rulesPostDryRun.isEmpty()) {
                // in same section?
                // iterate through the OIDs and see if any of them belong to this section
                Iterator iter3 = rulesPostDryRun.keySet().iterator();
                while (iter3.hasNext()) {
                    String fieldName = iter3.next().toString();
                    LOGGER.debug("found oid after post dry run " + fieldName);
                    // set up a listing of OIDs in the section
                    // BUT: Oids can have the group name in them.
                    int ordinal = -1;
                    String newFieldName = fieldName;
                    String[] fieldNames = fieldName.split("\\.");
                    if (fieldNames.length == 2) {
                        newFieldName = fieldNames[1];
                        // check items in item groups here?
                        if (fieldNames[0].contains("[")) {
                            int p1 = fieldNames[0].indexOf("[");
                            int p2 = fieldNames[0].indexOf("]");
                            try {
                                ordinal = Integer.valueOf(fieldNames[0].substring(p1 + 1, p2));
                            } catch (NumberFormatException e) {
                                ordinal = -1;
                            }
                            fieldNames[0] = fieldNames[0].substring(0, p1);
                        }
                    }
                    List<DisplayItemWithGroupBean> displayGroupsWithItems = section.getDisplayItemGroups();
                    //ArrayList<DisplayItemBean> displayItems = section.getItems();
                    for (int i = 0; i < displayGroupsWithItems.size(); i++) {
                        DisplayItemWithGroupBean itemWithGroup = displayGroupsWithItems.get(i);
                        if (itemWithGroup.isInGroup()) {
                            LOGGER.debug("found group: " + fieldNames[0]);
                            // do something there
                            List<DisplayItemGroupBean> digbs = itemWithGroup.getItemGroups();
                            LOGGER.debug("digbs size: " + digbs.size());
                            for (int j = 0; j < digbs.size(); j++) {
                                DisplayItemGroupBean displayGroup = digbs.get(j);
                                if (displayGroup.getItemGroupBean().getOid().equals(fieldNames[0]) && displayGroup.getOrdinal() == ordinal - 1) {
                                    List<DisplayItemBean> items = displayGroup.getItems();
                                    for (int k = 0; k < items.size(); k++) {
                                        DisplayItemBean dib = items.get(k);
                                        if (dib.getItem().getOid().equals(newFieldName)) {
                                            //inSameSection = true;
                                            if (!dib.getMetadata().isShowItem()) {
                                                LOGGER.debug("found item in group " + this.getGroupItemInputName(displayGroup, j, dib) + " vs. " + fieldName + " and is show item: " + dib.getMetadata().isShowItem());
                                                dib.getMetadata().setShowItem(true);
                                            }
                                            if (prevShownDynItemDataIds == null || !prevShownDynItemDataIds.contains(dib.getData().getId())) {
                                                inSameSection = true;
                                                errorsPostDryRun.put(this.getGroupItemInputName(displayGroup, j, dib), rulesPostDryRun.get(fieldName));
                                            }
                                        }
                                        items.set(k, dib);
                                    }
                                    displayGroup.setItems(items);
                                    digbs.set(j, displayGroup);
                                }
                            }
                            itemWithGroup.setItemGroups(digbs);
                        } else {
                            DisplayItemBean displayItemBean = itemWithGroup.getSingleItem();
                            ItemBean itemBean = displayItemBean.getItem();
                            if (newFieldName.equals(itemBean.getOid())) {
                                //System.out.println("check run dynamics item check " + runDynamicsItemCheck(displayItemBean).getMetadata().isShowItem());
                                if (!displayItemBean.getMetadata().isShowItem()) {
                                    // double check there?
                                    LOGGER.debug("found item " + this.getInputName(displayItemBean) + " vs. " + fieldName + " and is show item: " + displayItemBean.getMetadata().isShowItem());
                                    // if is repeating, use the other input name? no
                                    displayItemBean.getMetadata().setShowItem(true);
                                    if (prevShownDynItemDataIds == null || !prevShownDynItemDataIds.contains(displayItemBean.getData().getId())) {
                                        inSameSection = true;
                                        errorsPostDryRun.put(this.getInputName(displayItemBean), rulesPostDryRun.get(fieldName));
                                    }
                                }
                            }
                            itemWithGroup.setSingleItem(displayItemBean);
                        }
                        displayGroupsWithItems.set(i, itemWithGroup);
                    }
                    logMe("DisplayItemWithGroupBean allitems4  end,begin" + System.currentTimeMillis());
                    // check groups
                    //List<DisplayItemGroupBean> itemGroups = new ArrayList<DisplayItemGroupBean>();
                    //itemGroups = section.getDisplayFormGroups();
                    //   But in jsp: section.displayItemGroups.itemGroup.groupMetaBean.showGroup
                    List<DisplayItemWithGroupBean> itemGroups = section.getDisplayItemGroups();
                    // List<DisplayItemGroupBean> newItemGroups = new ArrayList<DisplayItemGroupBean>();
                    for (DisplayItemWithGroupBean itemGroup : itemGroups) {
                        DisplayItemGroupBean displayGroup = itemGroup.getItemGroup();
                        if (newFieldName.equals(displayGroup.getItemGroupBean().getOid())) {
                            if (!displayGroup.getGroupMetaBean().isShowGroup()) {
                                inSameSection = true;
                                LOGGER.debug("found itemgroup " + displayGroup.getItemGroupBean().getOid() + " vs. " + fieldName + " and is show item: " + displayGroup.getGroupMetaBean().isShowGroup());
                                // hmmm how to set highlighting for a group?
                                errorsPostDryRun.put(displayGroup.getItemGroupBean().getOid(), rulesPostDryRun.get(fieldName));
                                displayGroup.getGroupMetaBean().setShowGroup(true);
                                // add necessary rows to the display group here????
                                // we have to set the items in the itemGroup for the displayGroup
                                loadItemsWithGroupRows(itemGroup, sb, edcb, ecb, request);
                            }
                        }
                    // newItemGroups.add(displayGroup);
                    }
                    logMe("DisplayItemWithGroupBean allitems4  end,end" + System.currentTimeMillis());
                    // trying to reset the display form groups here, tbh
                    // section.setItems(displayItems);
                    section.setDisplayItemGroups(displayGroupsWithItems);
                    populateInstantOnChange(request.getSession(), ecb, section);
                // section.setDisplayFormGroups(newDisplayBean.getDisplayFormGroups());
                }
                //
                this.getItemMetadataService().updateGroupDynamicsInSection(displayItemWithGroups, section.getSection().getId(), ecb);
                toc = TableOfContentsServlet.getDisplayBeanWithShownSections(getDataSource(), (DisplayTableOfContentsBean) request.getAttribute(TOC_DISPLAY), (DynamicsMetadataService) SpringServletAccess.getApplicationContext(getServletContext()).getBean("dynamicsMetadataService"));
                request.setAttribute(TOC_DISPLAY, toc);
                sectionIdsInToc = TableOfContentsServlet.sectionIdsInToc(toc);
                sIndex = TableOfContentsServlet.sectionIndexInToc(section.getSection(), toc, sectionIdsInToc);
                previousSec = this.prevSection(section.getSection(), ecb, toc, sIndex);
                nextSec = this.nextSection(section.getSection(), ecb, toc, sIndex);
                section.setFirstSection(!previousSec.isActive());
                section.setLastSection(!nextSec.isActive());
                //
                // we need the following for repeating groups, tbh
                // >> tbh 06/2010
                // List<DisplayItemWithGroupBean> displayItemWithGroups2 = createItemWithGroups(section, hasGroup, eventDefinitionCRFId);
                // section.setDisplayItemGroups(displayItemWithGroups2);
                // if so, stay at this section
                LOGGER.debug(" in same section: " + inSameSection);
                if (inSameSection) {
                    // copy of one line from early on around line 400, forcing a re-show of the items
                    // section = getDisplayBean(hasGroup, true);// include all items, tbh
                    // below a copy of three lines from the if errors = true line, tbh 03/2010
                    String[] textFields = { INPUT_INTERVIEWER, INPUT_INTERVIEW_DATE };
                    fp.setCurrentStringValuesAsPreset(textFields);
                    setPresetValues(fp.getPresetValues(), request);
                    // below essetially a copy except for rulesPostDryRun
                    request.setAttribute(BEAN_DISPLAY, section);
                    request.setAttribute(BEAN_ANNOTATIONS, fp.getString(INPUT_ANNOTATIONS));
                    setInputMessages(errorsPostDryRun, request);
                    addPageMessage(respage.getString("your_answers_activated_hidden_items"), request);
                    request.setAttribute("hasError", "true");
                    request.setAttribute("hasShown", "true");
                    session.setAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME, discNotes);
                    setUpPanel(section);
                    forwardPage(getJSPPage(), request, response);
                }
            }
            if (!inSameSection) {
                // else if not in same section, progress as usual
                /*
                    toc =
                        TableOfContentsServlet.getDisplayBeanWithShownSections(getDataSource(), (DisplayTableOfContentsBean) request.getAttribute(TOC_DISPLAY),
                                (DynamicsMetadataService) SpringServletAccess.getApplicationContext(getServletContext()).getBean("dynamicsMetadataService"));
                    request.setAttribute(TOC_DISPLAY, toc);
                    sectionIdsInToc = TableOfContentsServlet.sectionIdsInToc(toc);
                    sIndex = TableOfContentsServlet.sectionIndexInToc(section.getSection(), toc, sectionIdsInToc);
                    previousSec = this.prevSection(section.getSection(), ecb, toc, sIndex);
                    nextSec = this.nextSection(section.getSection(), ecb, toc, sIndex);
                    section.setFirstSection(!previousSec.isActive());
                    section.setLastSection(!nextSec.isActive());
                    */
                // can we just forward page or do we actually need an ELSE here?
                // yes, we do. tbh 05/03/2010
                ArrayList<String> updateFailedItems = sc.redoCalculations(scoreItems, scoreItemdata, changedItems, itemOrdinals, sb.getId());
                success = updateFailedItems.size() > 0 ? false : true;
                // now check if CRF is marked complete
                boolean markComplete = fp.getString(INPUT_MARK_COMPLETE).equals(VALUE_YES);
                // if the CRF was marked
                boolean markSuccessfully = false;
                // successfully
                if (markComplete && section.isLastSection()) {
                    LOGGER.debug("need to mark CRF as complete");
                    markSuccessfully = markCRFComplete(request);
                    LOGGER.debug("...marked CRF as complete: " + markSuccessfully);
                    if (!markSuccessfully) {
                        request.setAttribute(BEAN_DISPLAY, section);
                        request.setAttribute(BEAN_ANNOTATIONS, fp.getString(INPUT_ANNOTATIONS));
                        setUpPanel(section);
                        forwardPage(getJSPPage(), request, response);
                        return;
                    }
                }
                // now write the event crf bean to the database
                String annotations = fp.getString(INPUT_ANNOTATIONS);
                setEventCRFAnnotations(annotations, request);
                Date now = new Date();
                ecb.setUpdatedDate(now);
                ecb.setUpdater(ub);
                ecb = (EventCRFBean) ecdao.update(ecb);
                success = success && ecb.isActive();
                StudyEventDAO sedao = new StudyEventDAO(getDataSource());
                StudyEventBean seb = (StudyEventBean) sedao.findByPK(ecb.getStudyEventId());
                seb.setUpdatedDate(now);
                seb.setUpdater(ub);
                seb = (StudyEventBean) sedao.update(seb);
                success = success && seb.isActive();
                request.setAttribute(INPUT_IGNORE_PARAMETERS, Boolean.TRUE);
                if (newUploadedFiles.size() > 0) {
                    if (this.unloadFiles(newUploadedFiles)) {
                    } else {
                        String missed = "";
                        Iterator iter = newUploadedFiles.keySet().iterator();
                        while (iter.hasNext()) {
                            missed += " " + newUploadedFiles.get(iter.next());
                        }
                        addPageMessage(respage.getString("uploaded_files_not_deleted_or_not_exist") + ": " + missed, request);
                    }
                }
                if (!success) {
                    // YW, 3-6-2008 <<
                    if (updateFailedItems.size() > 0) {
                        String mess = "";
                        for (String ss : updateFailedItems) {
                            mess += ss + ", ";
                        }
                        mess = mess.substring(0, mess.length() - 2);
                        addPageMessage(resexception.getString("item_save_failed_because_database_error") + mess, request);
                    } else {
                        // YW>>
                        addPageMessage(resexception.getString("database_error"), request);
                    }
                    request.setAttribute(BEAN_DISPLAY, section);
                    session.removeAttribute(GROUP_HAS_DATA);
                    session.removeAttribute(HAS_DATA_FLAG);
                    session.removeAttribute(DDE_PROGESS);
                    session.removeAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
                    LOGGER.debug("try to remove to_create_crf");
                    session.removeAttribute("to_create_crf");
                    session.removeAttribute(instantAtt);
                    // forwardPage(Page.SUBMIT_DATA_SERVLET);
                    forwardPage(Page.LIST_STUDY_SUBJECTS_SERVLET, request, response);
                // >> changed tbh, 06/2009
                } else {
                    boolean forwardingSucceeded = false;
                    if (!fp.getString(GO_PREVIOUS).equals("")) {
                        if (previousSec.isActive()) {
                            forwardingSucceeded = true;
                            request.setAttribute(INPUT_EVENT_CRF, ecb);
                            request.setAttribute(INPUT_SECTION, previousSec);
                            int tabNum = 0;
                            if (fp.getString("tab") == null) {
                                tabNum = 1;
                            } else {
                                tabNum = fp.getInt("tab");
                            }
                            request.setAttribute("tab", new Integer(tabNum - 1).toString());
                            //  forwardPage(getServletPage(request), request, response);
                            getServletContext().getRequestDispatcher(getServletPage(request)).forward(request, response);
                        }
                    } else if (!fp.getString(GO_NEXT).equals("")) {
                        if (nextSec.isActive()) {
                            forwardingSucceeded = true;
                            request.setAttribute(INPUT_EVENT_CRF, ecb);
                            request.setAttribute(INPUT_SECTION, nextSec);
                            int tabNum = 0;
                            if (fp.getString("tab") == null) {
                                tabNum = 1;
                            } else {
                                tabNum = fp.getInt("tab");
                            }
                            request.setAttribute("tab", new Integer(tabNum + 1).toString());
                            getServletContext().getRequestDispatcher(getServletPage(request)).forward(request, response);
                        //forwardPage(getServletPage(request), request, response);
                        }
                    }
                    if (!forwardingSucceeded) {
                        // ecb);
                        if (markSuccessfully) {
                            addPageMessage(respage.getString("data_saved_CRF_marked_complete"), request);
                            session.removeAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
                            session.removeAttribute(GROUP_HAS_DATA);
                            session.removeAttribute(HAS_DATA_FLAG);
                            session.removeAttribute(DDE_PROGESS);
                            session.removeAttribute("to_create_crf");
                            request.setAttribute("eventId", new Integer(ecb.getStudyEventId()).toString());
                            forwardPage(Page.ENTER_DATA_FOR_STUDY_EVENT_SERVLET, request, response);
                        } else {
                            // use clicked 'save'
                            addPageMessage(respage.getString("data_saved_continue_entering_edit_later"), request);
                            request.setAttribute(INPUT_EVENT_CRF, ecb);
                            request.setAttribute(INPUT_EVENT_CRF_ID, new Integer(ecb.getId()).toString());
                            // is not the last section
                            if (!section.isLastSection()) {
                                request.setAttribute(INPUT_SECTION, nextSec);
                                request.setAttribute(INPUT_SECTION_ID, new Integer(nextSec.getId()).toString());
                                session.removeAttribute("mayProcessUploading");
                            } else if (section.isLastSection()) {
                                //JN ADDED TO avoid return down
                                // already the last section, should go back to
                                // view event page
                                session.removeAttribute(GROUP_HAS_DATA);
                                session.removeAttribute(HAS_DATA_FLAG);
                                session.removeAttribute(DDE_PROGESS);
                                session.removeAttribute("to_create_crf");
                                session.removeAttribute("mayProcessUploading");
                                request.setAttribute("eventId", new Integer(ecb.getStudyEventId()).toString());
                                if (fromViewNotes != null && "1".equals(fromViewNotes)) {
                                    String viewNotesPageFileName = (String) session.getAttribute("viewNotesPageFileName");
                                    session.removeAttribute("viewNotesPageFileName");
                                    session.removeAttribute("viewNotesURL");
                                    if (viewNotesPageFileName != null && viewNotesPageFileName.length() > 0) {
                                        // forwardPage(Page.setNewPage(viewNotesPageFileName, "View Notes"), request, response);
                                        getServletContext().getRequestDispatcher(viewNotesPageFileName).forward(request, response);
                                    }
                                }
                                session.removeAttribute(instantAtt);
                                forwardPage(Page.ENTER_DATA_FOR_STUDY_EVENT_SERVLET, request, response);
                                return;
                            }
                            int tabNum = 0;
                            if (fp.getString("tab") == null) {
                                tabNum = 1;
                            } else {
                                tabNum = fp.getInt("tab");
                            }
                            if (!section.isLastSection()) {
                                request.setAttribute("tab", new Integer(tabNum + 1).toString());
                            }
                            //  forwardPage(getServletPage(request), request, response);
                            getServletContext().getRequestDispatcher(getServletPage(request)).forward(request, response);
                        }
                    // session.removeAttribute(AddNewSubjectServlet.
                    // FORM_DISCREPANCY_NOTES_NAME);
                    // forwardPage(Page.SUBMIT_DATA_SERVLET);
                    }
                }
            }
        // end of if-block for dynamic rules not in same section, tbh 05/2010
        }
    // end of save
    }
}
Also used : DisplayItemBean(org.akaza.openclinica.bean.submit.DisplayItemBean) ItemBean(org.akaza.openclinica.bean.submit.ItemBean) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StudyEventDefinitionBean(org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean) StudyEventBean(org.akaza.openclinica.bean.managestudy.StudyEventBean) EventCRFBean(org.akaza.openclinica.bean.submit.EventCRFBean) ItemDataBean(org.akaza.openclinica.bean.submit.ItemDataBean) TreeSet(java.util.TreeSet) StudyEventDAO(org.akaza.openclinica.dao.managestudy.StudyEventDAO) ScoreCalculator(org.akaza.openclinica.logic.score.ScoreCalculator) DiscrepancyNoteUtil(org.akaza.openclinica.service.DiscrepancyNoteUtil) DynamicsMetadataService(org.akaza.openclinica.service.crfdata.DynamicsMetadataService) StudyDAO(org.akaza.openclinica.dao.managestudy.StudyDAO) Status(org.akaza.openclinica.bean.core.Status) ResolutionStatus(org.akaza.openclinica.bean.core.ResolutionStatus) SubjectEventStatus(org.akaza.openclinica.bean.core.SubjectEventStatus) Validation(org.akaza.openclinica.control.form.Validation) DiscrepancyNoteDAO(org.akaza.openclinica.dao.managestudy.DiscrepancyNoteDAO) CRFVersionDAO(org.akaza.openclinica.dao.submit.CRFVersionDAO) FormDiscrepancyNotes(org.akaza.openclinica.control.form.FormDiscrepancyNotes) FormProcessor(org.akaza.openclinica.control.form.FormProcessor) DisplayItemWithGroupBean(org.akaza.openclinica.bean.submit.DisplayItemWithGroupBean) StudyBean(org.akaza.openclinica.bean.managestudy.StudyBean) EventDefinitionCRFDAO(org.akaza.openclinica.dao.managestudy.EventDefinitionCRFDAO) UserAccountDAO(org.akaza.openclinica.dao.login.UserAccountDAO) InconsistentStateException(org.akaza.openclinica.web.InconsistentStateException) DataEntryStage(org.akaza.openclinica.bean.core.DataEntryStage) SectionBean(org.akaza.openclinica.bean.submit.SectionBean) DisplaySectionBean(org.akaza.openclinica.bean.submit.DisplaySectionBean) SubjectBean(org.akaza.openclinica.bean.submit.SubjectBean) StudySubjectBean(org.akaza.openclinica.bean.managestudy.StudySubjectBean) ScoreItemValidator(org.akaza.openclinica.control.form.ScoreItemValidator) StudySubjectBean(org.akaza.openclinica.bean.managestudy.StudySubjectBean) StudyEventDefinitionDAO(org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO) DiscrepancyNoteBean(org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean) EventDefinitionCRFBean(org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean) Map(java.util.Map) HashMap(java.util.HashMap) SectionDAO(org.akaza.openclinica.dao.submit.SectionDAO) Phase(org.akaza.openclinica.domain.rule.action.RuleActionRunBean.Phase) Set(java.util.Set) TreeSet(java.util.TreeSet) StudySubjectDAO(org.akaza.openclinica.dao.managestudy.StudySubjectDAO) SubjectDAO(org.akaza.openclinica.dao.submit.SubjectDAO) ItemDataDAO(org.akaza.openclinica.dao.submit.ItemDataDAO) UserAccountBean(org.akaza.openclinica.bean.login.UserAccountBean) Iterator(java.util.Iterator) DisplayItemBean(org.akaza.openclinica.bean.submit.DisplayItemBean) EventCRFDAO(org.akaza.openclinica.dao.submit.EventCRFDAO) DiscrepancyNoteThread(org.akaza.openclinica.service.DiscrepancyNoteThread) DisplayItemGroupBean(org.akaza.openclinica.bean.submit.DisplayItemGroupBean) HttpSession(javax.servlet.http.HttpSession) SessionManager(org.akaza.openclinica.core.SessionManager) StudyUserRoleBean(org.akaza.openclinica.bean.login.StudyUserRoleBean) DisplayTableOfContentsBean(org.akaza.openclinica.bean.submit.DisplayTableOfContentsBean) StudySubjectDAO(org.akaza.openclinica.dao.managestudy.StudySubjectDAO) ResponseOptionBean(org.akaza.openclinica.bean.submit.ResponseOptionBean) Date(java.util.Date) DisplaySectionBean(org.akaza.openclinica.bean.submit.DisplaySectionBean) DiscrepancyValidator(org.akaza.openclinica.control.form.DiscrepancyValidator) SimpleConditionalDisplayService(org.akaza.openclinica.service.crfdata.SimpleConditionalDisplayService) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) CRFVersionBean(org.akaza.openclinica.bean.submit.CRFVersionBean) SimpleDateFormat(java.text.SimpleDateFormat) DynamicsItemFormMetadataBean(org.akaza.openclinica.domain.crfdata.DynamicsItemFormMetadataBean) ItemFormMetadataBean(org.akaza.openclinica.bean.submit.ItemFormMetadataBean) RuleSetBean(org.akaza.openclinica.domain.rule.RuleSetBean) RuleValidator(org.akaza.openclinica.control.form.RuleValidator)

Example 5 with ResponseOptionBean

use of org.akaza.openclinica.bean.submit.ResponseOptionBean in project OpenClinica by OpenClinica.

the class DoubleDataEntryServlet method validateDisplayItemBean.

@Override
protected DisplayItemBean validateDisplayItemBean(DiscrepancyValidator v, DisplayItemBean dib, String inputName, HttpServletRequest request) {
    org.akaza.openclinica.bean.core.ResponseType rt = dib.getMetadata().getResponseSet().getResponseType();
    HttpSession session = request.getSession();
    EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);
    boolean isSingleItem = false;
    if (StringUtil.isBlank(inputName)) {
        // for single items
        inputName = getInputName(dib);
        isSingleItem = true;
    }
    // we only give warning to user if data entered in DDE is different from
    // IDE when the first
    // time user hits 'save'
    int keyId = ecb.getId();
    Integer validationCount = (Integer) session.getAttribute(COUNT_VALIDATE + keyId);
    // @pgawade 12-Aug-2011 issue 10601:
    // 1. Moved the call to loadFormValue method setting values
    // from form here. It was at the end
    // of this method before that is after validations and so an extra
    // validation for checking value entered
    // against the data type was getting implemented for non-repeating group
    // items.
    // 2. Copying the form data into new object for non repeating items to
    // pass to validation
    // for matching IDE and DDE values. Id same reference is used, the way
    // code here was written, it affetcs
    // the value used in validation of data entered in DDE against the
    // related data type
    ItemDataBean valueToCompareTmp = dib.getData();
    ItemDataBean valueToCompare = copyItemDataBean(valueToCompareTmp);
    if (!isSingleItem) {
        valueToCompare = dib.getDbData();
    }
    // see formGroups = loadFormValueForItemGroup(digb,digbs,formGroups);
    if (isSingleItem) {
        dib = loadFormValue(dib, request);
    }
    // was dib.getData()
    boolean showOriginalItem = getItemMetadataService().isShown(dib.getItem().getId(), ecb, valueToCompare);
    boolean showItem = dib.getMetadata().isShowItem();
    if (!showItem && dib.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId() > 0) {
        showItem = true;
    }
    //.isShown(dib.getItem().getId(), ecb, dib.getDbData());// where is the set db data?
    boolean showDuplicateItem = getItemMetadataService().hasPassedDDE(dib.getMetadata(), ecb, valueToCompare);
    LOGGER.debug("*** show original item has value " + dib.getData().getValue() + " and show item has value " + valueToCompare.getValue());
    LOGGER.debug("--- show original: " + showOriginalItem + " show duplicate: " + showDuplicateItem + " and just show item: " + showItem);
    LOGGER.debug("VALIDATION COUNT " + validationCount);
    if (showOriginalItem && showDuplicateItem || showItem) {
        if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXT) || rt.equals(org.akaza.openclinica.bean.core.ResponseType.TEXTAREA)) {
            dib = validateDisplayItemBeanText(v, dib, inputName, request);
            if (validationCount == null || validationCount.intValue() == 0) {
                v.addValidation(inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
                v.setErrorMessage(respage.getString("value_you_specified") + " " + valueToCompare.getValue() + " " + respage.getString("from_initial_data_entry"));
            }
        } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.FILE)) {
            dib = validateDisplayItemBeanText(v, dib, inputName, request);
            if (validationCount == null || validationCount.intValue() == 0) {
                // we want to check if the current uploaded file matched the initial data file, quick way to do it is by using the hash
                // value of the file content that was added to the filename
                // cloned for prosperity
                ItemDataBean pathStrippedValueToCompare;
                try {
                    pathStrippedValueToCompare = (ItemDataBean) BeanUtils.cloneBean(valueToCompare);
                } catch (Throwable e) {
                    e.printStackTrace();
                    return dib;
                }
                // the value we want to check only has filename with no path, so we strip path from the one stored in database, and compare
                pathStrippedValueToCompare.setValue(FilenameUtils.getName(valueToCompare.getValue()));
                v.addValidation(inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, pathStrippedValueToCompare, false);
                v.setErrorMessage(respage.getString("value_you_specified") + " " + pathStrippedValueToCompare.getValue() + " " + respage.getString("from_initial_data_entry"));
            }
        } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.RADIO) || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECT)) {
            dib = validateDisplayItemBeanSingleCV(v, dib, inputName);
            if (validationCount == null || validationCount.intValue() == 0) {
                v.addValidation(inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, false);
                String errorValue = valueToCompare.getValue();
                java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();
                for (int u = 0; u < options.size(); u++) {
                    ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
                    if (rob.getValue().equals(errorValue)) {
                        errorValue = rob.getText();
                    }
                }
                v.setErrorMessage(respage.getString("value_you_specified") + " " + errorValue + " " + respage.getString("from_initial_data_entry"));
            }
        } else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CHECKBOX) || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECTMULTI)) {
            dib = validateDisplayItemBeanMultipleCV(v, dib, inputName);
            if (validationCount == null || validationCount.intValue() == 0) {
                v.addValidation(inputName, Validator.MATCHES_INITIAL_DATA_ENTRY_VALUE, valueToCompare, true);
                // repeated from above, tbh 112007
                String errorValue = valueToCompare.getValue();
                String errorTexts = "";
                java.util.ArrayList options = dib.getMetadata().getResponseSet().getOptions();
                for (int u = 0; u < options.size(); u++) {
                    ResponseOptionBean rob = (ResponseOptionBean) options.get(u);
                    if (errorValue.contains(rob.getValue())) {
                        errorTexts = errorTexts + rob.getText();
                        if (u < options.size() - 1) {
                            // the values for multi-select are seperated by
                            // comma
                            errorTexts = errorTexts + ", ";
                        }
                    }
                }
                v.setErrorMessage(respage.getString("value_you_specified") + " " + errorTexts + " " + respage.getString("from_initial_data_entry"));
            }
        }
    }
    return dib;
}
Also used : HttpSession(javax.servlet.http.HttpSession) ArrayList(java.util.ArrayList) ResponseOptionBean(org.akaza.openclinica.bean.submit.ResponseOptionBean) ArrayList(java.util.ArrayList) EventCRFBean(org.akaza.openclinica.bean.submit.EventCRFBean) DisplayEventCRFBean(org.akaza.openclinica.bean.submit.DisplayEventCRFBean) ItemDataBean(org.akaza.openclinica.bean.submit.ItemDataBean)

Aggregations

ResponseOptionBean (org.akaza.openclinica.bean.submit.ResponseOptionBean)31 ArrayList (java.util.ArrayList)20 DisplayItemBean (org.akaza.openclinica.bean.submit.DisplayItemBean)9 Element (org.jdom.Element)8 ItemBean (org.akaza.openclinica.bean.submit.ItemBean)7 ItemDataBean (org.akaza.openclinica.bean.submit.ItemDataBean)7 ItemFormMetadataBean (org.akaza.openclinica.bean.submit.ItemFormMetadataBean)7 ItemDataDAO (org.akaza.openclinica.dao.submit.ItemDataDAO)5 HashMap (java.util.HashMap)4 NumberFormat (java.text.NumberFormat)3 Iterator (java.util.Iterator)3 NullValue (org.akaza.openclinica.bean.core.NullValue)3 DisplayItemGroupBean (org.akaza.openclinica.bean.submit.DisplayItemGroupBean)3 DisplayItemWithGroupBean (org.akaza.openclinica.bean.submit.DisplayItemWithGroupBean)3 EventCRFBean (org.akaza.openclinica.bean.submit.EventCRFBean)3 Random (java.util.Random)2 HttpSession (javax.servlet.http.HttpSession)2 DiscrepancyNoteBean (org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean)2 ResponseSetBean (org.akaza.openclinica.bean.submit.ResponseSetBean)2 DiscrepancyNoteDAO (org.akaza.openclinica.dao.managestudy.DiscrepancyNoteDAO)2