001package org.slf4j.helpers; 002 003import org.slf4j.event.LoggingEvent; 004 005/** 006 * Holds normalized call parameters. 007 * 008 * Includes utility methods such as {@link #normalize(String, Object[], Throwable)} to help the normalization of parameters. 009 * 010 * @author ceki 011 * @since 2.0 012 */ 013public class NormalizedParameters { 014 015 final String message; 016 final Object[] arguments; 017 final Throwable throwable; 018 019 public NormalizedParameters(String message, Object[] arguments, Throwable throwable) { 020 this.message = message; 021 this.arguments = arguments; 022 this.throwable = throwable; 023 } 024 025 public NormalizedParameters(String message, Object[] arguments) { 026 this(message, arguments, null); 027 } 028 029 public String getMessage() { 030 return message; 031 } 032 033 public Object[] getArguments() { 034 return arguments; 035 } 036 037 public Throwable getThrowable() { 038 return throwable; 039 } 040 041 /** 042 * Helper method to determine if an {@link Object} array contains a 043 * {@link Throwable} as last element 044 * 045 * @param argArray The arguments off which we want to know if it contains a 046 * {@link Throwable} as last element 047 * @return if the last {@link Object} in argArray is a {@link Throwable} this 048 * method will return it, otherwise it returns null 049 */ 050 public static Throwable getThrowableCandidate(final Object[] argArray) { 051 if (argArray == null || argArray.length == 0) { 052 return null; 053 } 054 055 final Object lastEntry = argArray[argArray.length - 1]; 056 if (lastEntry instanceof Throwable) { 057 return (Throwable) lastEntry; 058 } 059 060 return null; 061 } 062 063 /** 064 * Helper method to get all but the last element of an array 065 * 066 * @param argArray The arguments from which we want to remove the last element 067 * 068 * @return a copy of the array without the last element 069 */ 070 public static Object[] trimmedCopy(final Object[] argArray) { 071 if (argArray == null || argArray.length == 0) { 072 throw new IllegalStateException("non-sensical empty or null argument array"); 073 } 074 075 final int trimmedLen = argArray.length - 1; 076 077 Object[] trimmed = new Object[trimmedLen]; 078 079 if (trimmedLen > 0) { 080 System.arraycopy(argArray, 0, trimmed, 0, trimmedLen); 081 } 082 083 return trimmed; 084 } 085 086 /** 087 * This method serves to normalize logging call invocation parameters. 088 * 089 * More specifically, if a throwable argument is not supplied directly, it 090 * attempts to extract it from the argument array. 091 */ 092 public static NormalizedParameters normalize(String msg, Object[] arguments, Throwable t) { 093 094 if (t != null) { 095 return new NormalizedParameters(msg, arguments, t); 096 } 097 098 if (arguments == null || arguments.length == 0) { 099 return new NormalizedParameters(msg, arguments, t); 100 } 101 102 Throwable throwableCandidate = NormalizedParameters.getThrowableCandidate(arguments); 103 if (throwableCandidate != null) { 104 Object[] trimmedArguments = MessageFormatter.trimmedCopy(arguments); 105 return new NormalizedParameters(msg, trimmedArguments, throwableCandidate); 106 } else { 107 return new NormalizedParameters(msg, arguments); 108 } 109 110 } 111 112 public static NormalizedParameters normalize(LoggingEvent event) { 113 return normalize(event.getMessage(), event.getArgumentArray(), event.getThrowable()); 114 } 115 116}