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.validators;
17  
18  import static org.seasar.cubby.internal.util.LogMessages.format;
19  
20  import java.text.DateFormat;
21  import java.text.ParsePosition;
22  import java.text.SimpleDateFormat;
23  import java.util.Date;
24  
25  import org.seasar.cubby.action.MessageInfo;
26  import org.seasar.cubby.controller.FormatPattern;
27  import org.seasar.cubby.internal.util.StringUtils;
28  import org.seasar.cubby.spi.ContainerProvider;
29  import org.seasar.cubby.spi.ProviderFactory;
30  import org.seasar.cubby.spi.container.Container;
31  import org.seasar.cubby.validator.ScalarFieldValidator;
32  import org.seasar.cubby.validator.ValidationContext;
33  
34  /**
35   * 日付パターンに適合するかを検証します。
36   * <p>
37   * 日付パターンを指定しない場合、「app-cubby.dicon」で指定した日付パターンが使用されます。
38   * </p>
39   * <p>
40   * <table>
41   * <caption>検証エラー時に設定するエラーメッセージ</caption> <tbody>
42   * <tr>
43   * <th scope="row">デフォルトのキー</th>
44   * <td>valid.dateFormat</td>
45   * </tr>
46   * <tr>
47   * <th scope="row">置換文字列</th>
48   * <td>
49   * <ol start="0">
50   * <li>フィールド名</li>
51   * </ol></td>
52   * </tr>
53   * </tbody>
54   * </table>
55   * </p>
56   * 
57   * @author agata
58   * @author baba
59   * @see SimpleDateFormat
60   */
61  public class DateFormatValidator implements ScalarFieldValidator {
62  
63  	/**
64  	 * メッセージキー。
65  	 */
66  	private final String messageKey;
67  
68  	/**
69  	 * 日付パターン
70  	 */
71  	private final String pattern;
72  
73  	/**
74  	 * 日付パターンを指定しないコンストラクタ
75  	 */
76  	public DateFormatValidator() {
77  		this(null);
78  	}
79  
80  	/**
81  	 * 日付パターンを指定するコンストラクタ
82  	 * 
83  	 * @param pattern
84  	 *            日付パターン(例:"yyyy/MM/dd")
85  	 */
86  	public DateFormatValidator(final String pattern) {
87  		this(pattern, "valid.dateFormat");
88  	}
89  
90  	/**
91  	 * 日付パターンとエラーメッセージキーを指定したコンストラクタ
92  	 * 
93  	 * @param pattern
94  	 *            日付パターン(例:"yyyy/MM/dd")
95  	 * @param messageKey
96  	 *            エラーメッセージキー
97  	 */
98  	public DateFormatValidator(final String pattern, final String messageKey) {
99  		this.pattern = pattern;
100 		this.messageKey = messageKey;
101 	}
102 
103 	/**
104 	 * {@inheritDoc}
105 	 */
106 	public void validate(final ValidationContext context, final Object value) {
107 		if (value == null) {
108 			return;
109 		}
110 		if (value instanceof String) {
111 			final String stringValue = (String) value;
112 			if (StringUtils.isEmpty((String) value)) {
113 				return;
114 			}
115 			try {
116 				final DateFormat dateFormat = createDateFormat(context, value);
117 				final ParsePosition parsePosition = new ParsePosition(0);
118 				final Date date = dateFormat.parse(stringValue, parsePosition);
119 				if (date != null
120 						&& parsePosition.getIndex() == stringValue.length()) {
121 					return;
122 				}
123 			} catch (final Exception e) {
124 			}
125 		}
126 
127 		final MessageInfo messageInfo = new MessageInfo();
128 		messageInfo.setKey(this.messageKey);
129 		context.addMessageInfo(messageInfo);
130 	}
131 
132 	/**
133 	 * {@link DateFormat} のインスタンスを生成します。
134 	 * 
135 	 * @param context
136 	 *            コンテキスト
137 	 * @param value
138 	 *            値
139 	 * @return {@link DateFormat} のインスタンス
140 	 */
141 	private DateFormat createDateFormat(final ValidationContext context,
142 			final Object value) {
143 		final SimpleDateFormat dateFormat = new SimpleDateFormat();
144 		final String pattern;
145 		if (StringUtils.isEmpty(this.pattern)) {
146 			final Container container = ProviderFactory.get(
147 					ContainerProvider.class).getContainer();
148 			final FormatPattern formatPattern = container
149 					.lookup(FormatPattern.class);
150 			if (formatPattern == null) {
151 				throw new IllegalStateException(format("ECUB0301", this, value));
152 			}
153 			pattern = formatPattern.getDatePattern();
154 		} else {
155 			pattern = this.pattern;
156 		}
157 		dateFormat.applyPattern(pattern);
158 		dateFormat.setLenient(false);
159 		return dateFormat;
160 	}
161 
162 }