diff --git a/agent/src/main/java/li/strolch/service/api/ServiceResult.java b/agent/src/main/java/li/strolch/service/api/ServiceResult.java index f90c18a47..94d681da1 100644 --- a/agent/src/main/java/li/strolch/service/api/ServiceResult.java +++ b/agent/src/main/java/li/strolch/service/api/ServiceResult.java @@ -24,6 +24,7 @@ import java.util.Locale; import java.util.ResourceBundle; import com.google.gson.JsonObject; +import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchUserMessageException; import li.strolch.model.Tags; import li.strolch.model.i18n.I18nMessageToJsonVisitor; @@ -229,10 +230,8 @@ public class ServiceResult { json.addProperty(EXCEPTION_MSG, getExceptionMessageWithCauses(this.throwable, false)); json.addProperty(THROWABLE, formatException(this.throwable)); - if (this.throwable instanceof StrolchUserMessageException - && ((StrolchUserMessageException) this.throwable).hasI18n()) - json.add(I_18_N, ((StrolchUserMessageException) this.throwable).getI18n() - .accept(new I18nMessageToJsonVisitor())); + if (this.throwable instanceof StrolchException ex && ex.hasI18n()) + json.add(I_18_N, ex.getI18n().accept(new I18nMessageToJsonVisitor())); } if (!json.has(I_18_N) && this.i18nMessage != null) diff --git a/model/src/main/java/li/strolch/exception/StrolchAccessDeniedException.java b/model/src/main/java/li/strolch/exception/StrolchAccessDeniedException.java index dfd965f94..7f7567d8f 100644 --- a/model/src/main/java/li/strolch/exception/StrolchAccessDeniedException.java +++ b/model/src/main/java/li/strolch/exception/StrolchAccessDeniedException.java @@ -26,14 +26,12 @@ public class StrolchAccessDeniedException extends StrolchException { private final Certificate certificate; private final Restrictable restrictable; - private final I18nMessage i18n; public StrolchAccessDeniedException(Certificate certificate, Restrictable restrictable, I18nMessage i18n, Throwable cause) { - super(i18n.getMessage(), cause); + super(i18n, cause); this.certificate = certificate; this.restrictable = restrictable; - this.i18n = i18n; } public Certificate getCertificate() { @@ -43,8 +41,4 @@ public class StrolchAccessDeniedException extends StrolchException { public Restrictable getRestrictable() { return restrictable; } - - public I18nMessage getI18n() { - return this.i18n; - } } diff --git a/model/src/main/java/li/strolch/exception/StrolchException.java b/model/src/main/java/li/strolch/exception/StrolchException.java index 981ccd7fb..e5a717238 100644 --- a/model/src/main/java/li/strolch/exception/StrolchException.java +++ b/model/src/main/java/li/strolch/exception/StrolchException.java @@ -15,16 +15,17 @@ */ package li.strolch.exception; -import java.util.Locale; - import li.strolch.utils.I18nMessage; +import java.util.Locale; +import java.util.ResourceBundle; + /** * @author Robert von Burg */ public class StrolchException extends RuntimeException { - private I18nMessage i18n; + protected I18nMessage i18n; public StrolchException(String message, Throwable cause) { super(message, cause); @@ -36,6 +37,41 @@ public class StrolchException extends RuntimeException { public StrolchException(I18nMessage i18n) { super(i18n.getMessage(Locale.getDefault())); + this.i18n = i18n; + if (i18n.hasException()) + initCause(i18n.getException()); + } + + public StrolchException(I18nMessage i18n, Throwable cause) { + super(i18n.getMessage(Locale.getDefault()), cause); + this.i18n = i18n; + } + + public StrolchException(ResourceBundle bundle, String key) { + this(new I18nMessage(bundle, key)); + } + + public StrolchException(ResourceBundle bundle, String key, String prop, Object value) { + this(new I18nMessage(bundle, key).value(prop, value)); + } + + public StrolchException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, + Object value2) { + this(new I18nMessage(bundle, key).value(prop1, value1).value(prop2, value2)); + } + + public StrolchException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, Object value2, + String prop3, Object value3) { + this(new I18nMessage(bundle, key).value(prop1, value1).value(prop2, value2).value(prop3, value3)); + } + + public StrolchException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, Object value2, + String prop3, Object value3, String prop4, Object value4) { + this(new I18nMessage(bundle, key) + .value(prop1, value1) + .value(prop2, value2) + .value(prop3, value3) + .value(prop4, value4)); } public boolean hasI18n() { @@ -54,4 +90,9 @@ public class StrolchException extends RuntimeException { this.i18n = i18n; return this; } + + public StrolchException cause(Throwable cause) { + initCause(cause); + return this; + } } diff --git a/model/src/main/java/li/strolch/exception/StrolchUserMessageException.java b/model/src/main/java/li/strolch/exception/StrolchUserMessageException.java index ee4dccf9f..3d56a65df 100644 --- a/model/src/main/java/li/strolch/exception/StrolchUserMessageException.java +++ b/model/src/main/java/li/strolch/exception/StrolchUserMessageException.java @@ -1,78 +1,40 @@ package li.strolch.exception; +import li.strolch.utils.I18nMessage; + import java.util.Locale; import java.util.ResourceBundle; -import li.strolch.utils.I18nMessage; - public class StrolchUserMessageException extends StrolchException { - private I18nMessage i18n; - public StrolchUserMessageException(I18nMessage i18n) { - super(i18n.getMessage(Locale.getDefault())); - this.i18n = i18n; - if (i18n.hasException()) - initCause(i18n.getException()); + super(i18n); } public StrolchUserMessageException(I18nMessage i18n, Throwable cause) { - super(i18n.getMessage(Locale.getDefault()), cause); - this.i18n = i18n; + super(i18n, cause); } public StrolchUserMessageException(ResourceBundle bundle, String key) { - this(new I18nMessage(bundle, key)); + super(bundle, key); } public StrolchUserMessageException(ResourceBundle bundle, String key, String prop, Object value) { - this(new I18nMessage(bundle, key) // - .value(prop, value)); + super(bundle, key, prop, value); } public StrolchUserMessageException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, Object value2) { - this(new I18nMessage(bundle, key) // - .value(prop1, value1) // - .value(prop2, value2)); + super(bundle, key, prop1, value1, prop2, value2); } public StrolchUserMessageException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, Object value2, String prop3, Object value3) { - this(new I18nMessage(bundle, key) // - .value(prop1, value1) // - .value(prop2, value2) // - .value(prop3, value3)); + super(bundle, key, prop1, value1, prop2, value2, prop3, value3); } public StrolchUserMessageException(ResourceBundle bundle, String key, String prop1, Object value1, String prop2, Object value2, String prop3, Object value3, String prop4, Object value4) { - this(new I18nMessage(bundle, key) // - .value(prop1, value1) // - .value(prop2, value2) // - .value(prop3, value3) // - .value(prop4, value4)); - } - - public StrolchUserMessageException cause(Throwable cause) { - initCause(cause); - return this; - } - - public boolean hasI18n() { - return this.i18n != null; - } - - public I18nMessage getI18n() { - return this.i18n; - } - - public void setI18n(I18nMessage i18n) { - this.i18n = i18n; - } - - public StrolchUserMessageException i18n(I18nMessage i18n) { - this.i18n = i18n; - return this; + super(bundle, key, prop1, value1, prop2, value2, prop3, value3, prop4, value4); } } diff --git a/utils/src/main/java/li/strolch/utils/helper/ExceptionHelper.java b/utils/src/main/java/li/strolch/utils/helper/ExceptionHelper.java index a90f3a999..ef185bb62 100644 --- a/utils/src/main/java/li/strolch/utils/helper/ExceptionHelper.java +++ b/utils/src/main/java/li/strolch/utils/helper/ExceptionHelper.java @@ -40,7 +40,8 @@ public class ExceptionHelper { public static String getCallerMethod(int depth) { return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE) // - .walk(frames -> frames.map((StackWalker.StackFrame sf) -> sf.getClassName() + "." + sf.getMethodName()) + .walk(frames -> frames + .map((StackWalker.StackFrame sf) -> sf.getClassName() + "." + sf.getMethodName()) .skip(depth) .findFirst()).orElse("UnknownClass.unknownMethod!"); } @@ -61,8 +62,7 @@ public class ExceptionHelper { * in such a case *

* - * @param t - * the {@link Throwable} + * @param t the {@link Throwable} * * @return the exception as string */ @@ -80,11 +80,9 @@ public class ExceptionHelper { * in such a case *

* - * @param t - * the {@link Throwable} - * @param withClassName - * if true, then exception class name is prepended to the exception message, if the exception message is null, - * then this param is ignored + * @param t the {@link Throwable} + * @param withClassName if true, then exception class name is prepended to the exception message, if the exception + * message is null, then this param is ignored * * @return the exception as string */ @@ -104,8 +102,7 @@ public class ExceptionHelper { * in such a case *

* - * @param t - * the {@link Throwable} + * @param t the {@link Throwable} * * @return the exception as string */ @@ -123,15 +120,15 @@ public class ExceptionHelper { * in such a case *

* - * @param t - * the {@link Throwable} - * @param withClassName - * if true, then exception class name is prepended to the exception message, if the exception message is null, - * then this param is ignored + * @param t the {@link Throwable} + * @param withClassName if true, then exception class name is prepended to the exception message, if the exception + * message is null, then this param is ignored * * @return the exception as string */ public static String getExceptionMessageWithCauses(Throwable t, boolean withClassName) { + if (t == null) + return "(null)"; if (t.getCause() == null) return getExceptionMessage(t, withClassName); @@ -142,13 +139,12 @@ public class ExceptionHelper { /** * Formats the given {@link Throwable}'s stack trace to a string * - * @param t - * the throwable for which the stack trace is to be formatted to string + * @param t the throwable for which the stack trace is to be formatted to string * * @return a string representation of the given {@link Throwable}'s stack trace */ public static String formatException(Throwable t) { - String ls = System.getProperty(PROP_LINE_SEPARATOR); + String ls = System.lineSeparator(); if (!ls.equals(UNIX_LINE_SEP)) System.setProperty(PROP_LINE_SEPARATOR, UNIX_LINE_SEP); try { @@ -165,8 +161,7 @@ public class ExceptionHelper { /** * Formats the given {@link Throwable}'s message including causes to a string * - * @param t - * the throwable for which the messages are to be formatted to a string + * @param t the throwable for which the messages are to be formatted to a string * * @return a string representation of the given {@link Throwable}'s messages including causes */ @@ -177,11 +172,9 @@ public class ExceptionHelper { /** * Formats the given {@link Throwable}'s message including causes to a string * - * @param t - * the throwable for which the messages are to be formatted to a string - * @param withClassName - * if true, then exception class name is prepended to the exception message, if the exception message is null, * - * then this param is ignored + * @param t the throwable for which the messages are to be formatted to a string + * @param withClassName if true, then exception class name is prepended to the exception message, if the exception + * message is null, * then this param is ignored * * @return a string representation of the given {@link Throwable}'s messages including causes */ @@ -196,8 +189,7 @@ public class ExceptionHelper { /** * Returns the root cause for the given {@link Throwable} * - * @param throwable - * the {@link Throwable} for which to get the root cause + * @param throwable the {@link Throwable} for which to get the root cause * * @return the root cause of the given {@link Throwable} */ @@ -213,8 +205,7 @@ public class ExceptionHelper { /** * Returns {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable} * - * @param throwable - * the throwable for which to get the message of the root cause + * @param throwable the throwable for which to get the message of the root cause * * @return {@link #getExceptionMessage(Throwable, boolean)} for the root cause of the given {@link Throwable} */ @@ -225,8 +216,7 @@ public class ExceptionHelper { /** * Walks the causes for the given {@link Throwable} and sees if the given cause exists * - * @param throwable - * the {@link Throwable} for which to find the given cause type + * @param throwable the {@link Throwable} for which to find the given cause type * * @return true if the cause was found, false if not */ diff --git a/web-rest/src/main/java/li/strolch/rest/helper/ResponseUtil.java b/web-rest/src/main/java/li/strolch/rest/helper/ResponseUtil.java index 6b4c85771..0db7a0873 100644 --- a/web-rest/src/main/java/li/strolch/rest/helper/ResponseUtil.java +++ b/web-rest/src/main/java/li/strolch/rest/helper/ResponseUtil.java @@ -8,6 +8,7 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response.Status; import li.strolch.exception.StrolchElementNotFoundException; +import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchNotAuthenticatedException; import li.strolch.exception.StrolchUserMessageException; import li.strolch.model.i18n.I18nMessageToJsonVisitor; @@ -139,34 +140,24 @@ public class ResponseUtil { if (svcResult.isOk()) return Response.ok().entity(json).type(MediaType.APPLICATION_JSON).build(); - Status status; - if (t instanceof AccessDeniedException) { - status = Status.FORBIDDEN; - } else if (t instanceof PrivilegeModelException) { - status = Status.INTERNAL_SERVER_ERROR; - } else if (t instanceof PrivilegeException) { - status = Status.UNAUTHORIZED; - } else if (t instanceof StrolchElementNotFoundException) { - status = Status.NOT_FOUND; - } else { - status = Status.INTERNAL_SERVER_ERROR; - } + Status status = switch (t) { + case AccessDeniedException ignored -> Status.FORBIDDEN; + case PrivilegeException ignored -> Status.UNAUTHORIZED; + case StrolchElementNotFoundException ignored -> Status.NOT_FOUND; + case null, default -> Status.INTERNAL_SERVER_ERROR; + }; return Response.status(status).entity(json).type(MediaType.APPLICATION_JSON).build(); } public static Response toResponse(Throwable t) { - if (t instanceof StrolchNotAuthenticatedException) - return ResponseUtil.toResponse(Status.UNAUTHORIZED, t); - if (t instanceof AccessDeniedException) - return ResponseUtil.toResponse(Status.FORBIDDEN, t); - if (t instanceof StrolchElementNotFoundException) - return ResponseUtil.toResponse(Status.NOT_FOUND, t); - if (t instanceof PrivilegeModelException) - return ResponseUtil.toResponse(Status.INTERNAL_SERVER_ERROR, t); - if (t instanceof PrivilegeException) - return ResponseUtil.toResponse(Status.FORBIDDEN, t); - return toResponse(Status.INTERNAL_SERVER_ERROR, t); + return switch (t) { + case StrolchNotAuthenticatedException ignored -> toResponse(Status.UNAUTHORIZED, t); + case AccessDeniedException ignored -> toResponse(Status.FORBIDDEN, t); + case StrolchElementNotFoundException ignored -> toResponse(Status.NOT_FOUND, t); + case PrivilegeException ignored -> toResponse(Status.FORBIDDEN, t); + case null, default -> toResponse(Status.INTERNAL_SERVER_ERROR, t); + }; } public static Response toResponse(Status status, String msg) { @@ -180,13 +171,13 @@ public class ResponseUtil { public static Response toResponse(Status status, Throwable t) { JsonObject response = new JsonObject(); - if (t instanceof StrolchUserMessageException ex && ((StrolchUserMessageException) t).hasI18n()) { - response.add("i18n", ex.getI18n().accept(new I18nMessageToJsonVisitor())); - } else { - Throwable rootCause = getRootCause(t); - if (rootCause instanceof StrolchUserMessageException ex && - ((StrolchUserMessageException) rootCause).hasI18n()) { - response.add("i18n", ex.getI18n().accept(new I18nMessageToJsonVisitor())); + switch (t) { + case StrolchException ex when ex.hasI18n() -> + response.add("i18n", ex.getI18n().accept(new I18nMessageToJsonVisitor())); + case null, default -> { + Throwable rootCause = getRootCause(t); + if (rootCause instanceof StrolchUserMessageException ex && ex.hasI18n()) + response.add("i18n", ex.getI18n().accept(new I18nMessageToJsonVisitor())); } }