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