SheetErrorFormatter.java
- package com.gh.mygreen.xlsmapper.validation;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import com.gh.mygreen.xlsmapper.localization.MessageInterpolator;
- import com.gh.mygreen.xlsmapper.localization.MessageResolver;
- import com.gh.mygreen.xlsmapper.localization.ResourceBundleMessageResolver;
- import com.gh.mygreen.xlsmapper.util.ArgUtils;
- import com.gh.mygreen.xlsmapper.util.Utils;
- /**
- * シート用のエラーオブジェクトを解釈して、メッセージに変換するクラス。
- * <p>オブジェクトの種類ごとに、デフォルトメッセージ変数が利用できます。</p>
- * <ul>
- * <li>'fieldLabel':フィールドのラベル。メッセージ用のプロパティファイルにフィールド名を定義している場合、自動的に設定されます。</li>
- * <li>'objectLabel':オブジェクトのラベル。メッセージ用のプロパティファイルにオブジェクト名を定義している場合、自動的に設定されます。</li>
- * <li>'label':ラベル変数'label'が指定されていない場合、エラー対象のオブジェクト名またはフィールド名から自動的に決定されます。</li>
- * <li>'sheetName':シート用のエラーの場合、シート名が設定されます。</li>
- * <li>'cellAddress':シート用のフィールドエラーの場合、セルのアドレスが設定されます。'A1'のような形式になります。</li>
- * </ul>
- *
- * @version 2.3
- * @since 2.0
- * @author T.TSUCHIE
- *
- */
- public class SheetErrorFormatter {
-
- private MessageResolver messageResolver = new ResourceBundleMessageResolver();
-
- private MessageInterpolator messageInterporlator = new MessageInterpolator();
-
- private MessageCodeGenerator messageCodeGenerator = new MessageCodeGenerator();
-
- /** エラーメッセージの定義が見つからないときのデフォルトのエラーコード */
- private String defaultErrorCode = "defaultError";
-
- public SheetErrorFormatter() {
-
- }
-
- /**
- * エラーオブジェクトのリストをメッセージにフォーマットする。
- * @param errors 変換対象のエラーオブジェクト。
- * @return
- * @throws IllegalArgumentException errors == null.
- */
- public List<String> format(final Collection<ObjectError> errors) {
- ArgUtils.notNull(errors, "errors");
-
- final List<String> messageList = new ArrayList<>();
- for(ObjectError error : errors) {
- messageList.add(format(error));
- }
-
- return messageList;
- }
-
- /**
- * エラーオブジェクトをメッセージにフォーマットする。
- * @param error エラーオブジェクト
- * @return メッセージ
- * @throws IllegalArgumentException {@literal error == null.}
- */
- public String format(final ObjectError error) {
- ArgUtils.notNull(error, "error");
-
- final Map<String, Object> vars = new HashMap<>();
- vars.putAll(error.getVariables());
-
- if(error instanceof FieldError) {
- // フィールドエラーのメッセージを処理する
-
- final FieldError fieldError = (FieldError) error;
- final String[] labelCode = messageCodeGenerator.generateFieldNameCodes(fieldError.getObjectName(), fieldError.getField());
-
- try {
- vars.put("fieldLabel", getMessage(labelCode, null));
- } catch(Throwable e) {
- }
-
- final Optional<String> label = error.getLabelAsOptional();
- if(label.isPresent()) {
- vars.put("label", label.get());
- } else {
- try {
- vars.put("label", getMessage(labelCode, null));
- } catch(Throwable e) {
- }
- }
-
- try {
- // 親のラベル名を取得する
- String[] parentCode = messageCodeGenerator.generateParentNameCodes(fieldError.getObjectName(), fieldError.getField());
- vars.put("parentLabel", getMessage(parentCode, null));
- } catch(Throwable e) {
- }
-
- try {
- String[] objectCode = messageCodeGenerator.generateObjectNameCodes(fieldError.getObjectName());
- vars.put("objectLabel", getMessage(objectCode, null));
- } catch(Throwable e) {
-
- }
-
- fieldError.getSheetName().ifPresent(s -> vars.put("sheetName", s));
- fieldError.getAddressAsOptional().ifPresent(a -> vars.put("cellAddress", a));
-
- } else {
- // オブジェクトエラーのメッセージを処理する。
-
- final String[] labelCode = messageCodeGenerator.generateObjectNameCodes(error.getObjectName());
-
- final Optional<String> label = error.getLabelAsOptional();
- if(label.isPresent()) {
- vars.put("label", label.get());
- } else {
- try {
- vars.put("label", getMessage(labelCode, null));
- } catch(Throwable e) {
- }
- }
-
- try {
- String[] objectCode = messageCodeGenerator.generateObjectNameCodes(error.getObjectName());
- vars.put("objectLabel", getMessage(objectCode, null));
- } catch(Throwable e) {
-
- }
-
- error.getSheetName().ifPresent(s -> vars.put("sheetName", s));
-
- }
- final String message;
- if(Utils.isEmpty(error.getCodes())) {
- // エラーコードの指定がない場合は、ユーザー指定のメッセージとして処理する。
- message = error.getDefaultMessage().orElse(defaultErrorCode);
- } else {
- message = getMessage(error.getCodes(), error.getDefaultMessage());
- }
- return messageInterporlator.interpolate(message, vars, true, messageResolver);
-
- }
-
- /**
- * 指定した引数の候補からメッセージを取得する。
- * @param codes メッセージコードの候補
- * @param defaultMessage メッセージコードが見つからない場合のメッセージ
- * @return メッセージ
- * @throws RuntimeException メッセージコード 'codes' で指定したメッセージキーが見つからない場合。
- */
- private String getMessage(final String[] codes, final Optional<String> defaultMessage) {
- for(String code : codes) {
- try {
- final Optional<String> message = messageResolver.getMessage(code);
- if(message.isPresent()) {
- return message.get();
- }
-
- } catch(Throwable e) {
- continue;
- }
- }
-
- if(defaultMessage.isPresent()) {
- return defaultMessage.get();
- }
-
- throw new RuntimeException(String.format("not found message code [%s].", Utils.join(codes, ",")));
- }
-
- public MessageResolver getMessageResolver() {
- return messageResolver;
- }
-
- public void setMessageResolver(MessageResolver messageResolver) {
- this.messageResolver = messageResolver;
- }
-
- public MessageInterpolator getMessageInterporlator() {
- return messageInterporlator;
- }
-
- public void setMessageInterporlator(MessageInterpolator messageInterporlator) {
- this.messageInterporlator = messageInterporlator;
- }
-
- public MessageCodeGenerator getMessageCodeGenerator() {
- return messageCodeGenerator;
- }
-
- public void setMessageCodeGenerator(MessageCodeGenerator messageCodeGenerator) {
- this.messageCodeGenerator = messageCodeGenerator;
- }
- }