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.validator;
17  
18  import static org.seasar.cubby.CubbyConstants.ATTR_CONVERSION_ERRORS;
19  
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Map.Entry;
24  
25  import javax.servlet.http.HttpServletRequest;
26  
27  import org.seasar.cubby.action.ActionErrors;
28  import org.seasar.cubby.action.FieldInfo;
29  import org.seasar.cubby.internal.controller.ThreadContext;
30  import org.seasar.cubby.internal.util.RequestUtils;
31  import org.seasar.cubby.util.Messages;
32  
33  /**
34   * リクエストパラメータをフォームオブジェクトへのバインドする時の型変換エラーを検証する入力検証ルールです。
35   * 
36   * @author baba
37   * @since 2.0.0
38   */
39  public class ConversionValidationRule implements ValidationRule {
40  
41  	/** デフォルトのメッセージを置換するメッセージ情報。 */
42  	private final Map<FieldInfo, MessageInfo> messages = new HashMap<FieldInfo, MessageInfo>();
43  
44  	/**
45  	 * {@inheritDoc}
46  	 */
47  	public void apply(final Map<String, Object[]> params, final Object form,
48  			final ActionErrors errors) throws ValidationException {
49  		final HttpServletRequest request = ThreadContext.getRequest();
50  		final ActionErrors conversionErrors = RequestUtils.getAttribute(
51  				request, ATTR_CONVERSION_ERRORS);
52  		if (conversionErrors != null) {
53  			merge(conversionErrors, errors);
54  		}
55  	}
56  
57  	/**
58  	 * デフォルトのメッセージを置換するメッセージ情報。
59  	 * 
60  	 * @param fieldName
61  	 *            フィールド名
62  	 * @param messageKey
63  	 *            {@link Messages}からメッセージを取得するためのキー
64  	 * @param arguments
65  	 *            メッセージの置換パターンを置き換えるオブジェクトからなる配列
66  	 * @return このオブジェクト
67  	 */
68  	public ConversionValidationRule add(final String fieldName,
69  			final String messageKey, final Object... arguments) {
70  		final FieldInfo fieldInfo = new FieldInfo(fieldName);
71  		putToMessages(fieldInfo, messageKey, arguments);
72  		return this;
73  	}
74  
75  	/**
76  	 * デフォルトのメッセージを置換するメッセージ情報。
77  	 * 
78  	 * @param fieldName
79  	 *            フィールド名
80  	 * @param index
81  	 *            フィールドのインデックス
82  	 * @param messageKey
83  	 *            {@link Messages}からメッセージを取得するためのキー
84  	 * @param arguments
85  	 *            メッセージの置換パターンを置き換えるオブジェクトからなる配列
86  	 * @return このオブジェクト
87  	 */
88  	public ConversionValidationRule add(final String fieldName,
89  			final int index, final String messageKey, final Object... arguments) {
90  		final FieldInfo fieldInfo = new FieldInfo(fieldName, index);
91  		putToMessages(fieldInfo, messageKey, arguments);
92  		return this;
93  	}
94  
95  	private void putToMessages(final FieldInfo fieldInfo,
96  			final String messageKey, final Object... arguments) {
97  		final MessageInfo messageInfo = new MessageInfo();
98  		messageInfo.setKey(messageKey);
99  		messageInfo.setArguments(arguments);
100 		this.messages.put(fieldInfo, messageInfo);
101 	}
102 
103 	private void merge(final ActionErrors from, final ActionErrors to) {
104 		for (final Entry<String, Map<Integer, List<String>>> indexedField : from
105 				.getIndexedFields().entrySet()) {
106 			final String fieldName = indexedField.getKey();
107 			for (final Entry<Integer, List<String>> field : indexedField
108 					.getValue().entrySet()) {
109 				final Integer index = field.getKey();
110 				for (final String message : field.getValue()) {
111 					final FieldInfo fieldInfo;
112 					if (index == null) {
113 						fieldInfo = new FieldInfo(fieldName);
114 					} else {
115 						fieldInfo = new FieldInfo(fieldName, index);
116 					}
117 					to.add(message(message, fieldInfo), fieldInfo);
118 				}
119 			}
120 		}
121 	}
122 
123 	private String message(final String message, final FieldInfo fieldInfo) {
124 		if (messages.containsKey(fieldInfo)) {
125 			final MessageInfo messageInfo = messages.get(fieldInfo);
126 			return messageInfo.builder().fieldNameKey(fieldInfo.getName())
127 					.toString();
128 		} else {
129 			return message;
130 		}
131 	}
132 
133 }