001/* 002 * Copyright (C) 2019 Michael N. Lipp (http://www.mnl.de) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package de.mnl.osgi.lf4osgi.core; 018 019import java.security.AccessController; 020import java.security.PrivilegedAction; 021import java.util.Arrays; 022import org.osgi.framework.Bundle; 023import org.osgi.service.log.LogLevel; 024import org.osgi.service.log.Logger; 025import org.osgi.service.log.LoggerFactory; 026 027/** 028 * Provides a container for the buffered event information. 029 */ 030@SuppressWarnings("PMD.DataflowAnomalyAnalysis") 031public class BufferedEvent { 032 033 private static final Object[] EMPTY_ARRAY = new Object[0]; 034 private final Bundle bundle; 035 private final String threadName; 036 private final String name; 037 private final LogLevel level; 038 private final String message; 039 private final Object[] arguments; 040 041 /** 042 * Instantiates a new buffered event. 043 * 044 * @param bundle the bundle 045 * @param name the name 046 * @param level the level 047 * @param message the message 048 * @param arguments the parameters 049 */ 050 public BufferedEvent(Bundle bundle, String name, LogLevel level, 051 String message, Object... arguments) { 052 this.bundle = bundle; 053 this.name = name; 054 this.level = level; 055 this.message = message; 056 this.arguments = Arrays.copyOf(arguments, arguments.length); 057 threadName = Thread.currentThread().getName(); 058 } 059 060 /** 061 * Instantiates a new buffered event. 062 * 063 * @param bundle the bundle 064 * @param name the name 065 * @param level the level 066 * @param message the message 067 */ 068 public BufferedEvent(Bundle bundle, String name, LogLevel level, 069 String message) { 070 this.bundle = bundle; 071 this.name = name; 072 this.level = level; 073 this.message = message; 074 arguments = EMPTY_ARRAY; 075 threadName = Thread.currentThread().getName(); 076 } 077 078 /** 079 * Forward the log event using the provided logger factory. 080 * 081 * @param factory the factory 082 */ 083 @SuppressWarnings({ "PMD.AvoidLiteralsInIfCondition", "PMD.EmptyCatchBlock", 084 "PMD.NcssCount" }) 085 public void forward(LoggerFactory factory) { 086 String savedName = Thread.currentThread().getName(); 087 try { 088 // Set thread name to get nice thread info 089 try { 090 AccessController.doPrivileged(new PrivilegedAction<Void>() { 091 @Override 092 public Void run() { 093 Thread.currentThread() 094 .setName(threadName + " [recorded]"); 095 return null; 096 } 097 }); 098 } catch (SecurityException e) { 099 // Ignored, was just a best effort. 100 } 101 // Now process 102 doForward(factory); 103 } finally { 104 try { 105 AccessController.doPrivileged(new PrivilegedAction<Void>() { 106 @Override 107 public Void run() { 108 Thread.currentThread().setName(savedName); 109 return null; // NOPMD 110 } 111 }); 112 } catch (SecurityException e) { 113 // Ignored. If resetting doesn't work, setting hasn't worked 114 // either 115 } 116 } 117 118 } 119 120 @SuppressWarnings({ "PMD.NcssCount", "PMD.CognitiveComplexity" }) 121 private void doForward(LoggerFactory factory) { 122 Logger logger; 123 if ((bundle.getState() & (Bundle.RESOLVED | Bundle.STARTING 124 | Bundle.ACTIVE | Bundle.STOPPING)) == 0) { 125 // Cannot log with unresolved bundle. 126 logger = factory.getLogger(name, Logger.class); 127 } else { 128 logger = factory.getLogger(bundle, name, Logger.class); 129 } 130 switch (level) { 131 case TRACE: 132 if (arguments.length == 0) { 133 logger.trace(l -> l.trace(message)); 134 } else { 135 logger.trace(l -> l.trace(message, arguments)); 136 } 137 break; 138 case DEBUG: 139 if (arguments.length == 0) { 140 logger.debug(l -> l.debug(message)); 141 } else { 142 logger.debug(l -> l.debug(message, arguments)); 143 } 144 break; 145 case INFO: 146 if (arguments.length == 0) { 147 logger.info(l -> l.info(message)); 148 } else { 149 logger.info(l -> l.info(message, arguments)); 150 } 151 break; 152 case WARN: 153 if (arguments.length == 0) { 154 logger.warn(l -> l.warn(message)); 155 } else { 156 logger.warn(l -> l.warn(message, arguments)); 157 } 158 break; 159 case ERROR: 160 if (arguments.length == 0) { 161 logger.error(l -> l.error(message)); 162 } else { 163 logger.error(l -> l.error(message, arguments)); 164 } 165 break; 166 case AUDIT: 167 if (arguments.length == 0) { 168 logger.audit(message); 169 } else { 170 logger.audit(message, arguments); 171 } 172 break; 173 } 174 } 175 176}