Created
August 22, 2012 13:09
-
-
Save aembleton/3425402 to your computer and use it in GitHub Desktop.
KeyValue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package utils; | |
import java.util.HashSet; | |
import java.util.Set; | |
public class KeyValue { | |
private static final char DELIMITER = ':'; | |
private static final char KEY_VALUE_DELIMITER = ','; | |
private static final char ESCAPE_CHAR = '\\'; | |
private static enum State { | |
key, value | |
}; | |
/** | |
* Converts a string of the format "key1:value1, key2:value2, key3:value3" into a set of {@link KeyValuePair}s containing the key value pairs. The control characters :, can be escaped with a | |
* backslash \ | |
* | |
* @param str | |
* The string to process | |
* @return A {@link Set} of {@link KeyValuePair}s made up from the values in the str | |
*/ | |
public static Set<KeyValuePair> fromString(String str) { | |
Set<KeyValuePair> set = new HashSet<KeyValuePair>(); | |
if (str != null) { | |
StringBuffer key = new StringBuffer(); | |
StringBuffer value = new StringBuffer(); | |
State state = State.key; | |
char previousChar = ' '; | |
KeyValue keyValue = new KeyValue(); | |
for (char c : str.toCharArray()) { | |
switch (c) { | |
case DELIMITER: | |
if (previousChar != ESCAPE_CHAR) { | |
state = State.value; | |
break; | |
} | |
case KEY_VALUE_DELIMITER: | |
if (previousChar != ESCAPE_CHAR) { | |
KeyValuePair pair = keyValue.new KeyValuePair(key, value); | |
set.add(pair); | |
// clean up | |
key = new StringBuffer(); | |
value = new StringBuffer(); | |
state = State.key; | |
break; | |
} | |
default: | |
if (c != ESCAPE_CHAR || previousChar == ESCAPE_CHAR) { | |
// append to the StringBuffer for either key or value | |
switch (state) { | |
case key: | |
key.append(c); | |
break; | |
case value: | |
value.append(c); | |
break; | |
} | |
} | |
break; | |
} | |
previousChar = c; | |
} | |
// add the remaining key value pair onto the set | |
KeyValuePair pair = keyValue.new KeyValuePair(key, value); | |
set.add(pair); | |
} | |
return set; | |
} | |
/** | |
* Bean to hold a key value pair. | |
* | |
* @author aembleton | |
* | |
*/ | |
public class KeyValuePair { | |
private String key = ""; | |
private String value = ""; | |
private KeyValuePair(final StringBuffer keySb, final StringBuffer valueSb) { | |
if (keySb != null) { | |
key = keySb.toString().trim(); | |
} | |
if (valueSb != null) { | |
value = valueSb.toString().trim(); | |
} | |
} | |
public String getKey() { | |
return key; | |
} | |
public String getValue() { | |
return value; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Iterator; | |
import java.util.Set; | |
import org.junit.Test; | |
import play.test.UnitTest; | |
import utils.KeyValue; | |
import utils.KeyValue.KeyValuePair; | |
public class KeyValueTest extends UnitTest { | |
@Test | |
public void singleKeyValue() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("hello:world"); | |
assertNotNull(keyValue); | |
assertEquals(1, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
assertEquals("hello", keyValuePair.getKey()); | |
assertEquals("world", keyValuePair.getValue()); | |
} | |
@Test | |
public void singleKeyValueWithEscapeInKey() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("he\\llo:world"); | |
assertNotNull(keyValue); | |
assertEquals(1, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
assertEquals("hello", keyValuePair.getKey()); | |
assertEquals("world", keyValuePair.getValue()); | |
} | |
@Test | |
public void singleKeyValueWithEscapeInValue() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("hello:wor\\ld"); | |
assertNotNull(keyValue); | |
assertEquals(1, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
assertEquals("hello", keyValuePair.getKey()); | |
assertEquals("world", keyValuePair.getValue()); | |
} | |
@Test | |
public void singleKeyValueWithEscapedDelimiter() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("hello\\:world"); | |
assertNotNull(keyValue); | |
assertEquals(1, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
assertEquals("hello:world", keyValuePair.getKey()); | |
assertEquals("", keyValuePair.getValue()); | |
} | |
@Test | |
public void multipleKeyValue() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("hello:world, foo:bar, name:arthur, customer:user123"); | |
assertNotNull(keyValue); | |
assertEquals(4, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
while (iterator.hasNext()) { | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
if (keyValuePair.getKey().equals("hello")) { | |
assertEquals("world", keyValuePair.getValue()); | |
} else if (keyValuePair.getKey().equals("foo")) { | |
assertEquals("bar", keyValuePair.getValue()); | |
} else if (keyValuePair.getKey().equals("name")) { | |
assertEquals("arthur", keyValuePair.getValue()); | |
} else if (keyValuePair.getKey().equals("customer")) { | |
assertEquals("user123", keyValuePair.getValue()); | |
} else { | |
fail("Unexpected key:" + keyValuePair.getKey() + " with value:" + keyValuePair.getValue()); | |
} | |
} | |
} | |
@Test | |
public void multipleKeyValueWithEscapedSeperator() { | |
Set<KeyValuePair> keyValue = KeyValue.fromString("hello:world\\, foo:bar, name:arthur, customer:user123"); | |
assertNotNull(keyValue); | |
assertEquals(3, keyValue.size()); | |
Iterator<KeyValuePair> iterator = keyValue.iterator(); | |
while (iterator.hasNext()) { | |
KeyValuePair keyValuePair = iterator.next(); | |
assertNotNull(keyValuePair); | |
if (keyValuePair.getKey().equals("hello")) { | |
assertEquals("world, foobar", keyValuePair.getValue()); | |
} else if (keyValuePair.getKey().equals("name")) { | |
assertEquals("arthur", keyValuePair.getValue()); | |
} else if (keyValuePair.getKey().equals("customer")) { | |
assertEquals("user123", keyValuePair.getValue()); | |
} else { | |
fail("Unexpected key:" + keyValuePair.getKey() + " with value:" + keyValuePair.getValue()); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment