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 */
017package org.apache.log4j.rewrite;
018
019import java.util.HashMap;
020import java.util.Iterator;
021import java.util.Map;
022
023import org.apache.log4j.Logger;
024import org.apache.log4j.spi.LoggingEvent;
025
026/**
027 * This policy rewrites events where the message of the
028 * original event implementes java.util.Map.
029 * All other events are passed through unmodified.
030 * If the map contains a "message" entry, the value will be
031 * used as the message for the rewritten event.  The rewritten
032 * event will have a property set that is the combination of the
033 * original property set and the other members of the message map.
034 * If both the original property set and the message map
035 * contain the same entry, the value from the message map
036 * will overwrite the original property set.
037 *
038 * The combination of the RewriteAppender and this policy
039 * performs the same actions as the MapFilter from log4j 1.3. 
040 */
041public class MapRewritePolicy implements RewritePolicy {
042    /**
043     * {@inheritDoc}
044     */
045    public LoggingEvent rewrite(final LoggingEvent source) {
046        Object msg = source.getMessage();
047        if (msg instanceof Map) {
048            Map props = new HashMap(source.getProperties());
049            Map eventProps = (Map) msg;
050            //
051            //   if the map sent in the logging request
052            //      has "message" entry, use that as the message body
053            //      otherwise, use the entire map.
054            //
055            Object newMsg = eventProps.get("message");
056            if (newMsg == null) {
057                newMsg = msg;
058            }
059
060            for(Iterator iter = eventProps.entrySet().iterator();
061                    iter.hasNext();
062                  ) {
063                Map.Entry entry = (Map.Entry) iter.next();
064                if (!("message".equals(entry.getKey()))) {
065                    props.put(entry.getKey(), entry.getValue());
066                }
067            }
068
069            return new LoggingEvent(
070                    source.getFQNOfLoggerClass(),
071                    source.getLogger() != null ? source.getLogger(): Logger.getLogger(source.getLoggerName()), 
072                    source.getTimeStamp(),
073                    source.getLevel(),
074                    newMsg,
075                    source.getThreadName(),
076                    source.getThrowableInformation(),
077                    source.getNDC(),
078                    source.getLocationInformation(),
079                    props);
080        } else {
081            return source;
082        }
083
084    }
085}