package org.akaza.openclinica.control.submit; 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.*; import org.akaza.openclinica.dao.submit.ItemDAO; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.text.StrSubstitutor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.sql.DataSource; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Performs the variable substitution in the CRF fields that support it. * * @author Douglas Rodrigues (drodrigues@openclinica.com) */ public class VariableSubstitutionHelper { private static final Logger LOG = LoggerFactory.getLogger(VariableSubstitutionHelper.class); private static final String ENCODING = "UTF-8"; private static final String TOKEN_REGEX = "\\$\\{.*?\\}"; /** * Replaces the variables in each {@link DisplayItemBean} of the {@link DisplaySectionBean}. * * @param section The display section to have its items processed. * @param study Study associated with the display section. * @param studySubject Subject associated with the display section. */ public static void replaceVariables(DisplaySectionBean section, StudyBean study, StudySubjectBean studySubject, StudyEventDefinitionBean eventDef, StudyEventBean event, DataSource dataSource) { StrSubstitutor subst = new StrSubstitutor(buildTokensMap(section, studySubject, study, eventDef, event, dataSource)); for (DisplayItemBean displayItem: section.getItems()) { ItemFormMetadataBean metadata = displayItem.getMetadata(); metadata.setRightItemText(replace(subst, metadata.getRightItemText())); metadata.setLeftItemText(replace(subst, metadata.getLeftItemText())); metadata.setHeader(replace(subst, metadata.getHeader())); metadata.setSubHeader(replace(subst, metadata.getSubHeader())); } } private static final String replace(StrSubstitutor subst, String value) { return subst.replace(value).replaceAll(TOKEN_REGEX, StringUtils.EMPTY); } @SuppressWarnings("unchecked") private static Map<String, String> buildTokensMap(DisplaySectionBean section, StudySubjectBean studySubject, StudyBean study, StudyEventDefinitionBean eventDef, StudyEventBean event, DataSource dataSource) { ItemDAO itemDAO = new ItemDAO(dataSource); List<ItemBean> items = itemDAO.findAllWithItemDataByCRFVersionId( section.getCrfVersion().getId(), section.getEventCRF().getId()); Map<String, String> tokensMap = new HashMap<String, String>(); tokensMap.put("studySubject", encode(studySubject.getName())); if (studySubject.getOid() != null && !studySubject.getOid().isEmpty()){ tokensMap.put("studySubjectOID", encode(studySubject.getOid())); } else tokensMap.put("studySubjectOID", ""); tokensMap.put("studyName", encode(study.getName())); tokensMap.put("eventName", encode(eventDef.getName())); if (event == null) tokensMap.put("eventOrdinal", ""); else tokensMap.put("eventOrdinal", encode(Integer.toString(event.getSampleOrdinal()))); tokensMap.put("crfName", encode(section.getCrf().getName())); tokensMap.put("crfVersion", encode(section.getCrfVersion().getName())); // Render a set of "item['ITEM_NAME']" tokens for existing item data for (ItemBean item : items) { // If the item has multiple values, combine them in a comma-separated list List<String> values = new ArrayList<String>(); for (ItemDataBean itemData: item.getItemDataElements()) { values.add(itemData.getValue()); } String value = StringUtils.join(values, ','); tokensMap.put("item['" + item.getName() + "']", encode(value)); } if (LOG.isDebugEnabled()) { for(String key : tokensMap.keySet()) { LOG.debug("Substitution context: {} = {}", key, tokensMap.get(key)); } } return tokensMap; } private static String encode(String value) { try { return URLEncoder.encode(value, ENCODING); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Invalid encoding " + ENCODING, e); } } }