1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.jdbc.util;
25
26 import java.util.Arrays;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29
30 import org.modeshape.jdbc.JdbcI18n;
31
32 /**
33 * Utilities for string processing and manipulation.
34 */
35 public class StringUtil {
36
37 public static final String[] EMPTY_STRING_ARRAY = new String[0];
38 private static final Pattern PARAMETER_COUNT_PATTERN = Pattern.compile("\\{(\\d+)\\}");
39
40
41
42 /**
43 * Create a string by substituting the parameters into all key occurrences in the supplied format. The pattern consists of
44 * zero or more keys of the form <code>{n}</code>, where <code>n</code> is an integer starting at 1. Therefore, the first
45 * parameter replaces all occurrences of "{1}", the second parameter replaces all occurrences of "{2}", etc.
46 * <p>
47 * If any parameter is null, the corresponding key is replaced with the string "null". Therefore, consider using an empty
48 * string when keys are to be removed altogether.
49 * </p>
50 * <p>
51 * If there are no parameters, this method does nothing and returns the supplied pattern as is.
52 * </p>
53 *
54 * @param pattern the pattern
55 * @param parameters the parameters used to replace keys
56 * @return the string with all keys replaced (or removed)
57 */
58 public static String createString( String pattern,
59 Object... parameters ) {
60 CheckArg.isNotNull(pattern, "pattern");
61 if (parameters == null) parameters = EMPTY_STRING_ARRAY;
62 Matcher matcher = PARAMETER_COUNT_PATTERN.matcher(pattern);
63 StringBuffer text = new StringBuffer();
64 int requiredParameterCount = 0;
65 boolean err = false;
66 while (matcher.find()) {
67 int ndx = Integer.valueOf(matcher.group(1));
68 if (requiredParameterCount <= ndx) {
69 requiredParameterCount = ndx + 1;
70 }
71 if (ndx >= parameters.length) {
72 err = true;
73 matcher.appendReplacement(text, matcher.group());
74 } else {
75 Object parameter = parameters[ndx];
76
77 // Automatically pretty-print arrays
78 if (parameter != null && parameter.getClass().isArray()) {
79 parameter = Arrays.asList((Object[])parameter);
80 }
81
82 matcher.appendReplacement(text, Matcher.quoteReplacement(parameter == null ? "null" : parameter.toString()));
83 }
84 }
85 if (err || requiredParameterCount < parameters.length) {
86 throw new IllegalArgumentException(
87 JdbcI18n.i18nRequiredToSuppliedParameterMismatch.text(parameters.length,
88 parameters.length == 1 ? "" : "s",
89 requiredParameterCount,
90 requiredParameterCount == 1 ? "" : "s",
91 pattern,
92 text.toString()));
93 }
94 matcher.appendTail(text);
95
96 return text.toString();
97 }
98
99 /**
100 * Create a new string containing the specified character repeated a specific number of times.
101 *
102 * @param charToRepeat the character to repeat
103 * @param numberOfRepeats the number of times the character is to repeat in the result; must be greater than 0
104 * @return the resulting string
105 */
106 public static String createString( final char charToRepeat,
107 int numberOfRepeats ) {
108 assert numberOfRepeats >= 0;
109 StringBuilder sb = new StringBuilder();
110 for (int i = 0; i < numberOfRepeats; ++i) {
111 sb.append(charToRepeat);
112 }
113 return sb.toString();
114 }
115
116 private StringUtil() {
117 // Prevent construction
118 }
119 }