package org.andork.format; import java.text.StringCharacterIterator; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.function.Supplier; public class CollectionFormat<T, C extends Collection<T>> implements Format<C> { public static void main(String[] args) throws Exception { CollectionFormat<String, Set<String>> format = new CollectionFormat<String, Set<String>>(',', StringFormat.instance, () -> new HashSet<String>()); System.out.println(format.parse(" a , b, \"cbd\"\"\"\"\"abc, e,")); } private char parseDelimiter; private String formatDelimiter; private Format<T> itemFormat; Supplier<C> collectionSupplier; public CollectionFormat(char delimiter, Format<T> itemFormat, Supplier<C> collectionSupplier) { this(delimiter, delimiter + " ", itemFormat, collectionSupplier); } public CollectionFormat(char parseDelimiter, String formatDelimiter, Format<T> itemFormat, Supplier<C> collectionSupplier) { super(); this.parseDelimiter = parseDelimiter; this.formatDelimiter = formatDelimiter; this.itemFormat = itemFormat; this.collectionSupplier = collectionSupplier; } @Override public String format(C t) { if (t == null) { return null; } StringBuilder sb = new StringBuilder(); for (T item : t) { String s = itemFormat.format(item); if (sb.length() > 0) { sb.append(formatDelimiter); } if (s.indexOf(parseDelimiter) >= 0) { sb.append('"').append(s.replaceAll("\"", "\"\"")).append('"'); } else { sb.append(s); } } return sb.toString(); } private String nextItem(StringCharacterIterator i) { StringBuilder sb = null; while (i.current() != '\uffff') { if (i.current() == parseDelimiter) { i.next(); break; } else { if (sb == null) { sb = new StringBuilder(); } if (i.current() == '"') { readUntilEndQuote(i, sb); } else { sb.append(i.current()); i.next(); } } } return sb == null ? null : sb.toString().trim(); } @Override public C parse(String s) throws Exception { if (s == null) { return collectionSupplier.get(); } if (parseDelimiter == ' ') { s = s.replaceAll("\\s+", " "); } C result = collectionSupplier.get(); StringCharacterIterator i = new StringCharacterIterator(s); String item; while ((item = nextItem(i)) != null) { result.add(itemFormat.parse(item)); } return result; } private void readUntilEndQuote(StringCharacterIterator i, StringBuilder sb) { while (true) { char c = i.next(); if (c == '"') { char c2 = i.next(); if (c2 != '"') { return; } } sb.append(c); } } }