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.util; 019 020import java.lang.reflect.Array; 021 022/** 023 * Copied from Apache Commons Lang (including the {@code @since} tags.) 024 */ 025public class ArrayUtils { 026 027 /** 028 * Checks if an array of Objects is empty or {@code null}. 029 * 030 * @param array the array to test 031 * @return {@code true} if the array is empty or {@code null} 032 * @since 2.1 033 */ 034 public static boolean isEmpty(final byte[] array) { 035 return getLength(array) == 0; 036 } 037 038 /** 039 * <p>Returns the length of the specified array. 040 * This method can deal with {@code Object} arrays and with primitive arrays.</p> 041 * 042 * <p>If the input array is {@code null}, {@code 0} is returned.</p> 043 * 044 * <pre> 045 * ArrayUtils.getLength(null) = 0 046 * ArrayUtils.getLength([]) = 0 047 * ArrayUtils.getLength([null]) = 1 048 * ArrayUtils.getLength([true, false]) = 2 049 * ArrayUtils.getLength([1, 2, 3]) = 3 050 * ArrayUtils.getLength(["a", "b", "c"]) = 3 051 * </pre> 052 * 053 * @param array the array to retrieve the length from, may be null 054 * @return The length of the array, or {@code 0} if the array is {@code null} 055 * @throws IllegalArgumentException if the object argument is not an array. 056 * @since 2.1 057 */ 058 public static int getLength(final Object array) { 059 if (array == null) { 060 return 0; 061 } 062 return Array.getLength(array); 063 } 064 065 /** 066 * <p>Removes the element at the specified position from the specified array. 067 * All subsequent elements are shifted to the left (subtracts one from 068 * their indices).</p> 069 * 070 * <p>This method returns a new array with the same elements of the input 071 * array except the element on the specified position. The component 072 * type of the returned array is always the same as that of the input 073 * array.</p> 074 * 075 * <p>If the input array is {@code null}, an IndexOutOfBoundsException 076 * will be thrown, because in that case no valid index can be specified.</p> 077 * 078 * @param array the array to remove the element from, may not be {@code null} 079 * @param index the position of the element to be removed 080 * @return A new array containing the existing elements except the element 081 * at the specified position. 082 * @throws IndexOutOfBoundsException if the index is out of range 083 * (index < 0 || index >= array.length), or if the array is {@code null}. 084 * @since 2.1 085 */ 086 private static Object remove(final Object array, final int index) { 087 final int length = getLength(array); 088 if (index < 0 || index >= length) { 089 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length); 090 } 091 092 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1); 093 System.arraycopy(array, 0, result, 0, index); 094 if (index < length - 1) { 095 System.arraycopy(array, index + 1, result, index, length - index - 1); 096 } 097 098 return result; 099 } 100 101 /** 102 * <p>Removes the element at the specified position from the specified array. 103 * All subsequent elements are shifted to the left (subtracts one from 104 * their indices).</p> 105 * 106 * <p>This method returns a new array with the same elements of the input 107 * array except the element on the specified position. The component 108 * type of the returned array is always the same as that of the input 109 * array.</p> 110 * 111 * <p>If the input array is {@code null}, an IndexOutOfBoundsException 112 * will be thrown, because in that case no valid index can be specified.</p> 113 * 114 * <pre> 115 * ArrayUtils.remove(["a"], 0) = [] 116 * ArrayUtils.remove(["a", "b"], 0) = ["b"] 117 * ArrayUtils.remove(["a", "b"], 1) = ["a"] 118 * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"] 119 * </pre> 120 * 121 * @param <T> the component type of the array 122 * @param array the array to remove the element from, may not be {@code null} 123 * @param index the position of the element to be removed 124 * @return A new array containing the existing elements except the element 125 * at the specified position. 126 * @throws IndexOutOfBoundsException if the index is out of range 127 * (index < 0 || index >= array.length), or if the array is {@code null}. 128 * @since 2.1 129 */ 130 @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input 131 public static <T> T[] remove(final T[] array, final int index) { 132 return (T[]) remove((Object) array, index); 133 } 134 135}