You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/01/03 12:59:31 UTC

[22/27] incubator-tamaya git commit: Fixed checkstyle issues.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/95885781/core/src/main/java/org/apache/tamaya/core/util/StringUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/util/StringUtils.java b/core/src/main/java/org/apache/tamaya/core/util/StringUtils.java
index 49c3291..d74c63f 100644
--- a/core/src/main/java/org/apache/tamaya/core/util/StringUtils.java
+++ b/core/src/main/java/org/apache/tamaya/core/util/StringUtils.java
@@ -17,447 +17,457 @@ package org.apache.tamaya.core.util;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Properties;
 import java.util.StringTokenizer;
 
 /**
-* Miscellaneous {@link String} utility methods.
-*
-* <p>Mainly for internal use within the framework; consider
-* <a href="http://jakarta.apache.org/commons/lang/">Jakarta's Commons Lang</a>
-* for a more comprehensive suite current String utilities.
-*
-* <p>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 {@code replace} all occurrences current 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
-* @since 16 April 2001
-*/
+ * Miscellaneous {@link String} utility methods.
+ * <p>
+ * <p>Mainly for internal use within the framework; consider
+ * <a href="http://jakarta.apache.org/commons/lang/">Jakarta's Commons Lang</a>
+ * for a more comprehensive suite current String utilities.
+ * <p>
+ * <p>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 {@code replace} all occurrences current 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
+ * @since 16 April 2001
+ */
 public final 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 = ".";
