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 package org.apache.any23.util;
18
19 import java.util.Locale;
20
21 /**
22 * This class provides a set of string utility methods.
23 *
24 * @author Michele Mostarda (mostarda@fbk.eu)
25 */
26 public class StringUtils {
27
28 /**
29 * Joins the given input sting <code>data</code> list using the specified <code>delimiter</code>.
30 *
31 * @param delimiter
32 * string delimiter.
33 * @param data
34 * list of data to be joined.
35 *
36 * @return the joined string.
37 */
38 public static String join(String delimiter, String... data) {
39 final StringBuilder sb = new StringBuilder();
40 for (int i = 0; i < data.length; i++) {
41 sb.append(data[i]);
42 if (i >= data.length - 1) {
43 break;
44 }
45 sb.append(delimiter);
46 }
47 return sb.toString();
48 }
49
50 /**
51 * Counts how many times <code>content</code> appears within <code>container</code> without string overlapping.
52 *
53 * @param container
54 * container string.
55 * @param content
56 * content string.
57 *
58 * @return occurrences count.
59 */
60 public static int countOccurrences(String container, String content) {
61 int lastIndex, currIndex = 0, occurrences = 0;
62 while (true) {
63 lastIndex = container.indexOf(content, currIndex);
64 if (lastIndex == -1) {
65 break;
66 }
67 currIndex = lastIndex + content.length();
68 occurrences++;
69 }
70 return occurrences;
71 }
72
73 /**
74 * Counts the number of <code>NL</code> in the given <i>in</i> string.
75 *
76 * @param in
77 * input string.
78 *
79 * @return the number of new line chars.
80 */
81 public static int countNL(String in) {
82 return countOccurrences(in, "\n");
83 }
84
85 /**
86 * Check whether string <code>candidatePrefix</code> is prefix of string <code>container</code>.
87 *
88 * @param candidatePrefix
89 * prefix to check
90 * @param container
91 * container to check against
92 *
93 * @return <code>true</code> if <code>candidatePrefix</code> is prefix of <code>container</code>, <code>false</code>
94 * otherwise.
95 */
96 public static boolean isPrefix(String candidatePrefix, String container) {
97 if (candidatePrefix == null || container == null) {
98 throw new NullPointerException("Arguments must be not null.");
99 }
100 if (candidatePrefix.length() > container.length()) {
101 return false;
102 }
103 for (int i = 0; i < candidatePrefix.length(); i++) {
104 if (candidatePrefix.charAt(i) != container.charAt(i)) {
105 return false;
106 }
107 }
108 return true;
109 }
110
111 /**
112 * Check whether string <code>candidateSuffix</code> is suffix of string <code>container</code>.
113 *
114 * @param candidateSuffix
115 * suffix to check
116 * @param container
117 * container to check against
118 *
119 * @return <code>true</code> if <code>candidateSuffix</code> is prefix of <code>container</code>, <code>false</code>
120 * otherwise.
121 */
122 public static boolean isSuffix(String candidateSuffix, String container) {
123 if (candidateSuffix == null || container == null) {
124 throw new NullPointerException("Arguments must be not null.");
125 }
126 if (candidateSuffix.length() > container.length()) {
127 return false;
128 }
129 final int lenDiff = container.length() - candidateSuffix.length();
130 for (int i = candidateSuffix.length() - 1; i >= 0; i--) {
131 if (candidateSuffix.charAt(i) != container.charAt(i + lenDiff)) {
132 return false;
133 }
134 }
135 return true;
136 }
137
138 /**
139 * Escapes all the unescaped double quotes when needed.
140 *
141 * @param in
142 * input string.
143 *
144 * @return unescaped output.
145 */
146 public static String escapeDoubleQuotes(String in) {
147 final StringBuilder out = new StringBuilder();
148 boolean escaped = false;
149 char current;
150 for (int i = 0; i < in.length(); i++) {
151 current = in.charAt(i);
152 if (current == '\\') {
153 escaped = !escaped;
154 } else if (current == '"' && !escaped) {
155 out.append('\\');
156 }
157 out.append(current);
158 }
159 return out.toString();
160 }
161
162 /**
163 * Escapes the <code>in</code> string as <b>JSON</b> string to let it being embeddable within a string field.
164 *
165 * @param in
166 * string to be escaped.
167 *
168 * @return escaped string.
169 */
170 public static String escapeAsJSONString(String in) {
171 return escapeDoubleQuotes(in.replaceAll("\n", "\\\\n"));
172 }
173
174 /**
175 * Builds a string composed of the given char <code>c</code> <code>n</code> times.
176 *
177 * @param c
178 * char to be multiplied.
179 * @param times
180 * number of times.
181 *
182 * @return the string containing the multiplied char.
183 */
184 public static String multiply(char c, int times) {
185 if (times <= 0) {
186 throw new IllegalArgumentException("Invalid number of times, must be > 0 .");
187 }
188 final char[] buffer = new char[times];
189 for (int i = 0; i < times; i++) {
190 buffer[i] = c;
191 }
192 return new String(buffer);
193 }
194
195 /**
196 * Changes string with following convention:
197 * <ul>
198 * <li>Changes '-' -> '_'
199 * <li>remove space characters and make first letter word uppercase: 'some string' -> 'someString'
200 * </ul>
201 * If input string does not contains a whitespace than return unchanged.
202 *
203 * @param in
204 * an input string to convert to Java code convention
205 *
206 * @return the correctly formatter string as per Java spec.
207 */
208 public static String implementJavaNaming(String in) {
209
210 in = in.trim().replaceAll("-", "_");
211
212 if (in.matches("\\S+")) {
213 return org.apache.commons.lang3.StringUtils.uncapitalize(in);
214 }
215
216 in = in.toLowerCase(Locale.ROOT);
217 String[] words = in.split("\\s+");
218 StringBuilder sb = new StringBuilder(in.length());
219 sb.append(words[0]);
220 for (int i = 1; i < words.length; i++) {
221 sb.append(org.apache.commons.lang3.StringUtils.capitalize(words[i]));
222 }
223 return sb.toString();
224 }
225
226 private StringUtils() {
227 }
228 }