You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JsonEncoder.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.communication;
  5. import java.util.Map;
  6. import com.google.gwt.json.client.JSONArray;
  7. import com.google.gwt.json.client.JSONBoolean;
  8. import com.google.gwt.json.client.JSONNull;
  9. import com.google.gwt.json.client.JSONObject;
  10. import com.google.gwt.json.client.JSONString;
  11. import com.google.gwt.json.client.JSONValue;
  12. import com.vaadin.terminal.gwt.client.VPaintable;
  13. import com.vaadin.terminal.gwt.client.VPaintableMap;
  14. /**
  15. * Encoder for converting RPC parameters and other values to JSON for transfer
  16. * between the client and the server.
  17. *
  18. * Currently, basic data types as well as Map, String[] and Object[] are
  19. * supported, where maps and Object[] can contain other supported data types.
  20. *
  21. * TODO extensible type support
  22. *
  23. * @since 7.0
  24. */
  25. public class JsonEncoder {
  26. public static final char VTYPE_PAINTABLE = 'p';
  27. public static final char VTYPE_BOOLEAN = 'b';
  28. public static final char VTYPE_DOUBLE = 'd';
  29. public static final char VTYPE_FLOAT = 'f';
  30. public static final char VTYPE_LONG = 'l';
  31. public static final char VTYPE_INTEGER = 'i';
  32. public static final char VTYPE_STRING = 's';
  33. public static final char VTYPE_ARRAY = 'a';
  34. public static final char VTYPE_STRINGARRAY = 'c';
  35. public static final char VTYPE_MAP = 'm';
  36. // TODO is this needed?
  37. public static final char VTYPE_UNDEFINED = 'u';
  38. /**
  39. * Encode a value to a JSON representation for transport from the client to
  40. * the server.
  41. *
  42. * @param value
  43. * value to convert
  44. * @param paintableMap
  45. * mapper from paintables to paintable IDs
  46. * @return JSON representation of the value
  47. */
  48. public static JSONValue encode(Object value, VPaintableMap paintableMap) {
  49. if (null == value) {
  50. // TODO as undefined type?
  51. return combineTypeAndValue(VTYPE_UNDEFINED, JSONNull.getInstance());
  52. } else if (value instanceof String[]) {
  53. String[] array = (String[]) value;
  54. JSONArray jsonArray = new JSONArray();
  55. for (int i = 0; i < array.length; ++i) {
  56. jsonArray.set(i, new JSONString(array[i]));
  57. }
  58. return combineTypeAndValue(VTYPE_STRINGARRAY, jsonArray);
  59. } else if (value instanceof String) {
  60. return combineTypeAndValue(VTYPE_STRING, new JSONString(
  61. (String) value));
  62. } else if (value instanceof Boolean) {
  63. return combineTypeAndValue(VTYPE_BOOLEAN,
  64. JSONBoolean.getInstance((Boolean) value));
  65. } else if (value instanceof Object[]) {
  66. Object[] array = (Object[]) value;
  67. JSONArray jsonArray = new JSONArray();
  68. for (int i = 0; i < array.length; ++i) {
  69. // TODO handle object graph loops?
  70. jsonArray.set(i, encode(array[i], paintableMap));
  71. }
  72. return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
  73. } else if (value instanceof Map) {
  74. Map<String, Object> map = (Map<String, Object>) value;
  75. JSONObject jsonMap = new JSONObject();
  76. for (String mapKey : map.keySet()) {
  77. // TODO handle object graph loops?
  78. Object mapValue = map.get(mapKey);
  79. jsonMap.put(mapKey, encode(mapValue, paintableMap));
  80. }
  81. return combineTypeAndValue(VTYPE_MAP, jsonMap);
  82. } else if (value instanceof VPaintable) {
  83. VPaintable paintable = (VPaintable) value;
  84. return combineTypeAndValue(VTYPE_PAINTABLE, new JSONString(
  85. paintableMap.getPid(paintable)));
  86. } else {
  87. return combineTypeAndValue(getTransportType(value), new JSONString(
  88. String.valueOf(value)));
  89. }
  90. }
  91. private static JSONValue combineTypeAndValue(char type, JSONValue value) {
  92. JSONArray outerArray = new JSONArray();
  93. outerArray.set(0, new JSONString(String.valueOf(type)));
  94. outerArray.set(1, value);
  95. return outerArray;
  96. }
  97. private static char getTransportType(Object value) {
  98. if (value instanceof String) {
  99. return VTYPE_STRING;
  100. } else if (value instanceof VPaintable) {
  101. return VTYPE_PAINTABLE;
  102. } else if (value instanceof Boolean) {
  103. return VTYPE_BOOLEAN;
  104. } else if (value instanceof Integer) {
  105. return VTYPE_INTEGER;
  106. } else if (value instanceof Float) {
  107. return VTYPE_FLOAT;
  108. } else if (value instanceof Double) {
  109. return VTYPE_DOUBLE;
  110. } else if (value instanceof Long) {
  111. return VTYPE_LONG;
  112. } else if (value instanceof Enum) {
  113. return VTYPE_STRING; // transported as string representation
  114. } else if (value instanceof String[]) {
  115. return VTYPE_STRINGARRAY;
  116. } else if (value instanceof Object[]) {
  117. return VTYPE_ARRAY;
  118. } else if (value instanceof Map) {
  119. return VTYPE_MAP;
  120. }
  121. // TODO throw exception?
  122. return VTYPE_UNDEFINED;
  123. }
  124. }