Coverage Report - net.sourceforge.acelogger.execution.LogController
 
Classes in this File Line Coverage Branch Coverage Complexity
LogController
61%
21/34
66%
4/6
1,615
LogController$1
60%
9/15
25%
1/4
1,615
LogController$2
16%
1/6
N/A
1,615
LogController$2$1
0%
0/4
N/A
1,615
LogController$3
50%
2/4
N/A
1,615
LogController$4
0%
0/3
N/A
1,615
LogController$5
0%
0/3
N/A
1,615
 
 1  
 /*
 2  
  * This file is part of AceLogger.
 3  
  * 
 4  
  * AceLogger is free software: you can redistribute it and/or modify it under the terms of the GNU
 5  
  * Lesser General Public License as published by the Free Software Foundation, either version 3 of
 6  
  * the License, or (at your option) any later version.
 7  
  * 
 8  
  * AceLogger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 9  
  * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 10  
  * Lesser General Public License for more details.
 11  
  * 
 12  
  * You should have received a copy of the GNU Lesser General Public License along with AceLogger.
 13  
  * If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
 14  
  */
 15  
 package net.sourceforge.acelogger.execution;
 16  
 
 17  
 import java.lang.Thread.UncaughtExceptionHandler;
 18  
 import java.util.ArrayList;
 19  
 import java.util.List;
 20  
 import java.util.concurrent.atomic.AtomicBoolean;
 21  
 
 22  
 import net.sourceforge.acelogger.GenericLogger;
 23  
 import net.sourceforge.acelogger.Logger;
 24  
 import net.sourceforge.acelogger.appender.Appender;
 25  
 import net.sourceforge.acelogger.appender.SystemErrAppender;
 26  
 import net.sourceforge.acelogger.constants.LevelFilterConstants;
 27  
 import net.sourceforge.acelogger.execution.manager.ExecutorManager;
 28  
 import net.sourceforge.acelogger.execution.manager.PooledExecutorManager;
 29  
 import net.sourceforge.acelogger.execution.manager.QueuedExecutorManager;
 30  
 import net.sourceforge.acelogger.execution.task.MonitorableTask;
 31  
 import net.sourceforge.acelogger.execution.task.NotifiableTask;
 32  
 import net.sourceforge.acelogger.factory.ExecutorManagerFactory;
 33  
 import net.sourceforge.acelogger.factory.LoggerFactory;
 34  
 import net.sourceforge.acelogger.formatter.Formatter;
 35  
 import net.sourceforge.acelogger.formatter.SimpleFormatter;
 36  
 import net.sourceforge.acelogger.level.filter.LevelFilter;
 37  
 import net.sourceforge.acelogger.location.gatherer.FullLocationGatherer;
 38  
 import net.sourceforge.acelogger.location.gatherer.LocationGatherer;
 39  
 import net.sourceforge.acelogger.location.resolver.InternalCodeFrameResolver;
 40  
 
 41  
 // FIXME: Holy Crap... Design this properly. It started as a workaround, but looks promising now.
 42  
 /**
 43  
  * TODO: Create Doc.
 44  
  * 
 45  
  * @author Zardi (https://sourceforge.net/users/daniel_zardi)
 46  
  * @version 1.0.0
 47  
  * @since 1.0.0
 48  
  */
 49  8
 public final class LogController {
 50  
 
 51  
         private static final int DEFAULT_POOL_SIZE = 3;
 52  
 
 53  
         private static final long SETUP_TIMEOUT = 10000;
 54  
 
 55  
         private static final long TERMINATION_TIMEOUT = 10000;
 56  
 
 57  1
         private static final LogController INSTANCE = new LogController();
 58  
 
 59  
         private List<Runnable> commandsBeforeShutdown;
 60  
 
 61  
         private ExecutorManager backgroundExecutor;
 62  
 
 63  
         private ExecutorManager shutdownExecutor;
 64  
 
 65  
         private Logger internalLogger;
 66  
 
 67  
         private AtomicBoolean initialized;
 68  
 
 69  
         private AtomicBoolean waitingBootstrap;
 70  
 
 71  1
         private Thread shutdownHook = new Thread(new Runnable() {
 72  
                 public void run() {
 73  1
                         internalLogger = new InternalLogger();
 74  1
                         shutdownExecutor.executeAll(commandsBeforeShutdown);
 75  1
                         shutdownExecutor.orderProperShutdown();
 76  1
                         shutdownExecutor.awaitTermination(TERMINATION_TIMEOUT);
 77  1
                         boolean terminatedAllTasks = ExecutorManagerFactory.doProperExecutorManagersShutdown();
 78  1
                         if (!terminatedAllTasks) {
 79  
                                 try {
 80  0
                                         terminatedAllTasks = ExecutorManagerFactory
 81  
                                                         .awaitExecutorManagersShutdown(TERMINATION_TIMEOUT);
 82  0
                                 } catch (TerminationException e) {
 83  0
                                         e.printStackTrace(System.err);
 84  0
                                 }
 85  0
                                 if (!terminatedAllTasks) {
 86  
                                         // FIXME: What should we do? wait forever? or just drop the tasks?
 87  
                                 }
 88  
                         }
 89  1
                         backgroundExecutor.orderProperShutdown();
 90  1
                         backgroundExecutor.awaitTermination(TERMINATION_TIMEOUT);
 91  0
                 }
 92  
         });
 93  
 
 94  1
         private MonitorableTask finalizeBootstrap = new MonitorableTask(new Runnable() {
 95  
                 public void run() {
 96  
                         try {
 97  0
                                 submitBackgroundTask(new Runnable() {
 98  
                                         public void run() {
 99  0
                                                 internalLogger = LoggerFactory.getLogger("net.sourceforge.acelogger");
 100  0
                                                 initialized.set(true);
 101  0
                                         }
 102  
                                 });
 103  0
                         } catch (Exception e) {
 104  
                                 // FIXME: Should we do this? If there's an exception the framework is compromised by now
 105  0
                                 shutdownHook.start();
 106  0
                         }
 107  0
                 }
 108  
         });
 109  
 
 110  1
         private Runnable setup = new NotifiableTask(new Runnable() {
 111  
                 public void run() {
 112  1
                         LoggerFactory.registerLogger(internalLogger);
 113  0
                         internalLogger.info("LogControlle.setupComplete");
 114  0
                 }
 115  
         }, finalizeBootstrap);
 116  
 
 117  1
         private LogController() {
 118  1
                 internalLogger = new InternalLogger();
 119  1
                 Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionLogger.getInstance());
 120  1
                 Runtime.getRuntime().addShutdownHook(shutdownHook);
 121  1
                 backgroundExecutor = new QueuedExecutorManager("background");
 122  1
                 shutdownExecutor = new PooledExecutorManager("commandsBeforeShutdown", DEFAULT_POOL_SIZE);
 123  1
                 commandsBeforeShutdown = new ArrayList<Runnable>();
 124  1
                 initialized = new AtomicBoolean(false);
 125  1
                 waitingBootstrap = new AtomicBoolean(true);
 126  1
                 backgroundExecutor.execute(setup);
 127  1
         }
 128  
 
 129  
         public static void submitBackgroundTask(Runnable command) {
 130  0
                 INSTANCE.backgroundExecutor.execute(command);
 131  0
         }
 132  
 
 133  
         public static void submitBackgroundTask(final Runnable command, final ExecutorManager executor) {
 134  0
                 final Runnable process = new Runnable() {
 135  
                         public void run() {
 136  0
                                 executor.execute(command);
 137  0
                         }
 138  
                 };
 139  0
                 submitBackgroundTask(process);
 140  0
         }
 141  
 
 142  
         public static void submitShutdownTask(Runnable command) {
 143  0
                 INSTANCE.commandsBeforeShutdown.add(command);
 144  0
         }
 145  
 
 146  
         public static void submitShutdownTask(final Runnable command, final ExecutorManager executor) {
 147  0
                 final Runnable process = new Runnable() {
 148  
                         public void run() {
 149  0
                                 executor.execute(command);
 150  0
                         }
 151  
                 };
 152  0
                 submitShutdownTask(process);
 153  0
         }
 154  
 
 155  
         public static void ensureInitialization() {
 156  62
                 if (!INSTANCE.initialized.get() && INSTANCE.waitingBootstrap.get()) {
 157  
                         try {
 158  1
                                 if (INSTANCE.waitingBootstrap.compareAndSet(true, false)) {
 159  1
                                         INSTANCE.finalizeBootstrap.awaitTermination(SETUP_TIMEOUT);
 160  
                                 }
 161  0
                         } catch (final InterruptedException e) {
 162  0
                                 INSTANCE.internalLogger.fatal("Could not initialize after {0} ms", SETUP_TIMEOUT);
 163  0
                         }
 164  
                 }
 165  61
         }
 166  
 
 167  
         public static Logger getInternalLogger() {
 168  12
                 return INSTANCE.internalLogger;
 169  
         }
 170  
 
 171  
 }