001    package com.agilejava.blammo;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    
006    /* 
007     * Copyright (C) 2006, Wilfred Springer
008     *
009     * This library is free software; you can redistribute it and/or
010     * modify it under the terms of the GNU Lesser General Public
011     * License as published by the Free Software Foundation; either
012     * version 2.1 of the License, or (at your option) any later version.
013     * 
014     * This library is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
022     */
023    
024    /**
025     * The class for creating a logger. Note that a logger is not required to
026     * implement a certain interface. The only requirement is that it implements an
027     * interface, and that this interface has <code>logXXXXXX</code> operations
028     * that have blammo annotations.
029     * 
030     * @author Wilfred Springer
031     */
032    public class BlammoLoggerFactory {
033    
034        /**
035         * Returns the Blammo generated implementation class of the Blammo logger
036         * interface defined by the user. Note that the class returned is expected
037         * to implement the {@link BlammoLogger} interface. Future versions of this
038         * operation might delegate the naming strategy to another object.
039         * 
040         * @param intf The interface for which we need the implementation class.
041         * @return The Blammo generated implementation class of the logger interface
042         *         defined by the user.
043         * @throws BlammoException If the operation fails to load the implementation
044         *         class from the class path.
045         */
046        private static Class getImplementationClass(Class intf)
047                throws BlammoException {
048            String fqn = intf.getName().replace('$', '_');
049            StringBuffer buffer = new StringBuffer();
050            buffer.append(intf.getPackage().getName());
051            buffer.append('.');
052            buffer.append("Blammo");
053            buffer.append(fqn.substring(fqn.lastIndexOf('.') + 1));
054            buffer.append("Impl");
055            try {
056                // Maybe change this in the future to use the ClassLoader used to
057                // load the intf class.
058                return Class.forName(buffer.toString());
059            } catch (ClassNotFoundException cnfe) {
060                throw new BlammoException(cnfe);
061            }
062        }
063    
064        /**
065         * Creates a new logger for the interface passed in.
066         * 
067         * @param intf The interface specifying the logger interface.
068         * @return An implementation of this interface.
069         * @throws BlammoException If this operation fails to create an
070         *         implementation of this interface.
071         */
072        public static Object create(Class intf) throws BlammoException {
073            return create(intf, new StdErrLoggingKitAdapter());
074        }
075    
076        /**
077         * Creates a new logger for the interface passed in, using the
078         * {@link LoggingKit} to create a low level logging kit specific version.
079         * 
080         * @param intf The interface for which we need to construct a new logger.
081         * @param kit An object representing a particular low level logging kit.
082         * @return A new logger, implementing the <code>intf</code> interface.
083         * @throws BlammoException If this operation fails to create an
084         *         implementation of this interface.
085         */
086        public static Object create(Class intf, LoggingKit kit)
087                throws BlammoException {
088            LoggingKitAdapter log = kit.createLogKitAdapter(intf);
089            return create(intf, log);
090        }
091    
092        /**
093         * Creates a new logger for the logging interface passed in, using the
094         * {@link LoggingKitAdapter} to create a low level logging kit specific
095         * version.
096         * 
097         * @param intf The interface for which we need to construct a new logger.
098         * @param adapter An object representing a particular low level logging
099         *        logger.
100         * @return A new logger, implementing the <code>intf</code> interface.
101         * @throws BlammoException If this operation fails to create an
102         *         implementation of this interface.
103         */
104        public static Object create(Class intf, LoggingKitAdapter adapter)
105                throws BlammoException {
106            Class implClass = getImplementationClass(intf);
107            try {
108                BlammoLogger logger = (BlammoLogger) implClass.newInstance();
109                logger.setLoggingKitAdapter(adapter);
110                return logger;
111            } catch (InstantiationException ie) {
112                throw new BlammoException(ie);
113            } catch (IllegalAccessException iae) {
114                throw new BlammoException(iae);
115            }
116        }
117        
118        /**
119         * Creates a new logger, using the {@link BlammoLogger.Interceptor}.
120         * 
121         * @param intf The interface for which we need to construct a new logger.
122         * @param interceptor The interceptor that gets the opportunity to veto
123         *        every message.
124         */
125        public static Object create(Class intf, BlammoLogger.Interceptor interceptor) {
126            BlammoLogger logger = (BlammoLogger) create(intf);
127            logger.setInterceptor(interceptor);
128            return logger;
129        }
130        
131    }