]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.server/src/org/simantics/document/server/JSONObject.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.document.server / src / org / simantics / document / server / JSONObject.java
index b43a98df357fcf1e84870b7a4520bd99e1090d21..36b4e69d14da377befb78017f5687a4c3f27bb32 100644 (file)
-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