package sample.model.account;
import java.util.*;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import org.springframework.security.crypto.password.PasswordEncoder;
import lombok.*;
import sample.ValidationException;
import sample.ValidationException.ErrorKeys;
import sample.context.Dto;
import sample.context.actor.Actor;
import sample.context.actor.Actor.ActorRoleType;
import sample.context.orm.*;
import sample.model.account.type.AccountStatusType;
import sample.model.constraints.*;
import sample.util.Validator;
/**
* 口座を表現します。
* low: サンプル用に必要最低限の項目だけ
*/
@Entity
@Data
@EqualsAndHashCode(callSuper = false)
public class Account extends OrmActiveRecord<Account> {
private static final long serialVersionUID = 1L;
/** 口座ID */
@Id
@IdStr
private String id;
/** 口座名義 */
@Name
private String name;
/** メールアドレス */
@Email
private String mail;
/** 口座状態 */
@NotNull
@Enumerated(EnumType.STRING)
private AccountStatusType statusType;
public Actor actor() {
return new Actor(id, name, ActorRoleType.User);
}
/** 口座に紐付くログイン情報を取得します。 */
public Login loadLogin(final OrmRepository rep) {
return Login.load(rep, id);
}
/** 口座を変更します。 */
public Account change(final OrmRepository rep, final ChgAccount p) {
return p.bind(this).update(rep);
}
/** 口座を取得します。 */
public static Optional<Account> get(final OrmRepository rep, String id) {
return rep.get(Account.class, id);
}
/** 有効な口座を取得します。 */
public static Optional<Account> getValid(final OrmRepository rep, String id) {
return get(rep, id).filter((acc) -> acc.getStatusType().valid());
}
/** 口座を取得します。(例外付) */
public static Account load(final OrmRepository rep, String id) {
return rep.load(Account.class, id);
}
/** 有効な口座を取得します。(例外付) */
public static Account loadValid(final OrmRepository rep, String id) {
return getValid(rep, id).orElseThrow(() -> new ValidationException("error.Account.loadValid"));
}
/**
* 口座の登録を行います。
* <p>ログイン情報も同時に登録されます。
*/
public static Account register(final OrmRepository rep, final PasswordEncoder encoder, final RegAccount p) {
Validator.validate((v) -> v.checkField(!get(rep, p.id).isPresent(), "id", ErrorKeys.DuplicateId));
p.createLogin(encoder.encode(p.plainPassword)).save(rep);
return p.create().save(rep);
}
/** 登録パラメタ */
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class RegAccount implements Dto {
private static final long serialVersionUID = 1l;
@IdStr
private String id;
@Name
private String name;
@Email
private String mail;
/** パスワード(未ハッシュ) */
@Password
private String plainPassword;
public Account create() {
Account m = new Account();
m.setId(id);
m.setName(name);
m.setMail(mail);
m.setStatusType(AccountStatusType.Normal);
return m;
}
public Login createLogin(String password) {
Login m = new Login();
m.setId(id);
m.setLoginId(id);
m.setPassword(password);
return m;
}
}
/** 変更パラメタ */
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ChgAccount implements Dto {
private static final long serialVersionUID = 1l;
@Name
private String name;
@Email
private String mail;
public Account bind(final Account m) {
m.setName(name);
m.setMail(mail);
return m;
}
}
}