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