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.juneau.rest.server.logging; 018 019import java.util.*; 020 021/** 022 * Logger-name normalization for resource classes. 023 * 024 * <p> 025 * Walks up known proxy class names and returns the first non-proxy superclass so default logger naming is 026 * stable across common runtime-generated proxies while preserving ordinary nested-class names. 027 * 028 * @since 10.0.0 029 */ 030public final class LoggerNaming { 031 032 private static final List<String> KNOWN_PROXY_INFIXES = List.of( 033 "$$SpringCGLIB$$", 034 "$$EnhancerBySpringCGLIB$$", 035 "$$EnhancerByCGLIB$$", 036 "$$FastClassBySpringCGLIB$$", 037 "$ByteBuddy$", 038 "$Proxy", 039 "$HibernateProxy$", 040 "$MockitoMock$" 041 ); 042 043 private LoggerNaming() {} 044 045 /** 046 * Returns the user-class binary name for a class used in default logger derivation. 047 * 048 * <p> 049 * If the supplied class name contains a known proxy infix, this walks superclasses until it finds a 050 * class name without a known proxy infix. Ordinary nested classes are returned unchanged. 051 * 052 * @param c The class to normalize. Must not be <jk>null</jk>. 053 * @return The normalized binary class name. 054 */ 055 public static String userClassName(Class<?> c) { 056 var original = c; 057 while (c != null && containsKnownProxyInfix(c.getName())) 058 c = c.getSuperclass(); 059 return (c != null ? c : original).getName(); 060 } 061 062 private static boolean containsKnownProxyInfix(String className) { 063 for (var infix : KNOWN_PROXY_INFIXES) 064 if (className.contains(infix)) 065 return true; 066 return false; 067 } 068}