View Javadoc
1   /*
2    * Copyright 2013 the original author or authors.
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, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.orangesignal.csv.filters;
18  
19  import java.io.IOException;
20  import java.lang.reflect.Field;
21  import java.util.Collection;
22  import java.util.Comparator;
23  import java.util.Map;
24  import java.util.regex.Pattern;
25  
26  import com.orangesignal.csv.bean.FieldUtils;
27  
28  /**
29   * Java プログラム要素フィルタの条件式ユーティリティを提供します。
30   * 
31   * @author Koji Sugisawa
32   * @since 1.2.3
33   */
34  abstract class BeanExpressionUtils {
35  
36  	/**
37  	 * デフォルトコンストラクタです。
38  	 */
39  	protected BeanExpressionUtils() {}
40  
41  	// ------------------------------------------------------------------------
42  
43  	/**
44  	 * 指定された Java プログラム要素のフィールド値が <code>null</code> であるかどうかを返します。
45  	 * 
46  	 * @param bean Java プログラム要素
47  	 * @param name フィールド名
48  	 * @return 指定された Java プログラム要素のフィールド値が <code>null</code> の場合は <code>true</code> それ以外の場合は <code>false</code>
49  	 * @throws IOException フィールド操作で例外が発生した場合
50  	 */
51  	public static boolean isNull(final Object bean, final String name) throws IOException {
52  		return getFieldValue(bean, name) == null;
53  	}
54  
55  	/**
56  	 * 指定された Java プログラム要素のフィールド値が <code>null</code> でないかどうかを返します。
57  	 * 
58  	 * @param bean Java プログラム要素
59  	 * @param name フィールド名
60  	 * @return 指定された Java プログラム要素のフィールド値が <code>null</code> でない場合は <code>true</code> それ以外の場合は <code>false</code>
61  	 * @throws IOException フィールド操作で例外が発生した場合
62  	 */
63  	public static boolean isNotNull(final Object bean, final String name) throws IOException {
64  		return !isNull(bean, name);
65  	}
66  
67  	/**
68  	 * 指定された Java プログラム要素のフィールド値が空かどうかを返します。
69  	 * 
70  	 * @param bean Java プログラム要素
71  	 * @param name フィールド名
72  	 * @return 指定された Java プログラム要素のフィールド値が空の場合は <code>true</code> それ以外の場合は <code>false</code>
73  	 * @throws IOException フィールド操作で例外が発生した場合
74  	 */
75  	public static boolean isEmpty(final Object bean, final String name) throws IOException {
76  		final Field field = FieldUtils.getField(bean.getClass(), name);
77  		final Object value = FieldUtils.getFieldValue(bean, field);
78  		if (value == null) {
79  			return true;
80  		}
81  		if (field.getType().isArray()) {
82  			return ((Object[]) value).length == 0;
83  		}
84  		if (value instanceof String) {
85  			return ((String) value).isEmpty();
86  		} else if (value instanceof Collection) {
87  			return ((Collection<?>) value).isEmpty();
88  		} else if (value instanceof Map) {
89  			return ((Map<?, ?>) value).isEmpty();
90  		}
91  		return false;
92  	}
93  
94  	/**
95  	 * 指定された Java プログラム要素のフィールド値が空でないかどうかを返します。
96  	 * 
97  	 * @param bean Java プログラム要素
98  	 * @param name フィールド名
99  	 * @return 指定された Java プログラム要素のフィールド値が空でない場合は <code>true</code> それ以外の場合は <code>false</code>
100 	 * @throws IOException フィールド操作で例外が発生した場合
101 	 */
102 	public static boolean isNotEmpty(final Object bean, final String name) throws IOException {
103 		return !isEmpty(bean, name);
104 	}
105 
106 	// ------------------------------------------------------------------------
107 
108 	/**
109 	 * 指定された Java プログラム要素のフィールド値が判定基準値と等しいかどうかを返します。
110 	 * 
111 	 * @param bean Java プログラム要素
112 	 * @param name フィールド名
113 	 * @param criteria 判定基準値
114 	 * @param ignoreCase 大文字と小文字を区別するかどうか
115 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値と等しい場合は <code>true</code> それ以外の場合は <code>false</code>
116 	 * @throws IOException フィールド操作で例外が発生した場合
117 	 */
118 	public static boolean eq(final Object bean, final String name, final Object criteria, final boolean ignoreCase) throws IOException {
119 		final Object value = getFieldValue(bean, name);
120 		if (criteria == null) {
121 			throw new IllegalArgumentException("Criteria must not be null");
122 		}
123 		if (ignoreCase) {
124 			return value != null && ((String) criteria).equalsIgnoreCase((String) value);
125 		}
126 		return criteria.equals(value);
127 	}
128 
129 	/**
130 	 * 指定された Java プログラム要素のフィールド値が判定基準値と等しくないかどうかを返します。
131 	 * 
132 	 * @param bean Java プログラム要素
133 	 * @param name フィールド名
134 	 * @param criteria 判定基準値
135 	 * @param ignoreCase 大文字と小文字を区別するかどうか
136 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値と等しくない場合は <code>true</code> それ以外の場合は <code>false</code>
137 	 * @throws IOException フィールド操作で例外が発生した場合
138 	 */
139 	public static boolean ne(final Object bean, final String name, final Object criteria, final boolean ignoreCase) throws IOException {
140 		return !eq(bean, name, criteria, ignoreCase);
141 	}
142 
143 	/**
144 	 * 指定された Java プログラム要素のフィールド値が判定基準値群のいずれかと等しいかどうかを返します。
145 	 * 
146 	 * @param bean Java プログラム要素
147 	 * @param name フィールド名
148 	 * @param criterias 判定基準値群
149 	 * @param ignoreCase 大文字と小文字を区別するかどうか
150 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値群のいずれかと等しい場合は <code>true</code> それ以外の場合は <code>false</code>
151 	 * @throws IOException フィールド操作で例外が発生した場合
152 	 */
153 	public static boolean in(final Object bean, final String name, final Object[] criterias, final boolean ignoreCase) throws IOException {
154 		if (criterias == null) {
155 			throw new IllegalArgumentException("Criterias must not be null");
156 		}
157 		for (final Object criteria : criterias) {
158 			if (eq(bean, name, criteria, ignoreCase)) {
159 				return true;
160 			}
161 		}
162 		return false;
163 	}
164 
165 	/**
166 	 * 指定された Java プログラム要素のフィールド値が判定基準値群のいずれとも等しくないかどうかを返します。
167 	 * 
168 	 * @param bean Java プログラム要素
169 	 * @param name フィールド名
170 	 * @param criterias 判定基準値群
171 	 * @param ignoreCase 大文字と小文字を区別するかどうか
172 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値群のいずれとも等しくない場合は <code>true</code> それ以外の場合は <code>false</code>
173 	 * @throws IOException フィールド操作で例外が発生した場合
174 	 */
175 	public static boolean notIn(final Object bean, final String name, final Object[] criterias, final boolean ignoreCase) throws IOException {
176 		return !in(bean, name, criterias, ignoreCase);
177 	}
178 
179 	// ------------------------------------------------------------------------
180 
181 	/**
182 	 * 指定された Java プログラム要素のフィールド値が正規表現パターンとマッチするかどうかを返します。
183 	 * 
184 	 * @param bean Java プログラム要素
185 	 * @param name フィールド名
186 	 * @param pattern 判定する正規表現パターン
187 	 * @return 指定された Java プログラム要素のフィールド値が正規表現パターンとマッチする場合は <code>true</code> それ以外の場合は <code>false</code>
188 	 * @throws IOException フィールド操作で例外が発生した場合
189 	 */
190 	public static boolean regex(final Object bean, final String name, final Pattern pattern) throws IOException {
191 		final Object value = getFieldValue(bean, name);
192 		return value != null && pattern.matcher((CharSequence) value).matches();
193 	}
194 
195 	// ------------------------------------------------------------------------
196 
197 	/**
198 	 * 指定された Java プログラム要素のフィールド値が判定基準値よりも大きいかどうかを返します。<p>
199 	 * この実装は、コンパレータが指定されている場合はコンパレータを使用して比較を行います。
200 	 * 
201 	 * @param bean Java プログラム要素
202 	 * @param name フィールド名
203 	 * @param criteria 判定基準値
204 	 * @param comparator コンパレータ (オプション)
205 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値よりも大きい場合は <code>true</code> それ以外の場合は <code>false</code>
206 	 * @throws IOException フィールド操作で例外が発生した場合
207 	 */
208 	@SuppressWarnings({ "unchecked", "rawtypes" })
209 	public static boolean gt(final Object bean, final String name, final Object criteria, final Comparator comparator) throws IOException {
210 		final Object value = getFieldValue(bean, name);
211 		if (comparator != null) {
212 			return value != null && criteria != null && comparator.compare(value, criteria) > 0;
213 		}
214 		return value != null && criteria != null && ((Comparable) value).compareTo(criteria) > 0;
215 	}
216 
217 	/**
218 	 * 指定された Java プログラム要素のフィールド値が判定基準値よりも小さいかどうかを返します。<p>
219 	 * この実装は、コンパレータが指定されている場合はコンパレータを使用して比較を行います。
220 	 * 
221 	 * @param bean Java プログラム要素
222 	 * @param name フィールド名
223 	 * @param criteria 判定基準値
224 	 * @param comparator コンパレータ (オプション)
225 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値よりも小さい場合は <code>true</code> それ以外の場合は <code>false</code>
226 	 * @throws IOException フィールド操作で例外が発生した場合
227 	 */
228 	@SuppressWarnings({ "unchecked", "rawtypes" })
229 	public static boolean lt(final Object bean, final String name, final Object criteria, final Comparator comparator) throws IOException {
230 		final Object value = getFieldValue(bean, name);
231 		if (comparator != null) {
232 			return value != null && criteria != null && comparator.compare(value, criteria) < 0;
233 		}
234 		return value != null && criteria != null && ((Comparable) value).compareTo(criteria) < 0;
235 	}
236 
237 	/**
238 	 * 指定された Java プログラム要素のフィールド値が判定基準値以上かどうかを返します。<p>
239 	 * この実装は、コンパレータが指定されている場合はコンパレータを使用して比較を行います。
240 	 * 
241 	 * @param bean Java プログラム要素
242 	 * @param name フィールド名
243 	 * @param criteria 判定基準値
244 	 * @param comparator コンパレータ (オプション)
245 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値以上の場合は <code>true</code> それ以外の場合は <code>false</code>
246 	 * @throws IOException フィールド操作で例外が発生した場合
247 	 */
248 	@SuppressWarnings({ "unchecked", "rawtypes" })
249 	public static boolean ge(final Object bean, final String name, final Object criteria, final Comparator comparator) throws IOException {
250 		final Object value = getFieldValue(bean, name);
251 		if (comparator != null) {
252 			return value != null && criteria != null && comparator.compare(value, criteria) >= 0;
253 		}
254 		return value != null && criteria != null && ((Comparable) value).compareTo(criteria) >= 0;
255 	}
256 
257 	/**
258 	 * 指定された Java プログラム要素のフィールド値が判定基準値以下かどうかを返します。<p>
259 	 * この実装は、コンパレータが指定されている場合はコンパレータを使用して比較を行います。
260 	 * 
261 	 * @param bean Java プログラム要素
262 	 * @param name フィールド名
263 	 * @param criteria 判定基準値
264 	 * @param comparator コンパレータ (オプション)
265 	 * @return 指定された Java プログラム要素のフィールド値が判定基準値以下の場合は <code>true</code> それ以外の場合は <code>false</code>
266 	 * @throws IOException フィールド操作で例外が発生した場合
267 	 */
268 	@SuppressWarnings({ "unchecked", "rawtypes" })
269 	public static boolean le(final Object bean, final String name, final Object criteria, final Comparator comparator) throws IOException {
270 		final Object value = getFieldValue(bean, name);
271 		if (comparator != null) {
272 			return value != null && criteria != null && comparator.compare(value, criteria) <= 0;
273 		}
274 		return value != null && criteria != null && ((Comparable) value).compareTo(criteria) <= 0;
275 	}
276 
277 	/**
278 	 * 指定された Java プログラム要素のフィールド値が下限値から上限値の範囲かどうかを返します。<p>
279 	 * この実装は、コンパレータが指定されている場合はコンパレータを使用して比較を行います。
280 	 * 
281 	 * @param bean Java プログラム要素
282 	 * @param name フィールド名
283 	 * @param low 下限値
284 	 * @param high 上限値
285 	 * @param comparator コンパレータ (オプション)
286 	 * @return 指定された Java プログラム要素のフィールド値が下限値から上限値の範囲の場合は <code>true</code> それ以外の場合は <code>false</code>
287 	 * @throws IOException フィールド操作で例外が発生した場合
288 	 */
289 	@SuppressWarnings("rawtypes")
290 	public static boolean between(final Object bean, final String name, final Object low, final Object high, final Comparator comparator) throws IOException {
291 		return ge(bean, name, low, comparator) && le(bean, name, high, comparator);
292 	}
293 
294 	/**
295 	 * 指定された Java プログラム要素について、指定されたフィールド名によって表されるフィールドの値を返します。
296 	 * プリミティブ型の場合、オブジェクト内に自動的に格納されてから返されます。
297 	 * 
298 	 * @param bean Java プログラム要素
299 	 * @param name フィールド名
300 	 * @return Java プログラム要素 <code>bean</code> 内で表現される値。プリミティブ値は適切なオブジェクト内にラップされてから返される
301 	 * @throws IOException 基本となるフィールドにアクセスできない場合。指定されたオブジェクトが基本となるフィールド (またはそのサブクラスか実装側) を宣言するクラスまたはインタフェースのインスタンスではない場合
302 	 * @throws NullPointerException 指定されたオブジェクトが null で、フィールドがインスタンスフィールドの場合
303 	 * @throws SecurityException 
304 	 */
305 	private static Object getFieldValue(final Object bean, final String name) throws IOException {
306 		return FieldUtils.getFieldValue(bean, FieldUtils.getField(bean.getClass(), name));
307 	}
308 
309 }