Просмотр исходного кода

lexer.SafeConsumer - zabezpiecza działanie tokenizera przed błędami w konsumencie

Ranides Atterwim 13 лет назад
Родитель
Сommit
0a23986888

+ 1 - 1
pom.xml

@@ -4,7 +4,7 @@
 
 
     <groupId>net.ranides</groupId>
     <groupId>net.ranides</groupId>
     <artifactId>assira</artifactId>
     <artifactId>assira</artifactId>
-    <version>0.60.1</version>
+    <version>0.60.2</version>
     <packaging>jar</packaging>
     <packaging>jar</packaging>
 
 
     <name>assira</name>
     <name>assira</name>

+ 96 - 0
src/main/java/net/ranides/assira/lexer/SafeConsumer.java

@@ -0,0 +1,96 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.lexer;
+
+import net.ranides.assira.events.CoreEvent;
+import net.ranides.assira.events.EventListener;
+import net.ranides.assira.trace.AdvLogger;
+import net.ranides.assira.trace.LoggerUtils;
+
+/**
+ *
+ * @author ranides
+ */
+public final class SafeConsumer {
+
+    private SafeConsumer() {
+        // utility class
+    }
+
+    public static <UserType> ByteConsumer<UserType> make(ByteConsumer<UserType> consumer) {
+        return new SafeBC<UserType>(consumer, new LogListener(consumer.getClass()));
+    }
+
+    public static <UserType> CharConsumer<UserType> make(CharConsumer<UserType> consumer) {
+        return new SafeCC<UserType>(consumer, new LogListener(consumer.getClass()));
+    }
+
+    public static <UserType> ByteConsumer<UserType> make(ByteConsumer<UserType> consumer, EventListener<? super CoreEvent.Failure> handler) {
+        return new SafeBC<UserType>(consumer, handler);
+    }
+
+    public static <UserType> CharConsumer<UserType> make(CharConsumer<UserType> consumer, EventListener<? super CoreEvent.Failure> handler) {
+        return new SafeCC<UserType>(consumer, handler);
+    }
+
+    private static final class SafeBC<UserType> implements ByteConsumer<UserType> {
+
+        private final EventListener<? super CoreEvent.Failure> handler;
+        private final ByteConsumer<UserType> consumer;
+
+        public SafeBC(ByteConsumer<UserType> consumer, EventListener<? super CoreEvent.Failure> handler) {
+            this.handler = handler;
+            this.consumer = consumer;
+        }
+
+        @Override
+        public void consume(UserType type, byte[] data) {
+            try {
+                consumer.consume(type, data);
+            } catch(Throwable cause) { //NOPMD - jesteśmy świadomi, że errors też tu lecą...
+                handler.handleEvent(CoreEvent.failure(handler, cause));
+            }
+        }
+
+    }
+
+    private static final class SafeCC<UserType> implements CharConsumer<UserType> {
+
+        private final EventListener<? super CoreEvent.Failure> handler;
+        private final CharConsumer<UserType> consumer;
+
+        public SafeCC(CharConsumer<UserType> consumer, EventListener<? super CoreEvent.Failure> handler) {
+            this.handler = handler;
+            this.consumer = consumer;
+        }
+
+        @Override
+        public void consume(UserType type, char[] data) {
+            try {
+                consumer.consume(type, data);
+            } catch(Throwable cause) { //NOPMD - jesteśmy świadomi, że errors też tu lecą...
+                handler.handleEvent(CoreEvent.failure(handler, cause));
+            }
+        }
+
+    }
+
+    private static final class LogListener implements EventListener<CoreEvent.Failure> {
+        private final AdvLogger logger;
+
+        public LogListener(Class<?> clazz) {
+            this.logger = LoggerUtils.getLogger(clazz);
+        }
+
+        @Override
+        public void handleEvent(CoreEvent.Failure event) {
+            logger.xerror("Unexpected exception: %s", event.cause(), event.cause());
+        }
+
+    }
+
+}

+ 19 - 15
src/main/java/net/ranides/assira/trace/LoggerUtils.java

