ValueProperties implements Serializable, Comparable<ValueProperties> { public static ValueProperties parse(String s) { if (StringUtils.isBlank(s) || EMPTY.toString().equals(s)) { return EMPTY; } s = s.trim(); if (INFINITE.toString().equals(s)) { return INFINITE; } boolean nearlyInfinite = false; Builder builder = null; ValueProperties nearlyInfiniteResult = null; if (s.startsWith("INFINITE-")) { nearlyInfinite = true; s = s.substring(9, s.length()); nearlyInfiniteResult = INFINITE; } else { builder = builder(); } if (s.charAt(0) == '{' && s.charAt(s.length() - 1) == '}') { s = s.substring(1, s.length() - 1); } int pos = 0; boolean isOptional = false; StringBuilder substring = new StringBuilder(); String name = null; Set<String> values = new HashSet<String>(); boolean bracketedValue = false; boolean inValue = false; int space = -1; while (pos <= s.length()) { char next = pos < s.length() ? s.charAt(pos) : 0; if (next == '\\') { pos++; if (pos < s.length()) { if (space > 0) { for (int i = 0; i < space; i++) { substring.append(' '); } } space = 0; char escapedCharacter = s.charAt(pos); if (escapedCharacter == '\\' || escapedCharacter == ',' || escapedCharacter == '=' || escapedCharacter == '[' || escapedCharacter == ']' || escapedCharacter == '?' || escapedCharacter == ' ') { substring.append(escapedCharacter); } else { throw new IllegalArgumentException("Unrecognised escape sequence: \\" + escapedCharacter); } } else { throw new IllegalArgumentException("Unexpected end of ValueProperties string: " + s); } } else if (next == '=') { if (inValue) { throw new IllegalArgumentException("Unexpected '=' at position " + pos); } space = -1; name = substring.toString(); substring = new StringBuilder(); inValue = true; while (pos + 1 < s.length()) { if (s.charAt(pos + 1) == ' ') { pos++; continue; } if (s.charAt(pos + 1) == '[') { bracketedValue = true; pos++; } break; } } else if (next == ']') { space = -1; inValue = false; while (pos + 1 < s.length()) { if (s.charAt(pos + 1) == ' ') { pos++; continue; } if (s.charAt(pos + 1) == '?') { isOptional = true; pos++; } break; } } else if (next == ',' || next == 0) { space = -1; if (substring.length() > 0) { if (name == null) { name = substring.toString(); } else { values.add(substring.toString()); } substring = new StringBuilder(); } if (!inValue || !bracketedValue) { if (values.isEmpty()) { if (nearlyInfinite) { nearlyInfiniteResult = nearlyInfiniteResult.withoutAny(name); } else { builder.withAny(name); } } else { if (nearlyInfinite) { throw new IllegalArgumentException("Property values not supported in nearly infinite ValueProperties. Found: " + values); } builder.with(name, values); } if (isOptional) { builder.withOptional(name); } name = null; values = new HashSet<String>(); isOptional = false; inValue = false; bracketedValue = false; } } else if (next != ' ') { if (space > 0) { for (int i = 0; i < space; i++) { substring.append(' '); } } space = 0; substring.append(next); } else { if (space >= 0) { space++; } } pos++; } if (name != null || substring.length() > 0) { throw new IllegalArgumentException("Unexpected end of ValueProperties string: " + s); } return nearlyInfinite ? nearlyInfiniteResult : builder.get(); } ValueProperties(); @Deprecated static boolean isNearInfiniteProperties(final ValueProperties properties); static ValueProperties none(); static ValueProperties all(); static Builder builder(); static Builder with(final String propertyName, final String propertyValue); static Builder with(final String propertyName, final String... propertyValues); static Builder with(final String propertyName, final Collection<String> propertyValues); static Builder withAny(final String propertyName); static Builder withOptional(final String propertyName); abstract Builder copy(); abstract Set<String> getProperties(); abstract boolean isDefined(String propertyName); abstract Set<String> getValues(String propertyName); abstract String getStrictValue(String propertyName); abstract String getSingleValue(String propertyName); abstract boolean isOptional(String propertyName); abstract boolean isSatisfiedBy(ValueProperties properties); abstract Set<String> getUnsatisfied(ValueProperties properties); abstract ValueProperties compose(ValueProperties properties); abstract ValueProperties intersect(ValueProperties properties); abstract ValueProperties union(ValueProperties properties); abstract boolean isStrict(); abstract boolean isEmpty(); abstract ValueProperties withoutAny(String propertyName); abstract String toSimpleString(); abstract void toFudgeMsg(MutableFudgeMsg message); static ValueProperties parse(String s); @Deprecated static String toString(final Map<String, Set<String>> properties, final Set<String> optional, final boolean strict);  }
@Test(expectedExceptions = IllegalArgumentException.class) public void testParseInvalidNoValue() { ValueProperties.parse("ValueName=["); }