Source Code for Apache Log4j Core Implementation

Apache Log4j Core Implementation provides the functional components of the logging system. Users are free to create their own plugins and include them in the logging configuration. Apache Log4j Core is a required module to use Apache Log4j.

Bytecode (Java 8) for Apache Log4j Core Implementation is provided in a separate JAR file like log4j-core-2.14.1.jar.

Source Code files for Apache Log4j API are provided in both binary packge like apache-log4j-2.14.1-bin.zip and source package like apache-log4j-2.14.1-src.zip. You can download them at Apache Log4j Website.

You can also browse Source Code files for Apache Log4j Core Implementation 2.14.1 below.

✍: FYIcenter.com

org/apache/logging/log4j/core/util/TypeUtil.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.core.util;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Utility class for working with Java {@link Type}s and derivatives. This class is adapted heavily from the
 * <a href="http://projects.spring.io/spring-framework/">Spring Framework</a>, specifically the
 * <a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/TypeUtils.html">TypeUtils</a>
 * class.
 *
 * @see java.lang.reflect.Type
 * @see java.lang.reflect.GenericArrayType
 * @see java.lang.reflect.ParameterizedType
 * @see java.lang.reflect.WildcardType
 * @see java.lang.Class
 * @since 2.1
 */
public final class TypeUtil {

    private TypeUtil() {
    }

    /**
     * Gets all declared fields for the given class (including superclasses).
     *
     * @param cls the class to examine
     * @return all declared fields for the given class (including superclasses).
     * @see Class#getDeclaredFields()
     */
    public static List<Field> getAllDeclaredFields(Class<?> cls) {
        final List<Field> fields = new ArrayList<>();
        while (cls != null) {
            Collections.addAll(fields, cls.getDeclaredFields());
            cls = cls.getSuperclass();
        }
        return fields;
    }
    /**
     * Indicates if two {@link Type}s are assignment compatible.
     *
     * @param lhs the left hand side to check assignability to
     * @param rhs the right hand side to check assignability from
     * @return {@code true} if it is legal to assign a variable of type {@code rhs} to a variable of type {@code lhs}
     * @see Class#isAssignableFrom(Class)
     */
    public static boolean isAssignable(final Type lhs, final Type rhs) {
        Objects.requireNonNull(lhs, "No left hand side type provided");
        Objects.requireNonNull(rhs, "No right hand side type provided");
        if (lhs.equals(rhs)) {
            return true;
        }
        if (Object.class.equals(lhs)) {
            // everything is assignable to Object
            return true;
        }
        // raw type on left
        if (lhs instanceof Class<?>) {
            final Class<?> lhsClass = (Class<?>) lhs;
            if (rhs instanceof Class<?>) {
                // no generics involved
                final Class<?> rhsClass = (Class<?>) rhs;
                return lhsClass.isAssignableFrom(rhsClass);
            }
            if (rhs instanceof ParameterizedType) {
                // check to see if the parameterized type has the same raw type as the lhs; this is legal
                final Type rhsRawType = ((ParameterizedType) rhs).getRawType();
                if (rhsRawType instanceof Class<?>) {
                    return lhsClass.isAssignableFrom((Class<?>) rhsRawType);
                }
            }
            if (lhsClass.isArray() && rhs instanceof GenericArrayType) {
                // check for compatible array component types
                return isAssignable(lhsClass.getComponentType(), ((GenericArrayType) rhs).getGenericComponentType());
            }
        }
        // parameterized type on left
        if (lhs instanceof ParameterizedType) {
            final ParameterizedType lhsType = (ParameterizedType) lhs;
            if (rhs instanceof Class<?>) {
                final Type lhsRawType = lhsType.getRawType();
                if (lhsRawType instanceof Class<?>) {
                    return ((Class<?>) lhsRawType).isAssignableFrom((Class<?>) rhs);
                }
            } else if (rhs instanceof ParameterizedType) {
                final ParameterizedType rhsType = (ParameterizedType) rhs;
                return isParameterizedAssignable(lhsType, rhsType);
            }
        }
        // generic array type on left
        if (lhs instanceof GenericArrayType) {
            final Type lhsComponentType = ((GenericArrayType) lhs).getGenericComponentType();
            if (rhs instanceof Class<?>) {
                // raw type on right
                final Class<?> rhsClass = (Class<?>) rhs;
                if (rhsClass.isArray()) {
                    return isAssignable(lhsComponentType, rhsClass.getComponentType());
                }
            } else if (rhs instanceof GenericArrayType) {
                return isAssignable(lhsComponentType, ((GenericArrayType) rhs).getGenericComponentType());
            }
        }
        // wildcard type on left
        if (lhs instanceof WildcardType) {
            return isWildcardAssignable((WildcardType) lhs, rhs);
        }
        // strange...
        return false;
    }

