/******************************************************************************* * Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.xpect.expectation.impl; import java.util.Collection; import java.util.Iterator; import java.util.regex.Pattern; import com.google.common.collect.HashMultiset; import com.google.common.collect.Lists; /** * @author Moritz Eysholdt - Initial contribution and API */ public class StringCollection<T extends StringCollection<T>.Item> implements Iterable<T> { public class Item implements Comparable<Item> { protected String escaped = null; protected String normalized = null; protected String pure; public Item(String pure) { super(); this.pure = pure; } @Override @SuppressWarnings("unchecked") public boolean equals(Object obj) { if (obj == null || !Item.class.isInstance(obj)) return false; return getNormalized().equals(((Item) obj).getNormalized()); } public String getEscaped() { if (escaped == null) escaped = escape(pure); return escaped; } public String getNormalized() { if (normalized == null) normalized = normalize(pure); return normalized; } public String getPure() { return pure; } @Override public int hashCode() { return getNormalized().hashCode(); } @Override public String toString() { return pure; } public int compareTo(Item o) { if (normalized == null) return -1; if (o == null || o.normalized == null) return 1; return normalized.compareTo(o.normalized); } } protected static final Pattern WS = Pattern.compile("\\s+", Pattern.MULTILINE); protected boolean caseSensitive = true; protected Collection<T> items; protected boolean ordered = true; protected char quote = '\"'; protected boolean quoted = true; protected char separator = ','; protected boolean whitespaceSensitive = true; protected Collection<T> createCollection() { return ordered ? Lists.<T> newArrayList() : HashMultiset.<T> create(); } protected String escape(String str) { str = str.replace("\\", "\\\\").replace("\n", "\\n").replace("\r", "\\r"); if (quoted) return quote + str.replace(String.valueOf(quote), "\\" + quote) + quote; if (str.startsWith("!") || str.equals("...")) str = "\\" + str; str = str.replace(String.valueOf(separator), "\\" + separator); if (whitespaceSensitive) return str; return str.trim(); } protected String escapeUnquoted(String str) { return str.replaceAll("\\s+", " "); } public char getQuote() { return quote; } public char getSeparator() { return separator; } public boolean isCaseSensitive() { return caseSensitive; } public boolean isOrdered() { return ordered; } public boolean isQuoted() { return quoted; } public boolean isWhitespaceSensitive() { return whitespaceSensitive; } public Iterator<T> iterator() { return items.iterator(); } protected String normalize(String item) { if (!quoted) item = item.trim(); if (!whitespaceSensitive) item = WS.matcher(item).replaceAll(""); if (!caseSensitive) item = item.toLowerCase(); return item; } public void setCaseSensitive(boolean caseSensitive) { this.caseSensitive = caseSensitive; } public void setOrdered(boolean ordered) { this.ordered = ordered; } public void setQuote(char quote) { this.quote = quote; } public void setQuoted(boolean quoted) { this.quoted = quoted; } public void setSeparator(char separator) { this.separator = separator; } public void setWhitespaceSensitive(boolean whitespaceSensitive) { this.whitespaceSensitive = whitespaceSensitive; } }