Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/JSONObject.java386
1 files changed, 386 insertions, 0 deletions
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/JSONObject.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/JSONObject.java
new file mode 100644
index 000000000..3ac36215e
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/JSONObject.java
@@ -0,0 +1,386 @@
+package org.eclipse.e4.core.services;
+
+import java.math.BigDecimal;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public final class JSONObject {
+ Map map = new HashMap();
+
+ public JSONObject() {
+ }
+
+ public void set(String name, JSONObject value) {
+ map.put(name, value.map);
+ }
+
+ public void set(String name, JSONObject[] values) {
+ List maps = new ArrayList();
+ for (int i = 0; i < values.length; i++) {
+ maps.add(values[i].map);
+ }
+ map.put(name, maps);
+ }
+
+ public void set(String name, String value) {
+ map.put(name, value);
+ }
+
+ public void set(String name, String[] values) {
+ map.put(name, Arrays.asList(values));
+ }
+
+ public JSONObject getObject(String name) {
+ Map resultMap = (Map) map.get(name);
+ JSONObject result = asJSONObject(resultMap);
+ return result;
+ }
+
+ private JSONObject asJSONObject(Map m) {
+ JSONObject result = new JSONObject();
+ result.map = m;
+ return result;
+ }
+
+ public JSONObject[] getObjects(String name) {
+ Collection collection = (Collection) map.get(name);
+ JSONObject[] result = new JSONObject[collection.size()];
+ int i = 0;
+ for (Iterator it = collection.iterator(); it.hasNext();) {
+ Map m = (Map) it.next();
+ result[i++] = asJSONObject(m);
+ }
+ return result;
+ }
+
+ public String getString(String name) {
+ return (String) map.get(name);
+ }
+
+ public String[] getStrings(String name) {
+ return (String[]) map.get(name);
+ }
+
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+ private static final String NULL = "null"; //$NON-NLS-1$
+
+ public static JSONObject deserialize(String jsonString) {
+ Object result = parse(new StringCharacterIterator(jsonString));
+ if (!(result instanceof Map)) {
+ throw new IllegalArgumentException("not an object");
+ }
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.map = (Map) result;
+ return jsonObject;
+ }
+
+ public String serialize() {
+ StringBuffer buffer = new StringBuffer();
+ writeValue(map, buffer);
+ return buffer.toString();
+ }
+
+ private static RuntimeException error(String message, CharacterIterator it) {
+ return new IllegalStateException("[" + it.getIndex() + "] " + message); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ private static RuntimeException error(String message) {
+ return new IllegalStateException(message);
+ }
+
+ private static Object parse(CharacterIterator it) {
+ parseWhitespace(it);
+ Object result = parseValue(it);
+ parseWhitespace(it);
+
+ if (it.current() != CharacterIterator.DONE)
+ throw error("should be done", it); //$NON-NLS-1$
+ return result;
+ }
+
+ private static void parseWhitespace(CharacterIterator it) {
+ char c = it.current();
+ while (Character.isWhitespace(c))
+ c = it.next();
+ }
+
+ private static Object parseValue(CharacterIterator it) {
+ switch (it.current()) {
+ case '{':
+ return parseObject(it);
+ case '[':
+ return parseArray(it);
+ case '"':
+ return parseString(it);
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return parseNumber(it);
+ case 't':
+ parseText(Boolean.TRUE.toString(), it);
+ return Boolean.TRUE;
+ case 'f':
+ parseText(Boolean.FALSE.toString(), it);
+ return Boolean.FALSE;
+ case 'n':
+ parseText(NULL, it);
+ return null;
+ }
+ throw error("Bad JSON starting character '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+
+ private static Map parseObject(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == '}') {
+ it.next();
+ return Collections.EMPTY_MAP;
+ }
+
+ Map map = new HashMap();
+ while (true) {
+ if (it.current() != '"')
+ throw error(
+ "expected a string start '\"' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ String key = parseString(it);
+ if (map.containsKey(key))
+ throw error("' already defined" + "key '" + key, it); //$NON-NLS-1$ //$NON-NLS-2$
+ parseWhitespace(it);
+ if (it.current() != ':')
+ throw error(
+ "expected a pair separator ':' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ it.next();
+ parseWhitespace(it);
+ Object value = parseValue(it);
+ map.put(key, value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != '}')
+ throw error(
+ "expected an object close '}' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return map;
+ }
+
+ private static List parseArray(CharacterIterator it) {
+ it.next();
+ parseWhitespace(it);
+ if (it.current() == ']') {
+ it.next();
+ return Collections.EMPTY_LIST;
+ }
+
+ List list = new ArrayList();
+ while (true) {
+ Object value = parseValue(it);
+ list.add(value);
+ parseWhitespace(it);
+ if (it.current() == ',') {
+ it.next();
+ parseWhitespace(it);
+ continue;
+ }
+
+ if (it.current() != ']')
+ throw error(
+ "expected an array close ']' but was '" + it.current() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+ it.next();
+ return list;
+ }
+
+ private static void parseText(String string, CharacterIterator it) {
+ int length = string.length();
+ char c = it.current();
+ for (int i = 0; i < length; i++) {
+ if (c != string.charAt(i))
+ throw error(
+ "expected to parse '" + string + "' but character " + (i + 1) + " was '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$;
+ c = it.next();
+ }
+ }
+
+ private static Object parseNumber(CharacterIterator it) {
+ StringBuffer buffer = new StringBuffer();
+ char c = it.current();
+ while (Character.isDigit(c) || c == '-' || c == '+' || c == '.' || c == 'e'
+ || c == 'E') {
+ buffer.append(c);
+ c = it.next();
+ }
+ try {
+ return new BigDecimal(buffer.toString());
+ } catch (NumberFormatException e) {
+ throw error("expected a number but was '" + buffer.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$;
+ }
+ }
+
+ private static String parseString(CharacterIterator it) {
+ char c = it.next();
+ if (c == '"') {
+ it.next();
+ return EMPTY_STRING;
+ }
+ StringBuffer buffer = new StringBuffer();
+ while (c != '"') {
+ if (Character.isISOControl(c))
+ throw error(
+ "illegal iso control character: '" + Integer.toHexString(c) + "'", it); //$NON-NLS-1$ //$NON-NLS-2$);
+
+ if (c == '\\') {
+ c = it.next();
+ switch (c) {
+ case '"':
+ case '\\':
+ case '/':
+ buffer.append(c);
+ break;
+ case 'b':
+ buffer.append('\b');
+ break;
+ case 'f':
+ buffer.append('\f');
+ break;
+ case 'n':
+ buffer.append('\n');
+ break;
+ case 'r':
+ buffer.append('\r');
+ break;
+ case 't':
+ buffer.append('\t');
+ break;
+ case 'u':
+ StringBuffer unicode = new StringBuffer(4);
+ for (int i = 0; i < 4; i++) {
+ unicode.append(it.next());
+ }
+ try {
+ buffer.append((char) Integer.parseInt(unicode.toString(), 16));
+ } catch (NumberFormatException e) {
+ throw error(
+ "expected a unicode hex number but was '" + unicode.toString() + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ break;
+ default:
+ throw error("illegal escape character '" + c + "'", it); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+ } else
+ buffer.append(c);
+
+ c = it.next();
+ }
+ c = it.next();
+ return buffer.toString();
+ }
+
+ private static void writeValue(Object value, StringBuffer buffer) {
+ if (value == null)
+ buffer.append(NULL);
+ else if (value instanceof Boolean || value instanceof Number)
+ buffer.append(value.toString());
+ else if (value instanceof String)
+ writeString((String) value, buffer);
+ else if (value instanceof Collection)
+ writeArray((Collection) value, buffer);
+ else if (value instanceof Map)
+ writeObject((Map) value, buffer);
+ else
+ throw error("Unexpected object instance type was '" + value.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ }
+
+ private static void writeObject(Map map, StringBuffer buffer) {
+ buffer.append('{');
+ for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
+ Object key = iterator.next();
+ if (!(key instanceof String))
+ throw error("Map keys must be an instance of String but was '" + key.getClass().getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$););
+ writeString((String) key, buffer);
+ buffer.append(':');
+ writeValue(map.get(key), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, '}');
+ else
+ buffer.append('}');
+ }
+
+ private static void writeArray(Collection collection, StringBuffer buffer) {
+ buffer.append('[');
+ for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
+ writeValue(iterator.next(), buffer);
+ buffer.append(',');
+ }
+ if (buffer.charAt(buffer.length() - 1) == ',')
+ buffer.setCharAt(buffer.length() - 1, ']');
+ else
+ buffer.append(']');
+ }
+
+ private static void writeString(String string, StringBuffer buffer) {
+ buffer.append('"');
+ int length = string.length();
+ for (int i = 0; i < length; i++) {
+ char c = string.charAt(i);
+ switch (c) {
+ case '"':
+ case '\\':
+ case '/':
+ buffer.append('\\');
+ buffer.append(c);
+ break;
+ case '\b':
+ buffer.append("\\b"); //$NON-NLS-1$
+ break;
+ case '\f':
+ buffer.append("\\f"); //$NON-NLS-1$
+ break;
+ case '\n':
+ buffer.append("\\n"); //$NON-NLS-1$
+ break;
+ case '\r':
+ buffer.append("\\r"); //$NON-NLS-1$
+ break;
+ case '\t':
+ buffer.append("\\t"); //$NON-NLS-1$
+ break;
+ default:
+ if (Character.isISOControl(c)) {
+ buffer.append("\\u"); //$NON-NLS-1$
+ String hexString = Integer.toHexString(c);
+ for (int j = hexString.length(); j < 4; j++)
+ buffer.append('0');
+ buffer.append(hexString);
+ } else
+ buffer.append(c);
+ }
+ }
+ buffer.append('"');
+ }
+
+}

Back to the top