    private static boolean isParameterizedAssignable(final ParameterizedType lhs, final ParameterizedType rhs) {
        if (lhs.equals(rhs)) {
            // that was easy
            return true;
        }
        final Type[] lhsTypeArguments = lhs.getActualTypeArguments();
        final Type[] rhsTypeArguments = rhs.getActualTypeArguments();
        final int size = lhsTypeArguments.length;
        if (rhsTypeArguments.length != size) {
            // clearly incompatible types
            return false;
        }
        for (int i = 0; i < size; i++) {
            // verify all type arguments are assignable
            final Type lhsArgument = lhsTypeArguments[i];
            final Type rhsArgument = rhsTypeArguments[i];
            if (!lhsArgument.equals(rhsArgument) &&
                !(lhsArgument instanceof WildcardType &&
                    isWildcardAssignable((WildcardType) lhsArgument, rhsArgument))) {
                return false;
            }
        }
        return true;
    }

    private static boolean isWildcardAssignable(final WildcardType lhs, final Type rhs) {
        final Type[] lhsUpperBounds = getEffectiveUpperBounds(lhs);
        final Type[] lhsLowerBounds = getEffectiveLowerBounds(lhs);
        if (rhs instanceof WildcardType) {
            // oh boy, this scenario requires checking a lot of assignability!
            final WildcardType rhsType = (WildcardType) rhs;
            final Type[] rhsUpperBounds = getEffectiveUpperBounds(rhsType);
            final Type[] rhsLowerBounds = getEffectiveLowerBounds(rhsType);
            for (final Type lhsUpperBound : lhsUpperBounds) {
                for (final Type rhsUpperBound : rhsUpperBounds) {
                    if (!isBoundAssignable(lhsUpperBound, rhsUpperBound)) {
                        return false;
                    }
                }
                for (final Type rhsLowerBound : rhsLowerBounds) {
                    if (!isBoundAssignable(lhsUpperBound, rhsLowerBound)) {
                        return false;
                    }
                }
            }
            for (final Type lhsLowerBound : lhsLowerBounds) {
                for (final Type rhsUpperBound : rhsUpperBounds) {
                    if (!isBoundAssignable(rhsUpperBound, lhsLowerBound)) {
                        return false;
                    }
                }
                for (final Type rhsLowerBound : rhsLowerBounds) {
                    if (!isBoundAssignable(rhsLowerBound, lhsLowerBound)) {
                        return false;
                    }
                }
            }
        } else {
            // phew, far less bounds to check
            for (final Type lhsUpperBound : lhsUpperBounds) {
                if (!isBoundAssignable(lhsUpperBound, rhs)) {
                    return false;
                }
            }
            for (final Type lhsLowerBound : lhsLowerBounds) {
                if (!isBoundAssignable(lhsLowerBound, rhs)) {
                    return false;
                }
            }
        }
        return true;
    }

    private static Type[] getEffectiveUpperBounds(final WildcardType type) {
        final Type[] upperBounds = type.getUpperBounds();
        return upperBounds.length == 0 ? new Type[]{Object.class} : upperBounds;
    }

    private static Type[] getEffectiveLowerBounds(final WildcardType type) {
        final Type[] lowerBounds = type.getLowerBounds();
        return lowerBounds.length == 0 ? new Type[]{null} : lowerBounds;
    }

    private static boolean isBoundAssignable(final Type lhs, final Type rhs) {
        return (rhs == null) || ((lhs != null) && isAssignable(lhs, rhs));
    }
}

org/apache/logging/log4j/core/util/TypeUtil.java

 

⇒ Source Code for Apache Log4j JDK Logging Adapter

⇐ Source Code for Apache Log4j API

⇑ Downloading and Reviewing Apache Log4j Packages

⇑⇑ FAQ for Apache Log4j

2015-11-03, 51320👍, 0💬