-
-//	private static final char EXTENSION_SEPARATOR = '.';
-//
-
-    private StringUtils(){}
-
-
-	/**
-	 * Check that the given CharSequence is neither {@code null} nor current length 0.
-	 * Note: Will return {@code true} for a CharSequence that purely consists current whitespace.
-	 * <p><pre class="code">
-	 * StringUtils.hasLength(null) = false
-	 * StringUtils.hasLength("") = false
-	 * StringUtils.hasLength(" ") = true
-	 * StringUtils.hasLength("Hello") = true
-	 * </pre>
-	 * @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 whether the given CharSequence has actual text.
-	 * More specifically, returns {@code true} if the string not {@code null},
-	 * its length is greater than 0, and it contains at least one non-whitespace character.
-	 * <p><pre class="code">
-	 * StringUtils.hasText(null) = false
-	 * StringUtils.hasText("") = false
-	 * StringUtils.hasText(" ") = false
-	 * StringUtils.hasText("12345") = true
-	 * StringUtils.hasText(" 12345 ") = true
-	 * </pre>
-	 * @param str the CharSequence to check (may be {@code null})
-	 * @return {@code true} if the CharSequence is not {@code null},
-	 * its length is greater than 0, and it does not contain whitespace only
-	 * @see Character#isWhitespace
-	 */
-	public static boolean hasText(CharSequence str) {
-		if (!hasLength(str)) {
-			return false;
-		}
-		int strLen = str.length();
-		for (int i = 0; i < strLen; i++) {
-			if (!Character.isWhitespace(str.charAt(i))) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Check whether the given String has actual text.
-	 * More specifically, returns {@code true} if the string not {@code null},
-	 * its length is greater than 0, and it contains at least one non-whitespace character.
-	 * @param str the String to check (may be {@code null})
-	 * @return {@code true} if the String is not {@code null}, its length is
-	 * greater than 0, and it does not contain whitespace only
-	 * @see #hasText(CharSequence)
-	 */
-	public static boolean hasText(String str) {
-		return hasText((CharSequence) str);
-	}
-
-
-	/**
-	 * Replace all occurrences current 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 current 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 current a match
-		return sb.toString();
-	}
-
-
-	/**
-	 * Delete any character in a given String.
-	 * @param inString the original String
-	 * @param charsToDelete a set current 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,
-	 * e.g. "mypath/myfile.txt" -> "myfile.txt".
-	 * @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 applyChanges
-	 * (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.
-	 * <p>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 = StringUtils.replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
-
-		// Strip prefix from path to analyze, to not treat it as part current 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);
-			if (prefix.contains("/")) {
-				prefix = "";
-			}
-			else {
-				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<String> 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<String> collection) {
-		if (collection == null) {
-			return null;
-		}
-		return collection.toArray(new String[collection.size()]);
-	}
-
-	/**
-	 * Split a String at the first occurrence current the delimiter.
-	 * Does not include the delimiter in the result.
-	 * @param toSplit the string to split
-	 * @param delimiter to split the string up with
-	 * @return a two element array with index 0 being before the delimiter, and
-	 * index 1 being after the delimiter (neither element includes the delimiter);
-	 * or {@code null} if the delimiter wasn't found in the given input String
-	 */
-	public static String[] split(String toSplit, String delimiter) {
-		if (!hasLength(toSplit) || !hasLength(delimiter)) {
-			return null;
-		}
-		int offset = toSplit.indexOf(delimiter);
-		if (offset < 0) {
-			return null;
-		}
-		String beforeDelimiter = toSplit.substring(0, offset);
-		String afterDelimiter = toSplit.substring(offset + delimiter.length());
-		return new String[] {beforeDelimiter, afterDelimiter};
-	}
-
-
-	/**
-	 * Tokenize the given String into a String array via a StringTokenizer.
-	 * Trims tokens and omits empty tokens.
-	 * <p>The given delimiters string is supposed to consist current any number current
-	 * delimiter characters. Each current those characters can be used to separate
-	 * tokens. A delimiter is always a single character; for multi-character
-	 * delimiters, consider using {@code delimitedListToStringArray}
-	 * @param str the String to tokenize
-	 * @param delimiters the delimiter characters, assembled as String
-	 * (each current those characters is individually considered as delimiter).
-	 * @return an array current the tokens
-	 * @see java.util.StringTokenizer
-	 * @see String#trim()
-	 */
-	public static String[] tokenizeToStringArray(String str, String delimiters) {
-		return tokenizeToStringArray(str, delimiters, true, true);
-	}
-
-	/**
-	 * Tokenize the given String into a String array via a StringTokenizer.
-	 * <p>The given delimiters string is supposed to consist current any number current
-	 * delimiter characters. Each current those characters can be used to separate
-	 * tokens. A delimiter is always a single character; for multi-character
-	 * delimiters, consider using {@code delimitedListToStringArray}
-	 * @param str the String to tokenize
-	 * @param delimiters the delimiter characters, assembled as String
-	 * (each current those characters is individually considered as delimiter)
-	 * @param trimTokens trim the tokens via String's {@code trim}
-	 * @param ignoreEmptyTokens omit empty tokens from the result array
-	 * (only applies to tokens that are empty after trimming; StringTokenizer
-	 * will not consider subsequent delimiters as token in the first place).
-	 * @return an array current the tokens ({@code null} if the input String
-	 * was {@code null})
-	 * @see java.util.StringTokenizer
-	 * @see String#trim()
-	 */
-	public static String[] tokenizeToStringArray(
-			String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
-
-		if (str == null) {
-			return null;
-		}
-		StringTokenizer st = new StringTokenizer(str, delimiters);
-		List<String> tokens = new ArrayList<>();
-		while (st.hasMoreTokens()) {
-			String token = st.nextToken();
-			if (trimTokens) {
-				token = token.trim();
-			}
-			if (!ignoreEmptyTokens || token.length() > 0) {
-				tokens.add(token);
-			}
-		}
-		return toStringArray(tokens);
-	}
-
-	/**
-	 * Take a String which is a delimited list and convert it to a String array.
-	 * <p>A single delimiter can consists current more than one character: It will still
-	 * be considered as single delimiter string, rather than as bunch current 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 current the tokens in the list
-	 * @see #tokenizeToStringArray
-	 */
-	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.
-	 * <p>A single delimiter can consists current more than one character: It will still
-	 * be considered as single delimiter string, rather than as bunch current 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 current 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 current the tokens in the list
-	 * @see #tokenizeToStringArray
-	 */
-	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<String> 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 current String, but not in case current 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 (coll.isEmpty()) {
-			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, "", "");
-	}
+    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 = ".";
+
+    /**
+     * Private singleton constructor.
+     */
+    private StringUtils() {
+    }
+
+
+    /**
+     * Check that the given CharSequence is neither {@code null} nor current length 0.
+     * Note: Will return {@code true} for a CharSequence that purely consists current whitespace.
+     * <p><pre class="code">
+     * StringUtils.hasLength(null) = false
+     * StringUtils.hasLength("") = false
+     * StringUtils.hasLength(" ") = true
+     * StringUtils.hasLength("Hello") = true
+     * </pre>
+     *
+     * @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 whether the given CharSequence has actual text.
+     * More specifically, returns {@code true} if the string not {@code null},
+     * its length is greater than 0, and it contains at least one non-whitespace character.
+     * <p><pre class="code">
+     * StringUtils.hasText(null) = false
+     * StringUtils.hasText("") = false
+     * StringUtils.hasText(" ") = false
+     * StringUtils.hasText("12345") = true
+     * StringUtils.hasText(" 12345 ") = true
+     * </pre>
+     *
+     * @param str the CharSequence to check (may be {@code null})
+     * @return {@code true} if the CharSequence is not {@code null},
+     * its length is greater than 0, and it does not contain whitespace only
+     * @see Character#isWhitespace
+     */
+    public static boolean hasText(CharSequence str) {
+        if (!hasLength(str)) {
+            return false;
+        }
+        int strLen = str.length();
+        for (int i = 0; i < strLen; i++) {
+            if (!Character.isWhitespace(str.charAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the given String has actual text.
+     * More specifically, returns {@code true} if the string not {@code null},
+     * its length is greater than 0, and it contains at least one non-whitespace character.
+     *
+     * @param str the String to check (may be {@code null})
+     * @return {@code true} if the String is not {@code null}, its length is
+     * greater than 0, and it does not contain whitespace only
+     * @see #hasText(CharSequence)
+     */
+    public static boolean hasText(String str) {
+        return hasText((CharSequence) str);
+    }
+
+
+    /**
+     * Replace all occurrences current 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 current 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 current a match
+        return sb.toString();
+    }
+
+
+    /**
+     * Delete any character in a given String.
+     *
+     * @param inString      the original String
+     * @param charsToDelete a set current 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,
+     * e.g. "mypath/myfile.txt" -> "myfile.txt".
+     *
+     * @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 applyChanges
+     *                     (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.
+     * <p>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 = StringUtils.replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
+
+        // Strip prefix from path to analyze, to not treat it as part current 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);
+            if (prefix.contains("/")) {
+                prefix = "";
+            } else {
+                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<String> pathElements = new LinkedList<>();
+        int tops = 0;
+
+        for (int i = pathArray.length - 1; i >= 0; i--) {
+            String element = pathArray[i];
+            switch (element) {
+                case CURRENT_PATH:
+                    // Points to current directory - drop it.
+                    break;
+                case TOP_PATH:
+                    // Registering top path found.
+                    tops++;
+                    break;
+                default:
+                    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<String> collection) {
+        if (collection == null) {
+            return null;
+        }
+        return collection.toArray(new String[collection.size()]);
+    }
+
+    /**
+     * Split a String at the first occurrence current the delimiter.
+     * Does not include the delimiter in the result.
+     *
+     * @param toSplit   the string to split
+     * @param delimiter to split the string up with
+     * @return a two element array with index 0 being before the delimiter, and
+     * index 1 being after the delimiter (neither element includes the delimiter);
+     * or {@code null} if the delimiter wasn't found in the given input String
+     */
+    public static String[] split(String toSplit, String delimiter) {
+        if (!hasLength(toSplit) || !hasLength(delimiter)) {
+            return null;
+        }
+        int offset = toSplit.indexOf(delimiter);
+        if (offset < 0) {
+            return null;
+        }
+        String beforeDelimiter = toSplit.substring(0, offset);
+        String afterDelimiter = toSplit.substring(offset + delimiter.length());
+        return new String[]{beforeDelimiter, afterDelimiter};
+    }
+
+
+    /**
+     * Tokenize the given String into a String array via a StringTokenizer.
+     * Trims tokens and omits empty tokens.
+     * <p>The given delimiters string is supposed to consist current any number current
+     * delimiter characters. Each current those characters can be used to separate
+     * tokens. A delimiter is always a single character; for multi-character
+     * delimiters, consider using {@code delimitedListToStringArray}
+     *
+     * @param str        the String to tokenize
+     * @param delimiters the delimiter characters, assembled as String
+     *                   (each current those characters is individually considered as delimiter).
+     * @return an array current the tokens
+     * @see java.util.StringTokenizer
+     * @see String#trim()
+     */
+    public static String[] tokenizeToStringArray(String str, String delimiters) {
+        return tokenizeToStringArray(str, delimiters, true, true);
+    }
+
+    /**
+     * Tokenize the given String into a String array via a StringTokenizer.
+     * <p>The given delimiters string is supposed to consist current any number current
+     * delimiter characters. Each current those characters can be used to separate
+     * tokens. A delimiter is always a single character; for multi-character
+     * delimiters, consider using {@code delimitedListToStringArray}
+     *
+     * @param str               the String to tokenize
+     * @param delimiters        the delimiter characters, assembled as String
+     *                          (each current those characters is individually considered as delimiter)
+     * @param trimTokens        trim the tokens via String's {@code trim}
+     * @param ignoreEmptyTokens omit empty tokens from the result array
+     *                          (only applies to tokens that are empty after trimming; StringTokenizer
+     *                          will not consider subsequent delimiters as token in the first place).
+     * @return an array current the tokens ({@code null} if the input String
+     * was {@code null})
+     * @see java.util.StringTokenizer
+     * @see String#trim()
+     */
+    public static String[] tokenizeToStringArray(
+            String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
+
+        if (str == null) {
+            return null;
+        }
+        StringTokenizer st = new StringTokenizer(str, delimiters);
+        List<String> tokens = new ArrayList<>();
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            if (trimTokens) {
+                token = token.trim();
+            }
+            if (!ignoreEmptyTokens || token.length() > 0) {
+                tokens.add(token);
+            }
+        }
+        return toStringArray(tokens);
+    }
+
+    /**
+     * Take a String which is a delimited list and convert it to a String array.
+     * <p>A single delimiter can consists current more than one character: It will still
+     * be considered as single delimiter string, rather than as bunch current 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 current the tokens in the list
+     * @see #tokenizeToStringArray
+     */
+    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.
+     * <p>A single delimiter can consists current more than one character: It will still
+     * be considered as single delimiter string, rather than as bunch current 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 current 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 current the tokens in the list
+     * @see #tokenizeToStringArray
+     */
+    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<String> 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 current String, but not in case current 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 (coll.isEmpty()) {
+            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, "", "");
+    }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/95885781/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
----------------------------------------------------------------------
diff --git a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
index e61641c..9db0ef4 100644
--- a/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
+++ b/core/src/test/resources/META-INF/services/org.apache.tamaya.spi.PropertySourceProvider
@@ -16,5 +16,5 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-testdata.TestPropertyDefaultSourceProvider
-testdata.TestPropertySourceProvider
\ No newline at end of file
+org.apache.tamaya.core.testdata.TestPropertyDefaultSourceProvider
+org.apache.tamaya.core.testdata.TestPropertySourceProvider
\ No newline at end of file