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