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 https://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.commons.cli.help;
19
20 import java.util.Arrays;
21
22 /**
23 * Contains useful helper methods for classes within this package.
24 */
25 final class Util {
26
27 /**
28 * A special value for index not found.
29 */
30 private static final int NOT_FOUND = -1;
31
32 /**
33 * Returns the {@code defaultValue} if {@code str} is empty.
34 *
35 * @param str The string to check.
36 * @param defaultValue the default value if the string is empty.
37 * @param <T> The type of arguments.
38 * @return the {@code defaultValue} if {@code str} is empty,
39 */
40 static <T extends CharSequence> T defaultValue(final T str, final T defaultValue) {
41 return isEmpty(str) ? defaultValue : str;
42 }
43
44 /**
45 * Finds the index of the first non whitespace character.
46 *
47 * @param text the text to search in.
48 * @param startPos the starting position to search from.
49 * @return the index of the first non whitespace character or -1 if non found.
50 */
51 static int indexOfNonWhitespace(final CharSequence text, final int startPos) {
52 if (isEmpty(text)) {
53 return NOT_FOUND;
54 }
55 // the line ends before the max wrap pos or a new line char found
56 int idx = startPos;
57 while (idx < text.length() && isWhitespace(text.charAt(idx))) {
58 idx++;
59 }
60 return idx < text.length() ? idx : NOT_FOUND;
61 }
62
63 /**
64 * Tests whether the given string is null or empty.
65 *
66 * @param str The string to test.
67 * @return Whether the given string is null or empty.
68 */
69 static boolean isEmpty(final CharSequence str) {
70 return str == null || str.length() == 0;
71 }
72
73 /**
74 * Works around https://bugs.java.com/bugdatabase/view_bug?bug_id=8341522
75 *
76 * Affected Version: 8, 11, 17, 21, 24.
77 */
78 static boolean isWhitespace(final char c) {
79 return Character.isWhitespace(c) || Character.PARAGRAPH_SEPARATOR == c;
80 }
81
82 /**
83 * Removes the leading whitespace from the specified String.
84 *
85 * @param s The String to remove the leading padding from.
86 * @return The String of without the leading padding.
87 */
88 static String ltrim(final String s) {
89 final int pos = indexOfNonWhitespace(s, 0);
90 return pos == NOT_FOUND ? "" : s.substring(pos);
91 }
92
93 /**
94 * Constructs a string of specified length filled with the specified char.
95 *
96 * @param len the length of the final string.
97 * @param fillChar the character to file it will.
98 * @return A string of specified length filled with the specified char.
99 */
100 static String repeat(final int len, final char fillChar) {
101 final char[] padding = new char[len];
102 Arrays.fill(padding, fillChar);
103 return new String(padding);
104 }
105
106 /**
107 * Creates a String of padding of length {@code len}.
108 *
109 * @param len The length of the String of padding to create.
110 * @return The String of padding.
111 */
112 static String repeatSpace(final int len) {
113 return repeat(len, ' ');
114 }
115
116 /**
117 * Removes the trailing whitespace from the specified String.
118 *
119 * @param s The String to remove the trailing padding from.
120 * @return The String of without the trailing padding.
121 */
122 static String rtrim(final String s) {
123 if (isEmpty(s)) {
124 return s;
125 }
126 int pos = s.length();
127 while (pos > 0 && isWhitespace(s.charAt(pos - 1))) {
128 --pos;
129 }
130 return s.substring(0, pos);
131 }
132
133 private Util() {
134 // no instances
135 }
136 }