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.lookup;
018
019 import org.apache.logging.log4j.Logger;
020 import org.apache.logging.log4j.core.LogEvent;
021 import org.apache.logging.log4j.core.config.plugins.PluginManager;
022 import org.apache.logging.log4j.core.config.plugins.PluginType;
023 import org.apache.logging.log4j.status.StatusLogger;
024
025 import java.util.HashMap;
026 import java.util.Map;
027
028 /**
029 * The Interpolator is a StrLookup that acts as a proxy for all the other StrLookups.
030 */
031 public class Interpolator implements StrLookup {
032
033 private static final Logger LOGGER = StatusLogger.getLogger();
034
035 /** Constant for the prefix separator. */
036 private static final char PREFIX_SEPARATOR = ':';
037
038 private final Map<String, StrLookup> lookups = new HashMap<String, StrLookup>();
039
040 private final StrLookup defaultLookup;
041
042 public Interpolator(final StrLookup defaultLookup) {
043 this.defaultLookup = defaultLookup == null ? new MapLookup(new HashMap<String, String>()) : defaultLookup;
044 final PluginManager manager = new PluginManager("Lookup");
045 manager.collectPlugins();
046 final Map<String, PluginType> plugins = manager.getPlugins();
047
048 for (final Map.Entry<String, PluginType> entry : plugins.entrySet()) {
049 @SuppressWarnings("unchecked")
050 final Class<StrLookup> clazz = entry.getValue().getPluginClass();
051 try {
052 lookups.put(entry.getKey(), clazz.newInstance());
053 } catch (final Exception ex) {
054 LOGGER.error("Unable to create Lookup for " + entry.getKey(), ex);
055 }
056 }
057 }
058
059 /**
060 * Create the default Interpolator using only Lookups that work without an event.
061 */
062 public Interpolator() {
063 this.defaultLookup = new MapLookup(new HashMap<String, String>());
064 lookups.put("sys", new SystemPropertiesLookup());
065 lookups.put("env", new EnvironmentLookup());
066 }
067
068 /**
069 * Resolves the specified variable. This implementation will try to extract
070 * a variable prefix from the given variable name (the first colon (':') is
071 * used as prefix separator). It then passes the name of the variable with
072 * the prefix stripped to the lookup object registered for this prefix. If
073 * no prefix can be found or if the associated lookup object cannot resolve
074 * this variable, the default lookup object will be used.
075 *
076 * @param var the name of the variable whose value is to be looked up
077 * @return the value of this variable or <b>null</b> if it cannot be
078 * resolved
079 */
080 @Override
081 public String lookup(final String var) {
082 return lookup(null, var);
083 }
084
085 /**
086 * Resolves the specified variable. This implementation will try to extract
087 * a variable prefix from the given variable name (the first colon (':') is
088 * used as prefix separator). It then passes the name of the variable with
089 * the prefix stripped to the lookup object registered for this prefix. If
090 * no prefix can be found or if the associated lookup object cannot resolve
091 * this variable, the default lookup object will be used.
092 *
093 * @param event The current LogEvent or null.
094 * @param var the name of the variable whose value is to be looked up
095 * @return the value of this variable or <b>null</b> if it cannot be
096 * resolved
097 */
098 @Override
099 public String lookup(final LogEvent event, String var) {
100 if (var == null) {
101 return null;
102 }
103
104 final int prefixPos = var.indexOf(PREFIX_SEPARATOR);
105 if (prefixPos >= 0) {
106 final String prefix = var.substring(0, prefixPos);
107 final String name = var.substring(prefixPos + 1);
108 final StrLookup lookup = lookups.get(prefix);
109 String value = null;
110 if (lookup != null) {
111 value = event == null ? lookup.lookup(name) : lookup.lookup(event, name);
112 }
113
114 if (value != null) {
115 return value;
116 }
117 var = var.substring(prefixPos + 1);
118 }
119 if (defaultLookup != null) {
120 return event == null ? defaultLookup.lookup(var) : defaultLookup.lookup(event, var);
121 }
122 return null;
123 }
124
125 @Override
126 public String toString() {
127 final StringBuilder sb = new StringBuilder();
128 for (final String name : lookups.keySet()) {
129 if (sb.length() == 0) {
130 sb.append("{");
131 } else {
132 sb.append(", ");
133 }
134
135 sb.append(name);
136 }
137 if (sb.length() > 0) {
138 sb.append("}");
139 }
140 return sb.toString();
141 }
142 }