001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.logging;
022    
023    import java.lang.reflect.Constructor;
024    
025    import org.granite.scan.ServiceLoader;
026    import org.granite.util.TypeUtil;
027    
028    /**
029     * @author Franck WOLFF
030     */
031    public abstract class Logger {
032    
033        ///////////////////////////////////////////////////////////////////////////
034        // Fields.
035    
036            public static final String LOGGER_IMPL_SYSTEM_PROPERTY = "org.granite.logger.impl";
037            
038            private static final boolean log4jAvailable;
039            static {
040                    boolean available = false;
041                    try {
042                            TypeUtil.forName("org.apache.log4j.Logger");
043                            available = true;
044                    } catch (Exception e) {
045                    }
046                    log4jAvailable = available;
047            }
048            
049        private final Object loggerImpl;
050        private final LoggingFormatter formatter;
051    
052        ///////////////////////////////////////////////////////////////////////////
053        // Constructor.
054        
055        protected Logger(Object loggerImpl, LoggingFormatter formatter) {
056            this.loggerImpl = loggerImpl;
057            this.formatter = formatter;
058        }
059    
060        ///////////////////////////////////////////////////////////////////////////
061        // Getters.
062        
063        protected Object getLoggerImpl() {
064            return loggerImpl;
065        }
066        
067        protected LoggingFormatter getFormatter() {
068                    return formatter;
069            }
070    
071        ///////////////////////////////////////////////////////////////////////////
072        // Static initializers.
073    
074            public static Logger getLogger() {
075            return getLogger(new DefaultLoggingFormatter());
076        }
077    
078        public static Logger getLogger(Class<?> clazz) {
079            return getLogger(clazz.getName(), new DefaultLoggingFormatter());
080        }
081    
082        public static Logger getLogger(String name) {
083            return getLogger(name, new DefaultLoggingFormatter());
084        }
085    
086        public static Logger getLogger(LoggingFormatter formatter) {
087            Throwable t = new Throwable();
088            StackTraceElement[] stes = t.getStackTrace();
089            if (stes.length < 2)
090                throw new RuntimeException("Illegal instantiation context (stacktrace elements should be of length >= 2)", t);
091            return getLogger(stes[1].getClassName());
092        }
093    
094        public static Logger getLogger(Class<?> clazz, LoggingFormatter formatter) {
095            return getLogger(clazz.getName(), formatter);
096        }
097    
098        public static Logger getLogger(String name, LoggingFormatter formatter) {
099            String loggerImplClass = System.getProperty(LOGGER_IMPL_SYSTEM_PROPERTY);
100            if (loggerImplClass != null) {
101                    try {
102                            Class<? extends Logger> clazz = TypeUtil.forName(loggerImplClass, Logger.class);
103                            Constructor<? extends Logger> constructor = clazz.getConstructor(String.class, LoggingFormatter.class);
104                            return constructor.newInstance(name, formatter);
105                            } catch (Exception e) {
106                                    throw new RuntimeException(
107                                            "Could not create instance of: " + loggerImplClass +
108                                            " (" + LOGGER_IMPL_SYSTEM_PROPERTY + " system property)", e);
109                            }
110            }
111            
112            ServiceLoader<Logger> loader = ServiceLoader.load(Logger.class);
113            loader.setConstructorParameters(new Class<?>[]{String.class, LoggingFormatter.class}, new Object[]{name, formatter});
114            for (Logger logger : loader)
115                    return logger;
116            
117            return log4jAvailable ? new Log4jLogger(name, formatter) : new JdkLogger(name, formatter);
118        }
119    
120        ///////////////////////////////////////////////////////////////////////////
121        // Logging methods.
122    
123        public abstract void info(String message, Object... args);
124        public abstract void info(Throwable t, String message, Object... args);
125    
126        public abstract void trace(String message, Object... args);
127        public abstract void trace(Throwable t, String message, Object... args);
128        
129        public abstract void warn(String message, Object... args);
130        public abstract void warn(Throwable t, String message, Object... args);
131    
132        public abstract void debug(String message, Object... args);
133        public abstract void debug(Throwable t, String message, Object... args);
134    
135        public abstract void error(String message, Object... args);
136        public abstract void error(Throwable t, String message, Object... args);
137    
138        public abstract void fatal(String message, Object... args);
139        public abstract void fatal(Throwable t, String message, Object... args);
140    
141        ///////////////////////////////////////////////////////////////////////////
142        // Configuration.
143    
144        public abstract void setLevel(Level level);
145    
146        public abstract boolean isDebugEnabled();
147    
148        public abstract boolean isErrorEnabled();
149    
150        public abstract boolean isFatalEnabled();
151    
152        public abstract boolean isInfoEnabled();
153    
154        public abstract boolean isTraceEnabled();
155    
156        public abstract boolean isWarnEnabled();
157    }