001package ch.qos.logback.classic.pattern;
002
003import java.util.List;
004
005import org.slf4j.event.KeyValuePair;
006
007import ch.qos.logback.classic.spi.ILoggingEvent;
008import ch.qos.logback.core.CoreConstants;
009
010/**
011 * Convert the contents of {@link KeyValuePair} list to a String.
012 * 
013 * Assuming the list contains the list {k1, v1}, {k2, v2}, the String output
014 * will be "k1=v1 k2=v2", without the quotes.
015 *
016 * 
017 * @since 1.3.0
018 * @author Ceki Gülcü
019 *
020 */
021public class KeyValuePairConverter extends ClassicConverter {
022
023    static final String DOUBLE_OPTION_STR = "DOUBLE";
024    static final String SINGLE_OPTION_STR = "SINGLE";
025    static final String NONE_OPTION_STR = "NONE";
026
027    enum ValueQuoteSpecification {
028        NONE, SINGLE, DOUBLE;
029
030        Character asChar() {
031            switch (this) {
032            case NONE:
033                return null;
034            case DOUBLE:
035                return '"';
036            case SINGLE:
037                return '\'';
038            default:
039                throw new IllegalStateException();
040            }
041        }
042    }
043
044    ValueQuoteSpecification valueQuoteSpec = ValueQuoteSpecification.DOUBLE;
045
046    public void start() {
047        String optStr = getFirstOption();
048        valueQuoteSpec = optionStrToSpec(optStr);
049        super.start();
050    }
051
052    private ValueQuoteSpecification optionStrToSpec(String optStr) {
053        if (optStr == null)
054            return ValueQuoteSpecification.DOUBLE;
055        if (DOUBLE_OPTION_STR.equalsIgnoreCase(optStr))
056            return ValueQuoteSpecification.DOUBLE;
057        if (SINGLE_OPTION_STR.equalsIgnoreCase(optStr))
058            return ValueQuoteSpecification.SINGLE;
059        if (NONE_OPTION_STR.equalsIgnoreCase(optStr))
060            return ValueQuoteSpecification.NONE;
061        return ValueQuoteSpecification.DOUBLE;
062    }
063
064    @Override
065    public String convert(ILoggingEvent event) {
066
067        List<KeyValuePair> kvpList = event.getKeyValuePairs();
068        if (kvpList == null || kvpList.isEmpty()) {
069            return CoreConstants.EMPTY_STRING;
070        }
071
072        StringBuilder sb = new StringBuilder();
073        for (int i = 0; i < kvpList.size(); i++) {
074            KeyValuePair kvp = kvpList.get(i);
075            if (i != 0)
076                sb.append(' ');
077            sb.append(String.valueOf(kvp.key));
078            sb.append('=');
079            Character quoteChar = valueQuoteSpec.asChar();
080            if (quoteChar != null)
081                sb.append(quoteChar);
082            sb.append(String.valueOf(kvp.value));
083            if (quoteChar != null)
084                sb.append(quoteChar);
085        }
086
087        return sb.toString();
088    }
089
090}