1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache license, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the license for the specific language governing permissions and
15 * limitations under the license.
16 */
17 package org.apache.logging.log4j.core.lookup;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.logging.log4j.core.LogEvent;
24 import org.apache.logging.log4j.core.config.plugins.Plugin;
25 import org.apache.logging.log4j.message.MapMessage;
26
27 /**
28 * A map-based lookup.
29 */
30 @Plugin(name = "map", category = StrLookup.CATEGORY)
31 public class MapLookup implements StrLookup {
32
33 /**
34 * Map keys are variable names and value.
35 */
36 private final Map<String, String> map;
37
38 /**
39 * Constructor when used directly as a plugin.
40 */
41 public MapLookup() {
42 this.map = null;
43 }
44
45 /**
46 * Creates a new instance backed by a Map. Used by the default lookup.
47 *
48 * @param map
49 * the map of keys to values, may be null
50 */
51 public MapLookup(final Map<String, String> map) {
52 this.map = map;
53 }
54
55 static Map<String, String> initMap(final String[] srcArgs, final Map<String, String> destMap) {
56 for (int i = 0; i < srcArgs.length; i++) {
57 final int next = i + 1;
58 final String value = srcArgs[i];
59 destMap.put(Integer.toString(i), value);
60 destMap.put(value, next < srcArgs.length ? srcArgs[next] : null);
61 }
62 return destMap;
63 }
64
65 static HashMap<String, String> newMap(final int initialCapacity) {
66 return new HashMap<>(initialCapacity);
67 }
68
69 /**
70 * An application's {@code public static main(String[])} method calls this method to make its main arguments
71 * available for lookup with the prefix {@code main}.
72 * <p>
73 * The map provides two kinds of access: First by index, starting at {@code "0"}, {@code "1"} and so on. For
74 * example, the command line {@code --file path/file.txt -x 2} can be accessed from a configuration file with:
75 * </p>
76 * <ul>
77 * <li>{@code "main:0"} = {@code "--file"}</li>
78 * <li>{@code "main:1"} = {@code "path/file.txt"}</li>
79 * <li>{@code "main:2"} = {@code "-x"}</li>
80 * <li>{@code "main:3"} = {@code "2"}</li>
81 * </ul>
82 * <p>
83 * Second using the argument at position n as the key to access the value at n+1.
84 * </p>
85 * <ul>
86 * <li>{@code "main:--file"} = {@code "path/file.txt"}</li>
87 * <li>{@code "main:-x"} = {@code "2"}</li>
88 * </ul>
89 *
90 * @param args
91 * An application's {@code public static main(String[])} arguments.
92 * @since 2.1
93 * @deprecated As of 2.4, use {@link MainMapLookup#setMainArguments(String[])}
94 */
95 @Deprecated
96 public static void setMainArguments(final String... args) {
97 MainMapLookup.setMainArguments(args);
98 }
99
100 static Map<String, String> toMap(final List<String> args) {
101 if (args == null) {
102 return null;
103 }
104 final int size = args.size();
105 return initMap(args.toArray(new String[size]), newMap(size));
106 }
107
108 static Map<String, String> toMap(final String[] args) {
109 if (args == null) {
110 return null;
111 }
112 return initMap(args, newMap(args.length));
113 }
114
115 protected Map<String, String> getMap() {
116 return map;
117 }
118
119 @Override
120 public String lookup(final LogEvent event, final String key) {
121 final boolean isMapMessage = event != null && event.getMessage() instanceof MapMessage;
122 if (map == null && !isMapMessage) {
123 return null;
124 }
125 if (map != null && map.containsKey(key)) {
126 final String obj = map.get(key);
127 if (obj != null) {
128 return obj;
129 }
130 }
131 if (isMapMessage) {
132 return ((MapMessage) event.getMessage()).get(key);
133 }
134 return null;
135 }
136
137 /**
138 * Looks up a String key to a String value using the map.
139 * <p>
140 * If the map is null, then null is returned. The map result object is converted to a string using toString().
141 * </p>
142 *
143 * @param key
144 * the key to be looked up, may be null
145 * @return the matching value, null if no match
146 */
147 @Override
148 public String lookup(final String key) {
149 if (map == null) {
150 return null;
151 }
152 return map.get(key);
153 }
154
155 }