1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache license, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the license for the specific language governing permissions and
15 * limitations under the license.
16 */
17
18 package org.apache.logging.log4j.core.util;
19
20 import java.lang.reflect.Array;
21
22 /**
23 * Copied from Apache Commons Lang (including the {@code @since} tags.)
24 */
25 public class ArrayUtils {
26
27 /**
28 * <p>Returns the length of the specified array.
29 * This method can deal with {@code Object} arrays and with primitive arrays.</p>
30 *
31 * <p>If the input array is {@code null}, {@code 0} is returned.</p>
32 *
33 * <pre>
34 * ArrayUtils.getLength(null) = 0
35 * ArrayUtils.getLength([]) = 0
36 * ArrayUtils.getLength([null]) = 1
37 * ArrayUtils.getLength([true, false]) = 2
38 * ArrayUtils.getLength([1, 2, 3]) = 3
39 * ArrayUtils.getLength(["a", "b", "c"]) = 3
40 * </pre>
41 *
42 * @param array the array to retrieve the length from, may be null
43 * @return The length of the array, or {@code 0} if the array is {@code null}
44 * @throws IllegalArgumentException if the object argument is not an array.
45 * @since 2.1
46 */
47 public static int getLength(final Object array) {
48 if (array == null) {
49 return 0;
50 }
51 return Array.getLength(array);
52 }
53
54 /**
55 * <p>Removes the element at the specified position from the specified array.
56 * All subsequent elements are shifted to the left (subtracts one from
57 * their indices).</p>
58 *
59 * <p>This method returns a new array with the same elements of the input
60 * array except the element on the specified position. The component
61 * type of the returned array is always the same as that of the input
62 * array.</p>
63 *
64 * <p>If the input array is {@code null}, an IndexOutOfBoundsException
65 * will be thrown, because in that case no valid index can be specified.</p>
66 *
67 * @param array the array to remove the element from, may not be {@code null}
68 * @param index the position of the element to be removed
69 * @return A new array containing the existing elements except the element
70 * at the specified position.
71 * @throws IndexOutOfBoundsException if the index is out of range
72 * (index < 0 || index >= array.length), or if the array is {@code null}.
73 * @since 2.1
74 */
75 private static Object remove(final Object array, final int index) {
76 final int length = getLength(array);
77 if (index < 0 || index >= length) {
78 throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
79 }
80
81 final Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
82 System.arraycopy(array, 0, result, 0, index);
83 if (index < length - 1) {
84 System.arraycopy(array, index + 1, result, index, length - index - 1);
85 }
86
87 return result;
88 }
89
90 /**
91 * <p>Removes the element at the specified position from the specified array.
92 * All subsequent elements are shifted to the left (subtracts one from
93 * their indices).</p>
94 *
95 * <p>This method returns a new array with the same elements of the input
96 * array except the element on the specified position. The component
97 * type of the returned array is always the same as that of the input
98 * array.</p>
99 *
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 }