/*
* OpenClinica is distributed under the
* GNU Lesser General Public License (GNU LGPL).
* For details see: http://www.openclinica.org/license
* copyright 2003-2011 Akaza Research
*/
package org.akaza.openclinica.control.submit;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import org.apache.commons.beanutils.BeanUtils;
import org.akaza.openclinica.bean.admin.AuditBean;
import org.akaza.openclinica.bean.admin.CRFBean;
import org.akaza.openclinica.bean.core.AuditableEntityBean;
import org.akaza.openclinica.bean.core.DataEntryStage;
import org.akaza.openclinica.bean.core.EntityBean;
import org.akaza.openclinica.bean.core.ItemDataType;
import org.akaza.openclinica.bean.core.NullValue;
import org.akaza.openclinica.bean.core.NumericComparisonOperator;
import org.akaza.openclinica.bean.core.ResolutionStatus;
import org.akaza.openclinica.bean.core.Status;
import org.akaza.openclinica.bean.core.SubjectEventStatus;
import org.akaza.openclinica.bean.core.Utils;
import org.akaza.openclinica.bean.login.StudyUserRoleBean;
import org.akaza.openclinica.bean.login.UserAccountBean;
import org.akaza.openclinica.bean.managestudy.DiscrepancyNoteBean;
import org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean;
import org.akaza.openclinica.bean.managestudy.StudyBean;
import org.akaza.openclinica.bean.managestudy.StudyEventBean;
import org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean;
import org.akaza.openclinica.bean.managestudy.StudySubjectBean;
import org.akaza.openclinica.bean.submit.CRFVersionBean;
import org.akaza.openclinica.bean.submit.DisplayItemBean;
import org.akaza.openclinica.bean.submit.DisplayItemGroupBean;
import org.akaza.openclinica.bean.submit.DisplayItemWithGroupBean;
import org.akaza.openclinica.bean.submit.DisplaySectionBean;
import org.akaza.openclinica.bean.submit.DisplayTableOfContentsBean;
import org.akaza.openclinica.bean.submit.EventCRFBean;
import org.akaza.openclinica.bean.submit.ItemBean;
import org.akaza.openclinica.bean.submit.ItemDataBean;
import org.akaza.openclinica.bean.submit.ItemFormMetadataBean;
import org.akaza.openclinica.bean.submit.ItemGroupBean;
import org.akaza.openclinica.bean.submit.ItemGroupMetadataBean;
import org.akaza.openclinica.bean.submit.ResponseOptionBean;
import org.akaza.openclinica.bean.submit.ResponseSetBean;
import org.akaza.openclinica.bean.submit.SCDItemDisplayInfo;
import org.akaza.openclinica.bean.submit.SectionBean;
import org.akaza.openclinica.bean.submit.SubjectBean;
import org.akaza.openclinica.control.SpringServletAccess;
import org.akaza.openclinica.control.core.CoreSecureController;
import org.akaza.openclinica.control.form.DiscrepancyValidator;
import org.akaza.openclinica.control.form.FormDiscrepancyNotes;
import org.akaza.openclinica.control.form.FormProcessor;
import org.akaza.openclinica.control.form.RuleValidator;
import org.akaza.openclinica.control.form.ScoreItemValidator;
import org.akaza.openclinica.control.form.Validation;
import org.akaza.openclinica.control.form.Validator;
import org.akaza.openclinica.control.managestudy.ViewNotesServlet;
import org.akaza.openclinica.core.SecurityManager;
import org.akaza.openclinica.core.SessionManager;
import org.akaza.openclinica.core.form.StringUtil;
import org.akaza.openclinica.dao.admin.AuditDAO;
import org.akaza.openclinica.dao.admin.CRFDAO;
import org.akaza.openclinica.dao.hibernate.DynamicsItemFormMetadataDao;
import org.akaza.openclinica.dao.login.UserAccountDAO;
import org.akaza.openclinica.dao.managestudy.DiscrepancyNoteDAO;
import org.akaza.openclinica.dao.managestudy.EventDefinitionCRFDAO;
import org.akaza.openclinica.dao.managestudy.StudyDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDAO;
import org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO;
import org.akaza.openclinica.dao.managestudy.StudySubjectDAO;
import org.akaza.openclinica.dao.submit.CRFVersionDAO;
import org.akaza.openclinica.dao.submit.EventCRFDAO;
import org.akaza.openclinica.dao.submit.ItemDAO;
import org.akaza.openclinica.dao.submit.ItemDataDAO;
import org.akaza.openclinica.dao.submit.ItemFormMetadataDAO;
import org.akaza.openclinica.dao.submit.ItemGroupDAO;
import org.akaza.openclinica.dao.submit.ItemGroupMetadataDAO;
import org.akaza.openclinica.dao.submit.SectionDAO;
import org.akaza.openclinica.dao.submit.SubjectDAO;
import org.akaza.openclinica.domain.crfdata.DynamicsItemFormMetadataBean;
import org.akaza.openclinica.domain.rule.RuleSetBean;
import org.akaza.openclinica.domain.rule.action.RuleActionRunBean.Phase;
import org.akaza.openclinica.exception.OpenClinicaException;
import org.akaza.openclinica.i18n.core.LocaleResolver;
import org.akaza.openclinica.i18n.util.ResourceBundleProvider;
import org.akaza.openclinica.logic.expressionTree.ExpressionTreeHelper;
import org.akaza.openclinica.logic.rulerunner.MessageContainer.MessageType;
import org.akaza.openclinica.logic.score.ScoreCalculator;
import org.akaza.openclinica.service.DiscrepancyNoteThread;
import org.akaza.openclinica.service.DiscrepancyNoteUtil;
import org.akaza.openclinica.service.crfdata.DynamicsMetadataService;
import org.akaza.openclinica.service.crfdata.InstantOnChangeService;
import org.akaza.openclinica.service.crfdata.SimpleConditionalDisplayService;
import org.akaza.openclinica.service.crfdata.front.InstantOnChangeFrontStrGroup;
import org.akaza.openclinica.service.crfdata.front.InstantOnChangeFrontStrParcel;
import org.akaza.openclinica.service.rule.RuleSetServiceInterface;
import org.akaza.openclinica.view.Page;
import org.akaza.openclinica.view.form.DataEntryInputGenerator;
import org.akaza.openclinica.view.form.FormBeanUtil;
import org.akaza.openclinica.web.InconsistentStateException;
import org.akaza.openclinica.web.InsufficientPermissionException;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.text.StrSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSenderImpl;
/**
* @author ssachs
*/
public abstract class DataEntryServlet extends CoreSecureController {
private static final Logger LOGGER = LoggerFactory.getLogger(DataEntryServlet.class);
Locale locale;
// < ResourceBundleresmessage,restext,resexception,respage;
// these inputs come from the form, from another JSP via POST,
// or from another JSP via GET
// e.g. InitialDataEntry?eventCRFId=123§ionId=234
public static final String INPUT_EVENT_CRF_ID = "eventCRFId";
public static final String INPUT_SECTION_ID = "sectionId";
// these inputs are used when other servlets redirect you here
// this is most typically the case when the user enters data and clicks the
// "Previous" or "Next" button
public static final String INPUT_EVENT_CRF = "event";
public static final String INPUT_SECTION = "section";
/**
* A bean used to indicate that servlets to which this servlet forwards should ignore any parameters, in particular the "submitted" parameter which controls
* FormProcessor.isSubmitted. If an attribute with this name is set in the request, the servlet to which this servlet forwards should consider
* fp.isSubmitted to always return false.
*/
public static final String INPUT_IGNORE_PARAMETERS = "ignore";
/**
* A bean used to indicate that we are not validating inputs, that is, that the user is "confirming" values which did not validate properly the first time.
* If an attribute with this name is set in the request, this servlet should not perform any validation on the form inputs.
*/
public static final String INPUT_CHECK_INPUTS = "checkInputs";
/**
* The name of the form input on which users write annotations.
*/
public static final String INPUT_ANNOTATIONS = "annotations";
/**
* The name of the attribute in the request which hold the preset annotations form value.
*/
public static final String BEAN_ANNOTATIONS = "annotations";
// names of submit buttons in the JSP
public static final String RESUME_LATER = "submittedResume";
public static final String GO_PREVIOUS = "submittedPrev";
public static final String GO_NEXT = "submittedNext";
public static final String BEAN_DISPLAY = "section";
public static final String TOC_DISPLAY = "toc"; // from
// TableOfContentServlet
// these inputs are displayed on the table of contents and
// are used to edit Event CRF properties
public static final String INPUT_INTERVIEWER = "interviewer";
public static final String INPUT_INTERVIEW_DATE = "interviewDate";
public static final String INTERVIEWER_NAME_NOTE = "InterviewerNameNote";
public static final String INTERVIEWER_DATE_NOTE = "InterviewerDateNote";
public static final String INPUT_TAB = "tabId";
public static final String INPUT_MARK_COMPLETE = "markComplete";
public static final String VALUE_YES = "Yes";
// these are only for use with ACTION_START_INITIAL_DATA_ENTRY
public static final String INPUT_EVENT_DEFINITION_CRF_ID = "eventDefinitionCRFId";
public static final String INPUT_CRF_VERSION_ID = "crfVersionId";
public static final String INPUT_STUDY_EVENT_ID = "studyEventId";
public static final String INPUT_SUBJECT_ID = "subjectId";
public static final String GO_EXIT = "submittedExit";
public static final String GROUP_HAS_DATA = "groupHasData";
public static final String HAS_DATA_FLAG = "hasDataFlag";
// See the session variable in DoubleDataEntryServlet
public static final String DDE_PROGESS = "doubleDataProgress";
public static final String INTERVIEWER_NAME = "interviewer_name";
public static final String DATE_INTERVIEWED = "date_interviewed";
public static final String NOTE_SUBMITTED = "note_submitted";
public static final String SECTION_BEAN = "section_bean";
public static final String ALL_SECTION_BEANS = "all_section_bean";
public static final String EVENT_DEF_CRF_BEAN = "event_def_crf_bean";
public static final String ALL_ITEMS_LIST = "all_items_list";
/**
* Session attribute, and will be followed by crf_version_id
*/
public static final String CV_INSTANT_META = "cvInstantMeta";
private DataSource dataSource;
@Override
public void init(ServletConfig config) throws ServletException
{
super.init(config);
try{
ServletContext context = getServletContext();
SessionManager sm = new SessionManager(SpringServletAccess.getApplicationContext(context));
dataSource = sm.getDataSource();
}catch(Exception ne){
ne.printStackTrace();
}
}
@Override
public DataSource getDataSource(){
return dataSource;
}
/*
* (non-Javadoc)
* @see org.akaza.openclinica.control.core.SecureController#mayProceed()
*/
@Override
protected abstract void mayProceed(HttpServletRequest request, HttpServletResponse response) throws InsufficientPermissionException;
/*
* locale = LocaleResolver.getLocale(request); //< resmessage = ResourceBundle.getBundle("org.akaza.openclinica.i18n.page_messages" ,locale); //< restext =
* ResourceBundle.getBundle("org.akaza.openclinica.i18n.notes",locale); //< resexception =ResourceBundle.getBundle("org.akaza.openclinica.i18n.exceptions"
* ,locale);
*/
/*
* (non-Javadoc)
* @see org.akaza.openclinica.control.core.SecureController#processRequest()
*/
private String getSectionFirstFieldId(int sectionId) {
ItemDAO itemDAO = new ItemDAO(getDataSource());
List<ItemBean> items = itemDAO.findAllBySectionId(sectionId);
if (!items.isEmpty()) {
return new Integer(items.get(0).getId()).toString();
}
return "";
}
private void logMe(String message)
{
// System.out.println(message);
LOGGER.trace(message);
}
@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);
// addPageMessage("You chose to exit the data entry page.");
// changed bu jxu 03/06/2007- we should use redirection to go to
// 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);
request.setAttribute(EVENT_DEF_CRF_BEAN, edcb);//JN:Putting the event_def_crf_bean in the request attribute.
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
dib = validateDisplayItemBean(v, dib, "", request);// this
// 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>();
// List<DisplayItemGroupBean> dbGroups2 = loadFormValueForItemGroup(dgb, dbGroups, formGroups, eventDefinitionCRFId);
// jxu- this part need to be refined, why need to validate
// 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 = "";
// note that we have to use
// 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);
// logger.debug("+++ try to populate notes, got count of field notes: " + discNotes.getFieldNotes().toString());
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;
// change everything here from changed items list to changed
// 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());
}
/*
* if(studyEventBean.getSubjectEventStatus().equals(SubjectEventStatus .SIGNED)){ if(edcBean.isDoubleEntry()){
* ecb.setStage(DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE); }else{ ecb.setStage(DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE); } }
*/
// 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);
// we don't write success = success && writeToDB here
// since the short-circuit mechanism may prevent Java
// 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("is show item for " + displayItemBean.getItem().getId() + ": " + displayItemBean.getMetadata().isShowItem());
//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);
boolean markSuccessfully = false; // if the CRF was marked
// complete
// 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) {
// request.setAttribute(TableOfContentsServlet.
// INPUT_EVENT_CRF_BEAN,
// 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());
// forward to the next section if the previous one
// 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
}
}
protected boolean writeDN(DisplayItemBean displayItem)
{
boolean writeDN=true;
if (StringUtils.isBlank(displayItem.getEditFlag())){
if (!displayItem.getData().isActive()) {
writeDN = true;
}
else
writeDN=false;
}
else{
if ("add".equalsIgnoreCase(displayItem.getEditFlag())){
writeDN=true;
}
else if ("edit".equalsIgnoreCase(displayItem.getEditFlag())){
if(displayItem.getData().getId()!=0)
{
writeDN=false;
}
else
{
writeDN=true;
}
}
}
return writeDN;
}
/**
* Changed by thickerson 05/2010
* @param idb
* @param formName
* @param error
* @param request TODO
*/
protected void setReasonForChangeError( EventCRFBean ecb, ItemBean item_bean, ItemDataBean idb, String formName, String error, HttpServletRequest request) {
HttpSession session = request.getSession();
/*
* Having existing notes is not enough to let it pass through after changing data. There has to be a DiscrepancyNote for the latest changed data
*/
HashMap<String, Boolean> noteSubmitted = (HashMap<String, Boolean>) session.getAttribute(DataEntryServlet.NOTE_SUBMITTED);
//String key_for_rfc = String.valueOf(idb.getId());
String key_for_rfc = String.valueOf(ecb.getId()+"_"+formName);
boolean isRFCFiled = false;
if ( noteSubmitted != null){
if ( noteSubmitted.get(key_for_rfc) != null){//item in database
isRFCFiled = true;
}
}
if (!isRFCFiled) {
errors.put(formName, error);
} else {
LOGGER.debug("has a note in db: entered an error here: " + formName + ": " + errors.toString());
}
}
/**
* Get the input beans - the EventCRFBean and the SectionBean. For both beans, look first in the request attributes to see if the bean has been stored
* there. If not, look in the parameters for the bean id, and then retrieve the bean from the database. The beans are stored as protected class members.
* @param request TODO
*/
protected void getInputBeans(HttpServletRequest request) throws InsufficientPermissionException {
HttpSession session = request.getSession();
StudyBean currentStudy = (StudyBean) session.getAttribute("study");
// BWP >>we should have the correct crfVersionId, in order to acquire
// the correct
// section IDs
FormProcessor fp = new FormProcessor(request);
EventCRFDAO ecdao = new EventCRFDAO(getDataSource());
SectionDAO sdao = new SectionDAO(getDataSource());
EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);
//JN:Happening when drilling down?
if (ecb == null) {
int eventCRFId = fp.getInt(INPUT_EVENT_CRF_ID, true);
LOGGER.debug("found event crf id: " + eventCRFId);
if (eventCRFId > 0) {
LOGGER.debug("***NOTE*** that we didnt have to create an event crf because we already have one: " + eventCRFId);
// there is an event CRF already, only need to update
ecb = (EventCRFBean) ecdao.findByPK(eventCRFId);
// ecb.setUpdatedDate(new Date());
// ecb.setUpdater(ub);
// ecb = (EventCRFBean) ecdao.update(ecb);
// logger.trace("found an event crf id "+eventCRFId);
// YW 11-12-2007 << if interviewer or/and interview date
// has/have been updated for study/site from "blank" to
// "pre-populated"
// But at this point, this update only shows on web page and
// will not be updated to database.
int studyEventId = fp.getInt(INPUT_STUDY_EVENT_ID);
request.setAttribute(INPUT_EVENT_CRF, ecb);
if (studyEventId > 0) {
StudyEventDAO sedao = new StudyEventDAO(getDataSource());
StudyEventBean sEvent = (StudyEventBean) sedao.findByPK(studyEventId);
ecb = updateECB(sEvent, request);
}
request.setAttribute(INPUT_EVENT_CRF, ecb);
// YW >>
} else {
// CRF id <=0, so we need to create a new CRF
// use toCreateCRF as a flag to prevent user to submit event CRF
// more than once
// for example, user reloads the page
String toCreateCRF = (String) session.getAttribute("to_create_crf");
if (StringUtil.isBlank(toCreateCRF) || "0".equals(toCreateCRF)) {
session.setAttribute("to_create_crf", "1");
}
try {
// if (ecb.getInterviewerName() != null) {
LOGGER.debug("Initial: to create an event CRF.");
String toCreateCRF1 = (String) session.getAttribute("to_create_crf");
if (!StringUtil.isBlank(toCreateCRF1) && "1".equals(toCreateCRF1)) {
ecb = createEventCRF(request, fp);
session.setAttribute("ecb", ecb);
request.setAttribute(INPUT_EVENT_CRF, ecb);
session.setAttribute("to_create_crf", "0");
} else {
ecb = (EventCRFBean) session.getAttribute("ecb");
}
// }
} catch (InconsistentStateException ie) {
ie.printStackTrace();
addPageMessage(ie.getOpenClinicaMessage(), request);
throw new InsufficientPermissionException(Page.LIST_STUDY_SUBJECTS_SERVLET, ie.getOpenClinicaMessage(), "1");
} catch (NullPointerException ne) {
ne.printStackTrace();
addPageMessage(ne.getMessage(), request);
throw new InsufficientPermissionException(Page.LIST_STUDY_SUBJECTS_SERVLET, ne.getMessage(), "1");
}
}
}
// added to allow sections shown on this page
DisplayTableOfContentsBean displayBean = new DisplayTableOfContentsBean();
displayBean = TableOfContentsServlet.getDisplayBean(ecb, getDataSource(), currentStudy);
// escape apostrophe in event name
displayBean.getStudyEventDefinition().setName(StringEscapeUtils.escapeJavaScript(displayBean.getStudyEventDefinition().getName()));
request.setAttribute(TOC_DISPLAY, displayBean);
int sectionId = fp.getInt(INPUT_SECTION_ID, true);
ArrayList sections;
if (sectionId <= 0) {
StudyEventDAO studyEventDao = new StudyEventDAO(getDataSource());
int maximumSampleOrdinal = studyEventDao.getMaxSampleOrdinal(displayBean.getStudyEventDefinition(), displayBean.getStudySubject());
request.setAttribute("maximumSampleOrdinal", maximumSampleOrdinal);
sections = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
for (int i = 0; i < sections.size(); i++) {
SectionBean sb = (SectionBean) sections.get(i);
sectionId = sb.getId();// find the first section of this CRF
break;
}
}
SectionBean sb = new SectionBean();
if (sectionId > 0) {
// int sectionId = fp.getInt(INPUT_SECTION_ID, true);
//synchronized(this)
{
sb = (SectionBean) sdao.findByPK(sectionId);
}
}
int tabId = fp.getInt("tab", true);
if (tabId <= 0) {
tabId = 1;
}
request.setAttribute(INPUT_TAB, new Integer(tabId));
request.setAttribute(SECTION_BEAN, sb);
}
/**
* Tries to check if a seciton has item groups
* @param fp TODO
* @param ecb TODO
*
* @return
*/
protected boolean checkGroups(FormProcessor fp, EventCRFBean ecb) {
int sectionId = fp.getInt(INPUT_SECTION_ID, true);
SectionDAO sdao = new SectionDAO(getDataSource());
if (sectionId <= 0) {
ArrayList sections = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
for (int i = 0; i < sections.size(); i++) {
SectionBean sb = (SectionBean) sections.get(i);
sectionId = sb.getId();// find the first section of this CRF
break;
}
}
// we will look into db to see if any repeating items for this CRF
// section
ItemGroupDAO igdao = new ItemGroupDAO(getDataSource());
// find any item group which doesn't equal to 'Ungrouped'
ItemGroupBean itemGroup = igdao.findTopOneGroupBySectionId(sectionId);
if (itemGroup!=null && itemGroup.getId()>0) {
LOGGER.trace("This section has group");
return true;
}
return false;
}
/**
* Creates a new Event CRF or update the exsiting one, that is, an event CRF can be created but not item data yet, in this case, still consider it is not
* started(called uncompleted before)
* @param request TODO
* @param fp TODO
*
* @return
* @throws Exception
*/
private EventCRFBean createEventCRF(HttpServletRequest request, FormProcessor fp) throws InconsistentStateException {
locale = LocaleResolver.getLocale(request);
// < resmessage =
// ResourceBundle.getBundle("org.akaza.openclinica.i18n.page_messages",
// locale);
// < restext =
// ResourceBundle.getBundle("org.akaza.openclinica.i18n.notes",locale);
// <
// resexception=ResourceBundle.getBundle(
// "org.akaza.openclinica.i18n.exceptions",locale);
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
StudyBean currentStudy = (StudyBean) request.getSession().getAttribute("study");
EventCRFBean ecb;
EventCRFDAO ecdao = new EventCRFDAO(getDataSource());
int crfVersionId = fp.getInt(INPUT_CRF_VERSION_ID);
LOGGER.trace("***FOUND*** crfversionid: " + crfVersionId);
int studyEventId = fp.getInt(INPUT_STUDY_EVENT_ID);
int eventDefinitionCRFId = fp.getInt(INPUT_EVENT_DEFINITION_CRF_ID);
int subjectId = fp.getInt(INPUT_SUBJECT_ID);
int eventCRFId = fp.getInt(INPUT_EVENT_CRF_ID);
LOGGER.trace("look specifically wrt event crf id: " + eventCRFId);
LOGGER.trace("Creating event CRF. Study id: " + currentStudy.getId() + "; CRF Version id: " + crfVersionId + "; Study Event id: " + studyEventId
+ "; Event Definition CRF id: " + eventDefinitionCRFId + "; Subject: " + subjectId);
StudySubjectDAO ssdao = new StudySubjectDAO(getDataSource());
StudySubjectBean ssb = ssdao.findBySubjectIdAndStudy(subjectId, currentStudy);
if (ssb.getId() <= 0) {
LOGGER.trace("throwing ISE with study subject bean id of " + ssb.getId());
// addPageMessage(resexception.getString(
// "begin_data_entry_without_event_but_subject"));
throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception.getString("begin_data_entry_without_event_but_subject"));
}
StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(getDataSource());
StudyEventDefinitionBean sedb = seddao.findByEventDefinitionCRFId(eventDefinitionCRFId);
// logger.trace("study event definition:" + sedb.getId());
if (sedb.getId() <= 0) {
addPageMessage(resexception.getString("begin_data_entry_without_event_but_study"), request);
throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception.getString("begin_data_entry_without_event_but_study"));
}
CRFVersionDAO cvdao = new CRFVersionDAO(getDataSource());
EntityBean eb = cvdao.findByPK(crfVersionId);
if (eb.getId() <= 0) {
//addPageMessage(resexception.getString("begin_data_entry_without_event_but_CRF"));
throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception.getString("begin_data_entry_without_event_but_CRF"));
}
StudyEventDAO sedao = new StudyEventDAO(getDataSource());
StudyEventBean sEvent = (StudyEventBean) sedao.findByPK(studyEventId);
StudyBean studyWithSED = currentStudy;
if (currentStudy.getParentStudyId() > 0) {
studyWithSED = new StudyBean();
studyWithSED.setId(currentStudy.getParentStudyId());
}
AuditableEntityBean aeb = sedao.findByPKAndStudy(studyEventId, studyWithSED);
if (aeb.getId() <= 0) {
addPageMessage(resexception.getString("begin_data_entry_without_event_but_especified_event"), request);
throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception
.getString("begin_data_entry_without_event_but_especified_event"));
}
ecb = new EventCRFBean();
if (eventCRFId == 0) {// no event CRF created yet
ArrayList ecList = ecdao.findByEventSubjectVersion(sEvent, ssb, (CRFVersionBean) eb);
if (ecList.size() > 0) {
ecb = (EventCRFBean) ecList.get(0);
} else {
ecb.setAnnotations("");
ecb.setCreatedDate(new Date());
ecb.setCRFVersionId(crfVersionId);
if (currentStudy.getStudyParameterConfig().getInterviewerNameDefault().equals("blank")) {
ecb.setInterviewerName("");
} else {
// default will be event's owner name
ecb.setInterviewerName(sEvent.getOwner().getName());
}
if (!currentStudy.getStudyParameterConfig().getInterviewDateDefault().equals("blank")) {
if (sEvent.getDateStarted() != null) {
ecb.setDateInterviewed(sEvent.getDateStarted());// default
// date
} else {
// logger.trace("evnet start date is null, so date
// interviewed is null");
ecb.setDateInterviewed(null);
}
} else {
ecb.setDateInterviewed(null);
// logger.trace("date interviewed is
// null,getInterviewDateDefault() is blank");
}
// ecb.setOwnerId(ub.getId());
// above depreciated, try without it, tbh
ecb.setOwner(ub);
ecb.setStatus(Status.AVAILABLE);
ecb.setCompletionStatusId(1);
ecb.setStudySubjectId(ssb.getId());
ecb.setStudyEventId(studyEventId);
ecb.setValidateString("");
ecb.setValidatorAnnotations("");
ecb = (EventCRFBean) ecdao.create(ecb);
LOGGER.debug("*********CREATED EVENT CRF");
}
} else {
// there is an event CRF already, only need to update
ecb = (EventCRFBean) ecdao.findByPK(eventCRFId);
ecb.setCRFVersionId(crfVersionId);
ecb.setUpdatedDate(new Date());
ecb.setUpdater(ub);
ecb = updateECB(sEvent, request);
ecb = (EventCRFBean) ecdao.update(ecb);
}
if (ecb.getId() <= 0) {
addPageMessage(resexception.getString("new_event_CRF_not_created"), request);
throw new InconsistentStateException(Page.LIST_STUDY_SUBJECTS_SERVLET, resexception.getString("new_event_CRF_not_created"));
} else {
if (sEvent.getSubjectEventStatus().equals(SubjectEventStatus.SIGNED)) {
sEvent.setSubjectEventStatus(SubjectEventStatus.COMPLETED);
sEvent.setUpdater(ub);
sEvent.setUpdatedDate(new Date());
sedao.update(sEvent);
} else {
sEvent.setSubjectEventStatus(SubjectEventStatus.DATA_ENTRY_STARTED);
sEvent.setUpdater(ub);
sEvent.setUpdatedDate(new Date());
sedao.update(sEvent);
}
}
return ecb;
}
/**
* Read in form values and write them to a display item bean. Note that this results in the form value being written to both the response set bean and the
* item data bean. The ResponseSetBean is used to display preset values on the form in the event of error, and the ItemDataBean is used to send values to
* the database.
*
* @param dib
* The DisplayItemBean to write data into.
* @param request TODO
* @return The DisplayItemBean, with form data loaded.
*/
protected DisplayItemBean loadFormValue(DisplayItemBean dib, HttpServletRequest request) {
String inputName = getInputName(dib);
FormProcessor fp = new FormProcessor(request);
org.akaza.openclinica.bean.core.ResponseType rt = dib.getMetadata().getResponseSet().getResponseType();
if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CHECKBOX) || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECTMULTI)
|| rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECT)) {
dib.loadFormValue(fp.getStringArray(inputName));
// YW, 2-4-2008 << calculation result has been written in dib-data
} else if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CALCULATION)
|| rt.equals(org.akaza.openclinica.bean.core.ResponseType.GROUP_CALCULATION)) {
dib.loadFormValue(dib.getData().getValue());
ResponseOptionBean rob = (ResponseOptionBean) dib.getMetadata().getResponseSet().getOptions().get(0);
LOGGER.trace("test print of options for coding: " + rob.getValue());
// YW >>
} else {
LOGGER.trace("test print: " + inputName + ": " + fp.getString(inputName));
dib.loadFormValue(fp.getString(inputName));
}
return dib;
}
/**
* This methods will create an array of DisplayItemGroupBean, which contains multiple rows for an item group on the data entry form.
*
* @param digb
* The Item group which has multiple data rows
* @param dbGroups
* The original array got from DB which contains multiple data rows
* @param formGroups
* The new array got from front end which contains multiple data rows
* @param request TODO
* @return new constructed formGroups, compare to dbGroups, some rows are update, some new ones are added and some are removed
*/
protected List<DisplayItemGroupBean> loadFormValueForItemGroup(DisplayItemGroupBean digb, List<DisplayItemGroupBean> dbGroups,
List<DisplayItemGroupBean> formGroups, int eventDefCRFId, HttpServletRequest request) {
SectionBean sb = (SectionBean)request.getAttribute(SECTION_BEAN);
int repeatMax = digb.getGroupMetaBean().getRepeatMax();
FormProcessor fp = new FormProcessor(request);
ItemDAO idao = new ItemDAO(getDataSource());
List<ItemBean> itBeans = idao.findAllItemsByGroupId(digb.getItemGroupBean().getId(), sb.getCRFVersionId());
LOGGER.debug("+++ starting to review groups: " + repeatMax);
long timeCheck = System.currentTimeMillis();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
// adding this code from below, since we want to pass a null values list
// in all cases of getDisplayBeansFromItems().
// For adding null values to display items
FormBeanUtil formBeanUtil = new FormBeanUtil();
List<String> nullValuesList = new ArrayList<String>();
// BWP>> Get a List<String> of any null values such as NA or NI
// method returns null values as a List<String>
nullValuesList = formBeanUtil.getNullValuesByEventCRFDefId(eventDefCRFId, getDataSource());
// >>BWP
// logger.trace("+++ starting to review groups 2: " + repeatMax);
long two = System.currentTimeMillis() - timeCheck;
// logger.trace("time 2: " + two + "ms");
// >>TBH below dual for loops need a breaker to avoid a performance hit
int firstLoopBreak = 0;
int secondLoopBreak = 0;
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
int maxOrdinal = iddao.getMaxOrdinalForGroup(ecb, sb, digb.getItemGroupBean());
repeatMax = ( repeatMax < maxOrdinal)? maxOrdinal:repeatMax;
for (int i = 0; i < repeatMax; i++) {
DisplayItemGroupBean formGroup = new DisplayItemGroupBean();
formGroup.setItemGroupBean(digb.getItemGroupBean());
formGroup.setGroupMetaBean(runDynamicsCheck(digb.getGroupMetaBean(), request));
ItemGroupBean igb = digb.getItemGroupBean();
// want to do deep copy here, so always get a fresh copy for items,
// may use other better way to do, like clone
List<DisplayItemBean> dibs = FormBeanUtil.getDisplayBeansFromItems(itBeans, getDataSource(), ecb, sb.getId(), nullValuesList, getServletContext());
// get the values from the manually created rows first- not from the
// rep model
// second half of the if line is here to protect against looping tbh 01/2010
// split the if loop into two parts, so that we can get what's existing first
// and then get newly created rows later, tbh 01/2010
if (fp.getStartsWith(igb.getOid() + "_manual" + i + "input")) {
formGroup.setOrdinal(i);
formGroup.setFormInputOrdinal(i);
formGroup.setAuto(false);
formGroup.setInputId(igb.getOid() + "_manual" + i);
LOGGER.debug("1: set auto to false for " + igb.getOid() + " " + i);
dibs = processInputForGroupItem(fp, dibs, i, digb, false);
formGroup.setItems(dibs);
formGroups.add(formGroup);
} else if (!StringUtil.isBlank(fp.getString(igb.getOid() + "_manual" + i + ".newRow"))) {
// ||
// (fp.getStartsWith(igb.getOid() + "_manual" + i + "input"))) {
// the ordinal is the number got from [ ] and submitted by
// repetition javascript
formGroup.setOrdinal(i);
formGroup.setFormInputOrdinal(i);
formGroup.setInputId(igb.getOid() + "_manual" + i + ".newRow");
formGroup.setAuto(false);
LOGGER.debug("2: set auto to false for " + igb.getOid() + " " + i);
dibs = processInputForGroupItem(fp, dibs, i, digb, false);
formGroup.setItems(dibs);
formGroups.add(formGroup);
} else {
firstLoopBreak++;
}
if (firstLoopBreak > 14) {
LOGGER.debug("break first loop");
break;
}
}// end of for (int i = 0; i < repeatMax; i++)
// >>TBH remove the above eventually, repeat some work here?
LOGGER.trace("+++ starting to review groups 3: " + repeatMax);
two = System.currentTimeMillis() - timeCheck;
LOGGER.trace("time 3: " + two + "ms");
// >>TBH taking the nullvalues list out of the for loop, since it should
// be the same for all display beans
// nullValuesList = formBeanUtil.getNullValuesByEventCRFDefId(
// eventDefCRFId,
// getDataSource());
/*
* logger.trace("+++ count for null values list: " + nullValuesList.size()); logger.trace(nullValuesList.toString() + " found with " + eventDefCRFId);
*/
// had the call to form bean utils here, tbh
for (int i = 0; i < repeatMax; i++) {
DisplayItemGroupBean formGroup = new DisplayItemGroupBean();
formGroup.setItemGroupBean(digb.getItemGroupBean());
// try {
// // set isShown here, tbh 04/2010
// boolean showGroup = getItemMetadataService().isGroupShown(digb.getGroupMetaBean().getId(), ecb);
// logger.debug("found show group for group meta bean " + digb.getGroupMetaBean().getId() + ": " + showGroup);
// if (showGroup) {
// digb.getGroupMetaBean().setShowGroup(showGroup);
// // we are only hiding, not showing (for now) tbh
// }
// // << tbh 04/2010
// } catch (OpenClinicaException oce) {
// // do nothing for right now, just store the bean
// logger.debug("throws an OCE for " + digb.getGroupMetaBean().getId());
// }
formGroup.setGroupMetaBean(runDynamicsCheck(digb.getGroupMetaBean(), request));
ItemGroupBean igb = digb.getItemGroupBean();
// adding this code from below, since we want to pass a null values
// list
// in all cases of getDisplayBeansFromItems().
// For adding null values to display items
// FormBeanUtil formBeanUtil = new FormBeanUtil();
// List<String> nullValuesList = new ArrayList<String>();
// BWP>> Get a List<String> of any null values such as NA or NI
// method returns null values as a List<String>
// >>BWP
// want to do deep copy here, so always get a fresh copy for items,
// may use other better way to do, like clone
// moved it back down here to fix another bug, tbh 12-3-2007
List<DisplayItemBean> dibs = FormBeanUtil.getDisplayBeansFromItems(itBeans, getDataSource(), ecb, sb.getId(), nullValuesList, getServletContext());
LOGGER.trace("+++count for dibs after deep copy: " + dibs.size());
two = System.currentTimeMillis() - timeCheck;
// logger.trace("time 3.dibs: " + two + "ms");
// >>tbh
// let's get the values from the rep model, which includes the first
// row and any new rows
// created by rep model(add button)
if (fp.getStartsWith(igb.getOid() + "_" + i + "input")) {
formGroup.setInputId(igb.getOid() + "_" + i);
if (i == 0) {
formGroup.setOrdinal(i);// ordinal that will be saved into
// DB
} else {
formGroup.setFormInputOrdinal(i);// from 0 again, the
// ordinal from front
// end page, needs to be
// reprocessed
}
formGroup.setAuto(true);
LOGGER.debug("1: set auto to TRUE for " + igb.getOid() + " " + i);
dibs = processInputForGroupItem(fp, dibs, i, digb, true);
LOGGER.trace("+++ group ordinal: " + i + " igb name " + igb.getName());
formGroup.setItems(dibs);
formGroups.add(formGroup);
} else if (!StringUtil.isBlank(fp.getString(igb.getOid() + "_" + i + ".newRow"))) {
// || (fp.getStartsWith(igb.getOid() + "_" + i + "input"))) {
// the ordinal is the number got from [ ] and submitted by
// repetition javascript
formGroup.setInputId(igb.getOid() + "_" + i);
if (i == 0) {
formGroup.setOrdinal(i);// ordinal that will be saved into
// DB
} else {
formGroup.setFormInputOrdinal(i);// from 0 again, the
// ordinal from front
// end page, needs to be
// reprocessed
}
// String fieldName = igb.getOid() + "_" + i + this.getInputName(dib);
// if (!StringUtil.isBlank(fp.getString(fieldName))) {
// if (i != repeatMax) {
// formGroup.setAuto(false);
// logger.debug("set auto to false for " + igb.getOid() + " " + i);
// } else {
formGroup.setAuto(true);
LOGGER.debug("2: set auto to TRUE for " + igb.getOid() + " " + i);
dibs = processInputForGroupItem(fp, dibs, i, digb, true);
LOGGER.trace("+++ group ordinal: " + i + " igb name " + igb.getName());
formGroup.setItems(dibs);
formGroups.add(formGroup);
} else {
secondLoopBreak++;
}
if (secondLoopBreak > 14) {
LOGGER.debug("break second loop");
break;
}
} // end of for (int i = 0; i < repeatMax; i++)
LOGGER.debug("first loop: " + firstLoopBreak);
LOGGER.debug("second loop: " + secondLoopBreak);
LOGGER.trace("+++ starting to review groups 4: " + repeatMax);
two = System.currentTimeMillis() - timeCheck;
LOGGER.trace("time 4: " + two + "ms");
// checks how many rows are manually created, not added by repetition
// model
int manualRows = getManualRows(formGroups);
// for (int j = 0; j < formGroups.size(); j++) {
// DisplayItemGroupBean formItemGroup = formGroups.get(j);
// // logger.trace("begin formGroup Ordinal:" +
// // formItemGroup.getOrdinal());
// if (formItemGroup.isAuto() == false) {
// manualRows = manualRows + 1;
// }
// }
LOGGER.debug(" manual rows " + manualRows + " formGroup size " + formGroups.size());
request.setAttribute("manualRows", new Integer(manualRows));
// reset ordinal for the auto-created rows except for the first row
for (int j = 0; j < formGroups.size(); j++) {
DisplayItemGroupBean formItemGroup = formGroups.get(j);
if (formItemGroup.isAuto() && formItemGroup.getFormInputOrdinal() > 0) {
LOGGER.trace("+++ formInputOrdinal() " + formItemGroup.getFormInputOrdinal());
// rows included in the model: first row, last existing row and
// new rows
// the rows in between are manually added
// set the correct ordinal that will be saved into DB
// the rows generated by model starts from 0, need to add the
// number of manual rows to
// get the correct ordinals, otherwise, we will have duplicate
// ordinals like two ordinal 0
formItemGroup.setOrdinal(formItemGroup.getFormInputOrdinal() + manualRows);
}
}
LOGGER.trace("+++ starting to review groups 5: " + repeatMax);
two = System.currentTimeMillis() - timeCheck;
LOGGER.trace("time 5: " + two + "ms");
Collections.sort(formGroups);// sort all the rows by ordinal
LOGGER.trace("group row size:" + formGroups.size());
// suppose we have 3 rows of data from db, the orginal order is 0,1,2,
// repetition model will submit row number in [ ] like the following:
// 0,1,2.. consecutive numbers, means no row removed in between
// 0,1,3,4.. the 2rd row is removed, 3 and 4 are new rows
int previous = -1;
for (int j = 0; j < formGroups.size(); j++) {
DisplayItemGroupBean formItemGroup = formGroups.get(j);
LOGGER.trace("formGroup Ordinal:" + formItemGroup.getOrdinal());
// logger.debug("=== formGroup Ordinal:" + formItemGroup.getOrdinal());
// the below if loop addresses a specific problem with the repeating model
// if we cut a row out of a long list, the repeater returns double ordinals of another row
// and a second row gets deleted by mistake.
// tbh 08/2009
if (formItemGroup.getOrdinal() == previous) {
LOGGER.debug("found a match btw previous and ordinal");
formItemGroup.setEditFlag("edit");
formItemGroup.setOrdinal(previous + 1);
// dbGroups.get(j).setEditFlag("edit");
}
// << tbh 08/2009
if (formItemGroup.getOrdinal() > dbGroups.size() - 1) {
formItemGroup.setEditFlag("add");
} else {
for (int i = 0; i < dbGroups.size(); i++) {
DisplayItemGroupBean dbItemGroup = dbGroups.get(i);
if (formItemGroup.getOrdinal() == i) {
// the first row is different, it could be blank on page
// just for
// display, so need to insert this row, not update
if ("initial".equalsIgnoreCase(dbItemGroup.getEditFlag())) {
formItemGroup.setEditFlag("add");
} else {
dbItemGroup.setEditFlag("edit");
// need to set up item data id in order to update
for (DisplayItemBean dib : dbItemGroup.getItems()) {
ItemDataBean data = dib.getData();
for (DisplayItemBean formDib : formItemGroup.getItems()) {
if (formDib.getItem().getId() == dib.getItem().getId()) {
formDib.getData().setId(data.getId());
// this will save the data from IDE
// complete, used only for DDE
formDib.setDbData(dib.getData());
// tbh removed below line so as not to
// log so much, 112007
LOGGER.debug("+++ +++ form dib get data set id " + data.getId());
break;
}
}
}
formItemGroup.setEditFlag("edit");
}// else
break;
}
}
} // else
previous = formItemGroup.getOrdinal();
}
LOGGER.trace("+++ === DB group row:" + dbGroups.size());
LOGGER.trace("+++ === DB group contents: " + dbGroups.toString());
// why do we need to remove this one row below?
// For the existing rows in dbGroups,if cannot get the edit flag or
// initial flag for a row,
// it means the row is removed on the front-end, so the back-end servlet
// cannot get it.-jxu
for (int i = 0; i < dbGroups.size(); i++) {
DisplayItemGroupBean dbItemGroup = dbGroups.get(i);
LOGGER.trace("+++ found edit flag of " + dbItemGroup.getEditFlag() + " for #" + dbItemGroup.getOrdinal());
// logger.debug("+++ found edit flag of " + dbItemGroup.getEditFlag() + " for #" + dbItemGroup.getOrdinal() + ": " + i);
if (!"edit".equalsIgnoreCase(dbItemGroup.getEditFlag()) && !"initial".equalsIgnoreCase(dbItemGroup.getEditFlag())) {
// && !"".equalsIgnoreCase(dbItemGroup.getEditFlag())) {
// >> tbh if the group is not shown, we should not touch it 05/2010
if (dbItemGroup.getGroupMetaBean().isShowGroup()) {
LOGGER.trace("+++ one row removed, edit flag was " + dbItemGroup.getEditFlag());
LOGGER.debug("+++ one row removed, edit flag was " + dbItemGroup.getEditFlag());
dbItemGroup.setEditFlag("remove");
}
// << tbh
}
}
LOGGER.debug("+++ about to return form groups: " + formGroups.toString());
for (int j = 0; j < formGroups.size(); j++) {
DisplayItemGroupBean formGroup = formGroups.get(j);
formGroup.setIndex(j);
}
return formGroups;
}
/**
* @return <code>true</code> if processRequest should validate inputs when the user clicks the "Save" button, <code>false</code> otherwise.
*/
protected abstract boolean validateInputOnFirstRound();
/**
* Validate the input from the form corresponding to the provided item. Implementing methods should load data from the form into the bean before validating.
* The loadFormValue method should be used for this purpose.
* <p/>
* validateDisplayItemBeanText, validateDisplayItemBeanSingleCV, and validateDisplayItemBeanMultipleCV are provided to make implementing this method easy.
*
* @param v
* The Validator to add validations to.
* @param dib
* The DisplayItemBean to validate.
* @param request TODO
* @return The DisplayItemBean which is validated and has form values loaded into it.
*/
protected abstract DisplayItemBean validateDisplayItemBean(DiscrepancyValidator v, DisplayItemBean dib, String inputName, HttpServletRequest request);
protected void validateSCDItemBean(DiscrepancyValidator v, DisplayItemBean dib) {
ItemFormMetadataBean ibMeta = dib.getMetadata();
ItemDataBean idb = dib.getData();
if (StringUtil.isBlank(idb.getValue())) {
//if (ibMeta.isRequired() && showSCDItemIds.contains(ibMeta.getId())) {
if (ibMeta.isRequired() && dib.getIsSCDtoBeShown()) {
v.addValidation(this.getInputName(dib), Validator.IS_REQUIRED);
/*if(dib.getIsSCDtoBeShown()) {
v.addValidation(this.getInputName(dib), Validator.IS_REQUIRED);
} else {
validateShownSCDToBeHiddenSingle(v,dib);
}*/
}
} else {
validateShownSCDToBeHiddenSingle(v,dib);
}
}
protected DisplayItemBean validateDisplayItemBean(DiscrepancyValidator v, DisplayItemBean dib, String inputName, RuleValidator rv,
HashMap<String, ArrayList<String>> groupOrdinalPLusItemOid, Boolean fireRuleValidation, ArrayList<String> messages, HttpServletRequest request) {
return dib;
}
protected abstract List<DisplayItemGroupBean> validateDisplayItemGroupBean(DiscrepancyValidator v, DisplayItemGroupBean dib,
List<DisplayItemGroupBean> digbs, List<DisplayItemGroupBean> formGroups, HttpServletRequest request, HttpServletResponse response);
protected List<DisplayItemGroupBean> validateDisplayItemGroupBean(DiscrepancyValidator v, DisplayItemGroupBean dib, List<DisplayItemGroupBean> digbs,
List<DisplayItemGroupBean> formGroups, RuleValidator rv, HashMap<String, ArrayList<String>> groupOrdinalPLusItemOid, HttpServletRequest request, HttpServletResponse response) {
return digbs;
}
/*
* function written out here to return itemMetadataGroupBeans after they have been checked for show/hide via dynamics.
* author: tbh 04/2010
*
*/
private ItemGroupMetadataBean runDynamicsCheck(ItemGroupMetadataBean metadataBean, HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
try {
if (!metadataBean.isShowGroup()) {
// set isShown here, tbh 04/2010
boolean showGroup = getItemMetadataService().isGroupShown(metadataBean.getId(), ecb);
// logger.debug("found show group for group meta bean " + metadataBean.getId() + ": " +
// metadataBean.getItemGroupId() +
// ": " + ecb.getId() + ": " + showGroup);
if (getServletPage(request).equals(Page.DOUBLE_DATA_ENTRY_SERVLET)) {
showGroup = getItemMetadataService().hasGroupPassedDDE(metadataBean.getId(), ecb.getId());
}
metadataBean.setShowGroup(showGroup);
// what about the items which should be shown?
// if (getServletPage().equals(Page.ADMIN_EDIT_SERVLET) && metadataBean.isShowGroup()) {
// metadataBean.setHighlighted(true);
// }
// sets highlighting for AE, tbh 05/2010
// unset highlighting for admin editing, tbh 06/2010
}
// << tbh 04/2010
} catch (OpenClinicaException oce) {
// do nothing for right now, just store the bean
LOGGER.debug("throws an OCE for " + metadataBean.getId());
}
return metadataBean;
}
private DisplayItemBean runDynamicsItemCheck(DisplayItemBean dib, Object newParam, HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
try {
LOGGER.debug("trying run dynamics item check: item id " + dib.getItem().getId() + " item data id " + dib.getData().getId());
if (!dib.getMetadata().isShowItem()) {
boolean showItem = getItemMetadataService().isShown(dib.getItem().getId(), ecb, dib.getData());
dib.getMetadata().setShowItem(showItem);
// //System.out.println("returning " + showItem);
}
} catch (NullPointerException npe) {
LOGGER.debug("found NPE! item id " + dib.getItem().getId());
}
return dib;
}
/*
* Perform validation for calculation and group-calculation type. <br> Pre-condition: passed DisplayItemBean parameter has been loaded with value. @param sv
* @param dib @param inputName @return dib @author ywang (Feb.,2008)
*/
protected DisplayItemBean validateCalcTypeDisplayItemBean(ScoreItemValidator sv, DisplayItemBean dib, String inputName, HttpServletRequest request) {
dib = validateDisplayItemBeanText(sv, dib, inputName, request);
return dib;
}
/**
* Peform validation on a item which has a TEXT or TEXTAREA response type. If the item has a null value, it's automatically validated. Otherwise, it's
* checked against its data type.
*
* @param v
* The Validator to add validations to.
* @param dib
* The DisplayItemBean to validate.
* @param request TODO
* @return The DisplayItemBean which is validated.
*/
protected DisplayItemBean validateDisplayItemBeanText(DiscrepancyValidator v, DisplayItemBean dib, String inputName, HttpServletRequest request) {
FormProcessor fp = new FormProcessor(request);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
if (StringUtil.isBlank(inputName)) {// for single items
inputName = getInputName(dib);
}
ItemBean ib = dib.getItem();
ItemFormMetadataBean ibMeta = dib.getMetadata();
ItemDataType idt = ib.getDataType();
ItemDataBean idb = dib.getData();
boolean isNull = false;
ArrayList nullValues = edcb.getNullValuesList();
for (int i = 0; i < nullValues.size(); i++) {
NullValue nv = (NullValue) nullValues.get(i);
if (nv.getName().equals(fp.getString(inputName))) {
isNull = true;
}
}
if (!isNull) {
if (StringUtil.isBlank(idb.getValue())) {
// check required first
if (ibMeta.isRequired() && ibMeta.isShowItem()) {
v.addValidation(inputName, Validator.IS_REQUIRED);
}
} else {
if (idt.equals(ItemDataType.ST)) {
// a string's size could be more than 3999, which is more
// than
// the db field length
v.addValidation(inputName, Validator.LENGTH_NUMERIC_COMPARISON, NumericComparisonOperator.LESS_THAN_OR_EQUAL_TO, 3999);
} else if (idt.equals(ItemDataType.INTEGER)) {
v.addValidation(inputName, Validator.IS_AN_INTEGER);
v.alwaysExecuteLastValidation(inputName);
} else if (idt.equals(ItemDataType.REAL)) {
v.addValidation(inputName, Validator.IS_A_NUMBER);
v.alwaysExecuteLastValidation(inputName);
} else if (idt.equals(ItemDataType.BL)) {
// there is no validation here since this data type is
// explicitly
// allowed to be null
// if the string input for this field parses to a non-zero
// number, the
// value will be true; otherwise, 0
} else if (idt.equals(ItemDataType.BN)) {
} else if (idt.equals(ItemDataType.SET)) {
// v.addValidation(inputName, Validator.NO_BLANKS_SET);
v.addValidation(inputName, Validator.IN_RESPONSE_SET_SINGLE_VALUE, dib.getMetadata().getResponseSet());
} else if (idt.equals(ItemDataType.DATE)) {
v.addValidation(inputName, Validator.IS_A_DATE);
v.alwaysExecuteLastValidation(inputName);
} else if (idt.equals(ItemDataType.PDATE)) {
v.addValidation(inputName, Validator.IS_PARTIAL_DATE);
v.alwaysExecuteLastValidation(inputName);
}
if (ibMeta.getWidthDecimal().length() > 0) {
ArrayList<String> params = new ArrayList<String>();
params.add(0, idt.getName());
params.add(1, ibMeta.getWidthDecimal());
v.addValidation(inputName, Validator.IS_VALID_WIDTH_DECIMAL, params);
v.alwaysExecuteLastValidation(inputName);
}
// >> tbh 4/30/2010 #4963 removing custom validations firing during AE
customValidation(v, dib, inputName);
/*
* if (!StringUtil.isBlank(customValidationString)) { Validation customValidation = null; if (customValidationString.startsWith("func:")) { try
* { customValidation = Validator.processCRFValidationFunction(customValidationString ); } catch (Exception e) { e.printStackTrace(); } } else
* if (customValidationString.startsWith("regexp:")) { try { customValidation = Validator.processCRFValidationRegex(customValidationString); }
* catch (Exception e) { } } if (customValidation != null) { customValidation .setErrorMessage(dib.getMetadata().getRegexpErrorMsg());
* v.addValidation(inputName, customValidation); } }
*/
}
}
return dib;
}
protected DisplayItemBean validateDisplayItemBeanSingleCV(RuleValidator v, DisplayItemBean dib, String inputName, ArrayList<String> messages) {
if (StringUtil.isBlank(inputName)) {
inputName = getInputName(dib);
}
ItemFormMetadataBean ibMeta = dib.getMetadata();
ItemDataBean idb = dib.getData();
if (StringUtil.isBlank(idb.getValue())) {
if (ibMeta.isRequired() && ibMeta.isShowItem()) {
v.addValidation(inputName, Validator.IS_REQUIRED);
}
v.addValidation(inputName, Validator.IS_AN_RULE, messages);
} else {
v.addValidation(inputName, Validator.IS_AN_RULE, messages);
}
// customValidation(v, dib, inputName);
return dib;
}
/**
* Peform validation on a item which has a RADIO or SINGLESELECTresponse type. This function checks that the input isn't blank, and that its value comes
* from the controlled vocabulary (ResponseSetBean) in the DisplayItemBean.
*
* @param v
* The Validator to add validations to.
* @param dib
* The DisplayItemBean to validate.
* @return The DisplayItemBean which is validated.
*/
protected DisplayItemBean validateDisplayItemBeanSingleCV(DiscrepancyValidator v, DisplayItemBean dib, String inputName) {
if (StringUtil.isBlank(inputName)) {
inputName = getInputName(dib);
}
ItemFormMetadataBean ibMeta = dib.getMetadata();
ItemDataBean idb = dib.getData();
if (StringUtil.isBlank(idb.getValue())) {
if (ibMeta.isRequired() && ibMeta.isShowItem()) {
v.addValidation(inputName, Validator.IS_REQUIRED);
}
} else {
v.addValidation(inputName, Validator.IN_RESPONSE_SET_SINGLE_VALUE, dib.getMetadata().getResponseSet());
}
customValidation(v, dib, inputName);
return dib;
}
//validate simple-conditional-display item to be changed from shown to hidden
protected void validateShownSCDToBeHiddenSingle(DiscrepancyValidator v, DisplayItemBean dib) {
ItemFormMetadataBean ifmb = dib.getMetadata();
String value = dib.getData().getValue();
boolean hasDN = dib.getDiscrepancyNotes() != null && dib.getDiscrepancyNotes().size()>0 ? true : false;
if(value != null && value.length()>0 && !dib.getIsSCDtoBeShown() && !hasDN) {
//String message = ifmb.getConditionalDisplay().replaceAll("\\\\,", "##").split(",")[2].trim();
//message = message.replaceAll("##", "\\,");
String message = dib.getScdData().getScdItemMetadataBean().getMessage();
Validation vl = new Validation(Validator.TO_HIDE_CONDITIONAL_DISPLAY);
vl.setErrorMessage(message);
v.addValidation(getInputName(dib), vl);
}
}
/**
* Peform validation on a item which has a RADIO or SINGLESELECT response type. This function checks that the input isn't blank, and that its value comes
* from the controlled vocabulary (ResponseSetBean) in the DisplayItemBean.
*
* @param v
* The Validator to add validations to.
* @param dib
* The DisplayItemBean to validate.
* @return The DisplayItemBean which is validated.
*/
protected DisplayItemBean validateDisplayItemBeanMultipleCV(DiscrepancyValidator v, DisplayItemBean dib, String inputName) {
if (StringUtil.isBlank(inputName)) {
inputName = getInputName(dib);
}
ItemFormMetadataBean ibMeta = dib.getMetadata();
ItemDataBean idb = dib.getData();
if (StringUtil.isBlank(idb.getValue())) {
if (ibMeta.isRequired() && ibMeta.isShowItem()) {
v.addValidation(inputName, Validator.IS_REQUIRED);
}
} else {
v.addValidation(inputName, Validator.IN_RESPONSE_SET, dib.getMetadata().getResponseSet());
}
customValidation(v, dib, inputName);
return dib;
}
/**
* @param dib
* A DisplayItemBean representing an input on the CRF.
* @return The name of the input in the HTML form.
*/
public final String getInputName(DisplayItemBean dib) {
ItemBean ib = dib.getItem();
String inputName = "input" + ib.getId();
return inputName;
}
/**
* Creates an input name for an item data entry in an item group
*
* @param digb
* @param dib
* @return
*/
public final String getGroupItemInputName(DisplayItemGroupBean digb, int rowCount, int manualRows, DisplayItemBean dib) {
int ordinal = rowCount - manualRows;
String inputName = digb.getItemGroupBean().getOid() + "_" + ordinal + getInputName(dib);
LOGGER.debug("===returning: " + inputName);
return inputName;
}
public final String getGroupItemInputName(DisplayItemGroupBean digb, int ordinal, DisplayItemBean dib) {
String inputName = digb.getItemGroupBean().getOid() + "_" + ordinal + getInputName(dib);
LOGGER.debug("+++returning: " + inputName);
return inputName;
}
/**
* Writes data from the DisplayItemBean to the database. Note that if the bean contains an inactive ItemDataBean, the ItemDataBean is created; otherwise,
* the ItemDataBean is updated.
*
* @param dib
* The DisplayItemBean from which to write data.
* @param iddao
* The DAO to use to access the database.
* @param request TODO
* @return <code>true</code> if the query succeeded, <code>false</code> otherwise.
*/
protected boolean writeToDB(DisplayItemBean dib, ItemDataDAO iddao, int ordinal, HttpServletRequest request) {
ItemDataBean idb = dib.getData();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
if (dib.getEditFlag()!=null && "remove".equalsIgnoreCase(dib.getEditFlag())
&& getItemMetadataService().isShown(idb.getItemId(), ecb, idb)) {
getItemMetadataService().hideItem(dib.getMetadata(), ecb, idb);
}else {
if (getServletPage(request).equals(Page.DOUBLE_DATA_ENTRY_SERVLET)) {
if (!dib.getMetadata().isShowItem() && !(dib.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId()>0) &&
idb.getValue().equals("") &&
!getItemMetadataService().hasPassedDDE(dib.getMetadata(), ecb, idb)) {//(dib.getItem().getId(), ecb, idb)) {// && !getItemMetadataService().isShown(dib.getItem().getId(), ecb, dib.getData())) {
LOGGER.debug("*** not shown - not writing for idb id " + dib.getData().getId() + " and item id " + dib.getItem().getId());
return true;
}
} else {
if (!dib.getMetadata().isShowItem() &&
idb.getValue().equals("") &&
!getItemMetadataService().isShown(dib.getItem().getId(), ecb, dib.getData()) &&
!(dib.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId()>0)) {
LOGGER.debug("*** not shown - not writing for idb id " + dib.getData().getId() + " and item id " + dib.getItem().getId());
return true;
}
}
}
return writeToDB(idb,dib,iddao,ordinal, request);
}
protected boolean writeToDB(ItemDataBean itemData, DisplayItemBean dib, ItemDataDAO iddao, int ordinal, HttpServletRequest request) {
ItemDataBean idb = itemData;
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
StudyBean currentStudy = (StudyBean) request.getSession().getAttribute("study");
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
idb.setItemId(dib.getItem().getId());
idb.setEventCRFId(ecb.getId());
if (idb.getValue().equals("")) {
idb.setStatus(getBlankItemStatus());
} else {
idb.setStatus(getNonBlankItemStatus(request));
}
if (StringUtils.isBlank(dib.getEditFlag())) {
if (!idb.isActive()) {
// will this need to change for double data entry?
idb.setOrdinal(ordinal);
idb.setCreatedDate(new Date());
idb.setOwner(ub);
idb = (ItemDataBean) iddao.create(idb);
} else {
idb.setUpdater(ub);
// tbh 5990: should we update the logic here for nonrepeats?
// //System.out.println("string util is blank: update an item data " + idb.getId() + " :" + idb.getValue());
LOGGER.debug("update item update_id " + idb.getUpdater().getId());
idb = (ItemDataBean) iddao.updateValue(idb);
}
} else {
// for the items in group, they have editFlag
if ("add".equalsIgnoreCase(dib.getEditFlag())) {
idb.setOrdinal(ordinal);
idb.setCreatedDate(new Date());
idb.setOwner(ub);
LOGGER.debug("create a new item data" + idb.getItemId() + idb.getValue());
// idb = (ItemDataBean) iddao.create(idb);
// >>tbh 08/2008
idb.setUpdater(ub);
// idb = (ItemDataBean) iddao.updateValue(idb);
// instead of two hits to the db, we perform an 'upsert'
// combining them into one
idb = (ItemDataBean) iddao.upsert(idb);
// <<tbh
} else if ("edit".equalsIgnoreCase(dib.getEditFlag())) {
idb.setUpdater(ub);
// //System.out.println("update an item data - running update value " + idb.getId() + " :" + idb.getValue());
LOGGER.debug("update item update_id " + idb.getUpdater().getId());
// update tbh #5999, #5998; if an item_data was not included in
// an import data, it won't exist; we need to check on item_data_id
// to make sure we are running the correct command on the db
if (idb.getId() != 0) {
idb.setUpdatedDate(new Date());
idb = (ItemDataBean) iddao.updateValue(idb);
} else {
idb.setCreatedDate(new Date());
idb.setOrdinal(ordinal);
idb.setOwner(ub);
idb = (ItemDataBean) iddao.upsert(idb);
LOGGER.debug("just ran upsert! " + idb.getId());
}
}
// else if ("remove".equalsIgnoreCase(dib.getEditFlag())) {
// LOGGER.debug("REMOVE an item data" + idb.getItemId() + idb.getValue());
// idb.setUpdater(ub);
// idb.setStatus(Status.DELETED);
// idb = (ItemDataBean) iddao.updateValueForRemoved(idb);
//
// DiscrepancyNoteDAO dnDao = new DiscrepancyNoteDAO(getDataSource());
// List dnNotesOfRemovedItem = dnDao.findExistingNotesForItemData(idb.getId());
// if (!dnNotesOfRemovedItem.isEmpty()) {
// DiscrepancyNoteBean itemParentNote = null;
// for (Object obj : dnNotesOfRemovedItem) {
// if (((DiscrepancyNoteBean) obj).getParentDnId() == 0) {
// itemParentNote = (DiscrepancyNoteBean) obj;
// }
// }
// DiscrepancyNoteBean dnb = new DiscrepancyNoteBean();
// if (itemParentNote != null) {
// dnb.setParentDnId(itemParentNote.getId());
// dnb.setDiscrepancyNoteTypeId(itemParentNote.getDiscrepancyNoteTypeId());
// }
// dnb.setResolutionStatusId(ResolutionStatus.CLOSED.getId());
// dnb.setStudyId(currentStudy.getId());
// dnb.setAssignedUserId(ub.getId());
// dnb.setOwner(ub);
// dnb.setEntityType(DiscrepancyNoteBean.ITEM_DATA);
// dnb.setEntityId(idb.getId());
// dnb.setCreatedDate(new Date());
// dnb.setColumn("value");
// dnb.setDescription("The item has been removed, this Discrepancy Note has been Closed.");
// dnDao.create(dnb);
// dnDao.createMapping(dnb);
// itemParentNote.setResolutionStatusId(ResolutionStatus.CLOSED.getId());
// dnDao.update(itemParentNote);
// }
// }
}
return idb.isActive();
}
protected String addAttachedFilePath(DisplayItemBean dib, String attachedFilePath) {
String fileName = "";
ItemDataBean idb = dib.getData();
String itemDataValue = idb.getValue();
String dbValue = dib.getDbData().getValue();
ResponseSetBean rsb = dib.getMetadata().getResponseSet();
org.akaza.openclinica.bean.core.ResponseType rt = rsb.getResponseType();
if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.FILE) && itemDataValue.length() > 0) {
File file = new File(itemDataValue);
fileName = file.getName();
if (itemDataValue.length() > fileName.length()) {
// itemDataValue includes file path
idb.setValue(itemDataValue);
} else {
File f = new File(dbValue);
fileName = f.getName();
if (fileName.equals(itemDataValue) && dbValue.length()>itemDataValue.length()) {
// since filename is unique by timestamp, re-upload will
// append
// another timestamp to the same filename
idb.setValue(dbValue);
} else {
idb.setValue(attachedFilePath + itemDataValue);
fileName = itemDataValue;
}
}
}
return fileName;
}
/**
* Retrieve the status which should be assigned to ItemDataBeans which have blank values for this data entry servlet.
*/
protected abstract Status getBlankItemStatus();
// unavailable in admin. editing
/**
* Retrieve the status which should be assigned to ItemDataBeans which have non-blank values for this data entry servlet.
* @param request TODO
*/
protected abstract Status getNonBlankItemStatus(HttpServletRequest request);
// unavailable in admin. editing
/**
* Get the eventCRF's annotations as appropriate for this data entry servlet.
* @param request TODO
*/
protected abstract String getEventCRFAnnotations(HttpServletRequest request);
/**
* Set the eventCRF's annotations properties as appropriate for this data entry servlet.
* @param request TODO
*/
protected abstract void setEventCRFAnnotations(String annotations, HttpServletRequest request);
/**
* Retrieve the DisplaySectionBean which will be used to display the Event CRF Section on the JSP, and also is used to controll processRequest.
* @param request TODO
* @param isSubmitted TODO
*/
protected DisplaySectionBean getDisplayBean(boolean hasGroup, boolean includeUngroupedItems, HttpServletRequest request, boolean isSubmitted) throws Exception {
DisplaySectionBean section = new DisplaySectionBean();
FormProcessor fp = new FormProcessor(request);
HttpSession session = request.getSession();
Locale loc = this.locale == null ? LocaleResolver.getLocale(request) : this.locale;
StudyBean study = (StudyBean) session.getAttribute("study");
SessionManager sm = (SessionManager)request.getSession().getAttribute("sm");
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
SectionBean sb = (SectionBean)request.getAttribute(SECTION_BEAN);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
SectionDAO sdao;
// Find out whether there are ungrouped items in this section
boolean hasUngroupedItems = false;
int eventDefinitionCRFId = fp.getInt("eventDefinitionCRFId");
if (eventDefinitionCRFId <= 0) { // TODO: this block of code repeats
// many times, need to clean up
//synchronized(this)
{
EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
EventDefinitionCRFBean edcBean = edcdao.findByStudyEventIdAndCRFVersionId(study, ecb.getStudyEventId(), ecb.getCRFVersionId());
eventDefinitionCRFId = edcBean.getId();
}
}
LOGGER.trace("eventDefinitionCRFId " + eventDefinitionCRFId);
// Use this class to find out whether there are ungrouped items in this
// section
FormBeanUtil formBeanUtil = new FormBeanUtil();
List<DisplayItemGroupBean> itemGroups = new ArrayList<DisplayItemGroupBean>();
if (hasGroup) {
DisplaySectionBean newDisplayBean = new DisplaySectionBean();
if (includeUngroupedItems) {
// Null values: this method adds null values to the
// displayitembeans
newDisplayBean =
formBeanUtil.createDisplaySectionBWithFormGroups(sb.getId(), ecb.getCRFVersionId(), getDataSource(), eventDefinitionCRFId, ecb, getServletContext());
} else {
newDisplayBean =
formBeanUtil.createDisplaySectionWithItemGroups(study, sb.getId(), ecb, ecb.getStudyEventId(), sm, eventDefinitionCRFId, getServletContext());
}
itemGroups = newDisplayBean.getDisplayFormGroups();
// setDataForDisplayItemGroups(itemGroups, sb,ecb,sm);
LOGGER.trace("found item group size: " + itemGroups.size() + " and to string: " + itemGroups.toString());
section.setDisplayFormGroups(itemGroups);
}
// Find out whether any display items are *not* grouped; see issue 1689
hasUngroupedItems = formBeanUtil.sectionHasUngroupedItems(getDataSource(), sb.getId(), itemGroups);
sdao = new SectionDAO(getDataSource());
//
sb.setHasSCDItem(hasUngroupedItems?sdao.hasSCDItem(sb.getId()):false);
section.setEventCRF(ecb);
if (sb.getParentId() > 0) {
SectionBean parent = (SectionBean) sdao.findByPK(sb.getParentId());
sb.setParent(parent);
}
section.setSection(sb);
CRFVersionDAO cvdao = new CRFVersionDAO(getDataSource());
CRFVersionBean cvb = (CRFVersionBean) cvdao.findByPK(ecb.getCRFVersionId());
section.setCrfVersion(cvb);
CRFDAO cdao = new CRFDAO(getDataSource());
CRFBean cb = (CRFBean) cdao.findByPK(cvb.getCrfId());
section.setCrf(cb);
EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
// EventDefinitionCRFBean edcb =
// edcdao.findByStudyEventIdAndCRFVersionId(study,
// ecb.getStudyEventId(), cvb.getId());
section.setEventDefinitionCRF(edcb);
// setup DAO's here to avoid creating too many objects
ItemDAO idao = new ItemDAO(getDataSource());
ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO(getDataSource());
ItemDataDAO iddao = new ItemDataDAO(getDataSource(), loc);
// Use itemGroups to determine if there are any ungrouped items
// get all the parent display item beans not in group
logMe("Entering getParentDisplayItems::: Thread is? "+Thread.currentThread());
ArrayList displayItems = getParentDisplayItems(hasGroup, sb, edcb, idao, ifmdao, iddao, hasUngroupedItems, request);
logMe("Entering getParentDisplayItems::: Done and Thread is? "+Thread.currentThread());
LOGGER.debug("just ran get parent display, has group " + hasGroup + " has ungrouped " + hasUngroupedItems);
// now sort them by ordinal,
//JN: Commenting out this logic, its wrong and will give erroneous results.
Collections.sort(displayItems);
// now get the child DisplayItemBeans
for (int i = 0; i < displayItems.size(); i++) {
DisplayItemBean dib = (DisplayItemBean) displayItems.get(i);
dib.setChildren(getChildrenDisplayItems(dib, edcb, request));
// TODO use the setData command here to make sure we get a value?
//On Submition of the Admin Editing form the loadDBValue does not required
//
if (ecb.getStage() == DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE || ecb.getStage() == DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE) {
if (shouldLoadDBValues(dib) && !isSubmitted) {
dib.loadDBValue();
}
} else {
if (shouldLoadDBValues(dib)) {
LOGGER.trace("should load db values is true, set value");
dib.loadDBValue();
LOGGER.trace("just got data loaded: " + dib.getData().getValue());
}
}
displayItems.set(i, dib);
}
section.setItems(displayItems);
return section;
}
/**
* Retrieve the DisplaySectionBean which will be used to display the Event CRF Section on the JSP, and also is used to controll processRequest.
* @param request TODO
*/
protected ArrayList getAllDisplayBeans(HttpServletRequest request) throws Exception {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ArrayList sections = new ArrayList();
HttpSession session = request.getSession();
StudyBean study = (StudyBean) session.getAttribute("study");
SectionDAO sdao = new SectionDAO(getDataSource());
ItemDataDAO iddao = new ItemDataDAO(getDataSource(), locale);
// ALL_SECTION_BEANS
ArrayList<SectionBean> allSectionBeans = (ArrayList<SectionBean>)request.getAttribute(ALL_SECTION_BEANS);
for (int j = 0; j < allSectionBeans.size(); j++) {
SectionBean sb = allSectionBeans.get(j);
DisplaySectionBean section = new DisplaySectionBean();
section.setEventCRF(ecb);
if (sb.getParentId() > 0) {
SectionBean parent = (SectionBean) sdao.findByPK(sb.getParentId());
sb.setParent(parent);
}
section.setSection(sb);
CRFVersionDAO cvdao = new CRFVersionDAO(getDataSource());
CRFVersionBean cvb = (CRFVersionBean) cvdao.findByPK(ecb.getCRFVersionId());
section.setCrfVersion(cvb);
CRFDAO cdao = new CRFDAO(getDataSource());
CRFBean cb = (CRFBean) cdao.findByPK(cvb.getCrfId());
section.setCrf(cb);
EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
EventDefinitionCRFBean edcb = edcdao.findByStudyEventIdAndCRFVersionId(study, ecb.getStudyEventId(), cvb.getId());
section.setEventDefinitionCRF(edcb);
// setup DAO's here to avoid creating too many objects
ItemDAO idao = new ItemDAO(getDataSource());
ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO(getDataSource());
iddao = new ItemDataDAO(getDataSource(),locale);
// get all the display item beans
ArrayList displayItems = getParentDisplayItems(false, sb, edcb, idao, ifmdao, iddao, false, request);
LOGGER.debug("222 just ran get parent display, has group " + " FALSE has ungrouped FALSE");
// now sort them by ordinal
Collections.sort(displayItems);
// now get the child DisplayItemBeans
for (int i = 0; i < displayItems.size(); i++) {
DisplayItemBean dib = (DisplayItemBean) displayItems.get(i);
dib.setChildren(getChildrenDisplayItems(dib, edcb, request));
if (shouldLoadDBValues(dib)) {
LOGGER.trace("should load db values is true, set value");
dib.loadDBValue();
}
displayItems.set(i, dib);
}
section.setItems(displayItems);
sections.add(section);
}
return sections;
}
/**
* For each single item in this section which is a parent, get a DisplayItemBean corresponding to that item. Note that an item is a parent iff its parentId
* == 0.
* @param sb
* The section whose items we are retrieving.
* @param hasUngroupedItems
* @param request TODO
*
* @return An array of DisplayItemBean objects, one per parent item in the section. Note that there is no guarantee on the ordering of the objects.
* @throws Exception
*/
private ArrayList getParentDisplayItems(boolean hasGroup, SectionBean sb, EventDefinitionCRFBean edcb, ItemDAO idao, ItemFormMetadataDAO ifmdao,
ItemDataDAO iddao, boolean hasUngroupedItems, HttpServletRequest request) throws Exception {
ArrayList answer = new ArrayList();
EventCRFBean ecb = (EventCRFBean) request.getAttribute(INPUT_EVENT_CRF);
HashMap displayItems = new HashMap();
// ArrayList items = idao.findAllParentsBySectionId(sb.getId());
ArrayList items = new ArrayList();
ArrayList itemsUngrped = new ArrayList();
if (hasGroup) {
// issue 1689: this method causes problems with items that have
// been defined as grouped, then redefined as ungrouped; thus it
// is "checked twice" with hasUngroupedItems.
// See: FormBeanUtil.sectionHasUngroupedItems.
if (hasUngroupedItems) {
// @pgawade 05-Aug-2011 fix for issue 10628 - commented out the
// if-else logic based on 'hasGroup' flag.
// 'if' part is unchanged but else part is changed to be
// executed always because that is to get the non-repeating and
// ungrouped item details and was getting skipped in case the
// section has repeating group items plus non-repeating group
// items
itemsUngrped = idao.findAllUngroupedParentsBySectionId(sb.getId(), sb.getCRFVersionId());
}
// however, if we have true:true, we exclude all grouped items
// items.addAll(
// idao.findAllGroupedParentsBySectionId(
// sb.getId(), sb.getCRFVersionId()));
}
// else {
LOGGER.trace("no item groups");
// items = idao.findAllParentsBySectionId(sb.getId());
items = idao.findAllNonRepeatingParentsBySectionId(sb.getId());
items.addAll(itemsUngrped);
// }
LOGGER.debug("items size" + items.size());
for (int i = 0; i < items.size(); i++) {
DisplayItemBean dib = new DisplayItemBean();
dib.setEventDefinitionCRF(edcb);
ItemBean ib = (ItemBean) items.get(i);
dib.setItem(ib);
displayItems.put(new Integer(dib.getItem().getId()), dib);
}
ArrayList data = iddao.findAllBySectionIdAndEventCRFId(sb.getId(), ecb.getId());
for (int i = 0; i < data.size(); i++) {
ItemDataBean idb = (ItemDataBean) data.get(i);
DisplayItemBean dib = (DisplayItemBean) displayItems.get(new Integer(idb.getItemId()));
if (dib != null) {
dib.setData(idb);
dib.setDbData((ItemDataBean) BeanUtils.cloneBean(idb));
displayItems.put(new Integer(idb.getItemId()), dib);
}
}
ArrayList metadata = ifmdao.findAllBySectionId(sb.getId());
for (int i = 0; i < metadata.size(); i++) {
ItemFormMetadataBean ifmb = (ItemFormMetadataBean) metadata.get(i);
DisplayItemBean dib = (DisplayItemBean) displayItems.get(new Integer(ifmb.getItemId()));
if (dib != null) {
// boolean showItem = false;
boolean needsHighlighting = !ifmb.isShowItem();
logMe("Entering thread before getting ItemMetadataService:::"+Thread.currentThread());
boolean showItem = getItemMetadataService().isShown(ifmb.getItemId(), ecb, dib.getData());
if (getServletPage(request).equals(Page.DOUBLE_DATA_ENTRY_SERVLET)) {
showItem = getItemMetadataService().hasPassedDDE(ifmb, ecb, dib.getData());
}
// is the above needed for children items too?
boolean passedDDE = getItemMetadataService().hasPassedDDE(ifmb, ecb, dib.getData());
if (showItem) { // we are only showing, not hiding
LOGGER.debug("set show item " + ifmb.getItemId() + " idb " + dib.getData().getId() + " show item " + showItem + " passed dde " + passedDDE);
// ifmb.setShowItem(showItem);
ifmb.setShowItem(true);
} else {
LOGGER.debug("DID NOT set show item " + ifmb.getItemId() + " idb " + dib.getData().getId() + " show item " + showItem + " passed dde "
+ passedDDE + " value " + dib.getData().getValue());
}
dib.setMetadata(ifmb);
displayItems.put(new Integer(ifmb.getItemId()), dib);
}
}
Iterator hmIt = displayItems.keySet().iterator();
while (hmIt.hasNext()) {
Integer key = (Integer) hmIt.next();
DisplayItemBean dib = (DisplayItemBean) displayItems.get(key);
answer.add(dib);
LOGGER.debug("*** getting with key: " + key + " display item bean with value: " + dib.getData().getValue());
}
LOGGER.debug("*** test of the display items: " + displayItems.toString());
return answer;
}
/**
* Get the DisplayItemBean objects corresponding to the items which are children of the specified parent.
*
* @param parent
* The item whose children are to be retrieved.
* @param request TODO
* @return An array of DisplayItemBean objects corresponding to the items which are children of parent, and are sorted by column number (ascending), then
* ordinal (ascending).
*/
private ArrayList getChildrenDisplayItems(DisplayItemBean parent, EventDefinitionCRFBean edcb, HttpServletRequest request) {
ArrayList answer = new ArrayList();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
int parentId = parent.getItem().getId();
ItemDAO idao = new ItemDAO(getDataSource());
ArrayList childItemBeans = idao.findAllByParentIdAndCRFVersionId(parentId, ecb.getCRFVersionId());
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO(getDataSource());
for (int i = 0; i < childItemBeans.size(); i++) {
ItemBean child = (ItemBean) childItemBeans.get(i);
ItemDataBean data = iddao.findByItemIdAndEventCRFId(child.getId(), ecb.getId());
ItemFormMetadataBean metadata = ifmdao.findByItemIdAndCRFVersionId(child.getId(), ecb.getCRFVersionId());
DisplayItemBean dib = new DisplayItemBean();
dib.setEventDefinitionCRF(edcb);
dib.setItem(child);
// tbh
if (!getServletPage(request).equals(Page.DOUBLE_DATA_ENTRY_SERVLET)) {
dib.setData(data);
}
// <<tbh 07/2009, bug #3883
// ItemDataBean dbData = iddao.findByItemIdAndEventCRFIdAndOrdinal(itemId, eventCRFId, ordinal)
dib.setDbData(data);
boolean showItem = getItemMetadataService().isShown(metadata.getItemId(), ecb, data);
if (getServletPage(request).equals(Page.DOUBLE_DATA_ENTRY_SERVLET)) {
showItem = getItemMetadataService().hasPassedDDE(metadata, ecb, data);
} //else {
// showItem = getItemMetadataService().isShown(metadata.getItemId(), ecb, dib.getDbData());
// }
// boolean passedDDE = getItemMetadataService().hasPassedDDE(data);
if (showItem) {
LOGGER.debug("set show item: " + metadata.getItemId() + " data " + data.getId());
// metadata.setShowItem(showItem);
metadata.setShowItem(true);
}
// logger.debug("did not catch NPE");
dib.setMetadata(metadata);
if (shouldLoadDBValues(dib)) {
LOGGER.trace("should load db values is true, set value");
dib.loadDBValue();
LOGGER.trace("just loaded the child value: " + dib.getData().getValue());
}
answer.add(dib);
}
// this is a pretty slow and memory intensive way to sort... see if we
// can
// have the db do this instead
Collections.sort(answer);
return answer;
}
/**
* gets the available dynamics service
*/
public DynamicsMetadataService getItemMetadataService() {
DynamicsMetadataService itemMetadataService =null;
itemMetadataService =
itemMetadataService != null ? itemMetadataService : (DynamicsMetadataService) SpringServletAccess.getApplicationContext(getServletContext()).getBean(
"dynamicsMetadataService");
return itemMetadataService;
}
/**
* @return The Page object which represents this servlet's JSP.
*/
protected abstract Page getJSPPage();
/**
* @param request TODO
* @return The Page object which represents this servlet.
*/
protected abstract String getServletPage(HttpServletRequest request);
protected abstract boolean shouldLoadDBValues(DisplayItemBean dib);
protected void setUpPanel(DisplaySectionBean section) {
resetPanel();
panel.setStudyInfoShown(false);
panel.setOrderedData(true);
}
/*
* 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);
dib.setNumDiscrepancyNotes(numNotes + notes.size());// + notes2.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;
}
private void setToolTipEventNotes(HttpServletRequest request) {
long t = System.currentTimeMillis();
logMe("Method:setToolTipEventNotes"+t);
DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ArrayList<DiscrepancyNoteBean> ecNotes = dndao.findEventCRFDNotesToolTips(ecb);
ArrayList<DiscrepancyNoteBean> nameNotes = new ArrayList();
ArrayList<DiscrepancyNoteBean> dateNotes = new ArrayList();
for (int i = 0; i < ecNotes.size(); i++) {
DiscrepancyNoteBean dn = ecNotes.get(i);
if (INTERVIEWER_NAME.equalsIgnoreCase(dn.getColumn())) {
nameNotes.add(dn);
}
if (DATE_INTERVIEWED.equalsIgnoreCase(dn.getColumn())) {
dateNotes.add(dn);
}
}
request.setAttribute("nameNotes", nameNotes);
request.setAttribute("intrvDates", dateNotes);
logMe("existing Method:setToolTipEventNotes, time took"+(System.currentTimeMillis()-t));
}
/**
* To set the totals of each resolution status on the DisplayItemBean for each item.
* @param dib
* @param notes
* @param ecbId TODO
*/
private DisplayItemBean setTotals(DisplayItemBean dib,int itemDataId,ArrayList<DiscrepancyNoteBean> notes, int ecbId)
{
long t = System.currentTimeMillis();
logMe("Method::::::setTotals"+t);
int resolutionStatus;
int totNew = 0,totRes = 0,totClosed = 0,totUpdated =0,totNA = 0;
boolean hasOtherThread = false;
DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
ArrayList<DiscrepancyNoteBean> existingNotes = dndao.findExistingNotesForToolTip(itemDataId);
dib.setDiscrepancyNotes(existingNotes);
for (DiscrepancyNoteBean obj : dib.getDiscrepancyNotes()) {
DiscrepancyNoteBean note = obj;
if (note.getParentDnId() == 0) {
resolutionStatus = note.getResolutionStatusId();
totNew++;//using totNew to show the total parent threads
/* if(resolutionStatus==ResolutionStatus.UPDATED.getId())totUpdated++;
else if(resolutionStatus==ResolutionStatus.RESOLVED.getId())totRes++;//Resolution proposed count
else if(resolutionStatus==ResolutionStatus.CLOSED.getId())totClosed++;
else if(resolutionStatus==ResolutionStatus.NOT_APPLICABLE.getId())totNA++;*/// not needed any more
}
}
ArrayList parentNotes = dndao.findExistingNotesForItemData(itemDataId);
//Adding this to show the value of only parent threads on discrepancy notes tool tip
for (Object obj : parentNotes) {
DiscrepancyNoteBean note = (DiscrepancyNoteBean) obj;
/*We would only take the resolution status of the parent note of any note thread. If there
* are more than one note thread, the thread with the worst resolution status will be taken.*/
if(note.getParentDnId()==0)
{
if(hasOtherThread)
{
totNew++;
}
hasOtherThread = true;
}
}
logMe("time taken thus far, before audit log check"+(System.currentTimeMillis()-t));
long t1 = System.currentTimeMillis();
AuditDAO adao = new AuditDAO(getDataSource());
ArrayList itemAuditEvents = adao.checkItemAuditEventsExist(dib.getItem().getId(), "item_data", ecbId);
if (itemAuditEvents.size() > 0) {
AuditBean itemFirstAudit = (AuditBean)itemAuditEvents.get(0);
String firstRFC = itemFirstAudit.getReasonForChange();
String oldValue = itemFirstAudit.getOldValue();
if(firstRFC != null && "initial value".equalsIgnoreCase(firstRFC)
&& (oldValue==null || oldValue.isEmpty())) {
dib.getData().setAuditLog(false);
} else {
dib.getData().setAuditLog(true);
}
}
logMe("time taken thus far, after audit log check"+(System.currentTimeMillis()-t));
logMe("Only for audit check::"+(System.currentTimeMillis()-t1));
dib.setTotNew(totNew);//totNew is used for parent thread count
dib.setTotRes(totRes);
dib.setTotUpdated(totUpdated);
dib.setTotClosed(totClosed);
dib.setTotNA(totNA);
logMe("returning back..time taken"+(System.currentTimeMillis()-t));
return dib;
}
/**
* The following methods are for 'mark CRF complete'
* @param request TODO
*
* @return
*/
protected boolean markCRFComplete(HttpServletRequest request) throws Exception {
locale = LocaleResolver.getLocale(request);
HttpSession session = request.getSession();
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
EventCRFDAO ecdao = new EventCRFDAO(getDataSource());
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
// < respage =
// ResourceBundle.getBundle("org.akaza.openclinica.i18n.page_messages",
// locale);
// < restext =
// ResourceBundle.getBundle("org.akaza.openclinica.i18n.notes",locale);
// <
// resexception=ResourceBundle.getBundle(
// "org.akaza.openclinica.i18n.exceptions",locale);
getEventCRFBean(request);
getEventDefinitionCRFBean(request);
DataEntryStage stage = ecb.getStage();
// request.setAttribute(TableOfContentsServlet.INPUT_EVENT_CRF_BEAN,
// ecb);
// request.setAttribute(INPUT_EVENT_CRF_ID, new Integer(ecb.getId()));
LOGGER.trace("inout_event_crf_id:" + ecb.getId());
if (stage.equals(DataEntryStage.UNCOMPLETED) || stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE) || stage.equals(DataEntryStage.LOCKED)) {
addPageMessage(respage.getString("not_mark_CRF_complete1"), request);
return false;
}
if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE) || stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY)) {
if (!edcb.isDoubleEntry()) {
addPageMessage(respage.getString("not_mark_CRF_complete2"), request);
return false;
}
}
/*
* if (!isEachSectionReviewedOnce()) { addPageMessage("You may not mark this Event CRF complete, because there are some sections which have not been
* reviewed once."); return false; }
*/
if (isEachRequiredFieldFillout(request) == false) {
addPageMessage(respage.getString("not_mark_CRF_complete4"), request);
return false;
}
/*
* if (ecb.getInterviewerName().trim().equals("")) { throw new InconsistentStateException(errorPage, "You may not mark this Event CRF complete, because
* the interviewer name is blank."); }
*/
Status newStatus = ecb.getStatus();
boolean ide = true;
if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY) && edcb.isDoubleEntry()) {
newStatus = Status.PENDING;
ecb.setUpdaterId(ub.getId());
ecb.setUpdater(ub);
ecb.setUpdatedDate(new Date());
ecb.setDateCompleted(new Date());
} else if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY) && !edcb.isDoubleEntry()) {
newStatus = Status.UNAVAILABLE;
ecb.setUpdaterId(ub.getId());
ecb.setUpdater(ub);
ecb.setUpdatedDate(new Date());
ecb.setDateCompleted(new Date());
ecb.setDateValidateCompleted(new Date());
} else if (stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE) && edcb.isDoubleEntry()) {
newStatus = Status.UNAVAILABLE;
ecb.setUpdaterId(ub.getId());
ecb.setUpdater(ub);
ecb.setUpdatedDate(new Date());
ecb.setDateCompleted(new Date());
ecb.setDateValidateCompleted(new Date());
ide=false;
}
else if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE) || stage.equals(DataEntryStage.DOUBLE_DATA_ENTRY)) {
newStatus = Status.UNAVAILABLE;
ecb.setDateValidateCompleted(new Date());
ecb.setUpdaterId(ub.getId());
ecb.setUpdater(ub);
ide = false;
}
// for the non-reviewed sections, no item data in DB yet, need to
// create them
if (!isEachSectionReviewedOnce(request)) {
boolean canSave = saveItemsToMarkComplete(newStatus, request);
if (canSave == false) {
addPageMessage(respage.getString("not_mark_CRF_complete3"), request);
return false;
}
}
ecb.setStatus(newStatus);
/*
* Marking the data entry as signed if the corresponding EventDefinitionCRF is being enabled for electronic signature.
*/
if (edcb.isElectronicSignature()) {
ecb.setElectronicSignatureStatus(true);
}
ecb = (EventCRFBean) ecdao.update(ecb);
// note the below statement only updates the DATES, not the STATUS
ecdao.markComplete(ecb, ide);
// update all the items' status to complete
iddao.updateStatusByEventCRF(ecb, newStatus);
// change status for study event
StudyEventDAO sedao = new StudyEventDAO(getDataSource());
StudyEventBean seb = (StudyEventBean) sedao.findByPK(ecb.getStudyEventId());
seb.setUpdatedDate(new Date());
seb.setUpdater(ub);
EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
ArrayList allCRFs = ecdao.findAllByStudyEventAndStatus(seb,Status.UNAVAILABLE);
StudyBean study = (StudyBean) session.getAttribute("study");
ArrayList allEDCs = (ArrayList) edcdao.findAllActiveByEventDefinitionId(study, seb.getStudyEventDefinitionId());
CRFVersionDAO crfversionDao= new CRFVersionDAO(getDataSource());
boolean eventCompleted = true;
boolean allRequired = true;
//JN Adding another flag
boolean allCrfsCompleted = false;
int allEDCsize = allEDCs.size();
ArrayList nonRequiredCrfIds = new ArrayList();
ArrayList requiredCrfIds = new ArrayList();
if ( allCRFs.size() == allEDCs.size()) {// was
//JN: all crfs are completed and then set the subject event status as complete
seb.setSubjectEventStatus(SubjectEventStatus.COMPLETED);
}
seb = (StudyEventBean) sedao.update(seb);
request.setAttribute(INPUT_EVENT_CRF,ecb);
request.setAttribute(EVENT_DEF_CRF_BEAN,edcb);
return true;
}
private void getEventCRFBean(HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
FormProcessor fp = new FormProcessor(request);
int eventCRFId = fp.getInt(INPUT_EVENT_CRF_ID);
EventCRFDAO ecdao = new EventCRFDAO(getDataSource());
ecb = (EventCRFBean) ecdao.findByPK(eventCRFId);
}
protected boolean isEachRequiredFieldFillout(HttpServletRequest request) {
HttpSession session = request.getSession();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
// need to update this method to accomodate dynamics, tbh
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ItemDAO idao = new ItemDAO(getDataSource());
ItemFormMetadataDAO itemFormMetadataDao = new ItemFormMetadataDAO(getDataSource());
// Below code will iterate all shown and hidden required fields/items in a crf version and verify if the data field is filled up with value or if not , then it is a hidden field with no show rule triggered for the item.
ArrayList<ItemFormMetadataBean> shownRequiredAllItemsInCrfVersion = itemFormMetadataDao.findAllItemsRequiredAndShownByCrfVersionId(ecb.getCRFVersionId());
ArrayList<ItemFormMetadataBean> hiddenRequiredAllItemsInCrfVersion = itemFormMetadataDao.findAllItemsRequiredAndHiddenByCrfVersionId(ecb
.getCRFVersionId());
ItemGroupMetadataDAO<String, ArrayList> igdao = new ItemGroupMetadataDAO<String, ArrayList>(dataSource);
ArrayList<ItemDataBean> itemdatas = null;
for (ItemFormMetadataBean shownItemMeta : shownRequiredAllItemsInCrfVersion) {
ItemGroupMetadataBean igBean= (ItemGroupMetadataBean) igdao.findByItemAndCrfVersion(shownItemMeta.getItemId(), ecb.getCRFVersionId());
// verifies if the group that the item belongs to is not hidden.
if (igBean!=null && igBean.isShowGroup()){
itemdatas = iddao.findAllByEventCRFIdAndItemId(ecb.getId(), shownItemMeta.getItemId());
if (itemdatas == null || itemdatas.size()==0)
return false;
for (ItemDataBean itemdata : itemdatas) {
System.out.println(itemdata.getItemId() +" : "+ itemdata.getValue());
if ((itemdata.getValue()==null || itemdata.getValue().equals("") || itemdata.getValue().trim().length()==0) && dndao.findNumExistingNotesForItem(itemdata.getId())<1 ) {
return false;
}
}
}
ArrayList<DynamicsItemFormMetadataBean> dynamicsItemFormMetadataBeans = null;
for (ItemFormMetadataBean hiddenItemMeta : hiddenRequiredAllItemsInCrfVersion) {
itemdatas = iddao.findAllByEventCRFIdAndItemId(ecb.getId(), hiddenItemMeta.getItemId());
dynamicsItemFormMetadataBeans = getItemMetadataService().getDynamicsItemFormMetadataDao().findByItemAndEventCrfShown(ecb,
hiddenItemMeta.getItemId());
if (itemdatas.size() == 0 && dynamicsItemFormMetadataBeans.size() > 0) {
return false;
}
for (ItemDataBean itemdata : itemdatas) {
if ((itemdata.getValue()==null || itemdata.getValue().equals("") || itemdata.getValue().trim().length()==0) && dndao.findNumExistingNotesForItem(itemdata.getId())<1 && dynamicsItemFormMetadataBeans.size() > 0) {
return false;
}
}
}
}
// had to change the query below to allow for hidden items here, tbh 04/2010
ArrayList allFilled = iddao.findAllBlankRequiredByEventCRFId(ecb.getId(), ecb.getCRFVersionId());
int numNotes = 0;
if (!allFilled.isEmpty()) {
LOGGER.trace("allFilled is not empty");
FormDiscrepancyNotes fdn = (FormDiscrepancyNotes) session.getAttribute(AddNewSubjectServlet.FORM_DISCREPANCY_NOTES_NAME);
HashMap idNotes = fdn.getIdNotes();
for (int i = 0; i < allFilled.size(); i++) {
ItemDataBean idb = (ItemDataBean) allFilled.get(i);
int exsitingNotes = dndao.findNumExistingNotesForItem(idb.getId());
if (exsitingNotes > 0) {
LOGGER.trace("has existing note");
numNotes++;
} else if (idNotes.containsKey(idb.getId())) {
LOGGER.trace("has note in session");
numNotes++;
}
}
LOGGER.trace("numNotes allFilled.size:" + numNotes + " " + allFilled.size());
if (numNotes >= allFilled.size()) {
LOGGER.trace("all required are filled out");
return true;
} else {
LOGGER.debug("numNotes < allFilled.size() " + numNotes + ": " + allFilled.size());
return false;
}
}
return true;
}
/**
* 06/13/2007- jxu Since we don't require users to review each section before mark a CRF as complete, we need to create item data in the database because
* items will not be created unless the section which contains the items is reviewed by users
* @param request TODO
*/
private boolean saveItemsToMarkComplete(Status completeStatus, HttpServletRequest request) throws Exception {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
SectionDAO sdao = new SectionDAO(getDataSource());
ArrayList sections = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ItemDAO idao = new ItemDAO(getDataSource());
for (int i = 0; i < sections.size(); i++) {
SectionBean sb = (SectionBean) sections.get(i);
if (!isCreateItemReqd(sb, request)) {
// ArrayList requiredItems =
// idao.findAllRequiredBySectionId(sb.getId());
// if (!requiredItems.isEmpty()) {
// return false;
// }
ArrayList items = idao.findAllBySectionId(sb.getId());
for (int j = 0; j < items.size(); j++) {
ItemBean item = (ItemBean) items.get(j);
ArrayList<ItemDataBean> itemBean = iddao.findAllByEventCRFIdAndItemIdNoStatus(ecb.getId(),item.getId());
ItemDataBean idb = new ItemDataBean();
idb.setItemId(item.getId());
idb.setEventCRFId(ecb.getId());
idb.setCreatedDate(new Date());
idb.setOrdinal(1);
idb.setOwner(ub);
if (completeStatus != null) {// to avoid null exception
idb.setStatus(completeStatus);
} else {
idb.setStatus(Status.UNAVAILABLE);
}
idb.setValue("");
boolean save = true;
if(itemBean.size()>0) save = false;
/* while(itemBean.iterator().hasNext())
{
ItemDataBean temp = itemBean.iterator().next();
if(idb.getEventCRFId()==(temp.getEventCRFId()))
{
if(idb.getItemId()==(temp.getItemId())){
save = false;
}
}
}*/
if(save)
{
iddao.create(idb);
}
}
}
}
return true;
}
/**
* Checks if a section is reviewed at least once by user
* updated tbh 03/2011, to fix duplicates issues
* @param sb
* @param request TODO
* @return
*/
protected boolean isSectionReviewedOnce(SectionBean sb, HttpServletRequest request) {
SectionDAO sdao = new SectionDAO(getDataSource());
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
DataEntryStage stage = ecb.getStage();
HashMap numItemsHM = sdao.getNumItemsBySectionId();
HashMap numItemsPendingHM = sdao.getNumItemsPendingBySectionId(ecb);
HashMap numItemsCompletedHM = sdao.getNumItemsCompletedBySectionId(ecb);
HashMap numItemsBlankHM = sdao.getNumItemsBlankBySectionId(ecb);
Integer key = new Integer(sb.getId());
int numItems = TableOfContentsServlet.getIntById(numItemsHM, key);
int numItemsPending = TableOfContentsServlet.getIntById(numItemsPendingHM, key);
int numItemsCompleted = TableOfContentsServlet.getIntById(numItemsCompletedHM, key);
int numItemsBlank = TableOfContentsServlet.getIntById(numItemsBlankHM, key);
LOGGER.debug(" for " + key + " num items " + numItems + " num items blank " + numItemsBlank + " num items pending " + numItemsPending + " completed " + numItemsCompleted);
if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY) && edcb.isDoubleEntry())
{
if (numItemsPending == 0 && numItems > 0) {
LOGGER.debug("returns false on ide loop " + key);
return false;
}
} else
{
if (numItemsCompleted == 0 && numItems > 0) {
LOGGER.debug("returns false on other loop " + key);
return false;
}
}
return true;
}
protected boolean isCreateItemReqd(SectionBean sb, HttpServletRequest request) {
SectionDAO sdao = new SectionDAO(getDataSource());
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
DataEntryStage stage = ecb.getStage();
HashMap numItemsHM = sdao.getNumItemsBySectionId();
HashMap numItemsPendingHM = sdao.getNumItemsPendingBySectionId(ecb);
HashMap numItemsCompletedHM = sdao.getNumItemsCompletedBySection(ecb);
HashMap numItemsBlankHM = sdao.getNumItemsBlankBySectionId(ecb);
Integer key = new Integer(sb.getId());
int numItems = TableOfContentsServlet.getIntById(numItemsHM, key);
int numItemsPending = TableOfContentsServlet.getIntById(numItemsPendingHM, key);
int numItemsCompleted = TableOfContentsServlet.getIntById(numItemsCompletedHM, key);
int numItemsBlank = TableOfContentsServlet.getIntById(numItemsBlankHM, key);
LOGGER.debug(" for " + key + " num items " + numItems + " num items blank " + numItemsBlank + " num items pending " + numItemsPending + " completed " + numItemsCompleted);
if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY) && edcb.isDoubleEntry())
{
if (numItemsPending == 0 && numItems > 0) {
// System.out.println("returns false on ide loop " + key);
return false;
}
} else
{
if(numItemsCompleted < numItems){
return false;
}
}
return true;
}
/**
* Checks if all the sections in an event crf are reviewed once
* tbh updated to prevent duplicates, 03/2011
* @param request TODO
*
* @return
*/
protected boolean isEachSectionReviewedOnce(HttpServletRequest request) {
SectionDAO sdao = new SectionDAO(getDataSource());
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
DataEntryStage stage = ecb.getStage();
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
// below block changed tbh 04/2011, to remove repeating items generated by mistake
ArrayList<SectionBean> sections = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
/* for (SectionBean section : sections) {
boolean toContinue = isSectionReviewedOnce(section, request);
if (!toContinue) {
return false;
}
}*/
HashMap numItemsHM = sdao.getNumItemsBySectionId();
HashMap numItemsPendingHM = sdao.getNumItemsPendingBySectionId(ecb);
HashMap numItemsCompletedHM = sdao.getNumItemsCompletedBySectionId(ecb);
for (int i = 0; i < sections.size(); i++) {
SectionBean sb = sections.get(i);
Integer key = new Integer(sb.getId());
int numItems = TableOfContentsServlet.getIntById(numItemsHM, key);
int numItemsPending = TableOfContentsServlet.getIntById(numItemsPendingHM, key);
int numItemsCompleted = TableOfContentsServlet.getIntById(numItemsCompletedHM, key);
if (stage.equals(DataEntryStage.INITIAL_DATA_ENTRY) && edcb.isDoubleEntry()) {
if (numItemsPending == 0 && numItems > 0) {
return false;
}
} else {
if (numItemsCompleted == 0 && numItems > 0) {
return false;
}
else if(numItemsCompleted < numItems){
return false;
}
}
}
return true;
// if we get this far, all sections are checked and we return a true
// return true;
}
protected void getEventDefinitionCRFBean(HttpServletRequest request) {
HttpSession session = request.getSession();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
{
EventDefinitionCRFDAO edcdao = new EventDefinitionCRFDAO(getDataSource());
StudyBean study = (StudyBean) session.getAttribute("study");
edcb = edcdao.findByStudyEventIdAndCRFVersionId(study, ecb.getStudyEventId(), ecb.getCRFVersionId());
}
}
//@pgawade 30-May-2012 Fix for issue 13963 - added an extra parameter 'isSubmitted' to method createItemWithGroups
protected List<DisplayItemWithGroupBean> createItemWithGroups(DisplaySectionBean dsb, boolean hasItemGroup, int eventCRFDefId, HttpServletRequest request, boolean isSubmitted) {
HttpSession session = request.getSession();
List<DisplayItemWithGroupBean> displayItemWithGroups = new ArrayList<DisplayItemWithGroupBean>();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ItemDAO idao = new ItemDAO(getDataSource());
SectionBean sb = (SectionBean)request.getAttribute(SECTION_BEAN);
EventDefinitionCRFBean edcb = (EventDefinitionCRFBean)request.getAttribute(EVENT_DEF_CRF_BEAN);
// BWP>> Get a List<String> of any null values such as NA or NI
// method returns null values as a List<String>
// >>BWP
ArrayList items = dsb.getItems();
// For adding null values to display items
FormBeanUtil formBeanUtil = new FormBeanUtil();
List<String> nullValuesList = formBeanUtil.getNullValuesByEventCRFDefId(eventCRFDefId, getDataSource());
LOGGER.trace("single items size: " + items.size());
for (int i = 0; i < items.size(); i++) {
DisplayItemBean item = (DisplayItemBean) items.get(i);
DisplayItemWithGroupBean newOne = new DisplayItemWithGroupBean();
newOne.setSingleItem(runDynamicsItemCheck(item, null, request));
newOne.setOrdinal(item.getMetadata().getOrdinal());
newOne.setInGroup(false);
newOne.setPageNumberLabel(item.getMetadata().getPageNumberLabel());
displayItemWithGroups.add(newOne);
// logger.trace("just added on line 1979:
// "+newOne.getSingleItem().getData().getValue());
}
if (hasItemGroup) {
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ArrayList<ItemDataBean> data = iddao.findAllBySectionIdAndEventCRFId(sb.getId(), ecb.getId());
HashMap<String,ItemDataBean> dataMap = (HashMap<String, ItemDataBean>) getAllActive(data);
if (data != null && data.size() > 0) {
session.setAttribute(HAS_DATA_FLAG, true);
}
LOGGER.trace("found data: " + data.size());
LOGGER.trace("data.toString: " + data.toString());
for (DisplayItemGroupBean itemGroup : dsb.getDisplayFormGroups()) {
LOGGER.debug("found one itemGroup");
DisplayItemWithGroupBean newOne = new DisplayItemWithGroupBean();
// to arrange item groups and other single items, the ordinal of
// a item group will be the ordinal of the first item in this
// group
DisplayItemBean firstItem = itemGroup.getItems().get(0);
// so we are either checking the first or the last item, BUT ONLY ONCE
newOne.setPageNumberLabel(firstItem.getMetadata().getPageNumberLabel());
newOne.setItemGroup(itemGroup);
newOne.setInGroup(true);
newOne.setOrdinal(itemGroup.getGroupMetaBean().getOrdinal());
List<ItemBean> itBeans = idao.findAllItemsByGroupIdOrdered(itemGroup.getItemGroupBean().getId(), sb.getCRFVersionId());
List<DisplayItemBean> dibs = new ArrayList();
boolean hasData = false;
int checkAllColumns = 0;
if(data.size()>0) hasData=true;
//@pgawade 30-May-2012 Fix for issue 13963 - added an extra parameter 'isSubmitted' to method buildMatrixForRepeatingGroups
newOne = buildMatrixForRepeatingGroups(newOne,itemGroup,ecb, sb,itBeans,dataMap, nullValuesList, isSubmitted);
if (hasData) {
//TODO: fix the group_has_data flag on bean not on session
session.setAttribute(GROUP_HAS_DATA, Boolean.TRUE);
}
else {
session.setAttribute(GROUP_HAS_DATA, Boolean.FALSE);
// no data, still add a blank row for displaying
if ( nullValuesList != null && nullValuesList.size() >0){
LOGGER.trace("set with nullValuesList of : " + nullValuesList);
}
dibs = FormBeanUtil.getDisplayBeansFromItems(itBeans, getDataSource(), ecb, sb.getId(), nullValuesList, getServletContext());
DisplayItemGroupBean digb2 = new DisplayItemGroupBean();
digb2.setItems(dibs);
digb2.setEditFlag("initial");
}
displayItemWithGroups.add(newOne);
}
}// if hasItemGroup
Collections.sort(displayItemWithGroups);
return displayItemWithGroups;
}
private Map getAllActive(List<ItemDataBean>al){
Map returnMap = new HashMap<String,ItemDataBean>();
for(ItemDataBean itBean:al){
if(itBean!=null)
returnMap.put(new String(itBean.getItemId()+","+itBean.getOrdinal()), itBean);
}
return returnMap;
}
//@pgawade 30-May-2012 Fix for issue 13963 - added an extra parameter 'isSubmitted' to method buildMatrixForRepeatingGroups
protected DisplayItemWithGroupBean buildMatrixForRepeatingGroups(DisplayItemWithGroupBean diwgb,
DisplayItemGroupBean itemGroup, EventCRFBean ecb,
SectionBean sb,List<ItemBean>itBeans, Map<String,ItemDataBean> dataMap,
List<String> nullValuesList, boolean isSubmitted)
{
int tempOrdinal = 1;
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
int maxOrdinal = iddao.getMaxOrdinalForGroup(ecb, sb, itemGroup.getItemGroupBean());
if(maxOrdinal==0)maxOrdinal = 1;//Incase of no data
ItemFormMetadataDAO ifmdao = new ItemFormMetadataDAO<String, ArrayList>(getDataSource());
List<DisplayItemGroupBean> itemGroups = new ArrayList<DisplayItemGroupBean>();
boolean groupHasData = false;
for(int i=1;i<=maxOrdinal;i++){
List<DisplayItemBean> displayItemBeans = new ArrayList<DisplayItemBean>();
DisplayItemGroupBean dig = new DisplayItemGroupBean();
for(ItemBean itBean:itBeans){
DisplayItemBean displayItemBean = new DisplayItemBean();
ItemFormMetadataBean ifm = ifmdao.findByItemIdAndCRFVersionId(itBean.getId(), ecb.getCRFVersionId());
// itBean.setItemMeta(ifm);//TODO:remove this or the one down displayItemBean.setMetadata(ifm);
displayItemBean.setMetadata(ifm);
displayItemBean.setItem(itBean);
ItemDataBean itemData = dataMap.get(itBean.getId()+","+i);
if(itemData!=null){
groupHasData = true;//to indicate any item in the group has data;
displayItemBean.setIsNewItem(false);
}
if(itemData==null)
{
itemData = displayItemBean.getData();
itemData.setValue("");
itemData.setOrdinal(i);
}
addNullValues(displayItemBean,nullValuesList);
displayItemBean.setData(itemData);
//@pgawade 30-May-2012 Fix for issue 13963 Call to method "displayItemBean.loadDBValue()" is made conditional to show
// the data wherever it is appropriate in the stages of data entry
// displayItemBean.loadDBValue();
if (ecb.getStage() == DataEntryStage.INITIAL_DATA_ENTRY_COMPLETE || ecb.getStage() == DataEntryStage.DOUBLE_DATA_ENTRY_COMPLETE) {
if (shouldLoadDBValues(displayItemBean) && !isSubmitted) {
displayItemBean.loadDBValue();
}
} else {
if (shouldLoadDBValues(displayItemBean)) {
LOGGER.trace("should load db values is true, set value");
displayItemBean.loadDBValue();
LOGGER.trace("just got data loaded: " + displayItemBean.getData().getValue());
}
}
displayItemBeans.add(displayItemBean);
}
Collections.sort(displayItemBeans);
dig.setItems(displayItemBeans);
dig.setHasData(groupHasData);
itemGroups.add(dig);
}
diwgb.setItemGroups(itemGroups);
diwgb.setDbItemGroups(itemGroups);
return diwgb;
}
/*
* * @param nullValuesList
* A List of Strings containing "null values" such as "not
* applicable" or NA.
*/
private void addNullValues( DisplayItemBean displayItemBean, List<String> nullValuesList) {
// logger = LoggerFactory.getLogger(getClass().getName());
boolean hasNullValues = nullValuesList != null && !nullValuesList.isEmpty();
if ( !hasNullValues) {return;}
String tmpVal = "";
String responseName = displayItemBean.getMetadata().getResponseSet().getResponseType().getName();;
List<ResponseOptionBean> respOptions = displayItemBean.getMetadata().getResponseSet().getOptions();
ResponseOptionBean respBean;
if ( respOptions != null
&& ("checkbox".equalsIgnoreCase(responseName) ||
"radio".equalsIgnoreCase(responseName) ||
"single-select".equalsIgnoreCase(responseName) ||
"multi-select".equalsIgnoreCase(responseName))) {
for (String val : nullValuesList) {
respBean = new ResponseOptionBean();
// BWP>> set text to the extended version, "not
// applicable"?
tmpVal = DataEntryInputGenerator.NULL_VALUES_LONGVERSION.get(val);
if (tmpVal != null && tmpVal.length() > 0) {
respBean.setText(tmpVal);
} else {
respBean.setText(val);
}
respBean.setValue(val);
displayItemBean.getMetadata().getResponseSet().addOption(respBean);
//respOptions.add(respBean);
}
}
}
protected void loadItemsWithGroupRows(DisplayItemWithGroupBean itemWithGroup, SectionBean sb, EventDefinitionCRFBean edcb, EventCRFBean ecb, HttpServletRequest request) {
//this method is a copy of the method: createItemWithGroups ,
//only modified for load one DisplayItemWithGroupBean.
//
ItemDAO idao = new ItemDAO(getDataSource());
// For adding null values to display items
FormBeanUtil formBeanUtil = new FormBeanUtil();
List<String> nullValuesList = new ArrayList<String>();
// BWP>> Get a List<String> of any null values such as NA or NI
// method returns null values as a List<String>
nullValuesList = formBeanUtil.getNullValuesByEventCRFDefId(edcb.getId(), getDataSource());
// >>BWP
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ArrayList data = iddao.findAllActiveBySectionIdAndEventCRFId(sb.getId(), ecb.getId());
DisplayItemGroupBean itemGroup = itemWithGroup.getItemGroup();
// to arrange item groups and other single items, the ordinal of
// a item group will be the ordinal of the first item in this
// group
DisplayItemBean firstItem = itemGroup.getItems().get(0);
DisplayItemBean checkItem = firstItem;
// does not work if there is not any data in the first item of the group
// i.e. imports.
// does it make a difference if we take a last item?
boolean noNeedToSwitch = false;
for (int i = 0; i < data.size(); i++) {
ItemDataBean idb = (ItemDataBean) data.get(i);
if (idb.getItemId() == firstItem.getItem().getId()) {
noNeedToSwitch = true;
}
}
if (!noNeedToSwitch) {
checkItem = itemGroup.getItems().get(itemGroup.getItems().size() - 1);
}
// so we are either checking the first or the last item, BUT ONLY ONCE
itemWithGroup.setPageNumberLabel(firstItem.getMetadata().getPageNumberLabel());
itemWithGroup.setItemGroup(itemGroup);
itemWithGroup.setInGroup(true);
itemWithGroup.setOrdinal(itemGroup.getGroupMetaBean().getOrdinal());
List<ItemBean> itBeans = idao.findAllItemsByGroupId(itemGroup.getItemGroupBean().getId(), sb.getCRFVersionId());
boolean hasData = false;
int checkAllColumns = 0;
// if a group has repetitions, the number of data of
// first item should be same as the row number
for (int i = 0; i < data.size(); i++) {
ItemDataBean idb = (ItemDataBean) data.get(i);
LOGGER.debug("check all columns: " + checkAllColumns);
if (idb.getItemId() == checkItem.getItem().getId()) {
hasData = true;
LOGGER.debug("set has data to --TRUE--");
checkAllColumns = 0;
// so that we only fire once a row
LOGGER.debug("has data set to true");
DisplayItemGroupBean digb = new DisplayItemGroupBean();
// always get a fresh copy for items, may use other
// better way to
// do deep copy, like clone
List<DisplayItemBean> dibs = FormBeanUtil.getDisplayBeansFromItems(itBeans, getDataSource(), ecb, sb.getId(), edcb, 0, getServletContext());
digb.setItems(dibs);
LOGGER.trace("set with dibs list of : " + dibs.size());
digb.setGroupMetaBean(runDynamicsCheck(itemGroup.getGroupMetaBean(), request));
digb.setItemGroupBean(itemGroup.getItemGroupBean());
itemWithGroup.getItemGroups().add(digb);
itemWithGroup.getDbItemGroups().add(digb);
}
}
List<DisplayItemGroupBean> groupRows = itemWithGroup.getItemGroups();
LOGGER.trace("how many group rows:" + groupRows.size());
LOGGER.trace("how big is the data:" + data.size());
if (hasData) {
// iterate through the group rows, set data for each item in
// the group
for (int i = 0; i < groupRows.size(); i++) {
DisplayItemGroupBean displayGroup = groupRows.get(i);
for (DisplayItemBean dib : displayGroup.getItems()) {
for (int j = 0; j < data.size(); j++) {
ItemDataBean idb = (ItemDataBean) data.get(j);
if (idb.getItemId() == dib.getItem().getId() && !idb.isSelected()) {
idb.setSelected(true);
dib.setData(idb);
LOGGER.debug("--> set data " + idb.getId() + ": " + idb.getValue());
if (shouldLoadDBValues(dib)) {
LOGGER.debug("+++should load db values is true, set value");
dib.loadDBValue();
LOGGER.debug("+++data loaded: " + idb.getName() + ": " + idb.getOrdinal() + " " + idb.getValue());
LOGGER.debug("+++try dib OID: " + dib.getItem().getOid());
}
break;
}
}
}
}
} else {
// no data, still add a blank row for displaying
DisplayItemGroupBean digb2 = new DisplayItemGroupBean();
List<DisplayItemBean> dibs = FormBeanUtil.getDisplayBeansFromItems(itBeans, getDataSource(), ecb, sb.getId(), nullValuesList, getServletContext());
digb2.setItems(dibs);
LOGGER.trace("set with nullValuesList of : " + nullValuesList);
digb2.setEditFlag("initial");
digb2.setGroupMetaBean(itemGroup.getGroupMetaBean());
digb2.setItemGroupBean(itemGroup.getItemGroupBean());
itemWithGroup.getItemGroups().add(digb2);
itemWithGroup.getDbItemGroups().add(digb2);
}
}
/**
* @param fp
* @param dibs
* @param i
* @param digb
* @return
*/
private List<DisplayItemBean> processInputForGroupItem(FormProcessor fp, List<DisplayItemBean> dibs, int i, DisplayItemGroupBean digb, boolean isAuto) {
for (int j = 0; j < dibs.size(); j++) {
DisplayItemBean displayItem = dibs.get(j);
String inputName = "";
org.akaza.openclinica.bean.core.ResponseType rt = displayItem.getMetadata().getResponseSet().getResponseType();
if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.CHECKBOX) || rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECTMULTI)) {
if (isAuto) {
inputName = getGroupItemInputName(digb, i, displayItem);
} else {
inputName = getGroupItemManualInputName(digb, i, displayItem);
}
ArrayList valueArray = fp.getStringArray(inputName);
displayItem.setFieldName(inputName);
displayItem.loadFormValue(valueArray);
} else {
if (isAuto) {
inputName = getGroupItemInputName(digb, i, displayItem);
} else {
inputName = getGroupItemManualInputName(digb, i, displayItem);
}
displayItem.setFieldName(inputName);
displayItem.loadFormValue(fp.getString(inputName));
// BWP issue 3257 << This seems to be an apt place to check any
// single-select options as "selected"
// if the data in the displayItem matches the options text;
// although this code is very
// confusing and murky, ; refactoring of form handling is
// necessary here
if (rt.equals(org.akaza.openclinica.bean.core.ResponseType.SELECT)) {
ensureSelectedOption(displayItem);
}
// BWP>>
}
}
return dibs;
}
/**
* @param digb
* @param ordinal
* @param dib
* @return
*/
public final String getGroupItemManualInputName(DisplayItemGroupBean digb, int ordinal, DisplayItemBean dib) {
String inputName = digb.getItemGroupBean().getOid() + "_manual" + ordinal + getInputName(dib);
LOGGER.debug("+++ returning manual: " + inputName);
return inputName;
}
// YW 11-12-2007
private EventCRFBean updateECB(StudyEventBean sEvent, HttpServletRequest request) {
StudyBean currentStudy = (StudyBean) request.getSession().getAttribute("study");
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
if (!currentStudy.getStudyParameterConfig().getInterviewerNameDefault().equals("blank")
&& ("".equals(ecb.getInterviewerName()) || ecb.getInterviewerName() == null)) {
// default will be event's owner name
ecb.setInterviewerName(sEvent.getOwner().getName());
}
if (!currentStudy.getStudyParameterConfig().getInterviewDateDefault().equals("blank")
&& ("".equals(ecb.getDateInterviewed()) || ecb.getDateInterviewed() == null)) {
if (sEvent.getDateStarted() != null) {
ecb.setDateInterviewed(sEvent.getDateStarted());// default date
} else {
// logger.trace("evnet start date is null, so date interviewed is
// null");
ecb.setDateInterviewed(null);
}
}
return ecb;
}
protected HashMap<String, ItemBean> prepareScoreItems(HttpServletRequest request) {
HashMap<String, ItemBean> scoreItems = new HashMap<String, ItemBean>();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ItemDAO idao = new ItemDAO(getDataSource());
ArrayList<ItemBean> ibs = idao.findAllItemsByVersionId(ecb.getCRFVersionId());
for (ItemBean ib : ibs) {
scoreItems.put(ib.getName(), ib);
}
return scoreItems;
}
protected HashMap<String, String> prepareScoreItemdata(HttpServletRequest request) {
HashMap<String, String> scoreItemdata = new HashMap<String, String>();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
SectionDAO sdao = new SectionDAO(getDataSource());
ArrayList<SectionBean> sbs = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
for (SectionBean section : sbs) {
HashMap<String, String> data = prepareSectionItemDataBeans(section.getId(), request);
if (data != null && data.size() > 0) {
scoreItemdata.putAll(data);
}
}
return scoreItemdata;
}
protected HashMap<String, String> prepareSectionItemDataBeans(int sectionId, HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
HashMap<String, String> scoreItemdata = new HashMap<String, String>();
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
ArrayList<ItemDataBean> idbs = iddao.findAllActiveBySectionIdAndEventCRFId(sectionId, ecb.getId());
for (ItemDataBean idb : idbs) {
if (idb.getId() > 0) {
int ordinal = idb.getOrdinal();
ordinal = ordinal > 0 ? ordinal : 1;
scoreItemdata.put(idb.getItemId() + "_" + ordinal, idb.getValue().length() > 0 ? idb.getValue() : "");
}
}
return scoreItemdata;
}
protected HashMap<Integer, TreeSet<Integer>> prepareItemdataOrdinals(HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
HashMap<Integer, TreeSet<Integer>> ordinals = new HashMap<Integer, TreeSet<Integer>>();
SectionDAO sdao = new SectionDAO(getDataSource());
ArrayList<SectionBean> sbs = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
for (SectionBean section : sbs) {
ArrayList<ItemDataBean> idbs = iddao.findAllActiveBySectionIdAndEventCRFId(section.getId(), ecb.getId());
if (idbs != null && idbs.size() > 0) {
for (ItemDataBean idb : idbs) {
int itemId = idb.getItemId();
TreeSet<Integer> os = new TreeSet<Integer>();
if (ordinals == null) {
os.add(idb.getOrdinal());
ordinals.put(itemId, os);
} else if (ordinals.containsKey(itemId)) {
os = ordinals.get(itemId);
os.add(idb.getOrdinal());
ordinals.put(itemId, os);
} else {
os.add(idb.getOrdinal());
ordinals.put(itemId, os);
}
}
}
}
return ordinals;
}
protected HashMap<Integer, Integer> prepareGroupSizes(HashMap<String, ItemBean> scoreItems, HttpServletRequest request) {
HashMap<Integer, Integer> groupSizes = new HashMap<Integer, Integer>();
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
SectionDAO sdao = new SectionDAO(getDataSource());
Iterator iter = scoreItems.keySet().iterator();
while (iter.hasNext()) {
int itemId = scoreItems.get(iter.next().toString()).getId();
groupSizes.put(itemId, 1);
}
ArrayList<SectionBean> sbs = sdao.findAllByCRFVersionId(ecb.getCRFVersionId());
for (SectionBean section : sbs) {
ArrayList<ItemDataBean> idbs = iddao.findAllActiveBySectionIdAndEventCRFId(section.getId(), ecb.getId());
for (ItemDataBean idb : idbs) {
int itemId = idb.getItemId();
if (groupSizes != null && groupSizes.containsKey(itemId)) {
int groupsize = iddao.getGroupSize(itemId, ecb.getId());
groupsize = groupsize > 0 ? groupsize : 1;
groupSizes.put(itemId, groupsize);
}
}
}
return groupSizes;
}
protected HashMap<Integer, String> prepareSectionItemdata(int sectionId, HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
HashMap<Integer, String> itemdata = new HashMap<Integer, String>();
ArrayList<ItemDataBean> idbs = iddao.findAllActiveBySectionIdAndEventCRFId(sectionId, ecb.getId());
for (ItemDataBean idb : idbs) {
itemdata.put(idb.getId(), idb.getValue());
}
return itemdata;
}
protected HashMap<String, ItemDataBean> prepareSectionItemdataObject(int sectionId, HttpServletRequest request) {
EventCRFBean ecb = (EventCRFBean)request.getAttribute(INPUT_EVENT_CRF);
ItemDataDAO iddao = new ItemDataDAO(getDataSource(),locale);
HashMap<String, ItemDataBean> itemdata = new HashMap<String, ItemDataBean>();
ArrayList<ItemDataBean> idbs = iddao.findAllActiveBySectionIdAndEventCRFId(sectionId, ecb.getId());
for (ItemDataBean idb : idbs) {
itemdata.put(idb.getItemId()+","+idb.getOrdinal(), idb);
}
return itemdata;
}
protected boolean isChanged(ItemDataBean idb, HashMap<Integer, String> oldItemdata) {
String value = idb.getValue();
if (!oldItemdata.containsKey(idb.getId()))
return true;
else {
String oldValue = oldItemdata.get(idb.getId());
if (oldValue != null) {
if (value == null)
return true;
else if (!oldValue.equals(value))
return true;
}else if(value.isEmpty())
{
return false;
} else if (value != null)
return true;
}
return false;
}
protected boolean isChanged(DisplayItemBean dib, HashMap<String, ItemDataBean> oldItemdata, String attachedFilePath) {
ItemDataBean idb = dib.getData();
String value = idb.getValue();
int ordinal = idb.getOrdinal();
// if(value != null && value.length()>0 && dib.getItem().getDataType().getId()==11) {
// value = attachedFilePath + value;
// }
//isChanged should not be run for calc/group-calc type, only for fields that they depend upon
org.akaza.openclinica.bean.core.ResponseType rt =dib.getMetadata().getResponseSet().getResponseType();
if ( rt.equals(org.akaza.openclinica.bean.core.ResponseType.CALCULATION )||
rt.equals(org.akaza.openclinica.bean.core.ResponseType.GROUP_CALCULATION )){
return false;
}
String tempKey = idb.getItemId()+","+idb.getOrdinal();
if (!oldItemdata.containsKey(tempKey))
{
if(value!=null && value.isEmpty())//This is to address the case where the record does not exist due to Import and upon saving the value could be empty string.
return false;
else
{
return true;
}
}
else {
ItemDataBean existingItemData = oldItemdata.get(tempKey);
String oldValue =existingItemData.getValue();
int oldOrdinal = existingItemData.getOrdinal();
if (oldValue != null) {
if (value == null)
{ if(ordinal==oldOrdinal)
return true;
}else if (dib.getItem().getDataType().getId() == 11) {
String theOldValue = oldValue.split("(/|\\\\)")[oldValue.split("(/|\\\\)").length - 1].trim();
return !value.equals(theOldValue);
} else if (!oldValue.equals(value) && (ordinal==oldOrdinal))
return true;
}
else if (value!=null && value.isEmpty())
return false;
else if (value != null)
{
return true;
}
}
return false;
}
protected boolean isChanged(ItemDataBean idb, HashMap<String, ItemDataBean> oldItemdata, DisplayItemBean dib,String attachedFilePath) {
//if(dib.getMetadata().isConditionalDisplayItem() && !dib.getIsSCDtoBeShown()) {
//return false;
//} else {
return isChanged(dib, oldItemdata, attachedFilePath);
//}
}
/**
* Output, just logs all contents of the allItems list. tbh, 01/2010
*
* @param displayItemWithGroups
*/
protected void output(List<DisplayItemWithGroupBean> displayItemWithGroups) {
for (int i = 0; i < displayItemWithGroups.size(); ++i) {
DisplayItemWithGroupBean diwb = displayItemWithGroups.get(i);
if (diwb.isInGroup()) {
List<DisplayItemGroupBean> dbGroups = diwb.getDbItemGroups();
LOGGER.trace("+++++++ DB ITEM GROUPS ++++++++");
for (int j = 0; j < dbGroups.size(); j++) {
DisplayItemGroupBean displayGroup = dbGroups.get(j);
List<DisplayItemBean> items = displayGroup.getItems();
for (DisplayItemBean displayItem : items) {
int itemId = displayItem.getItem().getId();
int ordinal = displayItem.getData().getOrdinal();
if ("initial".equalsIgnoreCase(displayGroup.getEditFlag())) {
// nextOrdinals.put(itemId, 1);
LOGGER.trace("* found initial: " + itemId + " " + ordinal);
} else {
LOGGER.trace("** found NOT initial: " + itemId + " " + ordinal);
}
// editFlags.put(displayItem.getData().getId(), displayGroup.getEditFlag());
}
}
List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
LOGGER.trace("+++++++++ ITEM GROUPS ++++++++++");
int nextOrdinal = 0;
for (int j = 0; j < dgbs.size(); j++) {
DisplayItemGroupBean displayGroup = dgbs.get(j);
List<DisplayItemBean> oItems = displayGroup.getItems();
String editFlag = displayGroup.getEditFlag();
for (DisplayItemBean displayItem : oItems) {
int itemId = displayItem.getItem().getId();
// nextOrdinal = nextOrdinals.get(itemId);
int ordinal = 0;
// String editflag = "add".equalsIgnoreCase(editFlag) ? editFlag : editFlags.get(displayItem.getData().getId());
// if (editflag.length() > 0) {
// logger.trace("*** found: edit flag for " + itemId + ": " + editflag);
LOGGER.trace("*** found edit Flag " + itemId + ": " + editFlag);
// }
}
}
}
}
}
protected void updateDataOrdinals(List<DisplayItemWithGroupBean> displayItemWithGroups) {
for (int i = 0; i < displayItemWithGroups.size(); ++i) {
DisplayItemWithGroupBean diwb = displayItemWithGroups.get(i);
HashMap<Integer, String> editFlags = new HashMap<Integer, String>();
HashMap<Integer, Integer> nextOrdinals = new HashMap<Integer, Integer>();
if (diwb.isInGroup()) {
List<DisplayItemGroupBean> dbGroups = diwb.getDbItemGroups();
for (int j = 0; j < dbGroups.size(); j++) {
DisplayItemGroupBean displayGroup = dbGroups.get(j);
List<DisplayItemBean> items = displayGroup.getItems();
for (DisplayItemBean displayItem : items) {
int itemId = displayItem.getItem().getId();
int ordinal = displayItem.getData().getOrdinal();
if ("initial".equalsIgnoreCase(displayGroup.getEditFlag())) {
nextOrdinals.put(itemId, 1);
} else {
if (nextOrdinals.containsKey(itemId)) {
int max = nextOrdinals.get(itemId);
nextOrdinals.put(itemId, ordinal > max ? ordinal + 1 : max);
} else {
nextOrdinals.put(itemId, ordinal + 1);
}
}
editFlags.put(displayItem.getData().getId(), displayGroup.getEditFlag());
}
}
List<DisplayItemGroupBean> dgbs = diwb.getItemGroups();
int nextOrdinal = 0;
for (int j = 0; j < dgbs.size(); j++) {
DisplayItemGroupBean displayGroup = dgbs.get(j);
List<DisplayItemBean> oItems = displayGroup.getItems();
String editFlag = displayGroup.getEditFlag();
for (DisplayItemBean displayItem : oItems) {
int itemId = displayItem.getItem().getId();
nextOrdinal = nextOrdinals.get(itemId);
int ordinal = 0;
String editflag = "add".equalsIgnoreCase(editFlag) ? editFlag : editFlags.get(displayItem.getData().getId());
if (editflag.length() > 0) {
if ("add".equalsIgnoreCase(editflag)) {
ordinal = nextOrdinals.get(itemId);
displayItem.getData().setOrdinal(ordinal);
nextOrdinals.put(itemId, nextOrdinal + 1);
} else if ("edit".equalsIgnoreCase(editflag)) {
displayItem.getData().setOrdinal(displayItem.getDbData().getOrdinal());
}
}
}
}
}
}
}
/**
* Customized validation for item input
*
* @param v
* @param dib
* @param inputName
*/
private void customValidation(DiscrepancyValidator v, DisplayItemBean dib, String inputName) {
String customValidationString = dib.getMetadata().getRegexp();
if (!StringUtil.isBlank(customValidationString)) {
Validation customValidation = null;
if (customValidationString.startsWith("func:")) {
try {
customValidation = Validator.processCRFValidationFunction(customValidationString);
} catch (Exception e) {
e.printStackTrace();
}
} else if (customValidationString.startsWith("regexp:")) {
try {
customValidation = Validator.processCRFValidationRegex(customValidationString);
} catch (Exception e) {
}
}
if (customValidation != null) {
customValidation.setErrorMessage(dib.getMetadata().getRegexpErrorMsg());
v.addValidation(inputName, customValidation);
}
}// custom validation
}
private String ifValueIsDate(ItemBean itemBean, String value, boolean dryRun) {
String dateFormat = ResourceBundleProvider.getFormatBundle().getString("date_format_string");
String dateRegexp = ResourceBundleProvider.getFormatBundle().getString("date_regexp");
// isValidDateMMddyyyy
String theFinalValue = value;
if (value != null && itemBean.getDataType() == ItemDataType.DATE && dryRun) {
theFinalValue = ExpressionTreeHelper.ifValidDateFormatAsyyyyMMdd(value, dateFormat, dateRegexp);
} else {
theFinalValue = ExpressionTreeHelper.isValidDateMMddyyyy(value);
}
return theFinalValue;
}
/**
* This method will populate grouped and variableAndValue HashMaps grouped : Used to correctly populate group ordinals variableAndValue : Holds itemOID ,
* value (in Form ) pairs passed in to rule processor
*
* @param allItems
*/
private Container populateRuleSpecificHashMaps(List<DisplayItemWithGroupBean> allItems, Container c, Boolean dryRun) {
for (DisplayItemWithGroupBean displayItemWithGroupBean : allItems) {
// Items in Non Repeating group also known as UNGROUPED
if (displayItemWithGroupBean.getSingleItem() != null) {
if (displayItemWithGroupBean.getSingleItem().getItem().getOid() != null) {
c.grouped.put(displayItemWithGroupBean.getSingleItem().getItem().getOid(), 1);
c.variableAndValue.put(displayItemWithGroupBean.getSingleItem().getItem().getOid(), ifValueIsDate(displayItemWithGroupBean.getSingleItem()
.getItem(), displayItemWithGroupBean.getSingleItem().getData().getValue(), dryRun));
LOGGER.debug("Type : " + displayItemWithGroupBean.getSingleItem().getItem().getItemDataTypeId());
for (Object displayItemBean : displayItemWithGroupBean.getSingleItem().getChildren()) {
String oid = ((DisplayItemBean) displayItemBean).getItem().getOid();
String value =
ifValueIsDate(((DisplayItemBean) displayItemBean).getItem(), ((DisplayItemBean) displayItemBean).getData().getValue(), dryRun);
LOGGER.debug("Type : " + ((DisplayItemBean) displayItemBean).getItem().getItemDataTypeId());
c.grouped.put(oid, 1);
c.variableAndValue.put(oid, value);
}
}
LOGGER.debug("Item Name : {} , Item Value : {} , Item Data Ordinal : {} , Item OID : {} ", new Object[] {
displayItemWithGroupBean.getSingleItem().getItem().getName(), displayItemWithGroupBean.getSingleItem().getData().getValue(),
displayItemWithGroupBean.getSingleItem().getData().getOrdinal(), displayItemWithGroupBean.getSingleItem().getItem().getOid() });
}
// Items in repeating groups
for (DisplayItemGroupBean itemGroupBean : displayItemWithGroupBean.getItemGroups()) {
LOGGER.debug("Item Group Name : {} , Item Group OID : {} , Ordinal : {} ", new Object[] { itemGroupBean.getItemGroupBean().getName(),
itemGroupBean.getItemGroupBean().getOid(), itemGroupBean.getIndex() });
for (DisplayItemBean displayItemBean : itemGroupBean.getItems()) {
String key1 = itemGroupBean.getItemGroupBean().getOid() + "[" + (itemGroupBean.getIndex() + 1) + "]." + displayItemBean.getItem().getOid();
String key = itemGroupBean.getItemGroupBean().getOid() + "." + displayItemBean.getItem().getOid();
c.variableAndValue.put(key1, ifValueIsDate(displayItemBean.getItem(), displayItemBean.getData().getValue(), dryRun));
if (c.grouped.containsKey(key)) {
c.grouped.put(key, c.grouped.get(key) + 1);
} else {
c.grouped.put(key, 1);
}
LOGGER.debug("Item Name : {} , Item Value : {} , Item OID : {} ", new Object[] { displayItemBean.getItem().getName(),
displayItemBean.getData().getValue(), displayItemBean.getItem().getOid() });
}
}
}
if (LOGGER.isDebugEnabled()) {
for (String key : c.grouped.keySet()) {
LOGGER.debug("key : {} , value : {}", key, c.grouped.get(key));
}
for (String key : c.variableAndValue.keySet()) {
LOGGER.debug("key : {} , value : {}", key, c.variableAndValue.get(key));
}
}
return c;
}
/**
* @deprecated Use {@link #createAndInitializeRuleSet(StudyBean,StudyEventDefinitionBean,CRFVersionBean,StudyEventBean,EventCRFBean,Boolean,HttpServletRequest,HttpServletResponse,List)} instead
*/
@Deprecated
private List<RuleSetBean> createAndInitializeRuleSet(StudyBean currentStudy,
StudyEventDefinitionBean studyEventDefinition,
CRFVersionBean crfVersionBean,
StudyEventBean studyEventBean,
EventCRFBean eventCrfBean,
Boolean shouldRunRules, HttpServletRequest request, HttpServletResponse response) {
return createAndInitializeRuleSet(currentStudy, studyEventDefinition, crfVersionBean, studyEventBean, eventCrfBean, shouldRunRules, request,
response, null);
}
private List<RuleSetBean> createAndInitializeRuleSet(StudyBean currentStudy,
StudyEventDefinitionBean studyEventDefinition,
CRFVersionBean crfVersionBean,
StudyEventBean studyEventBean,
EventCRFBean eventCrfBean,
Boolean shouldRunRules, HttpServletRequest request, HttpServletResponse response, List<ItemBean> itemBeansWithSCDShown) {
if (shouldRunRules) {
logMe("Current Thread:::"+Thread.currentThread());
List<RuleSetBean> ruleSets = getRuleSetService(request).getRuleSetsByCrfStudyAndStudyEventDefinition(currentStudy, studyEventDefinition, crfVersionBean);
logMe("Current Thread:::"+Thread.currentThread()+"RuleSet Now?"+ruleSets);
if(ruleSets!=null&&ruleSets.size()>0) {
ruleSets = getRuleSetService(request).filterByStatusEqualsAvailable(ruleSets);
ruleSets = getRuleSetService(request).filterRuleSetsByStudyEventOrdinal(ruleSets, studyEventBean, crfVersionBean, studyEventDefinition);
// place next line here, tbh
ruleSets = getRuleSetService(request).filterRuleSetsByHiddenItems(ruleSets, eventCrfBean, crfVersionBean,itemBeansWithSCDShown);
}
return ruleSets!=null&&ruleSets.size()>0?ruleSets:new ArrayList<RuleSetBean>();
} else
return new ArrayList<RuleSetBean>();
}
private HashMap<String, ArrayList<String>> runRules(List<DisplayItemWithGroupBean> allItems, List<RuleSetBean> ruleSets, Boolean dryRun,
Boolean shouldRunRules, MessageType mt, Phase phase,EventCRFBean ecb, HttpServletRequest request) {
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
StudyBean currentStudy = (StudyBean) request.getSession().getAttribute("study");
if (shouldRunRules) {
Container c = new Container();
try {
c = populateRuleSpecificHashMaps(allItems, c, dryRun);
ruleSets = getRuleSetService(request).filterRuleSetsBySectionAndGroupOrdinal(ruleSets, c.grouped);
ruleSets = getRuleSetService(request).solidifyGroupOrdinalsUsingFormProperties(ruleSets, c.grouped);
// next line here ?
} catch (NullPointerException npe) {
LOGGER.debug("found NPE " + npe.getMessage());
npe.printStackTrace();
}
// above throws NPE?
// return getRuleSetService().runRules(ruleSets, dryRun,
// currentStudy, c.variableAndValue, ub);
LOGGER.debug("running rules ... rule sets size is " + ruleSets.size());
return getRuleSetService(request).runRulesInDataEntry(ruleSets, dryRun, currentStudy, ub, c.variableAndValue, phase,ecb, request).getByMessageType(mt);
} else {
return new HashMap<String, ArrayList<String>>();
}
}
protected abstract boolean shouldRunRules();
protected abstract boolean isAdministrativeEditing();
protected abstract boolean isAdminForcedReasonForChange(HttpServletRequest request);
private RuleSetServiceInterface getRuleSetService(HttpServletRequest request) {
RuleSetServiceInterface ruleSetService = null;
ruleSetService =
ruleSetService != null ? ruleSetService : (RuleSetServiceInterface) SpringServletAccess.getApplicationContext(getServletContext()).getBean(
"ruleSetService");
ruleSetService.setContextPath(getContextPath(request));
ruleSetService.setMailSender((JavaMailSenderImpl) SpringServletAccess.getApplicationContext(getServletContext()).getBean("mailSender"));
ruleSetService.setRequestURLMinusServletPath(getRequestURLMinusServletPath(request));
return ruleSetService;
}
private RuleSetServiceInterface getRuleSetServicePerRequest(HttpServletRequest request) {
//TODO:where is the ruleservice initialized? does not have any references. Check it
RuleSetServiceInterface ruleSetService = null;
ruleSetService =
ruleSetService != null ? ruleSetService : (RuleSetServiceInterface) SpringServletAccess.getApplicationContext(getServletContext()).getBean(
"ruleSetServicePerRequest");
ruleSetService.setContextPath(getContextPath(request));
ruleSetService.setMailSender((JavaMailSenderImpl) SpringServletAccess.getApplicationContext(getServletContext()).getBean("mailSender"));
ruleSetService.setRequestURLMinusServletPath(getRequestURLMinusServletPath(request));
return ruleSetService;
}
private void ensureSelectedOption(DisplayItemBean displayItemBean) {
if (displayItemBean == null || displayItemBean.getData() == null) {
return;
}
ItemDataBean itemDataBean = displayItemBean.getData();
String dataName = itemDataBean.getName();
String dataValue = itemDataBean.getValue();
if ("".equalsIgnoreCase(dataValue)) {
return;
}
List<ResponseOptionBean> responseOptionBeans = new ArrayList<ResponseOptionBean>();
ResponseSetBean responseSetBean = displayItemBean.getMetadata().getResponseSet();
if (responseSetBean == null) {
return;
}
responseOptionBeans = responseSetBean.getOptions();
String tempVal = "";
for (ResponseOptionBean responseOptionBean : responseOptionBeans) {
tempVal = responseOptionBean.getValue();
if (tempVal != null && tempVal.equalsIgnoreCase(dataValue)) {
responseOptionBean.setSelected(true);
}
}
}
protected boolean unloadFiles(HashMap<String, String> newUploadedFiles) {
boolean success = true;
Iterator iter = newUploadedFiles.keySet().iterator();
while (iter.hasNext()) {
String itemId = (String) iter.next();
String filename = newUploadedFiles.get(itemId);
File f = new File(filename);
if (f.exists()) {
if (f.delete()) {
newUploadedFiles.remove("filename");
} else {
success = false;
}
} else {
newUploadedFiles.remove("filename");
// success = false;
}
}
return success;
}
class Container {
HashMap<String, Integer> grouped;
HashMap<String, String> variableAndValue;
public Container() {
super();
this.grouped = new HashMap<String, Integer>();
this.variableAndValue = new HashMap<String, String>();
}
}
public int getManualRows(List<DisplayItemGroupBean> formGroups) {
int manualRows = 0;
for (int j = 0; j < formGroups.size(); j++) {
DisplayItemGroupBean formItemGroup = formGroups.get(j);
LOGGER.debug("begin formGroup Ordinal:" + formItemGroup.getOrdinal());
if (formItemGroup.isAuto() == false) {
manualRows = manualRows + 1;
}
}
LOGGER.debug("+++ returning manual rows: " + manualRows + " from a form group size of " + formGroups.size());
// logger.debug("+++ returning manual rows: " + manualRows + " from a form group size of " + formGroups.size());
return manualRows;
}
private HashMap reshuffleErrorGroupNamesKK(HashMap errors, List<DisplayItemWithGroupBean> allItems,
HttpServletRequest request) {
int manualRows = 0;
if (errors == null || errors.size() <1){ return errors;}
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 digb = dgbs.get(j);
ItemGroupBean igb = digb.getItemGroupBean();
List<DisplayItemBean> dibs = digb.getItems();
if (j == 0) { // first repeat
for (DisplayItemBean dib : dibs) {
String intendedKey = digb.getInputId() + getInputName(dib);
String replacementKey = digb.getItemGroupBean().getOid() + "_" + j + getInputName(dib);
if (!replacementKey.equals(intendedKey) && errors.containsKey(intendedKey)) {
// String errorMessage = (String)errors.get(intendedKey);
errors.put(replacementKey, errors.get(intendedKey));
errors.remove(intendedKey);
LOGGER.debug("removing: " + intendedKey + " and replacing it with " + replacementKey);
}
}
}
else { // everything in between
manualRows++;
for (DisplayItemBean dib : dibs) {
String intendedKey = digb.getInputId() + getInputName(dib);
String replacementKey = digb.getItemGroupBean().getOid() + "_manual" + j + getInputName(dib);
if (!replacementKey.equals(intendedKey) && errors.containsKey(intendedKey)) {
// String errorMessage = (String)errors.get(intendedKey);
errors.put(replacementKey, errors.get(intendedKey));
errors.remove(intendedKey);
LOGGER.debug("removing: " + intendedKey + " and replacing it with " + replacementKey);
}
}
}
}
}
}
request.setAttribute("manualRows", new Integer(manualRows));
return errors;
}
private void reshuffleReasonForChangeHashAndDiscrepancyNotes( List<DisplayItemWithGroupBean> allItems, HttpServletRequest request, EventCRFBean ecb) {
int manualRows = 0;
HashMap<String, Boolean> noteSubmitted = (HashMap<String, Boolean>) request.getSession().getAttribute(DataEntryServlet.NOTE_SUBMITTED);
FormDiscrepancyNotes noteTree = (FormDiscrepancyNotes) request.getSession().getAttribute(CreateDiscrepancyNoteServlet.FLAG_DISCREPANCY_RFC);
ArrayList<DiscrepancyNoteBean> fieldNote = null;
String intendedKey = null;
String replacementKey = null;
if ((noteSubmitted == null || noteSubmitted.size() < 1)
&& ( noteTree == null || noteTree.getFieldNotes() == null || noteTree.getFieldNotes().size() < 1))
{ return; }
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 digb = dgbs.get(j);
ItemGroupBean igb = digb.getItemGroupBean();
List<DisplayItemBean> dibs = digb.getItems();
if (j == 0) { // first repeat
for (DisplayItemBean dib : dibs) {
intendedKey = ecb.getId()+"_"+ digb.getInputId() + getInputName(dib);
replacementKey = ecb.getId()+"_"+digb.getItemGroupBean().getOid() + "_" + j + getInputName(dib);
if (!replacementKey.equals(intendedKey) ){
if (noteSubmitted.containsKey(intendedKey)) {
noteSubmitted.put(replacementKey, Boolean.TRUE);
noteSubmitted.remove(intendedKey);
}
if( noteTree.getNotes(intendedKey) != null){
fieldNote = (ArrayList<DiscrepancyNoteBean>) noteTree.getNotes(intendedKey) ;
if ( fieldNote != null && fieldNote.size() > 0){
noteTree.getFieldNotes().put(replacementKey, fieldNote);
noteTree.getFieldNotes().remove(intendedKey);
}
//not changing here because this hash should not be used
// noteTree.addIdNote(note.getEntityId(), field);
//
}
}
}
}
else { // everything in between
manualRows++;
for (DisplayItemBean dib : dibs) {
intendedKey = ecb.getId()+"_"+digb.getInputId() + getInputName(dib);
replacementKey = ecb.getId()+"_"+digb.getItemGroupBean().getOid() + "_manual" + (j) + getInputName(dib);
if (!replacementKey.equals(intendedKey) ){
if( noteSubmitted!=null && noteSubmitted.containsKey(intendedKey)) {
noteSubmitted.put(replacementKey, Boolean.TRUE);
noteSubmitted.remove(intendedKey);
}
if( noteTree!=null && noteTree.getNotes(intendedKey) != null){
fieldNote = (ArrayList<DiscrepancyNoteBean>) noteTree.getNotes(intendedKey) ;
if ( fieldNote != null && fieldNote.size() > 0){
noteTree.getFieldNotes().put(replacementKey, fieldNote);
noteTree.getFieldNotes().remove(intendedKey);
}
}
}
}
}
LOGGER.debug("removing: " + intendedKey + " and replacing it with " + replacementKey);
}
}
}
request.getSession().setAttribute(DataEntryServlet.NOTE_SUBMITTED, noteSubmitted);
}
/*Determining the resolution status that will be shown in color flag for an item.*/
private int getDiscrepancyNoteResolutionStatus(int itemDataId, ArrayList formNotes) {
int resolutionStatus = 0;
boolean hasOtherThread = false;
int parentNotesNum = 0;
DiscrepancyNoteDAO dndao = new DiscrepancyNoteDAO(getDataSource());
ArrayList existingNotes = dndao.findExistingNotesForItemData(itemDataId);
for (Object obj : existingNotes) {
DiscrepancyNoteBean note = (DiscrepancyNoteBean) obj;
/*We would only take the resolution status of the parent note of any note thread. If there
* are more than one note thread, the thread with the worst resolution status will be taken.*/
if (note.getParentDnId() == 0) {
if (hasOtherThread) {
if (resolutionStatus > note.getResolutionStatusId()) {
resolutionStatus = note.getResolutionStatusId();
}
} else {
resolutionStatus = note.getResolutionStatusId();
}
hasOtherThread = true;
}
}
if (formNotes == null || formNotes.isEmpty()) {
return resolutionStatus;
}
for (Object obj : formNotes) {
DiscrepancyNoteBean note = (DiscrepancyNoteBean) obj;
if (note.getParentDnId() == 0) {
if (hasOtherThread) {
if (resolutionStatus > note.getResolutionStatusId()) {
resolutionStatus = note.getResolutionStatusId();
}
} else {
resolutionStatus = note.getResolutionStatusId();
}
hasOtherThread = true;
}
}
return resolutionStatus;
}
private int getDiscrepancyNoteResolutionStatus(List existingNotes) {
int resolutionStatus = 0;
boolean hasOtherThread = false;
for (Object obj : existingNotes) {
DiscrepancyNoteBean note = (DiscrepancyNoteBean) obj;
/*We would only take the resolution status of the parent note of any note thread. If there
* are more than one note thread, the thread with the worst resolution status will be taken.*/
if (note.getParentDnId() == 0) {
if (hasOtherThread) {
if (resolutionStatus > note.getResolutionStatusId()) {
resolutionStatus = note.getResolutionStatusId();
}
} else {
resolutionStatus = note.getResolutionStatusId();
}
hasOtherThread = true;
}
}
return resolutionStatus;
}
/*
* Update DisplaySectionBean's firstSection & lastSection;
*/
protected void updateDisplaySectionPlace(DisplaySectionBean displaySectionBean, DisplayTableOfContentsBean toc, HttpServletRequest request) {
if (toc != null) {
ArrayList<SectionBean> sectionBeans = toc.getSections();
if (sectionBeans != null && sectionBeans.size() > 0) {
int sid = displaySectionBean.getSection().getId();
displaySectionBean.setFirstSection(sid == sectionBeans.get(0).getId() ? true : false);
displaySectionBean.setLastSection(sid == sectionBeans.get(sectionBeans.size() - 1).getId() ? true : false);
}
}
}
protected SectionBean prevSection(SectionBean sb, EventCRFBean ecb, DisplayTableOfContentsBean toc, int sbPos) {
SectionBean p = new SectionBean();
ArrayList<SectionBean> sectionBeans = new ArrayList<SectionBean>();
if (toc != null) {
sectionBeans = toc.getSections();
if (sbPos > 0) {
p = sectionBeans.get(sbPos - 1);
}
}
return p != null && p.getId() > 0 ? p : new SectionBean();
}
protected SectionBean nextSection(SectionBean sb, EventCRFBean ecb, DisplayTableOfContentsBean toc, int sbPos) {
SectionBean n = new SectionBean();
ArrayList<SectionBean> sectionBeans = new ArrayList<SectionBean>();
if (toc != null) {
sectionBeans = toc.getSections();
int size = sectionBeans.size();
if (sbPos >= 0 && size > 1 && sbPos < size-1) {
n = sectionBeans.get(sbPos + 1);
}
}
return n != null && n.getId() > 0 ? n : new SectionBean();
}
public void mayAccess(HttpServletRequest request) throws InsufficientPermissionException {
FormProcessor fp = new FormProcessor(request);
EventCRFDAO edao = new EventCRFDAO(getDataSource());
UserAccountBean ub =(UserAccountBean) request.getSession().getAttribute(USER_BEAN_NAME);
int eventCRFId = fp.getInt("ecId", true);
if (eventCRFId == 0) {
eventCRFId = fp.getInt("eventCRFId", true);
}
if (eventCRFId > 0) {
if (!entityIncluded(eventCRFId, ub.getName(), edao, getDataSource())) {
addPageMessage(respage.getString("required_event_CRF_belong"), request);
throw new InsufficientPermissionException(Page.MENU_SERVLET, resexception.getString("entity_not_belong_studies"), "1");
}
}
}
protected void populateInstantOnChange(HttpSession session, EventCRFBean ecb, DisplaySectionBean section) {
int cvId = ecb.getCRFVersionId();
int sectionId = section.getSection().getId();
InstantOnChangeService ins = (InstantOnChangeService) SpringServletAccess.getApplicationContext(
getServletContext()).getBean("instantOnChangeService");
InstantOnChangeFrontStrParcel strsInSec = new InstantOnChangeFrontStrParcel();
HashMap<Integer,InstantOnChangeFrontStrGroup> nonRepOri = null;
HashMap<String,Map<Integer,InstantOnChangeFrontStrGroup>> grpOri = null;
HashMap<Integer, InstantOnChangeFrontStrParcel> instantOnChangeFrontStrParcels = (HashMap<Integer, InstantOnChangeFrontStrParcel>)session.getAttribute(CV_INSTANT_META+cvId);
if(instantOnChangeFrontStrParcels != null && instantOnChangeFrontStrParcels.containsKey(sectionId)) {
strsInSec = instantOnChangeFrontStrParcels.get(sectionId);
nonRepOri = (HashMap<Integer,InstantOnChangeFrontStrGroup>)strsInSec.getNonRepOrigins();
grpOri = (HashMap<String,Map<Integer,InstantOnChangeFrontStrGroup>>)strsInSec.getRepOrigins();
} else if(instantOnChangeFrontStrParcels == null || instantOnChangeFrontStrParcels.size() == 0) {
//if(ins.needRunInstantInSection(sectionId)) {
boolean shouldSetAtt = false;
instantOnChangeFrontStrParcels = (HashMap<Integer, InstantOnChangeFrontStrParcel>)ins.instantOnChangeFrontStrParcelInCrfVersion(cvId);
if(instantOnChangeFrontStrParcels.size()>0) {
session.setAttribute(CV_INSTANT_META+cvId, instantOnChangeFrontStrParcels);
if(instantOnChangeFrontStrParcels.containsKey(sectionId)) {
strsInSec = instantOnChangeFrontStrParcels.get(sectionId);
if(strsInSec != null) {
grpOri = (HashMap<String,Map<Integer,InstantOnChangeFrontStrGroup>>)strsInSec.getRepOrigins();
nonRepOri = (HashMap<Integer,InstantOnChangeFrontStrGroup>)strsInSec.getNonRepOrigins();
}
}
}
//}
}
if(grpOri != null && grpOri.size()>0) {
ins.itemGroupsInstantUpdate(section.getDisplayItemGroups(), grpOri);
}
if(nonRepOri != null && nonRepOri.size()>0) {
ins.itemsInstantUpdate(section.getDisplayItemGroups(), nonRepOri);
}
}
}