View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.plugins.oval.validation;
17  
18  import java.util.List;
19  import java.util.Map;
20  
21  import net.sf.oval.ConstraintViolation;
22  import net.sf.oval.Validator;
23  import net.sf.oval.context.ClassContext;
24  import net.sf.oval.context.ConstructorParameterContext;
25  import net.sf.oval.context.FieldContext;
26  import net.sf.oval.context.MethodEntryContext;
27  import net.sf.oval.context.MethodExitContext;
28  import net.sf.oval.context.MethodParameterContext;
29  import net.sf.oval.context.MethodReturnValueContext;
30  import net.sf.oval.context.OValContext;
31  
32  import org.seasar.cubby.action.ActionErrors;
33  import org.seasar.cubby.action.FieldInfo;
34  import org.seasar.cubby.spi.ContainerProvider;
35  import org.seasar.cubby.spi.ProviderFactory;
36  import org.seasar.cubby.spi.container.Container;
37  import org.seasar.cubby.spi.container.LookupException;
38  import org.seasar.cubby.validator.ValidationException;
39  import org.seasar.cubby.validator.ValidationRule;
40  
41  /**
42   * OVal によって入力を検証する {@link ValidationRule} です。
43   * 
44   * @author baba
45   */
46  public class OValValidationRule implements ValidationRule {
47  
48  	/** リソースのキープレフィックス。 */
49  	private final String resourceKeyPrefix;
50  
51  	/**
52  	 * キーのプレフィックスなしでインスタンス化します。
53  	 */
54  	public OValValidationRule() {
55  		this(null);
56  	}
57  
58  	/**
59  	 * 指定されたプレフィックスをフィールド名のキーのプレフィックスとしてインスタンス化します。
60  	 * 
61  	 * @param resourceKeyPrefix
62  	 *            リソースのキープレフィックス
63  	 */
64  	public OValValidationRule(final String resourceKeyPrefix) {
65  		this.resourceKeyPrefix = resourceKeyPrefix;
66  	}
67  
68  	/**
69  	 * {@inheritDoc}
70  	 */
71  	public void apply(final Map<String, Object[]> params, final Object form,
72  			final ActionErrors errors) throws ValidationException {
73  		final OValValidationContext context = OValValidationContext.get();
74  		context.setResourceKeyPrefix(resourceKeyPrefix);
75  		try {
76  			final Validator validator = buildValidator();
77  			final List<ConstraintViolation> violations = validator
78  					.validate(form);
79  			processViolations(violations, errors);
80  		} finally {
81  			OValValidationContext.remove();
82  		}
83  	}
84  
85  	/**
86  	 * バリデータを構築します。
87  	 * 
88  	 * @return バリデータ
89  	 */
90  	protected Validator buildValidator() {
91  		final Container container = ProviderFactory
92  				.get(ContainerProvider.class).getContainer();
93  		try {
94  			return container.lookup(Validator.class);
95  		} catch (final LookupException e) {
96  			return new Validator();
97  		}
98  	}
99  
100 	/**
101 	 * 入力検証で検出した制約違反を処理します。
102 	 * <p>
103 	 * <code>errors</code> に制約違反から抽出したメッセージを設定します。
104 	 * </p>
105 	 * 
106 	 * @param violations
107 	 *            制約違反のリスト
108 	 * @param errors
109 	 *            メッセージを設定するオブジェクト
110 	 */
111 	protected void processViolations(
112 			final List<ConstraintViolation> violations,
113 			final ActionErrors errors) {
114 		for (final ConstraintViolation violation : violations) {
115 			final String message = violation.getMessage();
116 			final FieldInfo fieldInfo = createFieldInfo(violation.getContext());
117 			if (fieldInfo != null) {
118 				errors.add(message, fieldInfo);
119 			} else {
120 				errors.add(message);
121 			}
122 		}
123 	}
124 
125 	/**
126 	 * <code>ovalContext</code> から {@link FieldInfo} を生成します。
127 	 * 
128 	 * @param ovalContext
129 	 *            OVal のコンテキスト
130 	 * @return <code>ovalContext</code> から生成された {@link FieldInfo}
131 	 */
132 	protected FieldInfo createFieldInfo(final OValContext ovalContext) {
133 		final FieldInfo fieldInfo;
134 		if (ovalContext instanceof ClassContext) {
135 			fieldInfo = null;
136 		} else if (ovalContext instanceof FieldContext) {
137 			final FieldContext ctx = (FieldContext) ovalContext;
138 			fieldInfo = new FieldInfo(ctx.getField().getName());
139 		} else if (ovalContext instanceof ConstructorParameterContext) {
140 			final ConstructorParameterContext ctx = (ConstructorParameterContext) ovalContext;
141 			fieldInfo = new FieldInfo(ctx.getParameterName());
142 		} else if (ovalContext instanceof MethodParameterContext) {
143 			final MethodParameterContext ctx = (MethodParameterContext) ovalContext;
144 			fieldInfo = new FieldInfo(ctx.getParameterName());
145 		} else if (ovalContext instanceof MethodEntryContext) {
146 			final MethodEntryContext ctx = (MethodEntryContext) ovalContext;
147 			fieldInfo = new FieldInfo(ctx.getMethod().getName());
148 		} else if (ovalContext instanceof MethodExitContext) {
149 			final MethodExitContext ctx = (MethodExitContext) ovalContext;
150 			fieldInfo = new FieldInfo(ctx.getMethod().getName());
151 		} else if (ovalContext instanceof MethodReturnValueContext) {
152 			final MethodReturnValueContext ctx = (MethodReturnValueContext) ovalContext;
153 			fieldInfo = new FieldInfo(ctx.getMethod().getName());
154 		} else {
155 			fieldInfo = null;
156 		}
157 
158 		return fieldInfo;
159 	}
160 
161 }