001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.log;
016    
017    import java.util.Map;
018    import java.util.concurrent.ConcurrentHashMap;
019    import java.util.concurrent.ConcurrentMap;
020    
021    /**
022     * @author Brian Wing Shun Chan
023     * @author Shuyang Zhou
024     */
025    public class LogFactoryUtil {
026    
027            public static Log getLog(Class<?> c) {
028                    return getLog(c.getName());
029            }
030    
031            public static Log getLog(String name) {
032    
033                    // The following concurrent collection retrieve has the side effect of a
034                    // memory fence read. This will invalidate all dirty cache data if there
035                    // are any. If the LogWrapper swap happens before this, the new Log will
036                    // be visible to the current Thread.
037    
038                    LogWrapper logWrapper = _logWrappers.get(name);
039    
040                    if (logWrapper == null) {
041                            logWrapper = new LogWrapper(_logFactory.getLog(name));
042    
043                            LogWrapper previousLogWrapper = _logWrappers.putIfAbsent(
044                                    name, logWrapper);
045    
046                            if (previousLogWrapper != null) {
047                                    logWrapper = previousLogWrapper;
048                            }
049                    }
050    
051                    return logWrapper;
052            }
053    
054            public static void setLogFactory(LogFactory logFactory) {
055                    for (Map.Entry<String, LogWrapper> entry : _logWrappers.entrySet()) {
056                            String name = entry.getKey();
057    
058                            LogWrapper logWrapper = entry.getValue();
059    
060                            logWrapper.setLog(logFactory.getLog(name));
061                    }
062    
063                    // The following volatile write will flush out all cache data. All
064                    // previously swapped LogWrappers will be visible for any reads after a
065                    // memory fence read according to the happens-before rules.
066    
067                    _logFactory = logFactory;
068            }
069    
070            private static volatile LogFactory _logFactory = new Jdk14LogFactoryImpl();
071            private static final ConcurrentMap<String, LogWrapper> _logWrappers =
072                    new ConcurrentHashMap<String, LogWrapper>();
073    
074    }