diff --git a/.gitmodules b/.gitmodules index 533f7b78365..6b59e25a71f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "external/xz-embedded"] path = external/xz-embedded url = https://github.com/tukaani-project/xz-embedded +[submodule "apache/commons-lang"] + path = apache/commons-lang + url = https://github.com/apache/commons-lang diff --git a/apache/build.gradle.kts b/apache/build.gradle.kts new file mode 100644 index 00000000000..af8055912b2 --- /dev/null +++ b/apache/build.gradle.kts @@ -0,0 +1,16 @@ +val androidSourceCompatibility: JavaVersion by rootProject.extra +val androidTargetCompatibility: JavaVersion by rootProject.extra + +plugins { + id("java-library") +} + +java { + sourceCompatibility = androidSourceCompatibility + targetCompatibility = androidTargetCompatibility + sourceSets { + main { + java.srcDirs("commons-lang/src/main/java", "local") + } + } +} diff --git a/apache/commons-lang b/apache/commons-lang new file mode 160000 index 00000000000..c2cd0525d97 --- /dev/null +++ b/apache/commons-lang @@ -0,0 +1 @@ +Subproject commit c2cd0525d97495daa820d2fcb29d6875b52c09a6 diff --git a/core/src/main/java/org/apache/commons/lang3/local/reflect/MemberUtilsX.java b/apache/local/org/apache/commons/lang3/reflect/MemberUtilsX.java similarity index 96% rename from core/src/main/java/org/apache/commons/lang3/local/reflect/MemberUtilsX.java rename to apache/local/org/apache/commons/lang3/reflect/MemberUtilsX.java index bd4c5aac004..36c872096fb 100644 --- a/core/src/main/java/org/apache/commons/lang3/local/reflect/MemberUtilsX.java +++ b/apache/local/org/apache/commons/lang3/reflect/MemberUtilsX.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.commons.lang3.local.reflect; +package org.apache.commons.lang3.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; diff --git a/core/build.gradle.kts b/core/build.gradle.kts index b199f3d77e3..baccd0e0bd7 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -57,7 +57,7 @@ copy { dependencies { api(libs.libxposed.api) - implementation(libs.commons.lang3) + implementation(projects.apache) implementation(projects.axml) implementation(projects.hiddenapi.bridge) implementation(projects.services.daemonService) diff --git a/core/src/main/java/de/robv/android/xposed/XposedHelpers.java b/core/src/main/java/de/robv/android/xposed/XposedHelpers.java index 284b8d7aca7..a0495fbf7e5 100644 --- a/core/src/main/java/de/robv/android/xposed/XposedHelpers.java +++ b/core/src/main/java/de/robv/android/xposed/XposedHelpers.java @@ -26,8 +26,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.apache.commons.lang3.local.ClassUtils; -import org.apache.commons.lang3.local.reflect.MemberUtilsX; +import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.lang3.reflect.MemberUtilsX; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; diff --git a/core/src/main/java/org/apache/commons/lang3/local/ArrayUtils.java b/core/src/main/java/org/apache/commons/lang3/local/ArrayUtils.java deleted file mode 100644 index f9e65908431..00000000000 --- a/core/src/main/java/org/apache/commons/lang3/local/ArrayUtils.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.apache.commons.lang3.local; - -import java.lang.reflect.Array; - -public class ArrayUtils { - - /** - * An empty immutable {@link Class} array. - */ - public static final Class>[] EMPTY_CLASS_ARRAY = {}; - - /** - * Defensive programming technique to change a {@code null} - * reference to an empty one. - *
- * This method returns an empty array for a {@code null} input array. - *
- *- * As a memory optimizing technique an empty array passed in will be overridden with - * the empty {@code public static} references in this class. - *
- * - * @param array the array to check for {@code null} or empty - * @return the same array, {@code public static} empty array if {@code null} or empty input - * @since 3.2 - */ - public static Class>[] nullToEmpty(final Class>[] array) { - return nullTo(array, EMPTY_CLASS_ARRAY); - } - - /** - * Defensive programming technique to change a {@code null} - * reference to an empty one. - *- * This method returns a default array for a {@code null} input array. - *
- *- * As a memory optimizing technique an empty array passed in will be overridden with - * the empty {@code public static} references in this class. - *
- * - * @param- * If the input array is {@code null}, {@code 0} is returned. - *
- *- * ArrayUtils.getLength(null) = 0 - * ArrayUtils.getLength([]) = 0 - * ArrayUtils.getLength([null]) = 1 - * ArrayUtils.getLength([true, false]) = 2 - * ArrayUtils.getLength([1, 2, 3]) = 3 - * ArrayUtils.getLength(["a", "b", "c"]) = 3 - *- * - * @param array the array to retrieve the length from, may be null - * @return The length of the array, or {@code 0} if the array is {@code null} - * @throws IllegalArgumentException if the object argument is not an array. - * @since 2.1 - */ - public static int getLength(final Object array) { - return array != null ? Array.getLength(array) : 0; - } - - /** - * Checks whether two arrays are the same length, treating - * {@code null} arrays as length {@code 0}. - *
- * Any multi-dimensional aspects of the arrays are ignored. - *
- * - * @param array1 the first array, may be {@code null} - * @param array2 the second array, may be {@code null} - * @return {@code true} if length of arrays matches, treating - * {@code null} as an empty array - * @since 3.11 - */ - public static boolean isSameLength(final Object array1, final Object array2) { - return getLength(array1) == getLength(array2); - } - - /** - * Outputs an array as a String, treating {@code null} as an empty array. - *- * Multi-dimensional arrays are handled correctly, including - * multi-dimensional primitive arrays. - *
- *- * The format is that of Java source code, for example {@code {a,b}}. - *
- * - * @param array the array to get a toString for, may be {@code null} - * @return a String representation of the array, '{}' if null array input - */ - public static String toString(final Object array) { - return toString(array, "{}"); - } - - /** - * Outputs an array as a String handling {@code null}s. - *- * Multi-dimensional arrays are handled correctly, including - * multi-dimensional primitive arrays. - *
- *- * The format is that of Java source code, for example {@code {a,b}}. - *
- * - * @param array the array to get a toString for, may be {@code null} - * @param stringIfNull the String to return if the array is {@code null} - * @return a String representation of the array - */ - public static String toString(final Object array, final String stringIfNull) { - if (array == null) { - return stringIfNull; - } - // return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString(); - // TODO: add a proper implement - return array.toString(); - } - -} diff --git a/core/src/main/java/org/apache/commons/lang3/local/ClassUtils.java b/core/src/main/java/org/apache/commons/lang3/local/ClassUtils.java deleted file mode 100644 index 32f03e128a0..00000000000 --- a/core/src/main/java/org/apache/commons/lang3/local/ClassUtils.java +++ /dev/null @@ -1,1633 +0,0 @@ -/* - * 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.commons.lang3.local; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.local.mutable.MutableObject; - -/** - * Operates on classes without using reflection. - * - *- * This class handles invalid {@code null} inputs as best it can. Each method documents its behavior in more detail. - *
- * - *- * The notion of a {@code canonical name} includes the human readable name for the type, for example {@code int[]}. The - * non-canonical method variants work with the JVM names, such as {@code [I}. - *
- * - * @since 2.0 - */ -public class ClassUtils { - - /** - * Inclusivity literals for {@link #hierarchy(Class, Interfaces)}. - * - * @since 3.2 - */ - public enum Interfaces { - - /** Includes interfaces. */ - INCLUDE, - - /** Excludes interfaces. */ - EXCLUDE - } - - private static final Comparator- * A new {@link List} is returned. {@code null} objects will be copied into the returned list as {@code null}. - *
- * - * @param classes the classes to change - * @return a {@link List} of class names corresponding to the Class objects, {@code null} if null input - * @throws ClassCastException if {@code classes} contains a non-{@link Class} entry - */ - public static List- * A new {@link List} is returned. If the class name cannot be found, {@code null} is stored in the {@link List}. If the - * class name in the {@link List} is {@code null}, {@code null} is stored in the output {@link List}. - *
- * - * @param classNames the classNames to change - * @return a {@link List} of Class objects corresponding to the class names, {@code null} if null input - * @throws ClassCastException if classNames contains a non String entry - */ - public static List- * The string passed in is assumed to be a class name - it is not checked. - *
- * - *- * The abbreviation algorithm will shorten the class name, usually without significant loss of meaning. - *
- * - *- * The abbreviated class name will always include the complete package hierarchy. If enough space is available, - * rightmost sub-packages will be displayed in full length. The abbreviated package names will be shortened to a single - * character. - *
- *- * Only package names are shortened, the class simple name remains untouched. (See examples.) - *
- *- * The result will be longer than the desired length only if all the package names shortened to a single character plus - * the class simple name with the separating dots together are longer than the desired length. In other words, when the - * class name cannot be shortened to the desired length. - *
- *- * If the class name can be shortened then the final length will be at most {@code lengthHint} characters. - *
- *- * If the {@code lengthHint} is zero or negative then the method throws exception. If you want to achieve the shortest - * possible version then use {@code 1} as a {@code lengthHint}. - *
- * - *className | - *len | - *return | - *
null | - *1 | - *"" | - *
"java.lang.String" | - *5 | - *"j.l.String" | - *
"java.lang.String" | - *15 | - *"j.lang.String" | - *
"java.lang.String" | - *30 | - *"java.lang.String" | - *
"org.apache.commons.lang3.ClassUtils" | - *18 | - *"o.a.c.l.ClassUtils" | - *
- * The order is determined by looking through each interface in turn as declared in the source file and following its - * hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order is - * maintained. - *
- * - * @param cls the class to look up, may be {@code null} - * @return the {@link List} of interfaces in order, {@code null} if null input - */ - public static List- * The method does not change the {@code $} separators in case the class is inner class. - *
- * - *- * Example: - *
- * The string passed in is assumed to be a class name - it is not checked. - *
- *- * If the class is in the default package, return an empty string. - *
- * - * @param name the name to get the package name for, may be {@code null} - * @return the package name or an empty string - * @since 2.4 - */ - public static String getPackageCanonicalName(final String name) { - return getPackageName(getCanonicalName(name)); - } - - /** - * Gets the package name of a {@link Class}. - * - * @param cls the class to get the package name for, may be {@code null}. - * @return the package name or an empty string - */ - public static String getPackageName(final Class> cls) { - if (cls == null) { - return StringUtils.EMPTY; - } - return getPackageName(cls.getName()); - } - - /** - * Gets the package name of an {@link Object}. - * - * @param object the class to get the package name for, may be null - * @param valueIfNull the value to return if null - * @return the package name of the object, or the null value - */ - public static String getPackageName(final Object object, final String valueIfNull) { - if (object == null) { - return valueIfNull; - } - return getPackageName(object.getClass()); - } - - /** - * Gets the package name from a {@link String}. - * - *- * The string passed in is assumed to be a class name - it is not checked. - *
- *- * If the class is unpackaged, return an empty string. - *
- * - * @param className the className to get the package name for, may be {@code null} - * @return the package name or an empty string - */ - public static String getPackageName(String className) { - if (StringUtils.isEmpty(className)) { - return StringUtils.EMPTY; - } - - // Strip array encoding - while (className.charAt(0) == '[') { - className = className.substring(1); - } - // Strip Object type encoding - if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') { - className = className.substring(1); - } - - final int i = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); - if (i == -1) { - return StringUtils.EMPTY; - } - return className.substring(0, i); - } - - /** - * Gets the primitive class for the given class name, for example "byte". - * - * @param className the primitive class for the given class name. - * @return the primitive class. - */ - static Class> getPrimitiveClass(final String className) { - return namePrimitiveMap.get(className); - } - - /** - * Returns the desired Method much like {@code Class.getMethod}, however it ensures that the returned Method is from a - * public class or interface and not from an anonymous inner class. This means that the Method is invokable and doesn't - * fall foul of Java bug 4071957). - * - *
- * Set set = Collections.unmodifiableSet(...);
- * Method method = ClassUtils.getPublicMethod(set.getClass(), "isEmpty", new Class[0]);
- * Object result = method.invoke(set, new Object[]);
- *
- *
- * @param cls the class to check, not null
- * @param methodName the name of the method
- * @param parameterTypes the list of parameters
- * @return the method
- * @throws NullPointerException if the class is null
- * @throws SecurityException if a security violation occurred
- * @throws NoSuchMethodException if the method is not found in the given class or if the method doesn't conform with the
- * requirements
- */
- public static Method getPublicMethod(final Class> cls, final String methodName, final Class>... parameterTypes) throws NoSuchMethodException {
-
- final Method declaredMethod = cls.getMethod(methodName, parameterTypes);
- if (isPublic(declaredMethod.getDeclaringClass())) {
- return declaredMethod;
- }
-
- final List- * The string passed in is assumed to be a class name - it is not checked. - *
- * - *- * Note that this method is mainly designed to handle the arrays and primitives properly. If the class is an inner class - * then the result value will not contain the outer classes. This way the behavior of this method is different from - * {@link #getShortClassName(String)}. The argument in that case is class name and not canonical name and the return - * value retains the outer classes. - *
- * - *- * Note that there is no way to reliably identify the part of the string representing the package hierarchy and the part - * that is the outer class or classes in case of an inner class. Trying to find the class would require reflective call - * and the class itself may not even be on the class path. Relying on the fact that class names start with capital - * letter and packages with lower case is heuristic. - *
- * - *- * It is recommended to use {@link #getShortClassName(String)} for cases when the class is an inner class and use this - * method for cases it is designed for. - *
- * - *return value | - *input | - *
{@code ""} | - *{@code (String)null} | - *
{@code "Map.Entry"} | - *{@code java.util.Map.Entry.class.getName()} | - *
{@code "Entry"} | - *{@code java.util.Map.Entry.class.getCanonicalName()} | - *
{@code "ClassUtils"} | - *{@code "org.apache.commons.lang3.ClassUtils"} | - *
{@code "ClassUtils[]"} | - *{@code "[Lorg.apache.commons.lang3.ClassUtils;"} | - *
{@code "ClassUtils[][]"} | - *{@code "[[Lorg.apache.commons.lang3.ClassUtils;"} | - *
{@code "ClassUtils[]"} | - *{@code "org.apache.commons.lang3.ClassUtils[]"} | - *
{@code "ClassUtils[][]"} | - *{@code "org.apache.commons.lang3.ClassUtils[][]"} | - *
{@code "int[]"} | - *{@code "[I"} | - *
{@code "int[]"} | - *{@code int[].class.getCanonicalName()} | - *
{@code "int[]"} | - *{@code int[].class.getName()} | - *
{@code "int[][]"} | - *{@code "[[I"} | - *
{@code "int[]"} | - *{@code "int[]"} | - *
{@code "int[][]"} | - *{@code "int[][]"} | - *
- * This method simply gets the name using {@code Class.getName()} and then calls {@link #getShortClassName(String)}. See - * relevant notes there. - *
- * - * @param cls the class to get the short name for. - * @return the class name without the package name or an empty string. If the class is an inner class then the returned - * value will contain the outer class or classes separated with {@code .} (dot) character. - */ - public static String getShortClassName(final Class> cls) { - if (cls == null) { - return StringUtils.EMPTY; - } - return getShortClassName(cls.getName()); - } - - /** - * Gets the class name of the {@code object} without the package name or names. - * - *- * The method looks up the class of the object and then converts the name of the class invoking - * {@link #getShortClassName(Class)} (see relevant notes there). - *
- * - * @param object the class to get the short name for, may be {@code null} - * @param valueIfNull the value to return if the object is {@code null} - * @return the class name of the object without the package name, or {@code valueIfNull} if the argument {@code object} - * is {@code null} - */ - public static String getShortClassName(final Object object, final String valueIfNull) { - if (object == null) { - return valueIfNull; - } - return getShortClassName(object.getClass()); - } - - /** - * Gets the class name minus the package name from a String. - * - *- * The string passed in is assumed to be a class name - it is not checked. The string has to be formatted the way as the - * JDK method {@code Class.getName()} returns it, and not the usual way as we write it, for example in import - * statements, or as it is formatted by {@code Class.getCanonicalName()}. - *
- * - *- * The difference is is significant only in case of classes that are inner classes of some other classes. In this case - * the separator between the outer and inner class (possibly on multiple hierarchy level) has to be {@code $} (dollar - * sign) and not {@code .} (dot), as it is returned by {@code Class.getName()} - *
- * - *- * Note that this method is called from the {@link #getShortClassName(Class)} method using the string returned by - * {@code Class.getName()}. - *
- * - *- * Note that this method differs from {@link #getSimpleName(Class)} in that this will return, for example - * {@code "Map.Entry"} whilst the {@link Class} variant will simply return {@code "Entry"}. In this example - * the argument {@code className} is the string {@code java.util.Map$Entry} (note the {@code $} sign. - *
- * - * @param className the className to get the short name for. It has to be formatted as returned by - * {@code Class.getName()} and not {@code Class.getCanonicalName()} - * @return the class name of the class without the package name or an empty string. If the class is an inner class then - * value contains the outer class or classes and the separator is replaced to be {@code .} (dot) character. - */ - public static String getShortClassName(String className) { - if (StringUtils.isEmpty(className)) { - return StringUtils.EMPTY; - } - - final StringBuilder arrayPrefix = new StringBuilder(); - - // Handle array encoding - if (className.startsWith("[")) { - while (className.charAt(0) == '[') { - className = className.substring(1); - arrayPrefix.append("[]"); - } - // Strip Object type encoding - if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') { - className = className.substring(1, className.length() - 1); - } - - if (reverseAbbreviationMap.containsKey(className)) { - className = reverseAbbreviationMap.get(className); - } - } - - final int lastDotIdx = className.lastIndexOf(PACKAGE_SEPARATOR_CHAR); - final int innerIdx = className.indexOf(INNER_CLASS_SEPARATOR_CHAR, lastDotIdx == -1 ? 0 : lastDotIdx + 1); - String out = className.substring(lastDotIdx + 1); - if (innerIdx != -1) { - out = out.replace(INNER_CLASS_SEPARATOR_CHAR, PACKAGE_SEPARATOR_CHAR); - } - return out + arrayPrefix; - } - - /** - * Null-safe version of {@code cls.getSimpleName()} - * - * @param cls the class for which to get the simple name; may be null - * @return the simple class name or the empty string in case the argument is {@code null} - * @since 3.0 - * @see Class#getSimpleName() - */ - public static String getSimpleName(final Class> cls) { - return getSimpleName(cls, StringUtils.EMPTY); - } - - /** - * Null-safe version of {@code cls.getSimpleName()} - * - * @param cls the class for which to get the simple name; may be null - * @param valueIfNull the value to return if null - * @return the simple class name or {@code valueIfNull} if the argument {@code cls} is {@code null} - * @since 3.0 - * @see Class#getSimpleName() - */ - public static String getSimpleName(final Class> cls, final String valueIfNull) { - return cls == null ? valueIfNull : cls.getSimpleName(); - } - - /** - * Null-safe version of {@code object.getClass().getSimpleName()} - * - *- * It is to note that this method is overloaded and in case the argument {@code object} is a {@link Class} object then - * the {@link #getSimpleName(Class)} will be invoked. If this is a significant possibility then the caller should check - * this case and call {@code - * getSimpleName(Class.class)} or just simply use the string literal {@code "Class"}, which is the result of the method - * in that case. - *
- * - * @param object the object for which to get the simple class name; may be null - * @return the simple class name or the empty string in case the argument is {@code null} - * @since 3.7 - * @see Class#getSimpleName() - */ - public static String getSimpleName(final Object object) { - return getSimpleName(object, StringUtils.EMPTY); - } - - /** - * Null-safe version of {@code object.getClass().getSimpleName()} - * - * @param object the object for which to get the simple class name; may be null - * @param valueIfNull the value to return if {@code object} is {@code null} - * @return the simple class name or {@code valueIfNull} if the argument {@code object} is {@code null} - * @since 3.0 - * @see Class#getSimpleName() - */ - public static String getSimpleName(final Object object, final String valueIfNull) { - return object == null ? valueIfNull : object.getClass().getSimpleName(); - } - - /** - * Gets an {@link Iterable} that can iterate over a class hierarchy in ascending (subclass to superclass) order, - * excluding interfaces. - * - * @param type the type to get the class hierarchy from - * @return Iterable an Iterable over the class hierarchy of the given class - * @since 3.2 - */ - public static Iterable- * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this method takes into account widenings of - * primitive classes and {@code null}s. - *
- * - *- * Primitive widenings allow an int to be assigned to a long, float or double. This method returns the correct result - * for these cases. - *
- * - *- * {@code null} may be assigned to any reference type. This method will return {@code true} if {@code null} is passed in - * and the toClass is non-primitive. - *
- * - *- * Specifically, this method tests whether the type represented by the specified {@link Class} parameter can be - * converted to the type represented by this {@link Class} object via an identity conversion widening primitive or - * widening reference conversion. See The Java Language - * Specification, sections 5.1.1, 5.1.2 and 5.1.4 for details. - *
- * - *- * Since Lang 3.0, this method will default behavior for calculating assignability between primitive - * and wrapper types corresponding to the running Java version; i.e. autoboxing will be the default behavior in - * VMs running Java versions > 1.5. - *
- * - * @param cls the Class to check, may be null - * @param toClass the Class to try to assign into, returns false if null - * @return {@code true} if assignment possible - */ - public static boolean isAssignable(final Class> cls, final Class> toClass) { - return isAssignable(cls, toClass, true); - } - - /** - * Checks if one {@link Class} can be assigned to a variable of another {@link Class}. - * - *- * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this method takes into account widenings of - * primitive classes and {@code null}s. - *
- * - *- * Primitive widenings allow an int to be assigned to a long, float or double. This method returns the correct result - * for these cases. - *
- * - *- * {@code null} may be assigned to any reference type. This method will return {@code true} if {@code null} is passed in - * and the toClass is non-primitive. - *
- * - *- * Specifically, this method tests whether the type represented by the specified {@link Class} parameter can be - * converted to the type represented by this {@link Class} object via an identity conversion widening primitive or - * widening reference conversion. See The Java Language - * Specification, sections 5.1.1, 5.1.2 and 5.1.4 for details. - *
- * - * @param cls the Class to check, may be null - * @param toClass the Class to try to assign into, returns false if null - * @param autoboxing whether to use implicit autoboxing/unboxing between primitives and wrappers - * @return {@code true} if assignment possible - */ - public static boolean isAssignable(Class> cls, final Class> toClass, final boolean autoboxing) { - if (toClass == null) { - return false; - } - // have to check for null, as isAssignableFrom doesn't - if (cls == null) { - return !toClass.isPrimitive(); - } - // autoboxing: - if (autoboxing) { - if (cls.isPrimitive() && !toClass.isPrimitive()) { - cls = primitiveToWrapper(cls); - if (cls == null) { - return false; - } - } - if (toClass.isPrimitive() && !cls.isPrimitive()) { - cls = wrapperToPrimitive(cls); - if (cls == null) { - return false; - } - } - } - if (cls.equals(toClass)) { - return true; - } - if (cls.isPrimitive()) { - if (!toClass.isPrimitive()) { - return false; - } - if (Integer.TYPE.equals(cls)) { - return Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Long.TYPE.equals(cls)) { - return Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Boolean.TYPE.equals(cls)) { - return false; - } - if (Double.TYPE.equals(cls)) { - return false; - } - if (Float.TYPE.equals(cls)) { - return Double.TYPE.equals(toClass); - } - if (Character.TYPE.equals(cls) || Short.TYPE.equals(cls)) { - return Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) || Double.TYPE.equals(toClass); - } - if (Byte.TYPE.equals(cls)) { - return Short.TYPE.equals(toClass) || Integer.TYPE.equals(toClass) || Long.TYPE.equals(toClass) || Float.TYPE.equals(toClass) - || Double.TYPE.equals(toClass); - } - // should never get here - return false; - } - return toClass.isAssignableFrom(cls); - } - - /** - * Checks if an array of Classes can be assigned to another array of Classes. - * - *- * This method calls {@link #isAssignable(Class, Class) isAssignable} for each Class pair in the input arrays. It can be - * used to check if a set of arguments (the first parameter) are suitably compatible with a set of method parameter - * types (the second parameter). - *
- * - *- * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this method takes into account widenings of - * primitive classes and {@code null}s. - *
- * - *- * Primitive widenings allow an int to be assigned to a {@code long}, {@code float} or {@code double}. This method - * returns the correct result for these cases. - *
- * - *- * {@code null} may be assigned to any reference type. This method will return {@code true} if {@code null} is passed in - * and the toClass is non-primitive. - *
- * - *- * Specifically, this method tests whether the type represented by the specified {@link Class} parameter can be - * converted to the type represented by this {@link Class} object via an identity conversion widening primitive or - * widening reference conversion. See The Java Language - * Specification, sections 5.1.1, 5.1.2 and 5.1.4 for details. - *
- * - *- * Since Lang 3.0, this method will default behavior for calculating assignability between primitive - * and wrapper types corresponding to the running Java version; i.e. autoboxing will be the default behavior in - * VMs running Java versions > 1.5. - *
- * - * @param classArray the array of Classes to check, may be {@code null} - * @param toClassArray the array of Classes to try to assign into, may be {@code null} - * @return {@code true} if assignment possible - */ - public static boolean isAssignable(final Class>[] classArray, final Class>... toClassArray) { - return isAssignable(classArray, toClassArray, true); - } - - /** - * Checks if an array of Classes can be assigned to another array of Classes. - * - *- * This method calls {@link #isAssignable(Class, Class) isAssignable} for each Class pair in the input arrays. It can be - * used to check if a set of arguments (the first parameter) are suitably compatible with a set of method parameter - * types (the second parameter). - *
- * - *- * Unlike the {@link Class#isAssignableFrom(java.lang.Class)} method, this method takes into account widenings of - * primitive classes and {@code null}s. - *
- * - *- * Primitive widenings allow an int to be assigned to a {@code long}, {@code float} or {@code double}. This method - * returns the correct result for these cases. - *
- * - *- * {@code null} may be assigned to any reference type. This method will return {@code true} if {@code null} is passed in - * and the toClass is non-primitive. - *
- * - *- * Specifically, this method tests whether the type represented by the specified {@link Class} parameter can be - * converted to the type represented by this {@link Class} object via an identity conversion widening primitive or - * widening reference conversion. See The Java Language - * Specification, sections 5.1.1, 5.1.2 and 5.1.4 for details. - *
- * - * @param classArray the array of Classes to check, may be {@code null} - * @param toClassArray the array of Classes to try to assign into, may be {@code null} - * @param autoboxing whether to use implicit autoboxing/unboxing between primitives and wrappers - * @return {@code true} if assignment possible - */ - public static boolean isAssignable(Class>[] classArray, Class>[] toClassArray, final boolean autoboxing) { - if (!ArrayUtils.isSameLength(classArray, toClassArray)) { - return false; - } - classArray = ArrayUtils.nullToEmpty(classArray); - toClassArray = ArrayUtils.nullToEmpty(toClassArray); - for (int i = 0; i < classArray.length; i++) { - if (!isAssignable(classArray[i], toClassArray[i], autoboxing)) { - return false; - } - } - return true; - } - - /** - * Is the specified class an inner class or static nested class. - * - * @param cls the class to check, may be null - * @return {@code true} if the class is an inner or static nested class, false if not or {@code null} - */ - public static boolean isInnerClass(final Class> cls) { - return cls != null && cls.getEnclosingClass() != null; - } - - /** - * Returns whether the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte}, - * {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). - * - * @param type The class to query or null. - * @return true if the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte}, - * {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). - * @since 3.1 - */ - public static boolean isPrimitiveOrWrapper(final Class> type) { - if (type == null) { - return false; - } - return type.isPrimitive() || isPrimitiveWrapper(type); - } - /** - * Returns whether the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, - * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). - * - * @param type The class to query or null. - * @return true if the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character}, - * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}). - * @since 3.1 - */ - public static boolean isPrimitiveWrapper(final Class> type) { - return wrapperPrimitiveMap.containsKey(type); - } - - /** - * Tests whether a {@link Class} is public. - * @param cls Class to test. - * @return {@code true} if {@code cls} is public. - * @since 3.13.0 - */ - public static boolean isPublic(final Class> cls) { - return Modifier.isPublic(cls.getModifiers()); - } - - /** - * Converts the specified array of primitive Class objects to an array of its corresponding wrapper Class objects. - * - * @param classes the class array to convert, may be null or empty - * @return an array which contains for each given class, the wrapper class or the original class if class is not a - * primitive. {@code null} if null input. Empty array if an empty array passed in. - * @since 2.1 - */ - public static Class>[] primitivesToWrappers(final Class>... classes) { - if (classes == null) { - return null; - } - - if (classes.length == 0) { - return classes; - } - - final Class>[] convertedClasses = new Class[classes.length]; - Arrays.setAll(convertedClasses, i -> primitiveToWrapper(classes[i])); - return convertedClasses; - } - - /** - * Converts the specified primitive Class object to its corresponding wrapper Class object. - * - *- * NOTE: From v2.2, this method handles {@code Void.TYPE}, returning {@code Void.TYPE}. - *
- * - * @param cls the class to convert, may be null - * @return the wrapper class for {@code cls} or {@code cls} if {@code cls} is not a primitive. {@code null} if null - * input. - * @since 2.1 - */ - public static Class> primitiveToWrapper(final Class> cls) { - Class> convertedClass = cls; - if (cls != null && cls.isPrimitive()) { - convertedClass = primitiveWrapperMap.get(cls); - } - return convertedClass; - } - - /** - * Converts a class name to a JLS style class name. - * - * @param className the class name - * @return the converted name - * @throws NullPointerException if the className is null - */ - private static String toCanonicalName(final String className) { - String canonicalName = StringUtils.deleteWhitespace(className); - Objects.requireNonNull(canonicalName, "className"); - if (canonicalName.endsWith("[]")) { - final StringBuilder classNameBuffer = new StringBuilder(); - while (canonicalName.endsWith("[]")) { - canonicalName = canonicalName.substring(0, canonicalName.length() - 2); - classNameBuffer.append("["); - } - final String abbreviation = abbreviationMap.get(canonicalName); - if (abbreviation != null) { - classNameBuffer.append(abbreviation); - } else { - classNameBuffer.append("L").append(canonicalName).append(";"); - } - canonicalName = classNameBuffer.toString(); - } - return canonicalName; - } - - /** - * Converts an array of {@link Object} in to an array of {@link Class} objects. If any of these objects is null, a null - * element will be inserted into the array. - * - *- * This method returns {@code null} for a {@code null} input array. - *
- * - * @param array an {@link Object} array - * @return a {@link Class} array, {@code null} if null array input - * @since 2.4 - */ - public static Class>[] toClass(final Object... array) { - if (array == null) { - return null; - } - if (array.length == 0) { - return ArrayUtils.EMPTY_CLASS_ARRAY; - } - final Class>[] classes = new Class[array.length]; - Arrays.setAll(classes, i -> array[i] == null ? null : array[i].getClass()); - return classes; - } - - /** - * Decides if the part that was just copied to its destination location in the work array can be kept as it was copied - * or must be abbreviated. It must be kept when the part is the last one, which is the simple name of the class. In this - * case the {@code source} index, from where the characters are copied points one position after the last character, - * a.k.a. {@code source == - * originalLength} - * - *- * If the part is not the last one then it can be kept unabridged if the number of the characters copied so far plus the - * character that are to be copied is less than or equal to the desired length. - *
- * - * @param runAheadTarget the target index (where the characters were copied to) pointing after the last character copied - * when the current part was copied - * @param source the source index (where the characters were copied from) pointing after the last character copied when - * the current part was copied - * @param originalLength the original length of the class full name, which is abbreviated - * @param desiredLength the desired length of the abbreviated class name - * @return {@code true} if it can be kept in its original length {@code false} if the current part has to be abbreviated - * and - */ - private static boolean useFull(final int runAheadTarget, final int source, final int originalLength, final int desiredLength) { - return source >= originalLength || runAheadTarget + originalLength - source <= desiredLength; - } - - /** - * Converts the specified array of wrapper Class objects to an array of its corresponding primitive Class objects. - * - *- * This method invokes {@code wrapperToPrimitive()} for each element of the passed in array. - *
- * - * @param classes the class array to convert, may be null or empty - * @return an array which contains for each given class, the primitive class or null if the original class is not - * a wrapper class. {@code null} if null input. Empty array if an empty array passed in. - * @see #wrapperToPrimitive(Class) - * @since 2.4 - */ - public static Class>[] wrappersToPrimitives(final Class>... classes) { - if (classes == null) { - return null; - } - - if (classes.length == 0) { - return classes; - } - - final Class>[] convertedClasses = new Class[classes.length]; - Arrays.setAll(convertedClasses, i -> wrapperToPrimitive(classes[i])); - return convertedClasses; - } - - /** - * Converts the specified wrapper class to its corresponding primitive class. - * - *- * This method is the counter part of {@code primitiveToWrapper()}. If the passed in class is a wrapper class for a - * primitive type, this primitive type will be returned (e.g. {@code Integer.TYPE} for {@code Integer.class}). For other - * classes, or if the parameter is null, the return value is null. - *
- * - * @param cls the class to convert, may be null - * @return the corresponding primitive type if {@code cls} is a wrapper class, null otherwise - * @see #primitiveToWrapper(Class) - * @since 2.4 - */ - public static Class> wrapperToPrimitive(final Class> cls) { - return wrapperPrimitiveMap.get(cls); - } - - /** - * ClassUtils instances should NOT be constructed in standard programming. Instead, the class should be used as - * {@code ClassUtils.getShortClassName(cls)}. - * - *- * This constructor is public to permit tools that require a JavaBean instance to operate. - *
- * - * @deprecated TODO Make private in 4.0. - */ - @Deprecated - public ClassUtils() { - // empty - } - -} diff --git a/core/src/main/java/org/apache/commons/lang3/local/StringUtils.java b/core/src/main/java/org/apache/commons/lang3/local/StringUtils.java deleted file mode 100644 index 3e926a7abc6..00000000000 --- a/core/src/main/java/org/apache/commons/lang3/local/StringUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.apache.commons.lang3.local; - -public class StringUtils { - - /** - * A String for a space character. - * - */ - public static final String SPACE = " "; - - /** - * The empty String {@code ""}. - */ - public static final String EMPTY = ""; - - /** - * Deletes all whitespaces from a String as defined by - * {@link Character#isWhitespace(char)}. - * - *- * StringUtils.deleteWhitespace(null) = null - * StringUtils.deleteWhitespace("") = "" - * StringUtils.deleteWhitespace("abc") = "abc" - * StringUtils.deleteWhitespace(" ab c ") = "abc" - *- * - * @param str the String to delete whitespace from, may be null - * @return the String without whitespaces, {@code null} if null String input - */ - public static String deleteWhitespace(final String str) { - if (isEmpty(str)) { - return str; - } - final int sz = str.length(); - final char[] chs = new char[sz]; - int count = 0; - for (int i = 0; i < sz; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - chs[count++] = str.charAt(i); - } - } - if (count == sz) { - return str; - } - if (count == 0) { - return EMPTY; - } - return new String(chs, 0, count); - } - - /** - * Checks if a CharSequence is empty ("") or null. - * - *
- * StringUtils.isEmpty(null) = true - * StringUtils.isEmpty("") = true - * StringUtils.isEmpty(" ") = false - * StringUtils.isEmpty("bob") = false - * StringUtils.isEmpty(" bob ") = false - *- * - *
NOTE: This method changed in Lang version 2.0. - * It no longer trims the CharSequence. - * That functionality is available in isBlank().
- * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is empty or null - * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence) - */ - public static boolean isEmpty(final CharSequence cs) { - return cs == null || cs.length() == 0; - } -} diff --git a/core/src/main/java/org/apache/commons/lang3/local/mutable/Mutable.java b/core/src/main/java/org/apache/commons/lang3/local/mutable/Mutable.java deleted file mode 100644 index 07ef4402016..00000000000 --- a/core/src/main/java/org/apache/commons/lang3/local/mutable/Mutable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.commons.lang3.local.mutable; - -/** - * Provides mutable access to a value. - *- * {@link Mutable} is used as a generic interface to the implementations in this package. - *
- *- * A typical use case would be to enable a primitive or string to be passed to a method and allow that method to - * effectively change the value of the primitive/string. Another use case is to store a frequently changing primitive in - * a collection (for example a total in a map) without needing to create new Integer/Long wrapper objects. - *
- * - * @param- * When a {@code public} class has a default access superclass with {@code public} members, - * these members are accessible. Calling them from compiled code works fine. - * Unfortunately, on some JVMs, using reflection to invoke these members - * seems to (wrongly) prevent access even when the modifier is {@code public}. - * Calling {@code setAccessible(true)} solves the problem but will only work from - * sufficiently privileged code. Better workarounds would be gratefully - * accepted. - *
- * - * @param obj the AccessibleObject to set as accessible, may be null. - * @return a boolean indicating whether the accessibility of the object was set to true. - */ - static