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.logging.log4j.core.config.plugins.visitors; 019 020import java.lang.annotation.Annotation; 021import java.lang.reflect.Member; 022import java.util.Map; 023import java.util.Objects; 024 025import org.apache.logging.log4j.Logger; 026import org.apache.logging.log4j.core.config.plugins.convert.TypeConverters; 027import org.apache.logging.log4j.core.lookup.StrSubstitutor; 028import org.apache.logging.log4j.status.StatusLogger; 029import org.apache.logging.log4j.util.Strings; 030 031/** 032 * Base class for PluginVisitor implementations. Provides convenience methods as well as all method implementations 033 * other than the {@code visit} method. 034 * 035 * @param <A> the Plugin annotation type. 036 */ 037public abstract class AbstractPluginVisitor<A extends Annotation> implements PluginVisitor<A> { 038 039 /** Status logger. */ 040 protected static final Logger LOGGER = StatusLogger.getLogger(); 041 042 /** 043 * 044 */ 045 protected final Class<A> clazz; 046 /** 047 * 048 */ 049 protected A annotation; 050 /** 051 * 052 */ 053 protected String[] aliases; 054 /** 055 * 056 */ 057 protected Class<?> conversionType; 058 /** 059 * 060 */ 061 protected StrSubstitutor substitutor; 062 /** 063 * 064 */ 065 protected Member member; 066 067 /** 068 * This constructor must be overridden by implementation classes as a no-arg constructor. 069 * 070 * @param clazz the annotation class this PluginVisitor is for. 071 */ 072 protected AbstractPluginVisitor(final Class<A> clazz) { 073 this.clazz = clazz; 074 } 075 076 @SuppressWarnings("unchecked") 077 @Override 078 public PluginVisitor<A> setAnnotation(final Annotation anAnnotation) { 079 final Annotation a = Objects.requireNonNull(anAnnotation, "No annotation was provided"); 080 if (this.clazz.isInstance(a)) { 081 this.annotation = (A) a; 082 } 083 return this; 084 } 085 086 @Override 087 public PluginVisitor<A> setAliases(final String... someAliases) { 088 this.aliases = someAliases; 089 return this; 090 } 091 092 @Override 093 public PluginVisitor<A> setConversionType(final Class<?> aConversionType) { 094 this.conversionType = Objects.requireNonNull(aConversionType, "No conversion type class was provided"); 095 return this; 096 } 097 098 @Override 099 public PluginVisitor<A> setStrSubstitutor(final StrSubstitutor aSubstitutor) { 100 this.substitutor = Objects.requireNonNull(aSubstitutor, "No StrSubstitutor was provided"); 101 return this; 102 } 103 104 @Override 105 public PluginVisitor<A> setMember(final Member aMember) { 106 this.member = aMember; 107 return this; 108 } 109 110 /** 111 * Removes an Entry from a given Map using a key name and aliases for that key. Keys are case-insensitive. 112 * 113 * @param attributes the Map to remove an Entry from. 114 * @param name the key name to look up. 115 * @param aliases optional aliases of the key name to look up. 116 * @return the value corresponding to the given key or {@code null} if nonexistent. 117 */ 118 protected static String removeAttributeValue(final Map<String, String> attributes, 119 final String name, 120 final String... aliases) { 121 for (final Map.Entry<String, String> entry : attributes.entrySet()) { 122 final String key = entry.getKey(); 123 final String value = entry.getValue(); 124 if (key.equalsIgnoreCase(name)) { 125 attributes.remove(key); 126 return value; 127 } 128 if (aliases != null) { 129 for (final String alias : aliases) { 130 if (key.equalsIgnoreCase(alias)) { 131 attributes.remove(key); 132 return value; 133 } 134 } 135 } 136 } 137 return null; 138 } 139 140 /** 141 * Converts the given value into the configured type falling back to the provided default value. 142 * 143 * @param value the value to convert. 144 * @param defaultValue the fallback value to use in case of no value or an error. 145 * @return the converted value whether that be based on the given value or the default value. 146 */ 147 protected Object convert(final String value, final Object defaultValue) { 148 if (defaultValue instanceof String) { 149 return TypeConverters.convert(value, this.conversionType, Strings.trimToNull((String) defaultValue)); 150 } 151 return TypeConverters.convert(value, this.conversionType, defaultValue); 152 } 153}