/* * OpenClinica is distributed under the * GNU Lesser General Public License (GNU LGPL). * For details see: http://www.openclinica.org/license * copyright 2003-2010 Akaza Research */ package org.akaza.openclinica.service.crfdata; import org.akaza.openclinica.bean.submit.DisplayItemBean; import org.akaza.openclinica.bean.submit.DisplaySectionBean; import org.akaza.openclinica.bean.submit.ItemFormMetadataBean; import org.akaza.openclinica.bean.submit.ResponseOptionBean; import org.akaza.openclinica.dao.hibernate.SCDItemMetadataDao; import org.akaza.openclinica.domain.crfdata.SCDItemMetadataBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.sql.DataSource; /** * For simple conditional display * @author ywang */ public class SimpleConditionalDisplayService { protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); DataSource dataSource; SCDItemMetadataDao scdItemMetadataDao; public SimpleConditionalDisplayService(DataSource dataSource) { this.dataSource = dataSource; } /** * Initialize ItemFormMetadataBean in DisplaySectionBean for simple conditional display * @param displaySection * @return */ public DisplaySectionBean initConditionalDisplays(DisplaySectionBean displaySection) { int sectionId = displaySection.getSection().getId(); Set<Integer> showSCDItemIds = displaySection.getShowSCDItemIds(); ArrayList<SCDItemMetadataBean> cds = scdItemMetadataDao.findAllBySectionId(sectionId); if(cds == null) { logger.info("SCDItemMetadataDao.findAllBySectionId with sectionId="+sectionId+" returned null."); } else if(cds.size()>0){ ArrayList<DisplayItemBean> displayItems = initSCDItems(displaySection.getItems(),cds,showSCDItemIds); HashMap<Integer, ArrayList<SCDItemMetadataBean>> scdPairMap = getControlMetaIdAndSCDSetMap(sectionId,cds); if(scdPairMap == null) { logger.info("SimpleConditionalDisplayService.getControlMetaIdAndSCDSetMap returned null."); } else { for(DisplayItemBean displayItem : displayItems) { if(scdPairMap.containsKey(displayItem.getMetadata().getId())) { //displayItem is control item ArrayList<SCDItemMetadataBean> sets = scdPairMap.get(displayItem.getMetadata().getId()); displayItem.getScdData().setScdSetsForControl(sets); for(SCDItemMetadataBean scd : sets) { if(SimpleConditionalDisplayService.initConditionalDisplayToBeShown(displayItem, scd)) { showSCDItemIds.add(scd.getScdItemId()); } } } //control item is ahead of its scd item(s) if(displayItem.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId()>0) { //displayItem is scd item displayItem.setIsSCDtoBeShown(showSCDItemIds.contains(displayItem.getMetadata().getItemId())); } if(displayItem.getChildren().size()>0) { ArrayList<DisplayItemBean> cs = displayItem.getChildren(); for(DisplayItemBean c : cs) { if(scdPairMap.containsKey(c.getMetadata().getId())) { //c is control item ArrayList<SCDItemMetadataBean> sets = scdPairMap.get(c.getMetadata().getId()); c.getScdData().setScdSetsForControl(sets); for(SCDItemMetadataBean scd : sets) { if(SimpleConditionalDisplayService.initConditionalDisplayToBeShown(c, scd)) { showSCDItemIds.add(scd.getScdItemId()); } } } //control item is ahead of its scd item(s) if(c.getScdData().getScdItemMetadataBean().getScdItemFormMetadataId()>0) { //c is scd item c.setIsSCDtoBeShown(showSCDItemIds.contains(c.getMetadata().getItemId())); } } } } } } return displaySection; } public ArrayList<DisplayItemBean> initSCDItems(ArrayList<DisplayItemBean> displayItems, ArrayList<SCDItemMetadataBean> cds, Set<Integer>showSCDItemIds) { ArrayList<DisplayItemBean> dis = displayItems; HashMap<Integer, SCDItemMetadataBean> scds = (HashMap<Integer, SCDItemMetadataBean>)this.getSCDMetaIdAndSCDSetMap(cds); for(DisplayItemBean displayItem : dis) { ItemFormMetadataBean meta = displayItem.getMetadata(); if(scds.containsKey(meta.getId())) { SCDItemMetadataBean scdItemMetadataBean = scds.get(meta.getId()); scdItemMetadataBean.setScdItemId(meta.getItemId()); displayItem.getScdData().setScdItemMetadataBean(scdItemMetadataBean); } if(meta.getParentId()<1) { ArrayList<DisplayItemBean> cs = displayItem.getChildren(); for(DisplayItemBean c : cs) { ItemFormMetadataBean cmeta = c.getMetadata(); if(scds.containsKey(cmeta.getId())) { SCDItemMetadataBean scdItemMetadataBean = scds.get(cmeta.getId()); scdItemMetadataBean.setScdItemId(cmeta.getItemId()); c.getScdData().setScdItemMetadataBean(scdItemMetadataBean); } } } } return dis; } public HashMap<Integer, ArrayList<SCDItemMetadataBean>> getControlMetaIdAndSCDSetMap(int sectionId, ArrayList<SCDItemMetadataBean> scdSets) { HashMap<Integer, ArrayList<SCDItemMetadataBean>> cdPairMap = new HashMap<Integer, ArrayList<SCDItemMetadataBean>>(); if(scdSets == null) { logger.info("SimpleConditionalDisplayService.getControlMetaIdAndSCDSetMap() ArrayList<SCDItemMetadataBean> parameter is null."); } else { for(SCDItemMetadataBean scd : scdSets) { Integer conId = scd.getControlItemFormMetadataId(); ArrayList<SCDItemMetadataBean> conScds = cdPairMap.containsKey(conId) ? cdPairMap.get(conId) : new ArrayList<SCDItemMetadataBean>(); conScds.add(scd); cdPairMap.put(conId,conScds); } } return cdPairMap; } public Map<Integer,SCDItemMetadataBean> getSCDMetaIdAndSCDSetMap(ArrayList<SCDItemMetadataBean> scdSets) { Map<Integer,SCDItemMetadataBean> map = new HashMap<Integer, SCDItemMetadataBean>(); if(scdSets==null) { logger.info("SimpleConditionalDisplayService.getSCDMetaIdAndSCDSetMap() ArrayList<SCDItemMetadataBean> parameter is null."); } else { for(SCDItemMetadataBean scd: scdSets) { map.put(scd.getScdItemFormMetadataId(), scd); } } return map; } /** * Base on chosen option of a control item. scdItemId has to be initialized for SCDItemMetadataBean. * @param dib * @param showSCDItemIds. * @return */ public static Set<Integer> conditionalDisplayToBeShown (DisplayItemBean dib, Set<Integer> showSCDItemIds) { Set<Integer> showIds = showSCDItemIds; //a conditional display item will be always after its control item. ArrayList<SCDItemMetadataBean> cds = dib.getScdData().getScdSetsForControl(); if(cds.size()>0) { for(SCDItemMetadataBean cd : cds) { Integer scdItemId = cd.getScdItemId(); if(scdItemId > 0) { if(conditionalDisplayToBeShown(dib.getData().getValue(), cd)) { showIds.add(scdItemId); } else if(showIds.contains(scdItemId)) { showIds.remove(scdItemId); } } } } return showIds; } /** * Return true if a SCDItemMetadataBean has a chosen optionValue * * @param chosenOption * @param cd * @return */ public static boolean conditionalDisplayToBeShown (String chosenOption, SCDItemMetadataBean cd) { if(chosenOption != null && chosenOption.length()>0) { chosenOption = chosenOption.replaceAll("\\\\,", "##"); if(chosenOption.contains(",")) { String[] ss = chosenOption.split(","); for(int i=0; i<ss.length; ++i) { if(ss[i].replaceAll("##", "\\\\,").trim().equalsIgnoreCase(cd.getOptionValue())) { return true; } } } else { chosenOption.replaceAll("##", "\\,"); if(chosenOption.equalsIgnoreCase(cd.getOptionValue())) { return true; } } } return false; } /** * Return true, if a SCDItemMetadataBean to show initially. * @param controlItem * @param cd * @return */ public static boolean initConditionalDisplayToBeShown (DisplayItemBean controlItem, SCDItemMetadataBean cd) { String chosenOption = controlItem.getData().getValue(); if(chosenOption != null && chosenOption.length()>0) { if(chosenOption.equals(cd.getOptionValue())) { return true; } } else { chosenOption = controlItem.getMetadata().getDefaultValue(); if(chosenOption != null && chosenOption.length()>0) { if(chosenOption.equals(cd.getOptionValue())) { return true; } }else { if(controlItem.getMetadata().getResponseSet().getResponseTypeId()==6) { //single-select chosenOption = ((ResponseOptionBean) controlItem.getMetadata().getResponseSet().getOptions().get(0)).getValue(); if(chosenOption != null && chosenOption.length()>0) { if(chosenOption.equals(cd.getOptionValue())) { return true; } } } } } return false; } public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public SCDItemMetadataDao getScdItemMetadataDao() { return scdItemMetadataDao; } public void setScdItemMetadataDao(SCDItemMetadataDao scdItemMetadataDao) { this.scdItemMetadataDao = scdItemMetadataDao; } }