All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.logging.log4j.message.MapMessage Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.message;

import java.util.Collections;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.logging.log4j.util.EnglishEnums;
import org.apache.logging.log4j.util.StringBuilders;
import org.apache.logging.log4j.util.Strings;

/**
 * Represents a Message that consists of a Map.
 * 

* Thread-safety note: the contents of this message can be modified after construction. * When using asynchronous loggers and appenders it is not recommended to modify this message after the message is * logged, because it is undefined whether the logged message string will contain the old values or the modified * values. */ public class MapMessage implements MultiformatMessage { /** * When set as the format specifier causes the Map to be formatted as XML. */ public enum MapFormat { /** The map should be formatted as XML. */ XML, /** The map should be formatted as JSON. */ JSON, /** The map should be formatted the same as documented by java.util.AbstractMap.toString(). */ JAVA } private static final long serialVersionUID = -5031471831131487120L; private final SortedMap data; /** * Constructor. */ public MapMessage() { data = new TreeMap(); } /** * Constructor based on an existing Map. * @param map The Map. */ public MapMessage(final Map map) { this.data = map instanceof SortedMap ? (SortedMap) map : new TreeMap(map); } @Override public String[] getFormats() { final String[] formats = new String[MapFormat.values().length]; int i = 0; for (final MapFormat format : MapFormat.values()) { formats[i++] = format.name(); } return formats; } /** * Returns the data elements as if they were parameters on the logging event. * @return the data elements. */ @Override public Object[] getParameters() { return data.values().toArray(); } /** * Returns the message. * @return the message. */ @Override public String getFormat() { return Strings.EMPTY; } /** * Returns the message data as an unmodifiable Map. * @return the message data as an unmodifiable map. */ public Map getData() { return Collections.unmodifiableMap(data); } /** * Clear the data. */ public void clear() { data.clear(); } /** * Add an item to the data Map. * @param key The name of the data item. * @param value The value of the data item. */ public void put(final String key, final String value) { if (value == null) { throw new IllegalArgumentException("No value provided for key " + key); } validate(key, value); data.put(key, value); } protected void validate(final String key, final String value) { } /** * Add all the elements from the specified Map. * @param map The Map to add. */ public void putAll(final Map map) { data.putAll(map); } /** * Retrieve the value of the element with the specified key or null if the key is not present. * @param key The name of the element. * @return The value of the element or null if the key is not present. */ public String get(final String key) { return data.get(key); } /** * Remove the element with the specified name. * @param key The name of the element. * @return The previous value of the element. */ public String remove(final String key) { return data.remove(key); } /** * Format the Structured data as described in RFC 5424. * * @return The formatted String. */ public String asString() { return asString((MapFormat) null); } public String asString(final String format) { try { return asString(EnglishEnums.valueOf(MapFormat.class, format)); } catch (final IllegalArgumentException ex) { return asString(); } } /** * Format the Structured data as described in RFC 5424. * * @param format The format identifier. Ignored in this implementation. * @return The formatted String. */ private String asString(final MapFormat format) { final StringBuilder sb = new StringBuilder(); if (format == null) { appendMap(sb); } else { switch (format) { case XML : { asXml(sb); break; } case JSON : { asJson(sb); break; } case JAVA : { asJava(sb); break; } default : { appendMap(sb); } } } return sb.toString(); } public void asXml(final StringBuilder sb) { sb.append("\n"); for (final Map.Entry entry : data.entrySet()) { sb.append(" ").append(entry.getValue()) .append("\n"); } sb.append(""); } /** * Format the message and return it. * @return the formatted message. */ @Override public String getFormattedMessage() { return asString(); } /** * * @param formats An array of Strings that provide extra information about how to format the message. * MapMessage uses the first format specifier it recognizes. The supported formats are XML, JSON, and * JAVA. The default format is key1="value1" key2="value2" as required by RFC 5424 messages. * * @return The formatted message. */ @Override public String getFormattedMessage(final String[] formats) { if (formats == null || formats.length == 0) { return asString(); } for (final String format : formats) { for (final MapFormat mapFormat : MapFormat.values()) { if (mapFormat.name().equalsIgnoreCase(format)) { return asString(mapFormat); } } } return asString(); } protected void appendMap(final StringBuilder sb) { boolean first = true; for (final Map.Entry entry : data.entrySet()) { if (!first) { sb.append(' '); } first = false; StringBuilders.appendKeyDqValue(sb, entry); } } protected void asJson(final StringBuilder sb) { boolean first = true; sb.append('{'); for (final Map.Entry entry : data.entrySet()) { if (!first) { sb.append(", "); } first = false; StringBuilders.appendDqValue(sb, entry.getKey()).append(':'); StringBuilders.appendDqValue(sb, entry.getValue()); } sb.append('}'); } protected void asJava(final StringBuilder sb) { boolean first = true; sb.append('{'); for (final Map.Entry entry : data.entrySet()) { if (!first) { sb.append(", "); } first = false; StringBuilders.appendKeyDqValue(sb, entry); } sb.append('}'); } public MapMessage newInstance(final Map map) { return new MapMessage(map); } @Override public String toString() { return asString(); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || this.getClass() != o.getClass()) { return false; } final MapMessage that = (MapMessage) o; return this.data.equals(that.data); } @Override public int hashCode() { return data.hashCode(); } /** * Always returns null. * * @return null */ @Override public Throwable getThrowable() { return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy