001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    
018    package org.apache.geronimo.kernel.log;
019    
020    import java.util.HashMap;
021    import java.util.HashSet;
022    import java.util.Iterator;
023    import java.util.Map;
024    import java.util.Set;
025    
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogConfigurationException;
028    import org.apache.commons.logging.LogFactory;
029    
030    /**
031     * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
032     */
033    public class GeronimoLogFactory extends LogFactory {
034        private final static Object factoryLock = new Object();
035        // todo this should use weak references
036        private static final HashMap instancesByClassLoader = new HashMap();
037    
038        private static LogFactory logFactory = new BootstrapLogFactory();
039    
040        public GeronimoLogFactory() {
041        }
042    
043        public LogFactory getLogFactory() {
044            synchronized (factoryLock) {
045                return logFactory;
046            }
047        }
048    
049        public void setLogFactory(LogFactory logFactory) {
050            // change the log factory
051            GeronimoLogFactory.logFactory = logFactory;
052    
053            // update all known logs to use instances of the new factory
054            Set logs = getInstances();
055            for (Iterator iterator = logs.iterator(); iterator.hasNext();) {
056                GeronimoLog log = (GeronimoLog) iterator.next();
057                log.setLog(logFactory.getInstance(log.getName()));
058            }
059        }
060    
061        public Set getInstances() {
062            synchronized (factoryLock) {
063                Set logs = new HashSet();
064                for (Iterator iterator = instancesByClassLoader.values().iterator(); iterator.hasNext();) {
065                    Map instanceMap = ((Map) iterator.next());
066                    logs.addAll(instanceMap.values());
067    
068                }
069                return logs;
070            }
071        }
072    
073        public Log getInstance(Class clazz) throws LogConfigurationException {
074            synchronized (factoryLock) {
075                return getInstance(clazz.getName());
076            }
077        }
078    
079        public Log getInstance(String name) throws LogConfigurationException {
080            synchronized (factoryLock) {
081                // get the instances for the context classloader
082                ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
083                Map instances = (Map) instancesByClassLoader.get(contextClassLoader);
084                if (instances == null) {
085                    instances = new HashMap();
086                    instancesByClassLoader.put(contextClassLoader, instances);
087                }
088    
089                // get the log
090                Log log = (Log) instances.get(name);
091                if (log == null) {
092                    log = new GeronimoLog(name, logFactory.getInstance(name));
093                    instances.put(name, log);
094                }
095                return log;
096            }
097        }
098    
099        public void release() {
100            synchronized (factoryLock) {
101    // TODO rethink this - it works for now
102    //            for (Iterator maps = instancesByClassLoader.values().iterator(); maps.hasNext();) {
103    //                Map instances = (Map) maps.next();
104    //                for (Iterator logs = instances.values().iterator(); logs.hasNext();) {
105    //                    GeronimoLog log = (GeronimoLog) logs.next();
106    //                    log.setLog(null);
107    //
108    //                }
109    //            }
110                instancesByClassLoader.clear();
111            }
112        }
113    
114        public Object getAttribute(String name) {
115            synchronized (factoryLock) {
116                return logFactory.getAttribute(name);
117            }
118        }
119    
120        public String[] getAttributeNames() {
121            synchronized (factoryLock) {
122                return logFactory.getAttributeNames();
123            }
124        }
125    
126        public void removeAttribute(String name) {
127            synchronized (factoryLock) {
128                logFactory.removeAttribute(name);
129            }
130        }
131    
132        public void setAttribute(String name, Object value) {
133            synchronized (factoryLock) {
134                logFactory.setAttribute(name, value);
135            }
136        }
137    }
138