PropertyMeta.java
package com.github.mygreen.sqlmapper.core.meta;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.Optional;
import org.springframework.util.LinkedCaseInsensitiveMap;
import com.github.mygreen.sqlmapper.core.annotation.CreatedAt;
import com.github.mygreen.sqlmapper.core.annotation.CreatedBy;
import com.github.mygreen.sqlmapper.core.annotation.EmbeddedId;
import com.github.mygreen.sqlmapper.core.annotation.GeneratedValue;
import com.github.mygreen.sqlmapper.core.annotation.Id;
import com.github.mygreen.sqlmapper.core.annotation.Lob;
import com.github.mygreen.sqlmapper.core.annotation.Transient;
import com.github.mygreen.sqlmapper.core.annotation.UpdatedAt;
import com.github.mygreen.sqlmapper.core.annotation.UpdatedBy;
import com.github.mygreen.sqlmapper.core.annotation.Version;
import com.github.mygreen.sqlmapper.core.id.IdGenerationContext;
import com.github.mygreen.sqlmapper.core.id.IdGenerator;
import com.github.mygreen.sqlmapper.core.type.ValueType;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
/**
* プロパティのメタ情報です。
*
* @author T.TSUCHIE
* @version 0.3
*
*/
public class PropertyMeta extends PropertyBase {
/**
* 埋め込み型の主キーの子プロパティかどうか。
*/
@Setter
private boolean embeddedableId = false;
/**
* 埋め込みプロパティの情報
* <p>key=プロパティ名</p>
*/
private LinkedCaseInsensitiveMap<PropertyMeta> embeddedablePropertyMetaMap = new LinkedCaseInsensitiveMap<>();
/**
* 埋め込みのときの親のプロパティ情報
*/
private Optional<PropertyMeta> parent = Optional.empty();
/**
* カラムのメタ情報
*/
@Getter
@Setter
private ColumnMeta columnMeta;
/**
* 値の変換処理
*/
@Getter
@Setter
private ValueType<?> valueType;
/**
* IDの生成タイプ
*/
@Getter
private Optional<GeneratedValue.GenerationType> idGenerationType = Optional.empty();
/**
* IDの生成処理
*/
@Getter
private Optional<IdGenerator> idGenerator = Optional.empty();
/**
* 生成対象の識別子の情報。
* <p>ID生成時に渡す際の情報として使用するので、効率化のためにここで事前に作成して保持しておく。
*/
@Getter
private Optional<IdGenerationContext> idGenerationContext = Optional.empty();
/**
* プロパティのインスタンス情報を作成します。
* @param name プロパティ名
* @param propertyType プロパティのクラスタイプ
*/
public PropertyMeta(String name, Class<?> propertyType) {
super(name, propertyType);
}
/**
* カラム用のプロパティかどうか判定する。
* @return カラム情報を持つときtrueを返す。
*/
public boolean isColumn() {
return columnMeta != null;
}
/**
* 埋め込みプロパティ情報を追加する
* @param embeddedablePropertyMeta 埋め込みプロパティ
*/
public void addEmbeddedablePropertyMeta(@NonNull PropertyMeta embeddedablePropertyMeta) {
embeddedablePropertyMeta.parent = Optional.of(this);
// 親が埋め込み主キーの時
if(hasAnnotation(EmbeddedId.class) && !isTransient()) {
embeddedablePropertyMeta.embeddedableId = true;
}
this.embeddedablePropertyMetaMap.put(embeddedablePropertyMeta.getName(), embeddedablePropertyMeta);
}
/**
* 埋め込み用のクラスのプロパティかどか判定する。
* @return 埋め込み用のクラスのプロパティの場合trueを変す。
*/
public boolean hasParent() {
return parent.isPresent();
}
/**
* 埋め込み用のクラスのプロパティの親情報を取得する。
* @return 親情のプロパティ情報
* @throws NoSuchElementException 親が存在しないときにスローされます。
*/
public PropertyMeta getParent() {
return parent.get();
}
/**
* 埋め込みプロパティの一覧を取得する。
* @return
*/
public Collection<PropertyMeta> getEmbeddedablePopertyMetaList() {
return embeddedablePropertyMetaMap.values();
}
/**
* 主キーかどうか判定する。
* <p>アノテーション {@link Id}を付与されているかどうかで判定する。</p>
* <p>また、親が{@link EmbeddedId} を付与された埋め込みIDの場合は、子も主キーとなるためtrueを返す。</p>
*
* @return 主キーの場合は {@literal true} を返す。
*/
public boolean isId() {
return hasAnnotation(Id.class) || embeddedableId;
}
/**
* 埋め込み用のプロパティかどうか判定する。
* <p>埋め込みプロパティの子の場合は、falseを返す。
* @return 埋め込みの場合trueを返す。
*/
public boolean isEmbedded() {
return hasAnnotation(EmbeddedId.class);
}
/**
* 識別子の生成タイプを設定する。
* @param generationType IDの生成タイプ
*/
public void setIdGeneratonType(GeneratedValue.GenerationType generationType) {
this.idGenerationType = Optional.ofNullable(generationType);
}
/**
* 識別子の生成処理を設定する。
* @param idGenerator 識別子の生成処理。
*/
public void setIdGenerator(IdGenerator idGenerator) {
this.idGenerator = Optional.ofNullable(idGenerator);
}
/**
* 生成対象の識別子の情報を設定する。
* @param idGenerationContext 生成対象の識別子の情報
*/
public void setIdGenerationContext(IdGenerationContext idGenerationContext) {
this.idGenerationContext = Optional.ofNullable(idGenerationContext);
}
/**
* 永続化対象外かどうか判定する。
* <p>永続化対象外とは、アノテーション {@link Transient}が付与されているか、
* または、フィールドに修飾子 {@literal transient} が付与されているかどうかで判定します。
* @return 永続化対象外のとき {@literal true} を返す。
*/
public boolean isTransient() {
return hasAnnotation(Transient.class)
|| field.map(f -> Modifier.isTransient(f.getModifiers())).orElse(false);
}
/**
* バージョンキーかどうか判定する。
* @return バージョンキーのとき {@literal true} を返す。
*/
public boolean isVersion() {
return hasAnnotation(Version.class);
}
/**
* SQLのカラムがLOB(CLOB/BLOC)かどうか判定する。
* <p>アノテーション {@link Lob} が付与されているかで判定する。</p>
* @return LOBの場合はtrueを返す。
*/
public boolean isLob() {
return hasAnnotation(Lob.class);
}
/**
* 作成日時用のプロパティがかどうか判定する。
* @return 作成日時用のプロパティのとき {@literal true} を返す。
*/
public boolean isCreatedAt() {
return hasAnnotation(CreatedAt.class);
}
/**
* 作成者用のプロパティがかどうか判定する。
* @return 作成者用のプロパティのとき {@literal true} を返す。
*/
public boolean isCreatedBy() {
return hasAnnotation(CreatedBy.class);
}
/**
* 修正日時用のプロパティがかどうか判定する。
* @return 修正日時用のプロパティのとき {@literal true} を返す。
*/
public boolean isUpdatedAt() {
return hasAnnotation(UpdatedAt.class);
}
/**
* 修正者用のプロパティがかどうか判定する。
* @return 修正者用のプロパティのとき {@literal true} を返す。
*/
public boolean isUpdatedBy() {
return hasAnnotation(UpdatedBy.class);
}
}