-package org.simantics.document.server;\r
-\r
-import java.io.IOException;\r
-import java.util.Arrays;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.Set;\r
-import java.util.TreeMap;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.adapter.AdaptException;\r
-import org.simantics.databoard.adapter.Adapter;\r
-import org.simantics.databoard.adapter.AdapterConstructionException;\r
-import org.simantics.databoard.binding.ArrayBinding;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.MapBinding;\r
-import org.simantics.databoard.binding.OptionalBinding;\r
-import org.simantics.databoard.binding.RecordBinding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.parser.repository.DataValueRepository;\r
-import org.simantics.databoard.type.Component;\r
-import org.simantics.databoard.type.RecordType;\r
-import org.simantics.databoard.util.Bean;\r
-import org.simantics.document.server.io.IJSONObject;\r
-import org.simantics.scl.runtime.tuple.Tuple;\r
-\r
-final public class JSONObject extends Bean implements IJSONObject {\r
-\r
- final public String id;\r
- final public TreeMap<String, Object> fields = new TreeMap<String, Object>();\r
- private int hashCode = 0;\r
-\r
- public JSONObject(Binding binding, String id) {\r
- super(binding);\r
- assert (binding != null);\r
- assert (id != null);\r
- this.id = id.intern();\r
- }\r
-\r
- public JSONObject(String id) {\r
- assert (id != null);\r
- this.id = id.intern();\r
- }\r
-\r
- public JSONObject clone() {\r
- JSONObject result = new JSONObject(binding, id);\r
- for (Map.Entry<String, Object> e : fields.entrySet())\r
- result.addJSONField(e.getKey(), e.getValue());\r
- return result;\r
- }\r
-\r
- public void add(Map<String, Object> fields) {\r
- for (Map.Entry<String, Object> e : fields.entrySet())\r
- addJSONField(e.getKey(), e.getValue());\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- \r
- if(hashCode == 0) {\r
- int result = id.hashCode();\r
- Iterator<Entry<String,Object>> i = fields.entrySet().iterator();\r
- while (i.hasNext()) {\r
- Entry<String,Object> entry = i.next();\r
- String key = entry.getKey();\r
- Object value = entry.getValue();\r
- if(value != null) {\r
- if(value.getClass().isArray())\r
- result += objectHashCode(key) ^ arrayHashCode(value);\r
- else \r
- result += objectHashCode(key) ^ objectHashCode(value);\r
- } else {\r
- result += objectHashCode(key);\r
- }\r
- }\r
- hashCode = result;\r
- }\r
- return hashCode;\r
-\r
- }\r
-\r
- /**\r
- * Returns the hash code of a non-{@code null} argument and 0 for\r
- * a {@code null} argument.\r
- *\r
- * @param o an object\r
- * @return the hash code of a non-{@code null} argument and 0 for\r
- * a {@code null} argument\r
- * @see Object#hashCode\r
- */\r
- private static int objectHashCode(Object o) {\r
- return o != null ? o.hashCode() : 0;\r
- }\r
-\r
- private final boolean arrayEquals(Object av1, Object av2) {\r
- if (av2 == null)\r
- return false;\r
- Class<?> c1 = av1.getClass().getComponentType();\r
- Class<?> c2 = av2.getClass().getComponentType();\r
- if (c2 == null || !c1.equals(c2))\r
- return false;\r
- boolean p1 = c1.isPrimitive();\r
- boolean p2 = c2.isPrimitive();\r
- if (p1 != p2)\r
- return false;\r
- if (!p1)\r
- return Arrays.equals((Object[]) av1, (Object[]) av2);\r
- if (boolean.class.equals(c1))\r
- return Arrays.equals((boolean[]) av1, (boolean[]) av2);\r
- else if (byte.class.equals(c1))\r
- return Arrays.equals((byte[]) av1, (byte[]) av2);\r
- else if (int.class.equals(c1))\r
- return Arrays.equals((int[]) av1, (int[]) av2);\r
- else if (long.class.equals(c1))\r
- return Arrays.equals((long[]) av1, (long[]) av2);\r
- else if (float.class.equals(c1))\r
- return Arrays.equals((float[]) av1, (float[]) av2);\r
- else if (double.class.equals(c1))\r
- return Arrays.equals((double[]) av1, (double[]) av2);\r
- throw new RuntimeException("??? Contact application querySupport.");\r
- }\r
-\r
- private final int arrayHashCode(Object av) {\r
- if (av == null)\r
- return 0;\r
- Class<?> c1 = av.getClass().getComponentType();\r
- boolean p1 = c1.isPrimitive();\r
- if (!p1)\r
- return Arrays.hashCode((Object[]) av);\r
- if (boolean.class.equals(c1))\r
- return Arrays.hashCode((boolean[]) av);\r
- else if (byte.class.equals(c1))\r
- return Arrays.hashCode((byte[]) av);\r
- else if (int.class.equals(c1))\r
- return Arrays.hashCode((int[]) av);\r
- else if (long.class.equals(c1))\r
- return Arrays.hashCode((long[]) av);\r
- else if (float.class.equals(c1))\r
- return Arrays.hashCode((float[]) av);\r
- else if (double.class.equals(c1))\r
- return Arrays.hashCode((double[]) av);\r
- throw new RuntimeException("??? Contact application querySupport.");\r
- }\r
- \r
- @Override\r
- public boolean equals(Object object) {\r
-\r
- if (this == object)\r
- return true;\r
- else if (object == null)\r
- return false;\r
- else if (!(object instanceof JSONObject))\r
- return false;\r
- JSONObject o = (JSONObject) object;\r
- \r
- if (!id.equals(o.id))\r
- return false;\r
-\r
- Set<String> keys = fields.keySet();\r
- Set<String> otherKeys = o.fields.keySet();\r
- \r
- if (!keys.equals(otherKeys))\r
- return false;\r
-\r
- for (String key : keys) {\r
-\r
- Object value = fields.get(key);\r
- Object otherValue = o.fields.get(key);\r
-\r
- if (otherValue != null) {\r
- if (otherValue.getClass().isArray()) {\r
- if (!arrayEquals(otherValue, value)) {\r
- return false;\r
- }\r
- } else {\r
- if (!otherValue.equals(value)) {\r
- return false;\r
- }\r
- }\r
- } else if (value != null)\r
- return false;\r
-\r
- }\r
-\r
- return true;\r
-\r
- }\r
-\r
- public void addJSONField(String key, Object content) {\r
- fields.put(key, content);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T> T getJSONField(String key) {\r
- return (T) fields.get(key);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T> T getJSONFieldDefault(String key, T defaultValue) {\r
- T value = (T) fields.get(key);\r
- if (value != null)\r
- return value;\r
- else\r
- return defaultValue;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public <T> T getBeanJSONFieldDefault(String key, Binding target,\r
- T defaultValue) {\r
- T value = (T) fields.get(key);\r
- try {\r
- if (value != null) {\r
-// if (value instanceof Bean) {\r
- Binding source = Bindings.getBinding(target.type());\r
- Adapter adapter = Bindings.getAdapter(source, target);\r
- return (T) adapter.adapt(value);\r
-// }\r
-// return value;\r
- }\r
- } catch (AdapterConstructionException e) {\r
- } catch (AdaptException e) {\r
- }\r
- return defaultValue;\r
- }\r
-\r
- public String getParent() {\r
- return (String) fields.get("parent");\r
- }\r
-\r
- public String getParentOrd() {\r
- return (String) fields.get("parentOrd");\r
- }\r
-\r
- public String getType() {\r
- return (String) fields.get("type");\r
- }\r
-\r
- public String toString() {\r
- StringBuilder b = new StringBuilder();\r
- b.append("{");\r
- boolean first = true;\r
- for (Map.Entry<String, Object> entry : fields.entrySet()) {\r
- if (first)\r
- first = false;\r
- else\r
- b.append(",");\r
- String key = entry.getKey();\r
- String value = fieldJSON(entry.getValue());\r
- if (value == null) {\r
- first = true; // prevents ", ," when no key and value are given\r
- continue;\r
- }\r
- b.append('"');\r
- b.append(key);\r
- b.append('"');\r
- b.append(':');\r
- b.append(value);\r
- b.append("\n");\r
- }\r
- b.append("}");\r
- return b.toString();\r
- }\r
-\r
- private void printValue(Object value, Binding binding_, StringBuilder sb)\r
- throws IOException {\r
- try {\r
- if (binding_ instanceof RecordBinding) {\r
- RecordBinding binding = (RecordBinding) binding_;\r
- sb.append("{");\r
- RecordType type = binding.type();\r
- for (int i = 0, j = 0; i < type.getComponentCount(); i++) {\r
-\r
- Component c = type.getComponent(i);\r
-\r
- Object field = binding.getComponent(value, i);\r
-\r
- Binding b = binding.getComponentBinding(i);\r
- if (b instanceof OptionalBinding) {\r
- OptionalBinding ob = (OptionalBinding) b;\r
- if (!ob.hasValueUnchecked(field))\r
- continue;\r
- b = ob.getComponentBinding();\r
- }\r
-\r
- if (j > 0)\r
- sb.append(",");\r
- sb.append("\n");\r
- j++;\r
-\r
- sb.append("\"");\r
- sb.append(c.name);\r
- sb.append("\" : ");\r
- printValue(field, b, sb);\r
- }\r
- sb.append("}");\r
- } else if (binding_ instanceof ArrayBinding) {\r
- ArrayBinding binding = (ArrayBinding) binding_;\r
- Binding b = binding.getComponentBinding();\r
- sb.append("[");\r
- for (int i = 0; i < binding.size(value); i++) {\r
- if (i > 0)\r
- sb.append(",");\r
- printValue(binding.get(value, i), b, sb);\r
- }\r
- sb.append("]");\r
- } else if (binding_ instanceof MapBinding) {\r
- sb.append("{");\r
- MapBinding binding = (MapBinding) binding_;\r
- int j = 0;\r
- for (Object key : binding.getKeys(value)) {\r
- Object val = binding.get(value, key);\r
- if (key instanceof String && val instanceof String) {\r
-\r
- if (j > 0)\r
- sb.append(",");\r
- sb.append("\n");\r
- j++;\r
-\r
- sb.append("\"");\r
- sb.append((String) key);\r
- sb.append("\" : \"");\r
- sb.append((String) val);\r
- sb.append("\"");\r
-\r
- }\r
- }\r
- sb.append("}");\r
- } else {\r
- DataValueRepository rep = new DataValueRepository();\r
- binding_.printValue(value, sb, rep, false);\r
- }\r
- } catch (BindingException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- private String printList(List<?> list) {\r
- StringBuilder b = new StringBuilder();\r
- b.append("[");\r
- boolean first = true;\r
- for (Object o : list) {\r
- if (first) {\r
- first = false;\r
- } else {\r
- b.append(",");\r
- }\r
- b.append(fieldJSON(o));\r
- }\r
- b.append("]");\r
- return b.toString();\r
- }\r
-\r
- private String fieldJSON(Object field) {\r
-\r
- if (field == null)\r
- return null;\r
-\r
- String valueString = null;\r
- if (field instanceof Bean) {\r
- // Try bean to JSON\r
- try {\r
- Bean bean = (Bean) field;\r
- StringBuilder sb = new StringBuilder();\r
- printValue(bean, bean.getBinding(), sb);\r
- valueString = sb.toString();\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- } else if (field instanceof List) {\r
- return printList((List<?>) field);\r
- } else if (field instanceof Tuple) {\r
- Tuple t = (Tuple) field;\r
- if (t.length() == 2) {\r
- Object o1 = t.get(0);\r
- Object o2 = t.get(1);\r
- if (o1 instanceof String) {\r
- return fieldJSON(o1) + " : " + fieldJSON(o2);\r
- } else {\r
- return "{" + fieldJSON(o1) + " , " + fieldJSON(o2) + "}";\r
- }\r
- } else {\r
- StringBuilder b = new StringBuilder();\r
- b.append("{");\r
- for (int i = 0; i < t.length(); i++) {\r
- if (i > 0)\r
- b.append(",");\r
- b.append(fieldJSON(t.get(i)));\r
- }\r
- b.append("}");\r
- return b.toString();\r
- }\r
- } else {\r
- if (field.getClass().isArray()) {\r
-\r
- Object[] array;\r
- if (field instanceof float[]) {\r
- array = new Float[((float[]) field).length];\r
- for (int i = 0; i < array.length; i++) {\r
- array[i] = ((float[]) field)[i];\r
- }\r
- } else if (field instanceof int[]) {\r
- array = new Integer[((int[]) field).length];\r
- for (int i = 0; i < array.length; i++) {\r
- array[i] = ((int[]) field)[i];\r
- }\r
- } else\r
- array = (Object[]) field;\r
-\r
- // Build a string of the value array. Format is: [ value, value,\r
- // value, ... ]\r
- StringBuilder arrayBuilder = new StringBuilder();\r
- arrayBuilder.append("[");\r
- for (int i = 0; i < array.length; i++) {\r
- Object o = array[i];\r
- if (i != 0)\r
- arrayBuilder.append(",");\r
-\r
- if (o instanceof String)\r
- arrayBuilder.append("\"");\r
-\r
- arrayBuilder.append(o.toString());\r
-\r
- if (o instanceof String)\r
- arrayBuilder.append("\"");\r
- }\r
- arrayBuilder.append("]");\r
- valueString = arrayBuilder.toString();\r
- } else {\r
- if (field instanceof String) {\r
- // Use a string representation of the value\r
- valueString = quote((String) field);\r
- } else {\r
- // Use a string representation of the value\r
- valueString = "\"" + field.toString() + "\"";\r
- }\r
-\r
- }\r
- }\r
-\r
- return valueString;\r
-\r
- }\r
- \r
- /*\r
- * Copied from org.json\r
- * \r
- Copyright (c) 2002 JSON.org\r
-\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
-\r
- The above copyright notice and this permission notice shall be included in all\r
- copies or substantial portions of the Software.\r
-\r
- The Software shall be used for Good, not Evil.\r
-\r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
- */\r
- /**\r
- * Produce a string in double quotes with backslash sequences in all the\r
- * right places. A backslash will be inserted within </, allowing JSON\r
- * text to be delivered in HTML. In JSON text, a string cannot contain a\r
- * control character or an unescaped quote or backslash.\r
- * @param string A String\r
- * @return A String correctly formatted for insertion in a JSON text.\r
- */\r
- public static String quote(String string) {\r
- if (string == null || string.length() == 0) {\r
- return "\"\"";\r
- }\r
-\r
- char b;\r
- char c = 0;\r
- int i;\r
- int len = string.length();\r
- StringBuffer sb = new StringBuffer(len + 4);\r
- String t;\r
-\r
- sb.append('"');\r
- for (i = 0; i < len; i += 1) {\r
- b = c;\r
- c = string.charAt(i);\r
- switch (c) {\r
- case '\\':\r
- case '"':\r
- sb.append('\\');\r
- sb.append(c);\r
- break;\r
- case '/':\r
- if (b == '<') {\r
- sb.append('\\');\r
- }\r
- sb.append(c);\r
- break;\r
- case '\b':\r
- sb.append("\\b");\r
- break;\r
- case '\t':\r
- sb.append("\\t");\r
- break;\r
- case '\n':\r
- sb.append("\\n");\r
- break;\r
- case '\f':\r
- sb.append("\\f");\r
- break;\r
- case '\r':\r
- sb.append("\\r");\r
- break;\r
- default:\r
- if (c < ' ' || (c >= '\u0080' && c < '\u00a0') ||\r
- (c >= '\u2000' && c < '\u2100')) {\r
- t = "000" + Integer.toHexString(c);\r
- sb.append("\\u" + t.substring(t.length() - 4));\r
- } else {\r
- sb.append(c);\r
- }\r
- }\r
- }\r
- sb.append('"');\r
- return sb.toString();\r
- } \r
- \r
- public String getId() {\r
- return id;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public <T> T getValue(String key) {\r
- return (T)fields.get(key);\r
- }\r
-\r
- @Override\r
- public Iterator<String> keys() {\r
- return fields.keySet().iterator();\r
- }\r
-\r
- @Override\r
- public IJSONObject clone(Map<String, Object> newObjects) {\r
- JSONObject result = new JSONObject(binding, id);\r
- for (Map.Entry<String, Object> e : fields.entrySet())\r
- result.addJSONField(e.getKey(), e.getValue());\r
- \r
- for (Map.Entry<String, Object> e : newObjects.entrySet())\r
- result.addJSONField(e.getKey(), e.getValue());\r
- return result;\r
- }\r
+package org.simantics.document.server;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.adapter.Adapter;
+import org.simantics.databoard.adapter.AdapterConstructionException;
+import org.simantics.databoard.binding.ArrayBinding;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.MapBinding;
+import org.simantics.databoard.binding.OptionalBinding;
+import org.simantics.databoard.binding.RecordBinding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.parser.repository.DataValueRepository;
+import org.simantics.databoard.type.Component;
+import org.simantics.databoard.type.RecordType;
+import org.simantics.databoard.util.Bean;
+import org.simantics.document.server.io.IJSONObject;
+import org.simantics.scl.runtime.tuple.Tuple;
+
+final public class JSONObject extends Bean implements IJSONObject {
+
+ final public String id;
+ final public TreeMap<String, Object> fields = new TreeMap<String, Object>();
+ private int hashCode = 0;
+
+ public JSONObject(Binding binding, String id) {
+ super(binding);
+ assert (binding != null);
+ assert (id != null);
+ this.id = id.intern();
+ }
+
+ public JSONObject(String id) {
+ assert (id != null);
+ this.id = id.intern();
+ }
+
+ public JSONObject clone() {
+ JSONObject result = new JSONObject(binding, id);
+ for (Map.Entry<String, Object> e : fields.entrySet())
+ result.addJSONField(e.getKey(), e.getValue());
+ return result;
+ }
+
+ public void add(Map<String, Object> fields) {
+ for (Map.Entry<String, Object> e : fields.entrySet())
+ addJSONField(e.getKey(), e.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+
+ if(hashCode == 0) {
+ int result = id.hashCode();
+ Iterator<Entry<String,Object>> i = fields.entrySet().iterator();
+ while (i.hasNext()) {
+ Entry<String,Object> entry = i.next();
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if(value != null) {
+ if(value.getClass().isArray())
+ result += objectHashCode(key) ^ arrayHashCode(value);
+ else
+ result += objectHashCode(key) ^ objectHashCode(value);
+ } else {
+ result += objectHashCode(key);
+ }
+ }
+ hashCode = result;
+ }
+ return hashCode;
+
+ }
+
+ /**
+ * Returns the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument.
+ *
+ * @param o an object
+ * @return the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument
+ * @see Object#hashCode
+ */
+ private static int objectHashCode(Object o) {
+ return o != null ? o.hashCode() : 0;
+ }
+
+ private final boolean arrayEquals(Object av1, Object av2) {
+ if (av2 == null)
+ return false;
+ Class<?> c1 = av1.getClass().getComponentType();
+ Class<?> c2 = av2.getClass().getComponentType();
+ if (c2 == null || !c1.equals(c2))
+ return false;
+ boolean p1 = c1.isPrimitive();
+ boolean p2 = c2.isPrimitive();
+ if (p1 != p2)
+ return false;
+ if (!p1)
+ return Arrays.equals((Object[]) av1, (Object[]) av2);
+ if (boolean.class.equals(c1))
+ return Arrays.equals((boolean[]) av1, (boolean[]) av2);
+ else if (byte.class.equals(c1))
+ return Arrays.equals((byte[]) av1, (byte[]) av2);
+ else if (int.class.equals(c1))
+ return Arrays.equals((int[]) av1, (int[]) av2);
+ else if (long.class.equals(c1))
+ return Arrays.equals((long[]) av1, (long[]) av2);
+ else if (float.class.equals(c1))
+ return Arrays.equals((float[]) av1, (float[]) av2);
+ else if (double.class.equals(c1))
+ return Arrays.equals((double[]) av1, (double[]) av2);
+ throw new RuntimeException("??? Contact application querySupport.");
+ }
+
+ private final int arrayHashCode(Object av) {
+ if (av == null)
+ return 0;
+ Class<?> c1 = av.getClass().getComponentType();
+ boolean p1 = c1.isPrimitive();
+ if (!p1)
+ return Arrays.hashCode((Object[]) av);
+ if (boolean.class.equals(c1))
+ return Arrays.hashCode((boolean[]) av);
+ else if (byte.class.equals(c1))
+ return Arrays.hashCode((byte[]) av);
+ else if (int.class.equals(c1))
+ return Arrays.hashCode((int[]) av);
+ else if (long.class.equals(c1))
+ return Arrays.hashCode((long[]) av);
+ else if (float.class.equals(c1))
+ return Arrays.hashCode((float[]) av);
+ else if (double.class.equals(c1))
+ return Arrays.hashCode((double[]) av);
+ throw new RuntimeException("??? Contact application querySupport.");
+ }
+
+ @Override
+ public boolean equals(Object object) {
+
+ if (this == object)
+ return true;
+ else if (object == null)
+ return false;
+ else if (!(object instanceof JSONObject))
+ return false;
+ JSONObject o = (JSONObject) object;
+
+ if (!id.equals(o.id))
+ return false;
+
+ Set<String> keys = fields.keySet();
+ Set<String> otherKeys = o.fields.keySet();
+
+ if (!keys.equals(otherKeys))
+ return false;
+
+ for (String key : keys) {
+
+ Object value = fields.get(key);
+ Object otherValue = o.fields.get(key);
+
+ if (otherValue != null) {
+ if (otherValue.getClass().isArray()) {
+ if (!arrayEquals(otherValue, value)) {
+ return false;
+ }
+ } else {
+ if (!otherValue.equals(value)) {
+ return false;
+ }
+ }
+ } else if (value != null)
+ return false;
+
+ }
+
+ return true;
+
+ }
+
+ public void addJSONField(String key, Object content) {
+ fields.put(key, content);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getJSONField(String key) {
+ return (T) fields.get(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getJSONFieldDefault(String key, T defaultValue) {
+ T value = (T) fields.get(key);
+ if (value != null)
+ return value;
+ else
+ return defaultValue;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getBeanJSONFieldDefault(String key, Binding target,
+ T defaultValue) {
+ T value = (T) fields.get(key);
+ try {
+ if (value != null) {
+// if (value instanceof Bean) {
+ Binding source = Bindings.getBinding(target.type());
+ Adapter adapter = Bindings.getAdapter(source, target);
+ return (T) adapter.adapt(value);
+// }
+// return value;
+ }
+ } catch (AdapterConstructionException e) {
+ } catch (AdaptException e) {
+ }
+ return defaultValue;
+ }
+
+ public String getParent() {
+ return (String) fields.get("parent");
+ }
+
+ public String getParentOrd() {
+ return (String) fields.get("parentOrd");
+ }
+
+ public String getType() {
+ return (String) fields.get("type");
+ }
+
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("{");
+ boolean first = true;
+ for (Map.Entry<String, Object> entry : fields.entrySet()) {
+ if (first)
+ first = false;
+ else
+ b.append(",");
+ String key = entry.getKey();
+ String value = fieldJSON(entry.getValue());
+ if (value == null) {
+ first = true; // prevents ", ," when no key and value are given
+ continue;
+ }
+ b.append('"');
+ b.append(key);
+ b.append('"');
+ b.append(':');
+ b.append(value);
+ b.append("\n");
+ }
+ b.append("}");
+ return b.toString();
+ }
+
+ private void printValue(Object value, Binding binding_, StringBuilder sb)
+ throws IOException {
+ try {
+ if (binding_ instanceof RecordBinding) {
+ RecordBinding binding = (RecordBinding) binding_;
+ sb.append("{");
+ RecordType type = binding.type();
+ for (int i = 0, j = 0; i < type.getComponentCount(); i++) {
+
+ Component c = type.getComponent(i);
+
+ Object field = binding.getComponent(value, i);
+
+ Binding b = binding.getComponentBinding(i);
+ if (b instanceof OptionalBinding) {
+ OptionalBinding ob = (OptionalBinding) b;
+ if (!ob.hasValueUnchecked(field))
+ continue;
+ b = ob.getComponentBinding();
+ }
+
+ if (j > 0)
+ sb.append(",");
+ sb.append("\n");
+ j++;
+
+ sb.append("\"");
+ sb.append(c.name);
+ sb.append("\" : ");
+ printValue(field, b, sb);
+ }
+ sb.append("}");
+ } else if (binding_ instanceof ArrayBinding) {
+ ArrayBinding binding = (ArrayBinding) binding_;
+ Binding b = binding.getComponentBinding();
+ sb.append("[");
+ for (int i = 0; i < binding.size(value); i++) {
+ if (i > 0)
+ sb.append(",");
+ printValue(binding.get(value, i), b, sb);
+ }
+ sb.append("]");
+ } else if (binding_ instanceof MapBinding) {
+ sb.append("{");
+ MapBinding binding = (MapBinding) binding_;
+ int j = 0;
+ for (Object key : binding.getKeys(value)) {
+ Object val = binding.get(value, key);
+ if (key instanceof String && val instanceof String) {
+
+ if (j > 0)
+ sb.append(",");
+ sb.append("\n");
+ j++;
+
+ sb.append("\"");
+ sb.append((String) key);
+ sb.append("\" : \"");
+ sb.append((String) val);
+ sb.append("\"");
+
+ }
+ }
+ sb.append("}");
+ } else {
+ DataValueRepository rep = new DataValueRepository();
+ binding_.printValue(value, sb, rep, false);
+ }
+ } catch (BindingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private String printList(List<?> list) {
+ StringBuilder b = new StringBuilder();
+ b.append("[");
+ boolean first = true;
+ for (Object o : list) {
+ if (first) {
+ first = false;
+ } else {
+ b.append(",");
+ }
+ b.append(fieldJSON(o));
+ }
+ b.append("]");
+ return b.toString();
+ }
+
+ private String fieldJSON(Object field) {
+
+ if (field == null)
+ return null;
+
+ String valueString = null;
+ if (field instanceof Bean) {
+ // Try bean to JSON
+ try {
+ Bean bean = (Bean) field;
+ StringBuilder sb = new StringBuilder();
+ printValue(bean, bean.getBinding(), sb);
+ valueString = sb.toString();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else if (field instanceof List) {
+ return printList((List<?>) field);
+ } else if (field instanceof Tuple) {
+ Tuple t = (Tuple) field;
+ if (t.length() == 2) {
+ Object o1 = t.get(0);
+ Object o2 = t.get(1);
+ if (o1 instanceof String) {
+ return fieldJSON(o1) + " : " + fieldJSON(o2);
+ } else {
+ return "{" + fieldJSON(o1) + " , " + fieldJSON(o2) + "}";
+ }
+ } else {
+ StringBuilder b = new StringBuilder();
+ b.append("{");
+ for (int i = 0; i < t.length(); i++) {
+ if (i > 0)
+ b.append(",");
+ b.append(fieldJSON(t.get(i)));
+ }
+ b.append("}");
+ return b.toString();
+ }
+ } else {
+ if (field.getClass().isArray()) {
+
+ Object[] array;
+ if (field instanceof float[]) {
+ array = new Float[((float[]) field).length];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = ((float[]) field)[i];
+ }
+ } else if (field instanceof int[]) {
+ array = new Integer[((int[]) field).length];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = ((int[]) field)[i];
+ }
+ } else
+ array = (Object[]) field;
+
+ // Build a string of the value array. Format is: [ value, value,
+ // value, ... ]
+ StringBuilder arrayBuilder = new StringBuilder();
+ arrayBuilder.append("[");
+ for (int i = 0; i < array.length; i++) {
+ Object o = array[i];
+ if (i != 0)
+ arrayBuilder.append(",");
+
+ if (o instanceof String)
+ arrayBuilder.append("\"");
+
+ arrayBuilder.append(o.toString());
+
+ if (o instanceof String)
+ arrayBuilder.append("\"");
+ }
+ arrayBuilder.append("]");
+ valueString = arrayBuilder.toString();
+ } else {
+ if (field instanceof String) {
+ // Use a string representation of the value
+ valueString = quote((String) field);
+ } else {
+ // Use a string representation of the value
+ valueString = "\"" + field.toString() + "\"";
+ }
+
+ }
+ }
+
+ return valueString;
+
+ }
+
+ /*
+ * Copied from org.json
+ *
+ Copyright (c) 2002 JSON.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ The Software shall be used for Good, not Evil.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+ */
+ /**
+ * Produce a string in double quotes with backslash sequences in all the
+ * right places. A backslash will be inserted within </, allowing JSON
+ * text to be delivered in HTML. In JSON text, a string cannot contain a
+ * control character or an unescaped quote or backslash.
+ * @param string A String
+ * @return A String correctly formatted for insertion in a JSON text.
+ */
+ public static String quote(String string) {
+ if (string == null || string.length() == 0) {
+ return "\"\"";
+ }
+
+ char b;
+ char c = 0;
+ int i;
+ int len = string.length();
+ StringBuffer sb = new StringBuffer(len + 4);
+ String t;
+
+ sb.append('"');
+ for (i = 0; i < len; i += 1) {
+ b = c;
+ c = string.charAt(i);
+ switch (c) {
+ case '\\':
+ case '"':
+ sb.append('\\');
+ sb.append(c);
+ break;
+ case '/':
+ if (b == '<') {
+ sb.append('\\');
+ }
+ sb.append(c);
+ break;
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ default:
+ if (c < ' ' || (c >= '\u0080' && c < '\u00a0') ||
+ (c >= '\u2000' && c < '\u2100')) {
+ t = "000" + Integer.toHexString(c);
+ sb.append("\\u" + t.substring(t.length() - 4));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ sb.append('"');
+ return sb.toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T getValue(String key) {
+ return (T)fields.get(key);
+ }
+
+ @Override
+ public Iterator<String> keys() {
+ return fields.keySet().iterator();
+ }
+
+ @Override
+ public IJSONObject clone(Map<String, Object> newObjects) {
+ JSONObject result = new JSONObject(binding, id);
+ for (Map.Entry<String, Object> e : fields.entrySet())
+ result.addJSONField(e.getKey(), e.getValue());
+
+ for (Map.Entry<String, Object> e : newObjects.entrySet())
+ result.addJSONField(e.getKey(), e.getValue());
+ return result;
+ }
}
\ No newline at end of file