Browse Source

fix #1774 improve validation error handling

Shinsuke Sugaya 7 years ago
parent
commit
4f3142ccc6

+ 15 - 3
src/main/java/org/codelibs/fess/app/web/admin/dict/kuromoji/AdminDictKuromojiAction.java

@@ -29,6 +29,7 @@ import org.codelibs.fess.app.service.KuromojiService;
 import org.codelibs.fess.app.web.CrudMode;
 import org.codelibs.fess.app.web.admin.dict.AdminDictAction;
 import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.app.web.base.FessBaseAction;
 import org.codelibs.fess.dict.kuromoji.KuromojiItem;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.RenderDataUtil;
@@ -39,6 +40,8 @@ import org.lastaflute.web.response.ActionResponse;
 import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.response.render.RenderData;
 import org.lastaflute.web.ruts.process.ActionRuntime;
+import org.lastaflute.web.validation.VaErrorHook;
+import org.lastaflute.web.validation.exception.ValidationErrorException;
 
 /**
  * @author shinsuke
@@ -269,7 +272,7 @@ public class AdminDictKuromojiAction extends FessAdminAction {
         verifyCrudMode(form.crudMode, CrudMode.CREATE, form.dictId);
         validate(form, messages -> {}, () -> asEditHtml());
         verifyToken(() -> asEditHtml());
-        createKuromojiItem(form).ifPresent(
+        createKuromojiItem(form, () -> asEditHtml()).ifPresent(
                 entity -> {
                     try {
                         kuromojiService.store(form.dictId, entity);
@@ -289,7 +292,7 @@ public class AdminDictKuromojiAction extends FessAdminAction {
         verifyCrudMode(form.crudMode, CrudMode.EDIT, form.dictId);
         validate(form, messages -> {}, () -> asEditHtml());
         verifyToken(() -> asEditHtml());
-        createKuromojiItem(form).ifPresent(
+        createKuromojiItem(form, () -> asEditHtml()).ifPresent(
                 entity -> {
                     try {
                         kuromojiService.store(form.dictId, entity);
@@ -349,7 +352,16 @@ public class AdminDictKuromojiAction extends FessAdminAction {
         return OptionalEntity.empty();
     }
 
-    public static OptionalEntity<KuromojiItem> createKuromojiItem(final CreateForm form) {
+    protected OptionalEntity<KuromojiItem> createKuromojiItem(final CreateForm form, final VaErrorHook hook) {
+        try {
+            return createKuromojiItem(this, form, hook);
+        } catch (final ValidationErrorException e) {
+            saveToken();
+            throw e;
+        }
+    }
+
+    public static OptionalEntity<KuromojiItem> createKuromojiItem(final FessBaseAction action, final CreateForm form, final VaErrorHook hook) {
         return getEntity(form).map(entity -> {
             entity.setNewToken(form.token);
             entity.setNewSegmentation(form.segmentation);

+ 19 - 6
src/main/java/org/codelibs/fess/app/web/admin/dict/mapping/AdminDictMappingAction.java

@@ -31,6 +31,7 @@ import org.codelibs.fess.app.service.CharMappingService;
 import org.codelibs.fess.app.web.CrudMode;
 import org.codelibs.fess.app.web.admin.dict.AdminDictAction;
 import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.app.web.base.FessBaseAction;
 import org.codelibs.fess.dict.mapping.CharMappingItem;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.RenderDataUtil;
@@ -42,6 +43,7 @@ import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.response.render.RenderData;
 import org.lastaflute.web.ruts.process.ActionRuntime;
 import org.lastaflute.web.validation.VaErrorHook;
+import org.lastaflute.web.validation.exception.ValidationErrorException;
 
 /**
  * @author nullpos
@@ -337,7 +339,7 @@ public class AdminDictMappingAction extends FessAdminAction {
     //                                                                        Assist Logic
     //                                                                        ============
 
-    private OptionalEntity<CharMappingItem> getEntity(final CreateForm form) {
+    private static OptionalEntity<CharMappingItem> getEntity(final CreateForm form) {
         switch (form.crudMode) {
         case CrudMode.CREATE:
             final CharMappingItem entity = new CharMappingItem(0, StringUtil.EMPTY_STRINGS, StringUtil.EMPTY);
@@ -353,10 +355,20 @@ public class AdminDictMappingAction extends FessAdminAction {
         return OptionalEntity.empty();
     }
 
-    public OptionalEntity<CharMappingItem> createCharMappingItem(final CreateForm form, final VaErrorHook hook) {
+    protected OptionalEntity<CharMappingItem> createCharMappingItem(final CreateForm form, final VaErrorHook hook) {
+        try {
+            return createCharMappingItem(this, form, hook);
+        } catch (final ValidationErrorException e) {
+            saveToken();
+            throw e;
+        }
+    }
+
+    public static OptionalEntity<CharMappingItem> createCharMappingItem(final FessBaseAction action, final CreateForm form,
+            final VaErrorHook hook) {
         return getEntity(form).map(entity -> {
             final String[] newInputs = splitLine(form.inputs);
-            validateMappingString(newInputs, "inputs", hook);
+            validateMappingString(action, newInputs, "inputs", hook);
             entity.setNewInputs(newInputs);
             final String newOutput = form.output;
             entity.setNewOutput(newOutput);
@@ -375,18 +387,19 @@ public class AdminDictMappingAction extends FessAdminAction {
         }
     }
 
-    private void validateMappingString(final String[] values, final String propertyName, final VaErrorHook hook) {
+    private static void validateMappingString(final FessBaseAction action, final String[] values, final String propertyName,
+            final VaErrorHook hook) {
         if (values.length == 0) {
             return;
         }
         for (final String value : values) {
             if (value.indexOf(',') >= 0) {
-                throwValidationError(messages -> {
+                action.throwValidationError(messages -> {
                     messages.addErrorsInvalidStrIsIncluded(propertyName, value, ",");
                 }, hook);
             }
             if (value.indexOf("=>") >= 0) {
-                throwValidationError(messages -> {
+                action.throwValidationError(messages -> {
                     messages.addErrorsInvalidStrIsIncluded(propertyName, value, "=>");
                 }, hook);
             }

+ 16 - 6
src/main/java/org/codelibs/fess/app/web/admin/dict/protwords/AdminDictProtwordsAction.java

@@ -29,6 +29,7 @@ import org.codelibs.fess.app.service.ProtwordsService;
 import org.codelibs.fess.app.web.CrudMode;
 import org.codelibs.fess.app.web.admin.dict.AdminDictAction;
 import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.app.web.base.FessBaseAction;
 import org.codelibs.fess.dict.protwords.ProtwordsItem;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.RenderDataUtil;
@@ -40,6 +41,7 @@ import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.response.render.RenderData;
 import org.lastaflute.web.ruts.process.ActionRuntime;
 import org.lastaflute.web.validation.VaErrorHook;
+import org.lastaflute.web.validation.exception.ValidationErrorException;
 
 /**
  * @author ma2tani
@@ -327,10 +329,20 @@ public class AdminDictProtwordsAction extends FessAdminAction {
         return OptionalEntity.empty();
     }
 
-    public static OptionalEntity<ProtwordsItem> createProtwordsItem(final CreateForm form, final VaErrorHook hook) {
+    protected OptionalEntity<ProtwordsItem> createProtwordsItem(final CreateForm form, final VaErrorHook hook) {
+        try {
+            return createProtwordsItem(this, form, hook);
+        } catch (final ValidationErrorException e) {
+            saveToken();
+            throw e;
+        }
+    }
+
+    public static OptionalEntity<ProtwordsItem> createProtwordsItem(final FessBaseAction action, final CreateForm form,
+            final VaErrorHook hook) {
         return getEntity(form).map(entity -> {
             final String newInput = form.input;
-            validateProtwordsString(newInput, "input", hook);
+            validateProtwordsString(action, newInput, "input", hook);
             entity.setNewInput(newInput);
             return entity;
         });
@@ -347,10 +359,8 @@ public class AdminDictProtwordsAction extends FessAdminAction {
         }
     }
 
-    private static void validateProtwordsString(final String values, final String propertyName, final VaErrorHook hook) {
-        if (values.length() == 0) {
-            return;
-        }
+    private static void validateProtwordsString(final FessBaseAction action, final String values, final String propertyName,
+            final VaErrorHook hook) {
         // TODO validation
     }
 

+ 21 - 8
src/main/java/org/codelibs/fess/app/web/admin/dict/synonym/AdminDictSynonymAction.java

@@ -31,6 +31,7 @@ import org.codelibs.fess.app.service.SynonymService;
 import org.codelibs.fess.app.web.CrudMode;
 import org.codelibs.fess.app.web.admin.dict.AdminDictAction;
 import org.codelibs.fess.app.web.base.FessAdminAction;
+import org.codelibs.fess.app.web.base.FessBaseAction;
 import org.codelibs.fess.dict.synonym.SynonymItem;
 import org.codelibs.fess.util.ComponentUtil;
 import org.codelibs.fess.util.RenderDataUtil;
@@ -42,6 +43,7 @@ import org.lastaflute.web.response.HtmlResponse;
 import org.lastaflute.web.response.render.RenderData;
 import org.lastaflute.web.ruts.process.ActionRuntime;
 import org.lastaflute.web.validation.VaErrorHook;
+import org.lastaflute.web.validation.exception.ValidationErrorException;
 
 /**
  * @author shinsuke
@@ -303,6 +305,7 @@ public class AdminDictSynonymAction extends FessAdminAction {
                                 () -> asEditHtml());
                     }
                 }).orElse(() -> {
+            saveToken();
             throwValidationError(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, form.getDisplayId()), () -> asEditHtml());
         });
         return redirectWith(getClass(), moreUrl("list/1").params("dictId", form.dictId));
@@ -337,7 +340,7 @@ public class AdminDictSynonymAction extends FessAdminAction {
     //                                                                        Assist Logic
     //                                                                        ============
 
-    private OptionalEntity<SynonymItem> getEntity(final CreateForm form) {
+    private static OptionalEntity<SynonymItem> getEntity(final CreateForm form) {
         switch (form.crudMode) {
         case CrudMode.CREATE:
             final SynonymItem entity = new SynonymItem(0, StringUtil.EMPTY_STRINGS, StringUtil.EMPTY_STRINGS);
@@ -353,13 +356,22 @@ public class AdminDictSynonymAction extends FessAdminAction {
         return OptionalEntity.empty();
     }
 
-    public OptionalEntity<SynonymItem> createSynonymItem(final CreateForm form, final VaErrorHook hook) {
+    protected OptionalEntity<SynonymItem> createSynonymItem(final CreateForm form, final VaErrorHook hook) {
+        try {
+            return createSynonymItem(this, form, hook);
+        } catch (final ValidationErrorException e) {
+            saveToken();
+            throw e;
+        }
+    }
+
+    public static OptionalEntity<SynonymItem> createSynonymItem(final FessBaseAction action, final CreateForm form, final VaErrorHook hook) {
         return getEntity(form).map(entity -> {
             final String[] newInputs = splitLine(form.inputs);
-            validateSynonymString(newInputs, "inputs", hook);
+            validateSynonymString(action, newInputs, "inputs", hook);
             entity.setNewInputs(newInputs);
             final String[] newOutputs = splitLine(form.outputs);
-            validateSynonymString(newOutputs, "outputs", hook);
+            validateSynonymString(action, newOutputs, "outputs", hook);
             entity.setNewOutputs(newOutputs);
             return entity;
         });
@@ -376,25 +388,26 @@ public class AdminDictSynonymAction extends FessAdminAction {
         }
     }
 
-    private void validateSynonymString(final String[] values, final String propertyName, final VaErrorHook hook) {
+    private static void validateSynonymString(final FessBaseAction action, final String[] values, final String propertyName,
+            final VaErrorHook hook) {
         if (values.length == 0) {
             return;
         }
         for (final String value : values) {
             if (value.indexOf(',') >= 0) {
-                throwValidationError(messages -> {
+                action.throwValidationError(messages -> {
                     messages.addErrorsInvalidStrIsIncluded(propertyName, value, ",");
                 }, hook);
             }
             if (value.indexOf("=>") >= 0) {
-                throwValidationError(messages -> {
+                action.throwValidationError(messages -> {
                     messages.addErrorsInvalidStrIsIncluded(propertyName, value, "=>");
                 }, hook);
             }
         }
     }
 
-    private String[] splitLine(final String value) {
+    private static String[] splitLine(final String value) {
         if (StringUtil.isBlank(value)) {
             return StringUtil.EMPTY_STRINGS;
         }

+ 8 - 2
src/main/java/org/codelibs/fess/app/web/api/admin/dict/kuromoji/ApiAdminDictKuromojiAction.java

@@ -70,7 +70,10 @@ public class ApiAdminDictKuromojiAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.CREATE;
-        final KuromojiItem entity = createKuromojiItem(body).orElseGet(() -> {
+        final KuromojiItem entity = createKuromojiItem(this, body, () -> {
+            throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL));
+            return null;
+        }).orElseGet(() -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL));
             return null;
         });
@@ -85,7 +88,10 @@ public class ApiAdminDictKuromojiAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.EDIT;
-        final KuromojiItem entity = createKuromojiItem(body).orElseGet(() -> {
+        final KuromojiItem entity = createKuromojiItem(this, body, () -> {
+            throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, String.valueOf(body.id)));
+            return null;
+        }).orElseGet(() -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudCouldNotFindCrudTable(GLOBAL, String.valueOf(body.id)));
             return null;
         });

+ 4 - 3
src/main/java/org/codelibs/fess/app/web/api/admin/dict/mapping/ApiAdminDictMappingAction.java

@@ -15,6 +15,8 @@
  */
 package org.codelibs.fess.app.web.api.admin.dict.mapping;
 
