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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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.Connector;
  13. import com.vaadin.terminal.gwt.client.ConnectorMap;
  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 String VTYPE_PAINTABLE = "p";
  27. public static final String VTYPE_BOOLEAN = "b";
  28. public static final String VTYPE_DOUBLE = "d";
  29. public static final String VTYPE_FLOAT = "f";
  30. public static final String VTYPE_LONG = "l";
  31. public static final String VTYPE_INTEGER = "i";
  32. public static final String VTYPE_STRING = "s";
  33. public static final String VTYPE_ARRAY = "a";
  34. public static final String VTYPE_STRINGARRAY = "c";
  35. public static final String VTYPE_MAP = "m";
  36. // TODO this will be replaced by the shared state class name
  37. public static final String VTYPE_SHAREDSTATE = "t";
  38. // TODO is this needed?
  39. public static final String VTYPE_UNDEFINED = "u";
  40. /**
  41. * Encode a value to a JSON representation for transport from the client to
  42. * the server.
  43. *
  44. * @param value
  45. * value to convert
  46. * @param connectorMap
  47. * mapper from connectors to connector IDs
  48. * @return JSON representation of the value
  49. */
  50. public static JSONValue encode(Object value, ConnectorMap connectorMap) {
  51. if (null == value) {
  52. // TODO as undefined type?
  53. return combineTypeAndValue(VTYPE_UNDEFINED, JSONNull.getInstance());
  54. } else if (value instanceof String[]) {
  55. String[] array = (String[]) value;
  56. JSONArray jsonArray = new JSONArray();
  57. for (int i = 0; i < array.length; ++i) {
  58. jsonArray.set(i, new JSONString(array[i]));
  59. }
  60. return combineTypeAndValue(VTYPE_STRINGARRAY, jsonArray);
  61. } else if (value instanceof String) {
  62. return combineTypeAndValue(VTYPE_STRING, new JSONString(
  63. (String) value));
  64. } else if (value instanceof Boolean) {
  65. return combineTypeAndValue(VTYPE_BOOLEAN,
  66. JSONBoolean.getInstance((Boolean) value));
  67. } else if (value instanceof Object[]) {
  68. Object[] array = (Object[]) value;
  69. JSONArray jsonArray = new JSONArray();
  70. for (int i = 0; i < array.length; ++i) {
  71. // TODO handle object graph loops?
  72. jsonArray.set(i, encode(array[i], connectorMap));
  73. }
  74. return combineTypeAndValue(VTYPE_ARRAY, jsonArray);
  75. } else if (value instanceof Map) {
  76. Map<String, Object> map = (Map<String, Object>) value;
  77. JSONObject jsonMap = new JSONObject();
  78. for (String mapKey : map.keySet()) {
  79. // TODO handle object graph loops?
  80. Object mapValue = map.get(mapKey);
  81. jsonMap.put(mapKey, encode(mapValue, connectorMap));
  82. }
  83. return combineTypeAndValue(VTYPE_MAP, jsonMap);
  84. } else if (value instanceof Connector) {
  85. Connector paintable = (Connector) value;
  86. return combineTypeAndValue(VTYPE_PAINTABLE, new JSONString(
  87. connectorMap.getConnectorId(paintable)));
  88. } else {
  89. return combineTypeAndValue(getTransportType(value), new JSONString(
  90. String.valueOf(value)));
  91. }
  92. }
  93. private static JSONValue combineTypeAndValue(String type, JSONValue value) {
  94. JSONArray outerArray = new JSONArray();
  95. outerArray.set(0, new JSONString(type));
  96. outerArray.set(1, value);
  97. return outerArray;
  98. }
  99. private static String getTransportType(Object value) {
  100. if (value instanceof String) {
  101. return VTYPE_STRING;
  102. } else if (value instanceof Connector) {
  103. return VTYPE_PAINTABLE;
  104. } else if (value instanceof Boolean) {
  105. return VTYPE_BOOLEAN;
  106. } else if (value instanceof Integer) {
  107. return VTYPE_INTEGER;
  108. } else if (value instanceof Float) {
  109. return VTYPE_FLOAT;
  110. } else if (value instanceof Double) {
  111. return VTYPE_DOUBLE;
  112. } else if (value instanceof Long) {
  113. return VTYPE_LONG;
  114. } else if (value instanceof Enum) {
  115. return VTYPE_STRING; // transported as string representation
  116. } else if (value instanceof String[]) {
  117. return VTYPE_STRINGARRAY;
  118. } else if (value instanceof Object[]) {
  119. return VTYPE_ARRAY;
  120. } else if (value instanceof Map) {
  121. return VTYPE_MAP;
  122. }
  123. // TODO throw exception?
  124. return VTYPE_UNDEFINED;
  125. }
  126. }