package ru.hflabs.rcd.service.document; import org.springframework.validation.Errors; import ru.hflabs.rcd.accessor.RuleFieldAccessor; import ru.hflabs.rcd.exception.constraint.IllegalPrimaryKeyException; import ru.hflabs.rcd.model.Essence; import ru.hflabs.rcd.model.path.MetaFieldNamedPath; import ru.hflabs.rcd.model.rule.RecodeRule; import ru.hflabs.rcd.model.rule.Rule; import ru.hflabs.rcd.service.IFilterService; import ru.hflabs.util.core.FormatUtil; /** * Класс <class>RuleValidator</class> реализует базовый валидатор для правил * * @author Nazin Alexander */ public abstract class RuleChangeValidator<NP extends MetaFieldNamedPath, T extends Essence, R extends Rule<NP, T, R>, RFS extends IFilterService<T>> extends ExistedDocumentChangeValidator<R> { /** Сервис установки значения источника поля в правило */ private final RuleFieldAccessor<NP, T, R> fromInjector; /** Сервис установки значения назначения поля в правило */ private final RuleFieldAccessor<NP, T, R> toInjector; /** Класс исключения при некорректном правиле */ private final Class<? extends Throwable> illegalRuleClass; /** Сервис поиска полей */ protected RFS recodeFieldService; protected RuleChangeValidator( boolean mustExist, Class<R> targetClass, RuleFieldAccessor<NP, T, R> fromInjector, RuleFieldAccessor<NP, T, R> toInjector, Class<? extends Throwable> illegalRuleClass) { super(targetClass, mustExist); this.fromInjector = fromInjector; this.toInjector = toInjector; this.illegalRuleClass = illegalRuleClass; } public void setRecodeFieldService(RFS recodeFieldService) { this.recodeFieldService = recodeFieldService; } /** * Выполняет форматирование именованного пути * * @param target именованный путь * @return Возвращает модифицированный именованный путь */ protected NP formatNamedPath(NP target) { target.setGroupName(FormatUtil.parseString(target.getGroupName())); target.setDictionaryName(FormatUtil.parseString(target.getDictionaryName())); target.setFieldName(FormatUtil.parseString(target.getFieldName())); return target; } @Override protected boolean doValidateAnnotations(Errors errors, Object target) { super.doValidateAnnotations(errors, target); R rule = retrieveTargetClass().cast(target); // Проверяем поле источника errors.pushNestedPath(R.FROM_PATH); try { rule = rule.injectFromNamedPath(formatNamedPath(rule.getFromNamedPath())); super.doValidateAnnotations(errors, rule.getFromNamedPath()); } finally { errors.popNestedPath(); } // Проверяем поле назначения errors.pushNestedPath(R.TO_PATH); try { rule = rule.injectToNamedPath(formatNamedPath(rule.getToNamedPath())); super.doValidateAnnotations(errors, rule.getToNamedPath()); } finally { errors.popNestedPath(); } return errors.hasErrors(); } /** * Выполняет валидацию поля для правила * * @param errors контейнер ошибок * @param target проверяемое правило * @param accessor серис доступа к полям правила */ protected void doValidateField(Errors errors, R target, RuleFieldAccessor<NP, T, R> accessor) { String fieldId = accessor.applyRelativeId(target); try { accessor.inject(target, recodeFieldService.findByID(fieldId, true, false)); } catch (IllegalPrimaryKeyException ex) { rejectValue(errors, RecodeRule.VALUE, ex, fieldId); } } /** * Выполняет валидацию полей источника и назначения * * @param errors контейнер ошибок * @param target проверяемое правило */ protected void doValidateFields(Errors errors, R target) { // Проверяем поле источника errors.pushNestedPath(R.FROM_PATH); try { doValidateField(errors, target, fromInjector); } finally { errors.popNestedPath(); } // Проверяем поле назначения errors.pushNestedPath(R.TO_PATH); try { doValidateField(errors, target, toInjector); } finally { errors.popNestedPath(); } } @Override protected void doValidateCommon(Errors errors, R target) { doValidateFields(errors, target); } @Override protected void rejectExisted(Errors errors, R target, R existed, boolean mustExist) { errors.reject( illegalRuleClass.getSimpleName(), new Object[]{target.getFromNamedPath(), target.getToNamedPath()}, String.format("%s '%s' to '%s' %s exist", retrieveTargetClass().getSimpleName(), target.getFromNamedPath(), target.getToNamedPath(), mustExist ? "not" : "already" ) ); } }