@@ -19,11 +19,11 @@ import net.ranides.assira.reflection.AutoConstructor;
  * @author ranides
  * @author ranides
  */
  */
 public final class LoggerUtils {
 public final class LoggerUtils {
-    
+
     private static final boolean SINGLE_TEST = PrivilegedActions.getProperty("test") != null;
     private static final boolean SINGLE_TEST = PrivilegedActions.getProperty("test") != null;
-    
+
     private static final Map<String, AdvLogger> CACHE = new HashMap<String, AdvLogger>();
     private static final Map<String, AdvLogger> CACHE = new HashMap<String, AdvLogger>();
-    
+
     private static final org.apache.log4j.Appender APPENDER = new org.apache.log4j.ConsoleAppender(new org.apache.log4j.PatternLayout("%d %p [%c %M] %m%n"), "System.out");
     private static final org.apache.log4j.Appender APPENDER = new org.apache.log4j.ConsoleAppender(new org.apache.log4j.PatternLayout("%d %p [%c %M] %m%n"), "System.out");
 
 
     private LoggerUtils() { }
     private LoggerUtils() { }
@@ -40,7 +40,7 @@ public final class LoggerUtils {
         global.setLevel(level);
         global.setLevel(level);
         return global;
         return global;
     }
     }
-    
+
     public static void initTest() {
     public static void initTest() {
         resetLogger4j(SINGLE_TEST);
         resetLogger4j(SINGLE_TEST);
     }
     }
@@ -48,11 +48,11 @@ public final class LoggerUtils {
     public static java.util.logging.Logger resetJavaLogger(boolean enable) {
     public static java.util.logging.Logger resetJavaLogger(boolean enable) {
         return resetJavaLogger(enable ? java.util.logging.Level.ALL : java.util.logging.Level.OFF );
         return resetJavaLogger(enable ? java.util.logging.Level.ALL : java.util.logging.Level.OFF );
     }
     }
-    
+
     public static org.apache.log4j.Logger resetLogger4j(boolean enable) {
     public static org.apache.log4j.Logger resetLogger4j(boolean enable) {
         return resetLogger4j(enable ? org.apache.log4j.Level.ALL : org.apache.log4j.Level.OFF);
         return resetLogger4j(enable ? org.apache.log4j.Level.ALL : org.apache.log4j.Level.OFF);
     }
     }
-    
+
     public static org.apache.log4j.Logger resetLogger4j(org.apache.log4j.Level level) {
     public static org.apache.log4j.Logger resetLogger4j(org.apache.log4j.Level level) {
         return resetLogger4j(level, APPENDER);
         return resetLogger4j(level, APPENDER);
     }
     }
@@ -67,16 +67,20 @@ public final class LoggerUtils {
     public static AdvLogger getLogger() {
     public static AdvLogger getLogger() {
         return getLogger( new Throwable().getStackTrace()[1].getClassName() );
         return getLogger( new Throwable().getStackTrace()[1].getClassName() );
     }
     }
-    
+
+    public static AdvLogger getLogger(Class<?> clazz) {
+        return getLogger(clazz.getName());
+    }
+
     public static AdvLogger getLogger(String name) {
     public static AdvLogger getLogger(String name) {
         // Może się okazać, że logger INNEJ KLASY został już utworzony dla podanego "name"
         // Może się okazać, że logger INNEJ KLASY został już utworzony dla podanego "name"
         // Wtedy nie ruszy nasza fabryka "FACTORY", tylko dostaniemy
         // Wtedy nie ruszy nasza fabryka "FACTORY", tylko dostaniemy
         // instancję wcześniej utworzoną (uwaga! skonfigurowaną!)
         // instancję wcześniej utworzoną (uwaga! skonfigurowaną!)
         //
         //
         // nawet jeśli chcemy ją zignorować, to musimy przepisać z niej konfigurację
         // nawet jeśli chcemy ją zignorować, to musimy przepisać z niej konfigurację
-        
+
         org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(name, AdvLogger.FACTORY);
         org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(name, AdvLogger.FACTORY);
-        
+
         if(logger instanceof AdvLogger) {
         if(logger instanceof AdvLogger) {
             return (AdvLogger)logger;
             return (AdvLogger)logger;
         } else {
         } else {
@@ -99,7 +103,7 @@ public final class LoggerUtils {
         }
         }
         return false;
         return false;
     }
     }
-    
+
     public static boolean invokedInsideSingleTest() {
     public static boolean invokedInsideSingleTest() {
         return SINGLE_TEST;
         return SINGLE_TEST;
     }
     }
@@ -111,7 +115,7 @@ public final class LoggerUtils {
      * to nie funkcja nie wyświetla komunikatu.
      * to nie funkcja nie wyświetla komunikatu.
      * @param locale
      * @param locale
      * @param format
      * @param format
-     * @param args 
+     * @param args
      */
      */
     @SuppressWarnings({"PMD.SystemPrintln", "NP_ALWAYS_NULL"})
     @SuppressWarnings({"PMD.SystemPrintln", "NP_ALWAYS_NULL"})
     public static void dump(Locale locale, String format, Object... args) {
     public static void dump(Locale locale, String format, Object... args) {
@@ -126,12 +130,12 @@ public final class LoggerUtils {
      * test jednostkowy: jeśli test uruchomiony jest np podczas budowania projektu,
      * test jednostkowy: jeśli test uruchomiony jest np podczas budowania projektu,
      * to nie funkcja nie wyświetla komunikatu.
      * to nie funkcja nie wyświetla komunikatu.
      * @param format
      * @param format
-     * @param args 
+     * @param args
      */
      */
     public static void dump(String format, Object... args) {
     public static void dump(String format, Object... args) {
         dump(Locale.ROOT, format, args);
         dump(Locale.ROOT, format, args);
     }
     }
-    
+
     public static void setThreadLogger(final org.apache.log4j.Logger logger) {
     public static void setThreadLogger(final org.apache.log4j.Logger logger) {
         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
             @Override
             @Override
@@ -140,7 +144,7 @@ public final class LoggerUtils {
             }
             }
         });
         });
     }
     }
-    
+
     public static void removeHandlers(final java.util.logging.Logger logger) {
     public static void removeHandlers(final java.util.logging.Logger logger) {
         for(java.util.logging.Handler handler : logger.getHandlers()) {
         for(java.util.logging.Handler handler : logger.getHandlers()) {
             if( handler instanceof java.util.logging.ConsoleHandler) {
             if( handler instanceof java.util.logging.ConsoleHandler) {
@@ -148,5 +152,5 @@ public final class LoggerUtils {
             }
             }
         }
         }
     }
     }
-   
+
 }
 }