AbstractWhere.java
package com.github.mygreen.sqlmapper.core.where.simple;
import java.util.ArrayList;
import java.util.List;
import com.github.mygreen.sqlmapper.core.where.Where;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
/**
* 項を保持する機能を提供します。
*
*
* @author T.TSUCHIE
*
* @param <T> 実装先のクラス。
*/
public abstract class AbstractWhere<T extends AbstractWhere<T>> implements Where {
/**
* 項のリスト。
* 式としては{@literal AND}条件で結合されます。
*
*/
@Getter(AccessLevel.PROTECTED)
protected final List<Term> terms = new ArrayList<>();
/**
* 式を追加します。
* @param exp 式を指定します。プレースホルダーとして {@literal ?}が使用可能です。
* @param values プレースホルダ―に対する値を指定します。
* @return 自身のインスタンスを返します。
* @throws IllegalArgumentException 指定した値の個数と式中のプレースホルダーの個数が一致しないときにスローされます。
*/
@SuppressWarnings("unchecked")
public T exp(@NonNull final String exp, final Object... values) {
// 式中にプレースホルダーが存在するかチェックする。
final int expCount = countChar(exp, '?');
final int valueCount = values == null ? 0 : values.length;
if(expCount != valueCount) {
String message = String.format("exp not containing the number of placeholder '?'."
+ "exp=[%s]."
+ " count of in exp = %d, count of value = %d"
, exp, expCount, valueCount);
throw new IllegalArgumentException(message);
}
addTerm(new Exp(exp, values));
return (T)this;
}
/**
* 指定した文字数をカウントします。
* @param text 検索対象の文字列
* @param c 検索する文字
* @return 文字数
*/
private static int countChar(final String text, final char c) {
if(text == null || text.isEmpty()) {
return 0;
}
int index = 0;
int count = 0;
int length = text.length();
while(length > index) {
index = text.indexOf(c, index) + 1;
if (index == 0) {
break;
}
count++;
}
return count;
}
/**
* 項を追加します。
* @param term 追加する項
*/
protected void addTerm(Term term) {
this.terms.add(term);
}
/**
* 現在のインスタンスを{@link SimpleWhere} として取り出します。
* <p>取り出したときには現在の条件式の情報はクリアされます。</p>
* @return 現在のインスタンスを{@link SimpleWhere}
*/
protected Where putAsSimpleWhere() {
final SimpleWhere where = new SimpleWhere();
where.terms.addAll(getTerms());
this.terms.clear();
return where;
}
}