+import static org.codelibs.fess.app.web.admin.dict.mapping.AdminDictMappingAction.createCharMappingItem;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -25,7 +27,6 @@ import javax.annotation.Resource;
 import org.codelibs.fess.app.pager.CharMappingPager;
 import org.codelibs.fess.app.service.CharMappingService;
 import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.dict.mapping.AdminDictMappingAction;
 import org.codelibs.fess.app.web.admin.dict.mapping.UploadForm;
 import org.codelibs.fess.app.web.api.ApiResult;
 import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
@@ -69,7 +70,7 @@ public class ApiAdminDictMappingAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.CREATE;
-        final CharMappingItem entity = new AdminDictMappingAction().createCharMappingItem(body, () -> {
+        final CharMappingItem entity = createCharMappingItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL));
             return null;
         }).orElseGet(() -> {
@@ -87,7 +88,7 @@ public class ApiAdminDictMappingAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.EDIT;
-        final CharMappingItem entity = new AdminDictMappingAction().createCharMappingItem(body, () -> {
+        final CharMappingItem entity = createCharMappingItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, String.valueOf(body.id)));
             return null;
         }).orElseGet(() -> {

+ 2 - 2
src/main/java/org/codelibs/fess/app/web/api/admin/dict/protwords/ApiAdminDictProtwordsAction.java

@@ -69,7 +69,7 @@ public class ApiAdminDictProtwordsAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.CREATE;
-        final ProtwordsItem entity = createProtwordsItem(body, () -> {
+        final ProtwordsItem entity = createProtwordsItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL));
             return null;
         }).orElseGet(() -> {
@@ -87,7 +87,7 @@ public class ApiAdminDictProtwordsAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.EDIT;
-        final ProtwordsItem entity = createProtwordsItem(body, () -> {
+        final ProtwordsItem entity = createProtwordsItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, String.valueOf(body.id)));
             return null;
         }).orElseGet(() -> {

+ 4 - 3
src/main/java/org/codelibs/fess/app/web/api/admin/dict/synonym/ApiAdminDictSynonymAction.java

@@ -15,6 +15,8 @@
  */
 package org.codelibs.fess.app.web.api.admin.dict.synonym;
 
+import static org.codelibs.fess.app.web.admin.dict.synonym.AdminDictSynonymAction.createSynonymItem;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -25,7 +27,6 @@ import javax.annotation.Resource;
 import org.codelibs.fess.app.pager.SynonymPager;
 import org.codelibs.fess.app.service.SynonymService;
 import org.codelibs.fess.app.web.CrudMode;
-import org.codelibs.fess.app.web.admin.dict.synonym.AdminDictSynonymAction;
 import org.codelibs.fess.app.web.admin.dict.synonym.UploadForm;
 import org.codelibs.fess.app.web.api.ApiResult;
 import org.codelibs.fess.app.web.api.admin.FessApiAdminAction;
@@ -69,7 +70,7 @@ public class ApiAdminDictSynonymAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.CREATE;
-        final SynonymItem entity = new AdminDictSynonymAction().createSynonymItem(body, () -> {
+        final SynonymItem entity = createSynonymItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateInstance(GLOBAL));
             return null;
         }).orElseGet(() -> {
@@ -87,7 +88,7 @@ public class ApiAdminDictSynonymAction extends FessApiAdminAction {
         body.dictId = dictId;
         validateApi(body, messages -> {});
         body.crudMode = CrudMode.EDIT;
-        final SynonymItem entity = new AdminDictSynonymAction().createSynonymItem(body, () -> {
+        final SynonymItem entity = createSynonymItem(this, body, () -> {
             throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToUpdateCrudTable(GLOBAL, String.valueOf(body.id)));
             return null;
         }).orElseGet(() -> {

+ 4 - 4
src/main/resources/fess_message_ja.properties

@@ -59,10 +59,10 @@ constraints.CronExpression.message = {item} は正しい CRON 表記ではあり
 # - - - - - - - - - -/
 errors.login.failure = ログインに失敗しました。
 errors.app.illegal.transition = 不正な遷移のため、再度実行してください。
-errors.app.db.already.deleted = 他の処理で削除されている可能性があります。操作を確認してください。
-errors.app.db.already.updated = 他の処理で更新されている可能性があります。操作を確認してください。
-errors.app.db.already.exists = データがすでに存在しています。操作を確認してください。
-errors.app.double.submit.request = このリクエストの前に処理されている場合があります。操作を確認してください。
+errors.app.db.already.deleted = 他の処理で削除されている可能性があります。再度、操作をやり直してください。
+errors.app.db.already.updated = 他の処理で更新されている可能性があります。再度、操作をやり直してください。
+errors.app.db.already.exists = データがすでに存在しています。再度、操作をやり直してください。
+errors.app.double.submit.request = このリクエストの前に処理されている場合があります。再度、操作をやり直してください。
 # _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 # you can define your messages here:
 # e.g.