| /* Copyright (c) 2006-2009 Jan S. Rellermeyer |
| * Systems Group, |
| * Department of Computer Science, ETH Zurich. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * - Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * - Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * - Neither the name of ETH Zurich nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| package ch.ethz.iks.util; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * String utilities. |
| * |
| * @author Jan S. Rellermeyer, ETH Zurich |
| * @since 0.2 |
| */ |
| public final class StringUtils { |
| |
| /** |
| * hide the default constructor. |
| */ |
| private StringUtils() { |
| } |
| |
| /** |
| * transforms a string list into an array of Strings. |
| * |
| * @param data |
| * the string list. |
| * @param delim |
| * the list delimiter. |
| * @return the array of strings. |
| * @since 0.2 |
| */ |
| public static String[] stringToArray(final String data, |
| final String delim) { |
| |
| if (data == null) { |
| return new String[0]; |
| } |
| |
| final List tokens = new ArrayList(data.length() / 10); |
| int pointer = 0; |
| int quotePointer = 0; |
| int tokenStart = 0; |
| int nextDelimiter; |
| while ((nextDelimiter = data.indexOf(delim, pointer)) > -1) { |
| final int openingQuote = data.indexOf("\"", quotePointer); |
| int closingQuote = data.indexOf("\"", openingQuote + 1); |
| if (openingQuote > closingQuote) { |
| throw new IllegalArgumentException( |
| "Missing closing quotation mark."); |
| } |
| if (openingQuote > -1 && openingQuote < nextDelimiter |
| && closingQuote < nextDelimiter) { |
| quotePointer = ++closingQuote; |
| continue; |
| } |
| if (openingQuote < nextDelimiter && nextDelimiter < closingQuote) { |
| pointer = ++closingQuote; |
| continue; |
| } |
| // TODO: for performance, fold the trim into the splitting |
| tokens.add(data.substring(tokenStart, nextDelimiter).trim()); |
| pointer = ++nextDelimiter; |
| quotePointer = pointer; |
| tokenStart = pointer; |
| } |
| tokens.add(data.substring(tokenStart).trim()); |
| return (String[]) tokens.toArray(new String[tokens.size()]); |
| } |
| |
| /** |
| * R \ L (comparison operation allows wildcards) |
| * |
| * @param left |
| * A set of matchers (supports wildcard at end) |
| * @param right |
| * A set of inputs |
| * @return The subset of right with all elements removed matching left |
| * @since 1.0 |
| */ |
| public static Collection rightDifference(Collection left, Collection right) { |
| // This is O(n²) due to substring (wildcard) matching |
| // It's also quick and dirty (better use pattern matcher instead) |
| // TODO use pattern matcher |
| // (pattern matcher would increase the BREE dependency, but we could |
| // hide |
| // the FilterUtils implementation behind an interface and provide |
| // different |
| // service implementations) |
| // A trie would also allow for faster lookup. |
| |
| // Have to convert c1 into List to support remove operation |
| final List result = new ArrayList(right); |
| |
| for (Iterator iterator = right.iterator(); iterator.hasNext();) { |
| final String f1 = (String) iterator.next(); |
| for (Iterator itr2 = left.iterator(); itr2.hasNext();) { |
| String f2 = (String) itr2.next(); |
| if (f2.endsWith("*")) { |
| f2 = f2.substring(0, f2.length() - 1); |
| if (f1.startsWith(f2)) { |
| result.remove(f1); |
| } |
| } else { |
| if (f1.equals(f2)) { |
| result.remove(f1); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| } |