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

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

Go to download

The Pax Logging API Library is to allow for the Pax Logging Service to be reloaded without stopping the many dependent bundles. It also contains the OSGi Log Service API and the Knopflerfish Log API.

There is a newer version: 2.2.8
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 - 2025 Weber Informatics LLC | Privacy Policy