001    package org.shiftone.jrat.util.log.target;
002    
003    
004    import org.shiftone.jrat.util.log.Logger;
005    
006    
007    /**
008     * This is a LogTarget that uses a delegate LogTarget that lives on the thread.
009     * This makes it possible to run a command within a scope, and have the
010     * activities of that scope to be logged to a different LogTarget - but only
011     * during the duration of that command.
012     *
013     * @author jeff@shiftone.org (Jeff Drost)
014     */
015    public class ThreadLocalLogTarget implements LogTarget {
016    
017        private static final Logger LOG = Logger.getLogger(ThreadLocalLogTarget.class);
018        public ThreadLocal threadLocal;
019    
020        public ThreadLocalLogTarget() {
021            this(NullLogTarget.INSTANCE);
022        }
023    
024    
025        public ThreadLocalLogTarget(final LogTarget target) {
026    
027            threadLocal = new ThreadLocal() {
028    
029                protected Object initialValue() {
030                    return target;
031                }
032            };
033        }
034    
035    
036        public boolean isLevelEnabled(String topic, int level) {
037            return getLogTarget().isLevelEnabled(topic, level);
038        }
039    
040    
041        public void log(String topic, int level, Object message, Throwable throwable) {
042            getLogTarget().log(topic, level, message, throwable);
043        }
044    
045    
046        private LogTarget getLogTarget() {
047            return (LogTarget) threadLocal.get();
048        }
049    
050    
051        private void setLogTarget(LogTarget logTarget) {
052            threadLocal.set(logTarget);
053        }
054    
055    
056        public void executeInScope(LogTarget newTarget, Runnable runnable) {
057    
058            LogTarget oldTarget = getLogTarget();
059    
060            try {
061                setLogTarget(newTarget);
062                runnable.run();
063            } catch (Throwable e) {
064                LOG.error("Process failed.", e);
065            }
066            finally {
067                setLogTarget(oldTarget);
068            }
069        }
070    }