001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.log4j.pattern;
019
020import org.apache.log4j.spi.LoggingEvent;
021
022import java.util.Iterator;
023import java.util.Set;
024import org.apache.log4j.helpers.*;
025
026
027/**
028 * Able to handle the contents of the LoggingEvent's Property bundle and either
029 * output the entire contents of the properties in a similar format to the
030 * java.util.Hashtable.toString(), or to output the value of a specific key
031 * within the property bundle
032 * when this pattern converter has the option set.
033 *
034 * @author Paul Smith
035 * @author Ceki Gülcü
036 */
037public final class PropertiesPatternConverter
038  extends LoggingEventPatternConverter {
039  /**
040   * Name of property to output.
041   */
042  private final String option;
043
044  /**
045   * Private constructor.
046   * @param options options, may be null.
047   */
048  private PropertiesPatternConverter(
049    final String[] options) {
050    super(
051      ((options != null) && (options.length > 0))
052      ? ("Property{" + options[0] + "}") : "Properties", "property");
053
054    if ((options != null) && (options.length > 0)) {
055      option = options[0];
056    } else {
057      option = null;
058    }
059  }
060
061  /**
062   * Obtains an instance of PropertiesPatternConverter.
063   * @param options options, may be null or first element contains name of property to format.
064   * @return instance of PropertiesPatternConverter.
065   */
066  public static PropertiesPatternConverter newInstance(
067    final String[] options) {
068    return new PropertiesPatternConverter(options);
069  }
070
071  /**
072   * {@inheritDoc}
073   */
074  public void format(final LoggingEvent event, final StringBuffer toAppendTo) {
075    // if there is no additional options, we output every single
076    // Key/Value pair for the MDC in a similar format to Hashtable.toString()
077    if (option == null) {
078      toAppendTo.append("{");
079
080      try {
081        Set keySet = MDCKeySetExtractor.INSTANCE.getPropertyKeySet(event);
082          if (keySet != null) {
083            for (Iterator i = keySet.iterator(); i.hasNext();) {
084                Object item = i.next();
085                Object val = event.getMDC(item.toString());
086                toAppendTo.append("{").append(item).append(",").append(val).append(
087                "}");
088            }
089          }
090      } catch(Exception ex) {
091              LogLog.error("Unexpected exception while extracting MDC keys", ex);
092      }
093
094      toAppendTo.append("}");
095    } else {
096      // otherwise they just want a single key output
097      Object val = event.getMDC(option);
098
099      if (val != null) {
100        toAppendTo.append(val);
101      }
102    }
103  }
104}