コードリーディングメモ バリデータ編

struts-config.xml

    <plug-in className="org.seasar.struts.validator.S2ValidatorPlugIn">
        <set-property
          property="pathnames"
          value="/WEB-INF/validator-rules.xml"/>
    </plug-in>

S2ValidatorPlugIn#initResources()

resources = new S2ValidatorResources(streamArray);

まず上記のようにS2ValidatorPlugInでS2ValidatorResourcesをnewしセットする。
このresourcesはapplicationにsetAttributeされる。

その後ActionCustomizer#setupValidatorでアノテーション(例:@Required)を取得し、formにセットし、
検証リソースにaddFormする。

ActionCustomizer#customize

    public void customize(ComponentDef componentDef) {
        S2ActionMapping actionMapping = createActionMapping(componentDef);
        S2FormBeanConfig formConfig = createFormBeanConfig(actionMapping);
        S2ModuleConfig moduleConfig = S2ModuleConfigUtil.getModuleConfig();
        moduleConfig.addActionConfig(actionMapping);
        moduleConfig.addFormBeanConfig(formConfig);
        S2ValidatorResources validatorResources = ValidatorResourcesUtil
                .getValidatorResources();
        setupValidator(actionMapping, validatorResources);
    }

ActionCustomizer#setupValidator

    /**
     * バリデータをセットアップします。
     * 
     * 
     * @param actionMapping
     *            アクションマッピング
     * @param validatorResources
     *            検証リソース
     */
    protected void setupValidator(S2ActionMapping actionMapping,
            S2ValidatorResources validatorResources) {
        Map<String, Form> forms = new HashMap<String, Form>();
        Form baseForm = new Form();
        baseForm.setName(actionMapping.getName());
        for (String methodName : actionMapping.getExecuteMethodNames()) {
            if (actionMapping.getExecuteConfig(methodName).isValidator()) {
                Form form = new Form();
                form.setName(actionMapping.getName() + "_" + methodName);
                forms.put(methodName, form);
            }
        }
        BeanDesc beanDesc = actionMapping.getActionFormBeanDesc();
        for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) {
            PropertyDesc pd = beanDesc.getPropertyDesc(i);
            Field field = pd.getField();
            if (field == null) {
                continue;
            }
            for (Annotation anno : field.getDeclaredAnnotations()) {
                processAnnotation(pd.getPropertyName(), anno,
                        validatorResources, forms, baseForm);
            }
        }
        validatorResources.addForm(baseForm);
        for (Iterator<Form> i = forms.values().iterator(); i.hasNext();) {
            validatorResources.addForm(i.next());
        }

    }

上記でaddFormしたformを検証リソースから取得して(getFormして)バリデーションが走る。

Validator

        Form form = this.resources.getForm(locale, this.formName);
        if (form != null) {
            this.setParameter(FORM_PARAM, this);
            return form.validate(
                this.parameters,
                this.resources.getValidatorActions(),
                this.page,
                this.fieldName);
        }