/* * OpenClinica is distributed under the * GNU Lesser General Public License (GNU LGPL). * For details see: http://www.openclinica.org/license * * Copyright 2003-2008 Akaza Research */ package org.akaza.openclinica.service.rule; import org.akaza.openclinica.bean.admin.CRFBean; import org.akaza.openclinica.bean.login.UserAccountBean; import org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean; import org.akaza.openclinica.bean.managestudy.StudyBean; import org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean; import org.akaza.openclinica.bean.managestudy.StudyGroupBean; import org.akaza.openclinica.bean.managestudy.StudyGroupClassBean; import org.akaza.openclinica.bean.oid.GenericOidGenerator; import org.akaza.openclinica.bean.oid.OidGenerator; import org.akaza.openclinica.bean.rule.action.EmailActionBean; import org.akaza.openclinica.dao.hibernate.RuleDao; import org.akaza.openclinica.dao.hibernate.RuleSetDao; import org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO; import org.akaza.openclinica.dao.managestudy.StudyGroupClassDAO; import org.akaza.openclinica.dao.managestudy.StudyGroupDAO; import org.akaza.openclinica.domain.Status; import org.akaza.openclinica.domain.rule.AuditableBeanWrapper; import org.akaza.openclinica.domain.rule.RuleBean; import org.akaza.openclinica.domain.rule.RuleSetBean; import org.akaza.openclinica.domain.rule.RuleSetRuleBean; import org.akaza.openclinica.domain.rule.RunOnSchedule; import org.akaza.openclinica.domain.rule.RuleSetRuleBean.RuleSetRuleBeanImportStatus; import org.akaza.openclinica.domain.rule.RulesPostImportContainer; import org.akaza.openclinica.domain.rule.action.EventActionBean; import org.akaza.openclinica.domain.rule.action.RuleActionRunBean; import org.akaza.openclinica.domain.rule.action.StratificationFactorBean; import org.akaza.openclinica.domain.rule.action.HideActionBean; import org.akaza.openclinica.domain.rule.action.InsertActionBean; import org.akaza.openclinica.domain.rule.action.NotificationActionBean; import org.akaza.openclinica.domain.rule.action.PropertyBean; import org.akaza.openclinica.domain.rule.action.RandomizeActionBean; import org.akaza.openclinica.domain.rule.action.RuleActionBean; import org.akaza.openclinica.domain.rule.action.ShowActionBean; import org.akaza.openclinica.domain.rule.action.EventActionBean; import org.akaza.openclinica.domain.rule.action.DiscrepancyNoteActionBean; import org.akaza.openclinica.domain.rule.expression.Context; import org.akaza.openclinica.domain.rule.expression.ExpressionBean; import org.akaza.openclinica.domain.rule.expression.ExpressionObjectWrapper; import org.akaza.openclinica.domain.rule.expression.ExpressionProcessor; import org.akaza.openclinica.domain.rule.expression.ExpressionProcessorFactory; import org.akaza.openclinica.exception.OpenClinicaSystemException; import org.akaza.openclinica.service.rule.expression.ExpressionService; import org.akaza.openclinica.validator.rule.action.EventActionValidator; import org.akaza.openclinica.validator.rule.action.InsertActionValidator; import org.akaza.openclinica.validator.rule.action.RandomizeActionValidator; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.DataBinder; import org.springframework.validation.Errors; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.sql.DataSource; /** * @author Krikor Krumlian * */ public class RulesPostImportContainerService { protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); DataSource ds; private RuleDao ruleDao; private RuleSetDao ruleSetDao; private final OidGenerator oidGenerator; private StudyBean currentStudy; private UserAccountBean userAccount; private RunOnSchedule runOnSchedule; private ExpressionService expressionService; private InsertActionValidator insertActionValidator; private EventActionValidator eventActionValidator; private RandomizeActionValidator randomizeActionValidator; ResourceBundle respage; public RulesPostImportContainerService(DataSource ds, StudyBean currentStudy) { oidGenerator = new GenericOidGenerator(); this.ds = ds; this.currentStudy = currentStudy; } public RulesPostImportContainerService(DataSource ds) { oidGenerator = new GenericOidGenerator(); this.ds = ds; } public RulesPostImportContainer validateRuleSetRuleDefs(RulesPostImportContainer importContainer, RuleSetRuleBean ruleSetRuleForm) { RuleSetBean ruleSetBean = ruleSetRuleForm.getRuleSetBean(); RuleSetRuleBean ruleSetRuleBean = ruleSetRuleForm; AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper = new AuditableBeanWrapper<RuleSetBean>(ruleSetBean); ruleSetBeanWrapper.getAuditableBean().setStudy(currentStudy); if (isRuleSetExpressionValid(ruleSetBeanWrapper)) { RuleSetBean persistentRuleSetBean = getRuleSetDao().findByExpressionAndStudy(ruleSetBean,currentStudy.getId()); if (persistentRuleSetBean != null) { List<RuleSetRuleBean> importedRuleSetRules = ruleSetBeanWrapper.getAuditableBean().getRuleSetRules(); persistentRuleSetBean.setUpdaterAndDate(getUserAccount()); ruleSetBeanWrapper.setAuditableBean(persistentRuleSetBean); for (RuleSetRuleBean persistentruleSetRuleBean : persistentRuleSetBean.getRuleSetRules()) { if (persistentruleSetRuleBean.getStatus() != Status.DELETED && ruleSetRuleBean.equals(persistentruleSetRuleBean)) { persistentruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.EXACT_DOUBLE); // TODO : DO SOMETHING HERE // itr.remove(); break; } else if (persistentruleSetRuleBean.getStatus() != Status.DELETED && ruleSetRuleBean.getRuleBean() != null && ruleSetRuleBean.getRuleBean().equals(persistentruleSetRuleBean.getRuleBean())) { // persistentruleSetRuleBean.setActions(ruleSetRuleBean.getActions()); persistentruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.TO_BE_REMOVED); // itr.remove(); break; } ruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.LINE); } ruleSetBeanWrapper.getAuditableBean().addRuleSetRules(importedRuleSetRules); // ruleSetBeanWrapper.getAuditableBean().setId(persistentRuleSetBean.getId()); } else { ruleSetBeanWrapper.getAuditableBean().setOwner(getUserAccount()); ruleSetBeanWrapper.getAuditableBean().setStudyEventDefinition( getExpressionService().getStudyEventDefinitionFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setCrf(getExpressionService().getCRFFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setCrfVersion(getExpressionService().getCRFVersionFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setItem(getExpressionService().getItemBeanFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setItemGroup(getExpressionService().getItemGroupExpression(ruleSetBean.getTarget().getValue())); } List<RuleSetBean> eventActionsRuleSetBean = getRuleSetDao().findAllEventActions(currentStudy); isRuleSetRuleValid(importContainer, ruleSetBeanWrapper ,eventActionsRuleSetBean); } putRuleSetInCorrectContainer(ruleSetBeanWrapper, importContainer); logger.info("# of Valid RuleSetDefs : " + importContainer.getValidRuleSetDefs().size()); logger.info("# of InValid RuleSetDefs : " + importContainer.getInValidRuleSetDefs().size()); logger.info("# of Overwritable RuleSetDefs : " + importContainer.getDuplicateRuleSetDefs().size()); return importContainer; } public RulesPostImportContainer validateRuleSetDefs(RulesPostImportContainer importContainer) { List<RuleSetBean> eventActionsRuleSetBean = getRuleSetDao().findAllEventActions(currentStudy); for (RuleSetBean ruleSetBean : importContainer.getRuleSets()) { AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper = new AuditableBeanWrapper<RuleSetBean>(ruleSetBean); ruleSetBeanWrapper.getAuditableBean().setStudy(currentStudy); if (isRuleSetExpressionValid(ruleSetBeanWrapper)) { RuleSetBean persistentRuleSetBean = getRuleSetDao().findByExpressionAndStudy(ruleSetBean,currentStudy.getId()); if (persistentRuleSetBean != null) { List<RuleSetRuleBean> importedRuleSetRules = ruleSetBeanWrapper.getAuditableBean().getRuleSetRules(); if (ruleSetBean.getRunTime() != null) { if (ruleSetBean.getRunOnSchedule() == null) { ruleSetBean.setRunOnSchedule(new RunOnSchedule(ruleSetBean.getRunTime())); } } if(ruleSetBean.getRunOnSchedule()!=null){ persistentRuleSetBean.setRunSchedule(true); if(ruleSetBean.getRunOnSchedule().getRunTime() !=null){ if(isRunTimeValid(ruleSetBeanWrapper, ruleSetBean.getRunOnSchedule().getRunTime())){ persistentRuleSetBean.setRunTime(ruleSetBean.getRunOnSchedule().getRunTime()); } }else{ persistentRuleSetBean.setRunTime(null); // supposed to act like 23:00 } }else{ persistentRuleSetBean.setRunSchedule(false); persistentRuleSetBean.setRunTime(null); } persistentRuleSetBean.setUpdaterAndDate(getUserAccount()); ruleSetBeanWrapper.setAuditableBean(persistentRuleSetBean); Iterator<RuleSetRuleBean> itr = importedRuleSetRules.iterator(); while (itr.hasNext()) { RuleSetRuleBean ruleSetRuleBean = itr.next(); ruleSetRuleBean.setRuleBean(getRuleDao().findByOid(ruleSetRuleBean.getOid(), persistentRuleSetBean.getStudyId())); // ruleSetRuleBean.setRuleSetBean(ruleSetBeanWrapper.getAuditableBean()); for (RuleSetRuleBean persistentruleSetRuleBean : persistentRuleSetBean.getRuleSetRules()) { if (persistentruleSetRuleBean.getStatus() != Status.DELETED && ruleSetRuleBean.equals(persistentruleSetRuleBean)) { persistentruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.EXACT_DOUBLE); itr.remove(); break; } else if (persistentruleSetRuleBean.getStatus() != Status.DELETED && ruleSetRuleBean.getRuleBean() != null && ruleSetRuleBean.getRuleBean().equals(persistentruleSetRuleBean.getRuleBean())) { // persistentruleSetRuleBean.setActions(ruleSetRuleBean.getActions()); persistentruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.TO_BE_REMOVED); // itr.remove(); break; } ruleSetRuleBean.setRuleSetRuleBeanImportStatus(RuleSetRuleBeanImportStatus.LINE); } } ruleSetBeanWrapper.getAuditableBean().addRuleSetRules(importedRuleSetRules); // ruleSetBeanWrapper.getAuditableBean().setId(persistentRuleSetBean.getId()); } else { if (importContainer.getValidRuleSetExpressionValues().contains(ruleSetBeanWrapper.getAuditableBean().getTarget().getValue())) { ruleSetBeanWrapper.error(createError("OCRERR_0031")); } ruleSetBeanWrapper.getAuditableBean().setOwner(getUserAccount()); ruleSetBeanWrapper.getAuditableBean().setStudyEventDefinition( getExpressionService().getStudyEventDefinitionFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setCrf(getExpressionService().getCRFFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setCrfVersion(getExpressionService().getCRFVersionFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setItem(getExpressionService().getItemBeanFromExpression(ruleSetBean.getTarget().getValue())); ruleSetBeanWrapper.getAuditableBean().setItemGroup(getExpressionService().getItemGroupExpression(ruleSetBean.getTarget().getValue())); if (ruleSetBean.getRunTime() != null) { if (ruleSetBean.getRunOnSchedule() == null) { ruleSetBeanWrapper.getAuditableBean().setRunOnSchedule(new RunOnSchedule(ruleSetBean.getRunTime())); } } if (ruleSetBean.getRunOnSchedule() != null) { ruleSetBeanWrapper.getAuditableBean().setRunSchedule(true); if (ruleSetBean.getRunOnSchedule().getRunTime() != null) { //validate Time isRunTimeValid if (isRunTimeValid(ruleSetBeanWrapper, ruleSetBean.getRunOnSchedule().getRunTime())) { ruleSetBeanWrapper.getAuditableBean().setRunTime(ruleSetBean.getRunOnSchedule().getRunTime()); } } else { ruleSetBeanWrapper.getAuditableBean().setRunTime(null); // supposed to act like DEFAULT_TIME } } else { ruleSetBeanWrapper.getAuditableBean().setRunSchedule(false); ruleSetBeanWrapper.getAuditableBean().setRunTime(null); } } isRuleSetRuleValid(importContainer, ruleSetBeanWrapper, eventActionsRuleSetBean); } putRuleSetInCorrectContainer(ruleSetBeanWrapper, importContainer); } logger.info("# of Valid RuleSetDefs : " + importContainer.getValidRuleSetDefs().size()); logger.info("# of InValid RuleSetDefs : " + importContainer.getInValidRuleSetDefs().size()); logger.info("# of Overwritable RuleSetDefs : " + importContainer.getDuplicateRuleSetDefs().size()); return importContainer; } public RulesPostImportContainer validateRuleDefs(RulesPostImportContainer importContainer) { for (RuleBean ruleBean : importContainer.getRuleDefs()) { AuditableBeanWrapper<RuleBean> ruleBeanWrapper = new AuditableBeanWrapper<RuleBean>(ruleBean); ruleBeanWrapper.getAuditableBean().setStudy(currentStudy); // Remove illegal characters from expression value ruleBeanWrapper.getAuditableBean().getExpression() .setValue(ruleBeanWrapper.getAuditableBean().getExpression().getValue().trim().replaceAll("(\n|\t|\r)", " ")); if (isRuleOidValid(ruleBeanWrapper) && isRuleExpressionValid(ruleBeanWrapper, null)) { RuleBean persistentRuleBean = getRuleDao().findByOid(ruleBeanWrapper.getAuditableBean()); if (persistentRuleBean != null) { String name = ruleBeanWrapper.getAuditableBean().getName(); String expressionValue = ruleBeanWrapper.getAuditableBean().getExpression().getValue(); String expressionContextName = ruleBeanWrapper.getAuditableBean().getExpression().getContextName(); String description = ruleBeanWrapper.getAuditableBean().getDescription(); Context context = expressionContextName != null ? Context.getByName(expressionContextName) : Context.OC_RULES_V1; persistentRuleBean.setUpdaterAndDate(getUserAccount()); ruleBeanWrapper.setAuditableBean(persistentRuleBean); ruleBeanWrapper.getAuditableBean().setName(name); ruleBeanWrapper.getAuditableBean().setDescription(description); ruleBeanWrapper.getAuditableBean().getExpression().setValue(expressionValue); ruleBeanWrapper.getAuditableBean().getExpression().setContext(context); doesPersistentRuleBeanBelongToCurrentStudy(ruleBeanWrapper); // ruleBeanWrapper.getAuditableBean().setId(persistentRuleBean.getId()); // ruleBeanWrapper.getAuditableBean().getExpression().setId(persistentRuleBean.getExpression().getId()); } else { ruleBeanWrapper.getAuditableBean().setOwner(getUserAccount()); } } putRuleInCorrectContainer(ruleBeanWrapper, importContainer); } logger.info("# of Valid RuleDefs : {} , # of InValid RuleDefs : {} , # of Overwritable RuleDefs : {}", new Object[] { importContainer.getValidRuleDefs().size(), importContainer.getInValidRuleDefs().size(), importContainer.getDuplicateRuleDefs().size() }); return importContainer; } private void putRuleSetInCorrectContainer(AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper, RulesPostImportContainer importContainer) { if (!ruleSetBeanWrapper.isSavable()) { importContainer.getInValidRuleSetDefs().add(ruleSetBeanWrapper); } else if (getExpressionService().getEventDefinitionCRF(ruleSetBeanWrapper.getAuditableBean().getTarget().getValue()) != null && getExpressionService().getEventDefinitionCRF(ruleSetBeanWrapper.getAuditableBean().getTarget().getValue()).getStatus().isDeleted()) { importContainer.getInValidRuleSetDefs().add(ruleSetBeanWrapper); } else if (ruleSetBeanWrapper.getAuditableBean().getId() == null) { importContainer.getValidRuleSetDefs().add(ruleSetBeanWrapper); importContainer.getValidRuleSetExpressionValues().add(ruleSetBeanWrapper.getAuditableBean().getTarget().getValue()); } else if (ruleSetBeanWrapper.getAuditableBean().getId() != null) { importContainer.getDuplicateRuleSetDefs().add(ruleSetBeanWrapper); } } private void putRuleInCorrectContainer(AuditableBeanWrapper<RuleBean> ruleBeanWrapper, RulesPostImportContainer importContainer) { if (!ruleBeanWrapper.isSavable()) { importContainer.getInValidRuleDefs().add(ruleBeanWrapper); importContainer.getInValidRules().put(ruleBeanWrapper.getAuditableBean().getOid(), ruleBeanWrapper); } else if (ruleBeanWrapper.getAuditableBean().getId() == null) { importContainer.getValidRuleDefs().add(ruleBeanWrapper); importContainer.getValidRules().put(ruleBeanWrapper.getAuditableBean().getOid(), ruleBeanWrapper); } else if (ruleBeanWrapper.getAuditableBean().getId() != null) { importContainer.getDuplicateRuleDefs().add(ruleBeanWrapper); importContainer.getValidRules().put(ruleBeanWrapper.getAuditableBean().getOid(), ruleBeanWrapper); } } /** * If the RuleSet contains any RuleSetRule object with an invalid RuleRef OID (OID that is not in DB or in the Valid Rule Lists) , Then add an error to the * ruleSetBeanWrapper, which in terms will make the RuleSet inValid. * * @param importContainer * @param ruleSetBeanWrapper */ private void isRuleSetRuleValid(RulesPostImportContainer importContainer, AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper ,List<RuleSetBean> eventActionsRuleSetBean) { for (RuleSetRuleBean ruleSetRuleBean : ruleSetBeanWrapper.getAuditableBean().getRuleSetRules()) { String ruleDefOid = ruleSetRuleBean.getOid(); if (ruleSetRuleBean.getId() == null || ruleSetRuleBean.getRuleSetRuleBeanImportStatus() == RuleSetRuleBeanImportStatus.EXACT_DOUBLE) { EventDefinitionCRFBean eventDefinitionCRFBean = getExpressionService().getEventDefinitionCRF(ruleSetBeanWrapper.getAuditableBean().getTarget().getValue()); if (eventDefinitionCRFBean != null && eventDefinitionCRFBean.getStatus().isDeleted()) { ruleSetBeanWrapper.error(createError("OCRERR_0026")); } if (importContainer.getInValidRules().get(ruleDefOid) != null || importContainer.getValidRules().get(ruleDefOid) == null && getRuleDao().findByOid(ruleDefOid, ruleSetBeanWrapper.getAuditableBean().getStudyId()) == null) { ruleSetBeanWrapper.error(createError("OCRERR_0025")); } if (importContainer.getValidRules().get(ruleDefOid) != null) { AuditableBeanWrapper<RuleBean> r = importContainer.getValidRules().get(ruleDefOid); if (!isRuleExpressionValid(r, ruleSetBeanWrapper.getAuditableBean())) ruleSetBeanWrapper.error(createError("OCRERR_0027")); } if (importContainer.getValidRules().get(ruleDefOid) == null) { RuleBean rule = getRuleDao().findByOid(ruleDefOid, ruleSetBeanWrapper.getAuditableBean().getStudyId()); AuditableBeanWrapper<RuleBean> r = new AuditableBeanWrapper<RuleBean>(rule); if (rule == null || !isRuleExpressionValid(r, ruleSetBeanWrapper.getAuditableBean())) ruleSetBeanWrapper.error(createError("OCRERR_0027")); } if (ruleSetRuleBean.getActions().size() == 0) { ruleSetBeanWrapper.error(createError("OCRERR_0027")); } for (RuleActionBean ruleActionBean : ruleSetRuleBean.getActions()) { isRuleActionValid(ruleActionBean, ruleSetBeanWrapper, eventDefinitionCRFBean, eventActionsRuleSetBean); } } } } private void isRuleActionValid(RuleActionBean ruleActionBean, AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper, EventDefinitionCRFBean eventDefinitionCRFBean ,List<RuleSetBean> eventActionsRuleSetBean ) { RuleActionRunBean ruleActionRun= ruleActionBean.getRuleActionRun(); if (ruleActionBean.getActionType().getCode() !=6 && !ruleActionRun.getInitialDataEntry() && !ruleActionRun.getAdministrativeDataEntry() && !ruleActionRun.getBatch() && !ruleActionRun.getDoubleDataEntry() && !ruleActionRun.getImportDataEntry()) ruleSetBeanWrapper.error(createError("OCRERR_0050")); String message =""; String emailSubject=""; if (ruleActionBean instanceof org.akaza.openclinica.domain.rule.action.NotificationActionBean){ message = ((NotificationActionBean) ruleActionBean).getMessage(); emailSubject = ((NotificationActionBean) ruleActionBean).getSubject(); if (emailSubject.length() > 330) ruleSetBeanWrapper.error(createError("OCRERR_0048")); if (message.length() > 2040) ruleSetBeanWrapper.error(createError("OCRERR_0049")); } if (ruleActionBean instanceof org.akaza.openclinica.domain.rule.action.EmailActionBean) isUploadedRuleSupportedForEventAction(ruleSetBeanWrapper); if (ruleActionBean instanceof DiscrepancyNoteActionBean) isUploadedRuleSupportedForEventAction(ruleSetBeanWrapper); if (ruleActionBean instanceof ShowActionBean) { if (!isUploadedRuleSupportedForEventAction (ruleSetBeanWrapper)){ List<PropertyBean> properties = ((ShowActionBean) ruleActionBean).getProperties(); //if (ruleActionBean.getRuleActionRun().getBatch() == true || ruleActionBean.getRuleActionRun().getImportDataEntry() == true) { if (ruleActionBean.getRuleActionRun().getBatch() == true ) { ruleSetBeanWrapper.error("ShowAction " + ((ShowActionBean) ruleActionBean).toString() + " is not Valid. You cannot have Batch=\"true\". "); //+ " is not Valid. You cannot have ImportDataEntry=\"true\" Batch=\"true\". "); } for (PropertyBean propertyBean : properties) { String result = getExpressionService().checkValidityOfItemOrItemGroupOidInCrf(propertyBean.getOid(), ruleSetBeanWrapper.getAuditableBean()); // String result = getExpressionService().isExpressionValid(oid, ruleSetBeanWrapper.getAuditableBean(), 2) ? "OK" : ""; if (!result.equals("OK")) { ruleSetBeanWrapper.error("ShowAction OID " + result + " is not Valid. "); } } } } if (ruleActionBean instanceof HideActionBean) { if (!isUploadedRuleSupportedForEventAction (ruleSetBeanWrapper)){ List<PropertyBean> properties = ((HideActionBean) ruleActionBean).getProperties(); //if (ruleActionBean.getRuleActionRun().getBatch() == true || ruleActionBean.getRuleActionRun().getImportDataEntry() == true) { if (ruleActionBean.getRuleActionRun().getBatch() == true ) { ruleSetBeanWrapper.error("HideAction " + ((HideActionBean) ruleActionBean).toString() + " is not Valid. You cannot have Batch=\"true\". "); //+ " is not Valid. You cannot have ImportDataEntry=\"true\" Batch=\"true\". "); } for (PropertyBean propertyBean : properties) { String result = getExpressionService().checkValidityOfItemOrItemGroupOidInCrf(propertyBean.getOid(), ruleSetBeanWrapper.getAuditableBean()); // String result = getExpressionService().isExpressionValid(oid, ruleSetBeanWrapper.getAuditableBean(), 2) ? "OK" : ""; if (!result.equals("OK")) { ruleSetBeanWrapper.error("HideAction OID " + result + " is not Valid. "); } } } } if (ruleActionBean instanceof InsertActionBean) { if (!isUploadedRuleSupportedForEventAction (ruleSetBeanWrapper)){ DataBinder dataBinder = new DataBinder(ruleActionBean); Errors errors = dataBinder.getBindingResult(); InsertActionValidator insertActionValidator = getInsertActionValidator(); insertActionValidator.setEventDefinitionCRFBean(eventDefinitionCRFBean); insertActionValidator.setRuleSetBean(ruleSetBeanWrapper.getAuditableBean()); insertActionValidator.setExpressionService(expressionService); insertActionValidator.validate(ruleActionBean, errors); if (errors.hasErrors()) { ruleSetBeanWrapper.error("InsertAction is not valid: " + errors.getAllErrors().get(0).getCode()); } } } if (ruleActionBean instanceof RandomizeActionBean) { if (!isUploadedRuleSupportedForEventAction (ruleSetBeanWrapper)){ DataBinder dataBinder = new DataBinder(ruleActionBean); Errors errors = dataBinder.getBindingResult(); RandomizeActionValidator randomizeActionValidator = getRandomizeActionValidator(); randomizeActionValidator.setEventDefinitionCRFBean(eventDefinitionCRFBean); randomizeActionValidator.setRuleSetBean(ruleSetBeanWrapper.getAuditableBean()); randomizeActionValidator.setExpressionService(expressionService); randomizeActionValidator.validate(ruleActionBean, errors); RandomizeActionBean randomizeActionBean = (RandomizeActionBean) ruleActionBean; // RuleActionRunBean ruleActionRun = randomizeActionBean.getRuleActionRun(); // if (ruleActionRun.getAdministrativeDataEntry() || ruleActionRun.getBatch() || ruleActionRun.getDoubleDataEntry() || ruleActionRun.getImportDataEntry()) // ruleSetBeanWrapper.error(createError("OCRERR_0050")); if (randomizeActionBean.getStratificationFactors()!=null){ for (StratificationFactorBean factor : randomizeActionBean.getStratificationFactors()){ if (factor.getStratificationFactor() != null && factor.getStratificationFactor().getValue() != null && factor.getStratificationFactor().getValue().length() != 0) { String expressionContextName = factor.getStratificationFactor().getContextName(); Context context = expressionContextName != null ? Context.getByName(expressionContextName) : Context.OC_RULES_V1; factor.getStratificationFactor().setContext(context); ExpressionBean expBean = factor.getStratificationFactor(); String expValue = expBean.getValue(); String prefix = "STUDYGROUPCLASSLIST"; boolean sgcExist=false; if (expValue.startsWith("SS.") ){ String param = expValue.split("\\.",-1)[1].trim() ; if (param.startsWith(prefix)){ String gcName= param.substring(21,param.indexOf("\"]")); StudyGroupClassDAO studyGroupClassDAO =new StudyGroupClassDAO(ds); ArrayList <StudyGroupClassBean> studyGroupClasses = studyGroupClassDAO.findAllByStudy(currentStudy); for (StudyGroupClassBean studyGroupClass :studyGroupClasses){ if (studyGroupClass.getName().equalsIgnoreCase(gcName.trim())){ sgcExist= true; break; } } } if (!param.equalsIgnoreCase("BIRTHDATE") && !param.equalsIgnoreCase("SEX") && !sgcExist){ ruleSetBeanWrapper.error(createError("OCRERR_0051",expBean.getValue())); } }else{ isStratificationExpressionValid(expBean, ruleSetBeanWrapper); } } } } if (errors.hasErrors()) ruleSetBeanWrapper.error("Randomize Action is not valid: " + errors.getAllErrors().get(0).getCode()); } } if (ruleActionBean instanceof EventActionBean) { DataBinder dataBinder = new DataBinder(ruleActionBean); Errors errors = dataBinder.getBindingResult(); eventActionValidator.setRuleSetBeanWrapper(ruleSetBeanWrapper); eventActionValidator.setExpressionService(expressionService); eventActionValidator.setRespage(respage); eventActionValidator.validate(ruleActionBean, errors); String currentTarget=null; currentTarget = ruleSetBeanWrapper.getAuditableBean().getOriginalTarget().getValue(); if (currentTarget.contains(".STARTDATE") || currentTarget.contains(".STATUS")){ if (ruleActionBean.getActionType().getCode()==6) inValidateInfiniteLoop(ruleActionBean,ruleSetBeanWrapper, eventActionsRuleSetBean); //Validation , move to Validate Rule page under eventActinValidator }else{ ruleSetBeanWrapper.error(createError("OCRERR_0044")); } if (errors.hasErrors()) { ruleSetBeanWrapper.error("EventAction is not valid: " + errors.getAllErrors().get(0).getDefaultMessage()); } } } private boolean isUploadedRuleSupportedForEventAction(AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper) { String currentTarget = null; currentTarget = ruleSetBeanWrapper.getAuditableBean().getOriginalTarget().getValue(); if (currentTarget.contains(".STARTDATE") || currentTarget.contains(".STATUS")) { ruleSetBeanWrapper.error(createError("OCRERR_0045")); return true; } return false; } public void inValidateInfiniteLoop(RuleActionBean ruleActionBean, AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper, List<RuleSetBean> eventActionsRuleSetBean) { String target = null; String destination = null; target = ruleSetBeanWrapper.getAuditableBean().getOriginalTarget().getValue(); destination = ((EventActionBean) ruleActionBean).getOc_oid_reference(); if (isDestinationAndTargetMatch(parseTarget(target), parseDestination(destination))) ruleSetBeanWrapper.error(createError("OCRERR_0042")); if (isDestinationAndTargetAcceptable(parseTarget(target), parseDestination(destination))) ruleSetBeanWrapper.error(createError("OCRERR_0043")); // List<RuleSetBean> eventActionsRuleSetBean = // getRuleSetDao().findAllEventActions(currentStudy); runValidationInList(target, destination, ruleSetBeanWrapper, eventActionsRuleSetBean); } public void runValidationInList(String target, String destination, AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper, List<RuleSetBean> eventActionsRuleSetBean) { // eventActionsRuleSetBean is the list of all events from rule set table Boolean isDestinationATarget = false; RuleSetBean isDestination = null; for (RuleSetBean ruleSetBean : eventActionsRuleSetBean) { if (isDestinationAndTargetMatch(parseTarget(ruleSetBean.getOriginalTarget().getValue()), parseDestination(destination)) || isDestinationAndTargetAcceptable(parseTarget(ruleSetBean.getOriginalTarget().getValue()), parseDestination(destination))) { isDestinationATarget = true; isDestination = ruleSetBean; break; } } // destination = (destination.contains(".STARTDATE")) ? destination : // destination +".STARTDATE" ; if (isDestinationATarget == true && isDestination != null) { List<RuleActionBean> ruleActions = getAllRuleActions(isDestination); for (RuleActionBean ruleActionBean : ruleActions) { if (ruleActionBean.getActionType().getCode()==6){ if (isDestinationAndTargetMatch(parseTarget(target), parseDestination(((EventActionBean) ruleActionBean).getOc_oid_reference() + ".STARTDATE"))) { ruleSetBeanWrapper.error(createError("OCRERR_0042")); break; } if (isDestinationAndTargetAcceptable(parseTarget(target), parseDestination(((EventActionBean) ruleActionBean).getOc_oid_reference()))) { ruleSetBeanWrapper.error(createError("OCRERR_0043")); break; } runValidationInList(target, ((EventActionBean) ruleActionBean).getOc_oid_reference(), ruleSetBeanWrapper, eventActionsRuleSetBean); } } } else { addNewRuleSetBeanInList(target, destination, eventActionsRuleSetBean); } } private void addNewRuleSetBeanInList(String target, String destination, List<RuleSetBean> eventActionsRuleSetBean) { ExpressionBean expression = new ExpressionBean(); expression.setValue(target); RuleSetBean ruleSetBean = new RuleSetBean(); ruleSetBean.setOriginalTarget(expression); EventActionBean eventActionBean = new EventActionBean(); eventActionBean.setOc_oid_reference(destination); List<RuleActionBean> listRuleActionBean = new ArrayList<RuleActionBean>(); listRuleActionBean.add(eventActionBean); RuleSetRuleBean ruleSetRuleBean = new RuleSetRuleBean(); ruleSetRuleBean.setActions(listRuleActionBean); ruleSetBean.addRuleSetRule(ruleSetRuleBean); eventActionsRuleSetBean.add(ruleSetBean); } private List<RuleActionBean> getAllRuleActions(RuleSetBean ruleSetBean) { List<RuleActionBean> ruleActions = new ArrayList<RuleActionBean>(); for (RuleSetRuleBean ruleSetRuleBean : ruleSetBean.getRuleSetRules()) { ruleActions.addAll(ruleSetRuleBean.getActions()); } return ruleActions; } public boolean isEventTypeRepeating(String event) { boolean isRepeating = false; StudyEventDefinitionDAO seddao = new StudyEventDefinitionDAO(ds); StudyEventDefinitionBean studyEventDefinition = (StudyEventDefinitionBean) seddao.findByOid(event); return studyEventDefinition.isRepeating(); } public Map<String, String> parseTarget(String target) { target = (target.contains(".STARTDATE")) ? target : target + ".STARTDATE"; Map<String, String> targetValues = new HashMap<String, String>(); String targetStudyEventDefOid = null; String targetStudyEventRepeatNumber = null; String targetProperty = null; if (target.contains("[")) { targetStudyEventDefOid = target.substring(0, target.indexOf("[")); targetStudyEventRepeatNumber = target.substring(target.indexOf("[") + 1, target.indexOf("]")); } else { targetStudyEventDefOid = target.substring(0, target.indexOf(".")); if (isEventTypeRepeating(targetStudyEventDefOid)) targetStudyEventRepeatNumber = "ALL"; else targetStudyEventRepeatNumber = "1"; } targetProperty = target.substring(target.indexOf(".") + 1); targetValues.put("targetStudyEventDefOid", targetStudyEventDefOid); targetValues.put("targetStudyEventRepeatNumber", targetStudyEventRepeatNumber); targetValues.put("targetProperty", targetProperty); return targetValues; } public Map<String, String> parseDestination(String destination) { destination = (destination.contains(".STARTDATE")) ? destination : destination + ".STARTDATE"; Map<String, String> destinationValues = new HashMap<String, String>(); String destinationStudyEventDefOid = null; String destinationStudyEventRepeatNumber = null; String destinationProperty = null; if (destination.contains("[")) { destinationStudyEventDefOid = destination.substring(0, destination.indexOf("[")); destinationStudyEventRepeatNumber = destination.substring(destination.indexOf("[") + 1, destination.indexOf("]")); } else { destinationStudyEventDefOid = destination.substring(0, destination.indexOf(".")); destinationStudyEventRepeatNumber = "1"; } destinationProperty = destination.substring(destination.indexOf(".") + 1); destinationValues.put("destinationStudyEventDefOid", destinationStudyEventDefOid); destinationValues.put("destinationStudyEventRepeatNumber", destinationStudyEventRepeatNumber); destinationValues.put("destinationProperty", destinationProperty); return destinationValues; } private boolean isDestinationAndTargetMatch(Map<String, String> target, Map<String, String> destination) { String targetProperty = (String) target.get("targetProperty"); String targetStudyEventDefOid = (String) target.get("targetStudyEventDefOid"); String targetStudyEventRepeatNumber = (String) target.get("targetStudyEventRepeatNumber"); String destinationStudyEventDefOid = (String) destination.get("destinationStudyEventDefOid"); String destinationStudyEventRepeatNumber = (String) destination.get("destinationStudyEventRepeatNumber"); String destinationProperty = (String) destination.get("destinationProperty"); if (targetProperty.equals(destinationProperty) && targetStudyEventRepeatNumber.equals(destinationStudyEventRepeatNumber) && targetStudyEventDefOid.equals(destinationStudyEventDefOid)) { return true; } else { return false; } } private boolean isDestinationAndTargetAcceptable(Map<String, String> target, Map<String, String> destination) { String targetProperty = (String) target.get("targetProperty"); String targetStudyEventDefOid = (String) target.get("targetStudyEventDefOid"); String targetStudyEventRepeatNumber = (String) target.get("targetStudyEventRepeatNumber"); String destinationStudyEventDefOid = (String) destination.get("destinationStudyEventDefOid"); String destinationStudyEventRepeatNumber = (String) destination.get("destinationStudyEventRepeatNumber"); String destinationProperty = (String) destination.get("destinationProperty"); if (targetProperty.equals(destinationProperty) && targetStudyEventRepeatNumber.equals("ALL") && targetStudyEventDefOid.equals(destinationStudyEventDefOid)) { return true; } else { return false; } } private String createError(String key) { MessageFormat mf = new MessageFormat(""); mf.applyPattern(respage.getString(key)); Object[] arguments = {}; return key + ": " + mf.format(arguments); } private String createError(String key, String var) { MessageFormat mf = new MessageFormat(""); mf.applyPattern(respage.getString(key)); Object[] arguments = { var }; return key + ": " + mf.format(arguments); } private boolean isRuleExpressionValid(AuditableBeanWrapper<RuleBean> ruleBeanWrapper, RuleSetBean ruleSet) { boolean isValid = true; ExpressionBean expressionBean = isExpressionValid(ruleBeanWrapper.getAuditableBean().getExpression(), ruleBeanWrapper); ExpressionObjectWrapper eow = new ExpressionObjectWrapper(ds, currentStudy, expressionBean, ruleSet, ExpressionObjectWrapper.CONTEXT_EXPRESSION); ExpressionProcessor ep = ExpressionProcessorFactory.createExpressionProcessor(eow); ep.setRespage(respage); String errorString = ep.isRuleExpressionValid(); if (errorString != null) { ruleBeanWrapper.error(errorString); isValid = false; } return isValid; } public boolean isStratificationExpressionValid(ExpressionBean expBean , AuditableBeanWrapper<RuleSetBean> beanWrapper) { boolean isValid = true; ExpressionBean expressionBean = isExpressionValid(expBean, beanWrapper); ExpressionObjectWrapper eow = new ExpressionObjectWrapper(ds, currentStudy, expressionBean,ExpressionObjectWrapper.CONTEXT_TARGET); ExpressionProcessor ep = ExpressionProcessorFactory.createExpressionProcessor(eow); ep.setRespage(respage); // String errorString = ep.isRuleExpressionValid(); String errorString = ep.isRuleAssignmentExpressionValid(); if (errorString != null) { beanWrapper.error(errorString); isValid = false; } return isValid; } private boolean isRuleSetExpressionValid(AuditableBeanWrapper<RuleSetBean> beanWrapper) { boolean isValid = true; ExpressionBean expressionBean = isExpressionValid(beanWrapper.getAuditableBean().getTarget(), beanWrapper); ExpressionObjectWrapper eow = new ExpressionObjectWrapper(ds, currentStudy, expressionBean,ExpressionObjectWrapper.CONTEXT_TARGET); ExpressionProcessor ep = ExpressionProcessorFactory.createExpressionProcessor(eow); ep.setRespage(respage); String errorString = ep.isRuleAssignmentExpressionValid(); if (errorString != null) { beanWrapper.error(errorString); isValid = false; } return isValid; } private ExpressionBean isExpressionValid(ExpressionBean expressionBean, AuditableBeanWrapper<?> beanWrapper) { if (expressionBean.getContextName() == null && expressionBean.getContext() == null) { expressionBean.setContext(Context.OC_RULES_V1); } if (expressionBean.getContextName() != null && expressionBean.getContext() == null) { beanWrapper.warning(createError("OCRERR_0029")); expressionBean.setContext(Context.OC_RULES_V1); } return expressionBean; } private boolean isRuleOidValid(AuditableBeanWrapper<RuleBean> ruleBeanWrapper) { boolean isValid = true; try { oidGenerator.validate(ruleBeanWrapper.getAuditableBean().getOid()); } catch (Exception e) { ruleBeanWrapper.error(createError("OCRERR_0028")); isValid = false; } return isValid; } private boolean isRunTimeValid(AuditableBeanWrapper<RuleSetBean> ruleSetBeanWrapper , String runTime) { boolean isValid = true; DateTimeFormatter formatter = DateTimeFormat.forPattern("HH:mm"); try { formatter.parseDateTime(runTime); if(!runTime.matches("\\d{2}:\\d{2}")){ ruleSetBeanWrapper.error(createError("OCRERR_0047")); isValid = false; } } catch (Exception e) { ruleSetBeanWrapper.error(createError("OCRERR_0047")); isValid = false; } return isValid; } private boolean doesPersistentRuleBeanBelongToCurrentStudy(AuditableBeanWrapper<RuleBean> ruleBeanWrapper) { boolean isValid = true; if (ruleBeanWrapper.getAuditableBean().getRuleSetRules().size() > 0) { int studyId = ruleBeanWrapper.getAuditableBean().getRuleSetRules().get(0).getRuleSetBean().getStudyId(); if (studyId != currentStudy.getId()) { ruleBeanWrapper.error(createError("OCRERR_0030")); isValid = false; } } return isValid; } /** * @return the ruleDao */ public RuleDao getRuleDao() { return ruleDao; } /** * @param ruleDao * the ruleDao to set */ public void setRuleDao(RuleDao ruleDao) { this.ruleDao = ruleDao; } /** * @return the ruleSetDao */ public RuleSetDao getRuleSetDao() { return ruleSetDao; } /** * @param ruleSetDao * the ruleSetDao to set */ public void setRuleSetDao(RuleSetDao ruleSetDao) { this.ruleSetDao = ruleSetDao; } /** * @return the currentStudy */ public StudyBean getCurrentStudy() { return currentStudy; } /** * @param currentStudy * the currentStudy to set */ public void setCurrentStudy(StudyBean currentStudy) { this.currentStudy = currentStudy; } public InsertActionValidator getInsertActionValidator() { return insertActionValidator; } public void setInsertActionValidator(InsertActionValidator insertActionValidator) { this.insertActionValidator = insertActionValidator; } public EventActionValidator getEventActionValidator() { return eventActionValidator; } public void setEventActionValidator(EventActionValidator eventActionValidator) { this.eventActionValidator = eventActionValidator; } public RandomizeActionValidator getRandomizeActionValidator() { return randomizeActionValidator; } public void setRandomizeActionValidator(RandomizeActionValidator randomizeActionValidator) { this.randomizeActionValidator = randomizeActionValidator; } /** * @return the respage */ public ResourceBundle getRespage() { return respage; } /** * @param respage */ public void setRespage(ResourceBundle respage) { this.respage = respage; } /** * @return userAccount */ public UserAccountBean getUserAccount() { return userAccount; } /** * @param userAccount */ public void setUserAccount(UserAccountBean userAccount) { this.userAccount = userAccount; } private ExpressionService getExpressionService() { expressionService = this.expressionService != null ? expressionService : new ExpressionService(new ExpressionObjectWrapper(ds, currentStudy, (ExpressionBean)null, (RuleSetBean)null)); expressionService.setExpressionWrapper(new ExpressionObjectWrapper(ds, currentStudy, (ExpressionBean)null, (RuleSetBean)null)); return expressionService; } }