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 package org.apache.logging.log4j.core.pattern;
018
019 import java.util.List;
020 import java.util.regex.Pattern;
021
022 import org.apache.logging.log4j.core.LogEvent;
023 import org.apache.logging.log4j.core.config.Configuration;
024 import org.apache.logging.log4j.core.config.plugins.Plugin;
025 import org.apache.logging.log4j.core.layout.PatternLayout;
026
027 /**
028 * Replacement pattern converter.
029 */
030 @Plugin(name = "replace", category = PatternConverter.CATEGORY)
031 @ConverterKeys({ "replace" })
032 public final class RegexReplacementConverter extends LogEventPatternConverter {
033
034 private final Pattern pattern;
035
036 private final String substitution;
037
038 private final List<PatternFormatter> formatters;
039
040 /**
041 * Construct the converter.
042 * @param formatters The PatternFormatters to generate the text to manipulate.
043 * @param pattern The regular expression Pattern.
044 * @param substitution The substitution string.
045 */
046 private RegexReplacementConverter(final List<PatternFormatter> formatters,
047 final Pattern pattern, final String substitution) {
048 super("replace", "replace");
049 this.pattern = pattern;
050 this.substitution = substitution;
051 this.formatters = formatters;
052 }
053
054 /**
055 * Gets an instance of the class.
056 *
057 * @param config The current Configuration.
058 * @param options pattern options, may be null. If first element is "short",
059 * only the first line of the throwable will be formatted.
060 * @return instance of class.
061 */
062 public static RegexReplacementConverter newInstance(final Configuration config, final String[] options) {
063 if (options.length != 3) {
064 LOGGER.error("Incorrect number of options on replace. Expected 3 received " + options.length);
065 return null;
066 }
067 if (options[0] == null) {
068 LOGGER.error("No pattern supplied on replace");
069 return null;
070 }
071 if (options[1] == null) {
072 LOGGER.error("No regular expression supplied on replace");
073 return null;
074 }
075 if (options[2] == null) {
076 LOGGER.error("No substitution supplied on replace");
077 return null;
078 }
079 final Pattern p = Pattern.compile(options[1]);
080 final PatternParser parser = PatternLayout.createPatternParser(config);
081 final List<PatternFormatter> formatters = parser.parse(options[0]);
082 return new RegexReplacementConverter(formatters, p, options[2]);
083 }
084
085
086 /**
087 * {@inheritDoc}
088 */
089 @Override
090 public void format(final LogEvent event, final StringBuilder toAppendTo) {
091 final StringBuilder buf = new StringBuilder();
092 for (final PatternFormatter formatter : formatters) {
093 formatter.format(event, buf);
094 }
095 toAppendTo.append(pattern.matcher(buf.toString()).replaceAll(substitution));
096 }
097 }