View Javadoc
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 '-' -&gt; '_'
199      * <li>remove space characters and make first letter word uppercase: 'some string' -&gt; '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 }