001/* 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2026, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v2.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014 015package ch.qos.logback.classic.pattern; 016 017import java.util.List; 018 019import org.slf4j.event.KeyValuePair; 020 021import ch.qos.logback.classic.spi.ILoggingEvent; 022import ch.qos.logback.core.CoreConstants; 023 024/** 025 * Convert the contents of {@link KeyValuePair} list to a String. 026 * 027 * Assuming the list contains the list {k1, v1}, {k2, v2}, the String output 028 * will be "k1=v1 k2=v2", without the quotes. 029 * 030 * 031 * @since 1.3.0 032 * @author Ceki Gülcü 033 * 034 */ 035public class KeyValuePairConverter extends ClassicConverter { 036 037 static final String DOUBLE_OPTION_STR = "DOUBLE"; 038 static final String SINGLE_OPTION_STR = "SINGLE"; 039 static final String NONE_OPTION_STR = "NONE"; 040 041 enum ValueQuoteSpecification { 042 NONE, SINGLE, DOUBLE; 043 044 Character asChar() { 045 switch (this) { 046 case NONE: 047 return null; 048 case DOUBLE: 049 return '"'; 050 case SINGLE: 051 return '\''; 052 default: 053 throw new IllegalStateException(); 054 } 055 } 056 } 057 058 ValueQuoteSpecification valueQuoteSpec = ValueQuoteSpecification.DOUBLE; 059 060 public void start() { 061 String optStr = getFirstOption(); 062 valueQuoteSpec = optionStrToSpec(optStr); 063 super.start(); 064 } 065 066 private ValueQuoteSpecification optionStrToSpec(String optStr) { 067 if (optStr == null) 068 return ValueQuoteSpecification.DOUBLE; 069 if (DOUBLE_OPTION_STR.equalsIgnoreCase(optStr)) 070 return ValueQuoteSpecification.DOUBLE; 071 if (SINGLE_OPTION_STR.equalsIgnoreCase(optStr)) 072 return ValueQuoteSpecification.SINGLE; 073 if (NONE_OPTION_STR.equalsIgnoreCase(optStr)) 074 return ValueQuoteSpecification.NONE; 075 return ValueQuoteSpecification.DOUBLE; 076 } 077 078 @Override 079 public String convert(ILoggingEvent event) { 080 081 List<KeyValuePair> kvpList = event.getKeyValuePairs(); 082 if (kvpList == null || kvpList.isEmpty()) { 083 return CoreConstants.EMPTY_STRING; 084 } 085 086 StringBuilder sb = new StringBuilder(); 087 for (int i = 0; i < kvpList.size(); i++) { 088 KeyValuePair kvp = kvpList.get(i); 089 if (i != 0) 090 sb.append(' '); 091 sb.append(String.valueOf(kvp.key)); 092 sb.append('='); 093 Character quoteChar = valueQuoteSpec.asChar(); 094 if (quoteChar != null) 095 sb.append(quoteChar); 096 sb.append(String.valueOf(kvp.value)); 097 if (quoteChar != null) 098 sb.append(quoteChar); 099 } 100 101 return sb.toString(); 102 } 103 104}