001    /**
002     * Copyright (c) 2000-2013 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 com.liferay.portal.kernel.security.pacl.permission.PortalRuntimePermission;
018    
019    import java.util.Map;
020    import java.util.concurrent.ConcurrentHashMap;
021    import java.util.concurrent.ConcurrentMap;
022    
023    /**
024     * @author Brian Wing Shun Chan
025     * @author Shuyang Zhou
026     * @author Raymond Aug??
027     */
028    public class LogFactoryUtil {
029    
030            public static Log getLog(Class<?> c) {
031                    return getLog(c.getName());
032            }
033    
034            public static Log getLog(String name) {
035    
036                    // The following concurrent collection retrieve has the side effect of a
037                    // memory fence read. This will invalidate all dirty cache data if there
038                    // are any. If the LogWrapper swap happens before this, the new Log will
039                    // be visible to the current Thread.
040    
041                    LogWrapper logWrapper = _logWrappers.get(name);
042    
043                    if (logWrapper == null) {
044                            if (SanitizerLogWrapper.isEnabled()) {
045                                    logWrapper = new SanitizerLogWrapper(_logFactory.getLog(name));
046                            }
047                            else {
048                                    logWrapper = new LogWrapper(_logFactory.getLog(name));
049                            }
050    
051                            LogWrapper previousLogWrapper = _logWrappers.putIfAbsent(
052                                    name, logWrapper);
053    
054                            if (previousLogWrapper != null) {
055                                    logWrapper = previousLogWrapper;
056                            }
057                    }
058    
059                    return logWrapper;
060            }
061    
062            public static LogFactory getLogFactory() {
063                    PortalRuntimePermission.checkGetBeanProperty(LogFactoryUtil.class);
064    
065                    return _logFactory;
066            }
067    
068            public static void setLogFactory(LogFactory logFactory) {
069                    PortalRuntimePermission.checkSetBeanProperty(LogFactoryUtil.class);
070    
071                    for (Map.Entry<String, LogWrapper> entry : _logWrappers.entrySet()) {
072                            String name = entry.getKey();
073    
074                            LogWrapper logWrapper = entry.getValue();
075    
076                            logWrapper.setLog(logFactory.getLog(name));
077                    }
078    
079                    // The following volatile write will flush out all cache data. All
080                    // previously swapped LogWrappers will be visible for any reads after a
081                    // memory fence read according to the happens-before rules.
082    
083                    _logFactory = logFactory;
084            }
085    
086            private static volatile LogFactory _logFactory = new Jdk14LogFactoryImpl();
087    
088            private static final ConcurrentMap<String, LogWrapper> _logWrappers =
089                    new ConcurrentHashMap<String, LogWrapper>();
090    
091    }