All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spark.utils.StringUtils Maven / Gradle / Ivy

Go to download

A micro framework for creating web applications in Kotlin and Java 8 with minimal effort

The newest version!
/*
 * Copyright 2002-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package spark.utils;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Miscellaneous {@link String} utility methods.
 * 

Mainly for internal use within the framework; consider * Jakarta's Commons Lang * for a more comprehensive suite of String utilities. *

This class delivers some simple functionality that should really * be provided by the core Java {@code String} and {@link StringBuilder} * classes, such as the ability to {@link #replace} all occurrences of a given * substring in a target string. It also provides easy-to-use methods to convert * between delimited strings, such as CSV strings, and collections and arrays. * * @author Rod Johnson * @author Juergen Hoeller * @author Keith Donald * @author Rob Harrop * @author Rick Evans * @author Arjen Poutsma * Code copied from Spring source. Modifications made (mostly removal of methods) by Per Wendel. */ public abstract class StringUtils { private static final String FOLDER_SEPARATOR = "/"; private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; private static final String TOP_PATH = ".."; private static final String CURRENT_PATH = "."; //--------------------------------------------------------------------- // General convenience methods for working with Strings //--------------------------------------------------------------------- public static boolean isBlank(final CharSequence cs) { int strLen; if (cs == null || (strLen = cs.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (Character.isWhitespace(cs.charAt(i)) == false) { return false; } } return true; } public static boolean isNotBlank(final CharSequence cs) { return !isBlank(cs); } /** * Check whether the given String is empty. *

This method accepts any Object as an argument, comparing it to * {@code null} and the empty String. As a consequence, this method * will never return {@code true} for a non-null non-String object. *

The Object signature is useful for general attribute handling code * that commonly deals with Strings but generally has to iterate over * Objects since attributes may e.g. be primitive value objects as well. * * @param str the candidate String * @return if the String is empty * @since 3.2.1 */ public static boolean isEmpty(Object str) { return (str == null || "".equals(str)); } /** * Checks if the given String is not empty * * @param str the candidate String * @return if the String is not empty */ public static boolean isNotEmpty(String str) { return !isEmpty(str); } /** * Check that the given CharSequence is neither {@code null} nor of length 0. * * @param str the CharSequence to check (may be {@code null}) * @return {@code true} if the CharSequence is not null and has length */ public static boolean hasLength(CharSequence str) { return (str != null && str.length() > 0); } /** * Check that the given String is neither {@code null} nor of length 0. * Note: Will return {@code true} for a String that purely consists of whitespace. * * @param str the String to check (may be {@code null}) * @return {@code true} if the String is not null and has length * @see #hasLength(CharSequence) */ public static boolean hasLength(String str) { return hasLength((CharSequence) str); } /** * Replace all occurrences of a substring within a string with * another string. * * @param inString String to examine * @param oldPattern String to replace * @param newPattern String to insert * @return a String with the replacements */ public static String replace(String inString, String oldPattern, String newPattern) { if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) { return inString; } StringBuilder sb = new StringBuilder(); int pos = 0; // our position in the old string int index = inString.indexOf(oldPattern); // the index of an occurrence we've found, or -1 int patLen = oldPattern.length(); while (index >= 0) { sb.append(inString.substring(pos, index)); sb.append(newPattern); pos = index + patLen; index = inString.indexOf(oldPattern, pos); } sb.append(inString.substring(pos)); // remember to append any characters to the right of a match return sb.toString(); } /** * Delete any character in a given String. * * @param inString the original String * @param charsToDelete a set of characters to delete. * E.g. "az\n" will delete 'a's, 'z's and new lines. * @return the resulting String */ public static String deleteAny(String inString, String charsToDelete) { if (!hasLength(inString) || !hasLength(charsToDelete)) { return inString; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < inString.length(); i++) { char c = inString.charAt(i); if (charsToDelete.indexOf(c) == -1) { sb.append(c); } } return sb.toString(); } /** * Extract the filename from the given path. * * @param path the file path (may be {@code null}) * @return the extracted filename, or {@code null} if none */ public static String getFilename(String path) { if (path == null) { return null; } int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path); } /** * Apply the given relative path to the given path, * assuming standard Java folder separation (i.e. "/" separators). * * @param path the path to start from (usually a full file path) * @param relativePath the relative path to apply * (relative to the full file path above) * @return the full file path that results from applying the relative path */ public static String applyRelativePath(String path, String relativePath) { int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); if (separatorIndex != -1) { String newPath = path.substring(0, separatorIndex); if (!relativePath.startsWith(FOLDER_SEPARATOR)) { newPath += FOLDER_SEPARATOR; } return newPath + relativePath; } else { return relativePath; } } /** * Normalize the path by suppressing sequences like "path/.." and * inner simple dots. *

The result is convenient for path comparison. For other uses, * notice that Windows separators ("\") are replaced by simple slashes. * * @param path the original path * @return the normalized path */ public static String cleanPath(String path) { if (path == null) { return null; } String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); // Strip prefix from path to analyze, to not treat it as part of the // first path element. This is necessary to correctly parse paths like // "file:core/../core/io/Resource.class", where the ".." should just // strip the first "core" directory while keeping the "file:" prefix. int prefixIndex = pathToUse.indexOf(":"); String prefix = ""; if (prefixIndex != -1) { prefix = pathToUse.substring(0, prefixIndex + 1); pathToUse = pathToUse.substring(prefixIndex + 1); } if (pathToUse.startsWith(FOLDER_SEPARATOR)) { prefix = prefix + FOLDER_SEPARATOR; pathToUse = pathToUse.substring(1); } String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR); List pathElements = new LinkedList<>(); int tops = 0; for (int i = pathArray.length - 1; i >= 0; i--) { String element = pathArray[i]; if (CURRENT_PATH.equals(element)) { // Points to current directory - drop it. } else if (TOP_PATH.equals(element)) { // Registering top path found. tops++; } else { if (tops > 0) { // Merging path element with element corresponding to top path. tops--; } else { // Normal path element found. pathElements.add(0, element); } } } // Remaining top paths need to be retained. for (int i = 0; i < tops; i++) { pathElements.add(0, TOP_PATH); } return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); } /** * Copy the given Collection into a String array. * The Collection must contain String elements only. * * @param collection the Collection to copy * @return the String array ({@code null} if the passed-in * Collection was {@code null}) */ public static String[] toStringArray(Collection collection) { if (collection == null) { return null; } return collection.toArray(new String[collection.size()]); } /** * Take a String which is a delimited list and convert it to a String array. *

A single delimiter can consists of more than one character: It will still * be considered as single delimiter string, rather than as bunch of potential * delimiter characters - in contrast to {@code tokenizeToStringArray}. * * @param str the input String * @param delimiter the delimiter between elements (this is a single delimiter, * rather than a bunch individual delimiter characters) * @return an array of the tokens in the list */ public static String[] delimitedListToStringArray(String str, String delimiter) { return delimitedListToStringArray(str, delimiter, null); } /** * Take a String which is a delimited list and convert it to a String array. *

A single delimiter can consists of more than one character: It will still * be considered as single delimiter string, rather than as bunch of potential * delimiter characters - in contrast to {@code tokenizeToStringArray}. * * @param str the input String * @param delimiter the delimiter between elements (this is a single delimiter, * rather than a bunch individual delimiter characters) * @param charsToDelete a set of characters to delete. Useful for deleting unwanted * line breaks: e.g. "\r\n\f" will delete all new lines and line feeds in a String. * @return an array of the tokens in the list */ public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { if (str == null) { return new String[0]; } if (delimiter == null) { return new String[] {str}; } List result = new ArrayList<>(); if ("".equals(delimiter)) { for (int i = 0; i < str.length(); i++) { result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); } } else { int pos = 0; int delPos; while ((delPos = str.indexOf(delimiter, pos)) != -1) { result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); pos = delPos + delimiter.length(); } if (str.length() > 0 && pos <= str.length()) { // Add rest of String, but not in case of empty input. result.add(deleteAny(str.substring(pos), charsToDelete)); } } return toStringArray(result); } /** * Convenience method to return a Collection as a delimited (e.g. CSV) * String. E.g. useful for {@code toString()} implementations. * * @param coll the Collection to display * @param delim the delimiter to use (probably a ",") * @param prefix the String to start each element with * @param suffix the String to end each element with * @return the delimited String */ public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) { if (CollectionUtils.isEmpty(coll)) { return ""; } StringBuilder sb = new StringBuilder(); Iterator it = coll.iterator(); while (it.hasNext()) { sb.append(prefix).append(it.next()).append(suffix); if (it.hasNext()) { sb.append(delim); } } return sb.toString(); } /** * Convenience method to return a Collection as a delimited (e.g. CSV) * String. E.g. useful for {@code toString()} implementations. * * @param coll the Collection to display * @param delim the delimiter to use (probably a ",") * @return the delimited String */ public static String collectionToDelimitedString(Collection coll, String delim) { return collectionToDelimitedString(coll, delim, "", ""); } public static String toString(byte[] bytes, String encoding) { String str; if (encoding != null && Charset.isSupported(encoding)) { try { str = new String(bytes, encoding); } catch (UnsupportedEncodingException e) { // Uses same func as Charset.isSupported (cannot happen) str = new String(bytes); } } else { str = new String(bytes); } return str; } public static String removeLeadingAndTrailingSlashesFrom(String string) { String trimmed = string; if (trimmed.endsWith("/") || trimmed.endsWith("\\")) { trimmed = trimmed.substring(0, trimmed.length() - 1); } if (trimmed.startsWith("/")) { trimmed = trimmed.substring(1); } return trimmed; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy