001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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    }