/*
* 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;
}
}