Fallback mechanism in case System.getLogger is not supported (e.g.
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 7 Jun 2022 10:50:29 +0000 (12:50 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 7 Jun 2022 10:50:40 +0000 (12:50 +0200)
Android).

org.argeo.api.cms/src/org/argeo/api/cms/CmsLog.java
org.argeo.api.cms/src/org/argeo/api/cms/SystemLogger.java [new file with mode: 0644]

index 3454dfc613745936247c23a93653168994b2ad02..1c88441f77a5b2febaa1bf43840760458f5f780f 100644 (file)
@@ -1,16 +1,17 @@
 package org.argeo.api.cms;
 
 import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
 import java.util.Objects;
 import java.util.function.Supplier;
 
+import org.argeo.api.cms.SystemLogger.Level;
+
 /**
  * A Commons Logging / SLF4J style logging utilities wrapping a standard Java
  * platform {@link Logger}.
  */
 public interface CmsLog {
-       Logger getLogger();
+       SystemLogger getLogger();
 
        default boolean isDebugEnabled() {
                return getLogger().isLoggable(Level.DEBUG);
@@ -181,23 +182,13 @@ public interface CmsLog {
        }
 
        static CmsLog getLog(String name) {
-               Logger logger = System.getLogger(Objects.requireNonNull(name));
-               return new LoggerWrapper(logger);
-       }
-
-       /** A trivial implementation wrapping a platform logger. */
-       static class LoggerWrapper implements CmsLog {
-               private final Logger logger;
-
-               LoggerWrapper(Logger logger) {
-                       this.logger = logger;
+               SystemLogger logger;
+               try {
+                       logger = new RealSystemLogger(name);
+               } catch (NoSuchMethodError | NoClassDefFoundError e) {// Android
+                       logger = new FallBackSystemLogger();
                }
-
-               @Override
-               public Logger getLogger() {
-                       return logger;
-               }
-
+               return new LoggerWrapper(logger);
        }
 
 }
diff --git a/org.argeo.api.cms/src/org/argeo/api/cms/SystemLogger.java b/org.argeo.api.cms/src/org/argeo/api/cms/SystemLogger.java
new file mode 100644 (file)
index 0000000..9d6ca8d
--- /dev/null
@@ -0,0 +1,128 @@
+package org.argeo.api.cms;
+
+import java.lang.System.Logger;
+import java.util.Objects;
+import java.util.function.Supplier;
+
+/** Workaround because Android does not support {@link Logger}. */
+abstract class SystemLogger {
+       public enum Level {
+               ALL(Integer.MIN_VALUE, java.lang.System.Logger.Level.ALL), //
+               TRACE(400, java.lang.System.Logger.Level.TRACE), //
+               DEBUG(500, java.lang.System.Logger.Level.DEBUG), //
+               INFO(800, java.lang.System.Logger.Level.INFO), //
+               WARNING(900, java.lang.System.Logger.Level.WARNING), //
+               ERROR(1000, java.lang.System.Logger.Level.ERROR), //
+               OFF(Integer.MAX_VALUE, java.lang.System.Logger.Level.OFF); //
+
+               private final int severity;
+               private java.lang.System.Logger.Level systemLevel;
+
+               private Level(int severity, java.lang.System.Logger.Level systemLevel) {
+                       this.severity = severity;
+                       this.systemLevel = systemLevel;
+               }
+
+               public final int getSeverity() {
+                       return severity;
+               }
+
+               public java.lang.System.Logger.Level getSystemLevel() {
+                       return systemLevel;
+               }
+       }
+
+       public boolean isLoggable(Level level) {
+               return false;
+       }
+
+       public abstract void log(Level level, Supplier<String> msgSupplier, Throwable thrown);
+
+       public abstract void log(Level level, String msg, Throwable thrown);
+
+       public void log(Level level, String msg) {
+               log(level, msg, (Throwable) null);
+       }
+
+       public void log(Level level, Supplier<String> msgSupplier) {
+               log(level, msgSupplier, (Throwable) null);
+       }
+
+       public void log(Level level, Object obj) {
+               Objects.requireNonNull(obj);
+               log(level, obj.toString());
+       }
+
+       public void log(Level level, String format, Object... params) {
+               // FIXME implement it
+               String msg = null;
+               log(level, msg);
+       }
+
+}
+
+/** A trivial implementation wrapping a platform logger. */
+class LoggerWrapper implements CmsLog {
+       private final SystemLogger logger;
+
+       LoggerWrapper(SystemLogger logger) {
+               this.logger = logger;
+       }
+
+       @Override
+       public SystemLogger getLogger() {
+               return logger;
+       }
+
+}
+
+class RealSystemLogger extends SystemLogger {
+       final Logger logger;
+
+       RealSystemLogger(String name) {
+               logger = System.getLogger(name);
+       }
+
+       @Override
+       public boolean isLoggable(Level level) {
+               return logger.isLoggable(convertSystemLevel(level));
+       }
+
+       @Override
+       public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
+               logger.log(convertSystemLevel(level), msgSupplier, thrown);
+       }
+
+       @Override
+       public void log(Level level, String msg, Throwable thrown) {
+               logger.log(convertSystemLevel(level), msg, thrown);
+       }
+
+       System.Logger.Level convertSystemLevel(Level level) {
+               return level.getSystemLevel();
+       }
+};
+
+class FallBackSystemLogger extends SystemLogger {
+       @Override
+       public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
+               if (isLoggable(level))
+                       if (thrown != null) {
+                               System.err.println(msgSupplier.get());
+                               thrown.printStackTrace();
+                       } else {
+                               System.out.println(msgSupplier.get());
+                       }
+       }
+
+       @Override
+       public void log(Level level, String msg, Throwable thrown) {
+               if (isLoggable(level))
+                       if (thrown != null) {
+                               System.err.println(msg);
+                               thrown.printStackTrace();
+                       } else {
+                               System.out.println(msg);
+                       }
+       }
+}
\ No newline at end of file