16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.logger; 27 28 import java.lang.ref.Reference; 29 import java.lang.ref.WeakReference; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.function.Function; 33 import java.lang.System.LoggerFinder; 34 import java.lang.System.Logger; 35 import java.lang.ref.ReferenceQueue; 36 import java.util.Collection; 37 import java.util.ResourceBundle; 38 39 /** 40 * Internal Service Provider Interface (SPI) that makes it possible to use 41 * {@code java.util.logging} as backend when the {@link 42 * sun.util.logging.internal.LoggingProviderImpl 43 * sun.util.logging.internal.LoggingProviderImpl} is present. 44 * <p> 45 * The JDK default implementation of the {@link LoggerFinder} will 46 * attempt to locate and load an {@linkplain 47 * java.util.ServiceLoader#loadInstalled(java.lang.Class) installed} 48 * implementation of the {@code DefaultLoggerFinder}. If {@code java.util.logging} 49 * is present, this will usually resolve to an instance of {@link 50 * sun.util.logging.internal.LoggingProviderImpl sun.util.logging.internal.LoggingProviderImpl}. 51 * Otherwise, if no concrete service provider is declared for 52 * {@code DefaultLoggerFinder}, the default implementation provided by this class 53 * will be used. 54 * <p> 55 * When the {@link sun.util.logging.internal.LoggingProviderImpl 112 new HashMap<>(); 113 private final ReferenceQueue<Logger> queue = new ReferenceQueue<>(); 114 115 synchronized Logger get(Function<String, Logger> loggerSupplier, final String name) { 116 Reference<? extends Logger> ref = loggers.get(name); 117 Logger w = ref == null ? null : ref.get(); 118 if (w == null) { 119 w = loggerSupplier.apply(name); 120 loggers.put(name, new WeakReference<>(w, queue)); 121 } 122 123 // Remove stale mapping... 124 Collection<Reference<Logger>> values = null; 125 while ((ref = queue.poll()) != null) { 126 if (values == null) values = loggers.values(); 127 values.remove(ref); 128 } 129 return w; 130 } 131 132 133 final static SharedLoggers system = new SharedLoggers(); 134 final static SharedLoggers application = new SharedLoggers(); 135 } 136 137 @Override 138 public final Logger getLogger(String name, /* Module */ Class<?> caller) { 139 checkPermission(); 140 return demandLoggerFor(name, caller); 141 } 142 143 @Override 144 public final Logger getLocalizedLogger(String name, ResourceBundle bundle, 145 /* Module */ Class<?> caller) { 146 return super.getLocalizedLogger(name, bundle, caller); 147 } 148 149 150 151 /** 152 * Returns a {@link Logger logger} suitable for the caller usage. 153 * 154 * @implSpec The default implementation for this method is to return a 155 * simple logger that will print all messages of INFO level and above 156 * to the console. That simple logger is not configurable. 157 * 158 * @param name The name of the logger. 159 * @param caller The class on behalf of which the logger is created. 160 * @return A {@link Logger logger} suitable for the application usage. 161 * @throws SecurityException if the calling code does not have the 162 * {@code RuntimePermission("loggerFinder")}. 163 */ 164 protected Logger demandLoggerFor(String name, /* Module */ Class<?> caller) { 165 checkPermission(); 166 if (caller.getClassLoader() == null) { 167 return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name); 168 } else { 169 return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name); 170 } 171 } 172 173 } | 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.logger; 27 28 import java.lang.ref.Reference; 29 import java.lang.ref.WeakReference; 30 import java.util.HashMap; 31 import java.util.Map; 32 import java.util.function.Function; 33 import java.lang.System.LoggerFinder; 34 import java.lang.System.Logger; 35 import java.lang.ref.ReferenceQueue; 36 import java.lang.reflect.Module; 37 import java.security.AccessController; 38 import java.security.PrivilegedAction; 39 import java.util.Collection; 40 import java.util.ResourceBundle; 41 42 /** 43 * Internal Service Provider Interface (SPI) that makes it possible to use 44 * {@code java.util.logging} as backend when the {@link 45 * sun.util.logging.internal.LoggingProviderImpl 46 * sun.util.logging.internal.LoggingProviderImpl} is present. 47 * <p> 48 * The JDK default implementation of the {@link LoggerFinder} will 49 * attempt to locate and load an {@linkplain 50 * java.util.ServiceLoader#loadInstalled(java.lang.Class) installed} 51 * implementation of the {@code DefaultLoggerFinder}. If {@code java.util.logging} 52 * is present, this will usually resolve to an instance of {@link 53 * sun.util.logging.internal.LoggingProviderImpl sun.util.logging.internal.LoggingProviderImpl}. 54 * Otherwise, if no concrete service provider is declared for 55 * {@code DefaultLoggerFinder}, the default implementation provided by this class 56 * will be used. 57 * <p> 58 * When the {@link sun.util.logging.internal.LoggingProviderImpl 115 new HashMap<>(); 116 private final ReferenceQueue<Logger> queue = new ReferenceQueue<>(); 117 118 synchronized Logger get(Function<String, Logger> loggerSupplier, final String name) { 119 Reference<? extends Logger> ref = loggers.get(name); 120 Logger w = ref == null ? null : ref.get(); 121 if (w == null) { 122 w = loggerSupplier.apply(name); 123 loggers.put(name, new WeakReference<>(w, queue)); 124 } 125 126 // Remove stale mapping... 127 Collection<Reference<Logger>> values = null; 128 while ((ref = queue.poll()) != null) { 129 if (values == null) values = loggers.values(); 130 values.remove(ref); 131 } 132 return w; 133 } 134 135 final static SharedLoggers system = new SharedLoggers(); 136 final static SharedLoggers application = new SharedLoggers(); 137 } 138 139 public static boolean isSystem(Module m) { 140 ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<>() { 141 @Override 142 public ClassLoader run() { 143 return m.getClassLoader(); 144 } 145 }); 146 return cl == null; 147 } 148 149 @Override 150 public final Logger getLogger(String name, Module module) { 151 checkPermission(); 152 return demandLoggerFor(name, module); 153 } 154 155 @Override 156 public final Logger getLocalizedLogger(String name, ResourceBundle bundle, 157 Module module) { 158 return super.getLocalizedLogger(name, bundle, module); 159 } 160 161 /** 162 * Returns a {@link Logger logger} suitable for use within the 163 * given {@code module}. 164 * 165 * @implSpec The default implementation for this method is to return a 166 * simple logger that will print all messages of INFO level and above 167 * to the console. That simple logger is not configurable. 168 * 169 * @param name The name of the logger. 170 * @param module The module on behalf of which the logger is created. 171 * @return A {@link Logger logger} suitable for the application usage. 172 * @throws SecurityException if the calling code does not have the 173 * {@code RuntimePermission("loggerFinder")}. 174 */ 175 protected Logger demandLoggerFor(String name, Module module) { 176 checkPermission(); 177 if (isSystem(module)) { 178 return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name); 179 } else { 180 return SharedLoggers.application.get(SimpleConsoleLogger::makeSimpleLogger, name); 181 } 182 } 183 184 } |