Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

JsonEncoder.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. if (getTransportType(value) != VTYPE_UNDEFINED) {
  90. return combineTypeAndValue(getTransportType(value),
  91. new JSONString(String.valueOf(value)));
  92. } else {
  93. // Try to find a generated serializer object, class name is the
  94. // type
  95. String type = value.getClass().getName();
  96. VaadinSerializer serializer = JsonDecoder.serializerMap
  97. .getSerializer(type);
  98. // TODO handle case with no serializer found
  99. return combineTypeAndValue(type,
  100. serializer.serialize(value, connectorMap));
  101. }
  102. }
  103. }
  104. private static JSONValue combineTypeAndValue(String type, JSONValue value) {
  105. JSONArray outerArray = new JSONArray();
  106. outerArray.set(0, new JSONString(type));
  107. outerArray.set(1, value);
  108. return outerArray;
  109. }
  110. private static String getTransportType(Object value) {
  111. if (value instanceof String) {
  112. return VTYPE_STRING;
  113. } else if (value instanceof Connector) {
  114. return VTYPE_PAINTABLE;
  115. } else if (value instanceof Boolean) {
  116. return VTYPE_BOOLEAN;
  117. } else if (value instanceof Integer) {
  118. return VTYPE_INTEGER;
  119. } else if (value instanceof Float) {
  120. return VTYPE_FLOAT;
  121. } else if (value instanceof Double) {
  122. return VTYPE_DOUBLE;
  123. } else if (value instanceof Long) {
  124. return VTYPE_LONG;
  125. } else if (value instanceof Enum) {
  126. return VTYPE_STRING; // transported as string representation
  127. } else if (value instanceof String[]) {
  128. return VTYPE_STRINGARRAY;
  129. } else if (value instanceof Object[]) {
  130. return VTYPE_ARRAY;
  131. } else if (value instanceof Map) {
  132. return VTYPE_MAP;
  133. }
  134. // TODO throw exception?
  135. return VTYPE_UNDEFINED;
  136. }
  137. }