|
25 | 25 | import com.swiftmq.amqp.v100.types.*;
|
26 | 26 | import com.swiftmq.tools.util.DataByteArrayOutputStream;
|
27 | 27 | import java.io.IOException;
|
28 |
| -import java.util.Date; |
29 |
| -import java.util.LinkedHashMap; |
30 |
| -import java.util.Map; |
31 |
| -import java.util.UUID; |
| 28 | +import java.lang.reflect.Array; |
| 29 | +import java.nio.charset.StandardCharsets; |
| 30 | +import java.util.*; |
32 | 31 |
|
33 | 32 | public class SwiftMqCodec implements Codec {
|
34 | 33 |
|
@@ -69,13 +68,48 @@ private static Object convertAmqpMapValue(AMQPType value) {
|
69 | 68 | return ((AMQPUuid) value).getValue();
|
70 | 69 | } else if (value instanceof AMQPSymbol) {
|
71 | 70 | return ((AMQPSymbol) value).getValue();
|
| 71 | + } else if (value instanceof AMQPList) { |
| 72 | + try { |
| 73 | + List<AMQPType> source = ((AMQPList) value).getValue(); |
| 74 | + List<Object> target = new ArrayList<>(source.size()); |
| 75 | + for (AMQPType o : source) { |
| 76 | + target.add(convertAmqpMapValue(o)); |
| 77 | + } |
| 78 | + return target; |
| 79 | + } catch (IOException e) { |
| 80 | + throw new StreamException("Error while reading SwiftMQ list", e); |
| 81 | + } |
| 82 | + } else if (value instanceof AMQPMap) { |
| 83 | + try { |
| 84 | + Map<AMQPType, AMQPType> source = ((AMQPMap) value).getValue(); |
| 85 | + Map<Object, Object> target = new LinkedHashMap<>(source.size()); |
| 86 | + for (Map.Entry<AMQPType, AMQPType> entry : source.entrySet()) { |
| 87 | + target.put(convertAmqpMapValue(entry.getKey()), convertAmqpMapValue(entry.getValue())); |
| 88 | + } |
| 89 | + return target; |
| 90 | + } catch (IOException e) { |
| 91 | + throw new StreamException("Error while reading SwiftMQ map", e); |
| 92 | + } |
| 93 | + } else if (value instanceof AMQPArray) { |
| 94 | + try { |
| 95 | + AMQPType[] source = ((AMQPArray) value).getValue(); |
| 96 | + Object target = |
| 97 | + Array.newInstance( |
| 98 | + source.length == 0 ? Object.class : convertAmqpMapValue(source[0]).getClass(), |
| 99 | + source.length); |
| 100 | + for (int i = 0; i < source.length; i++) { |
| 101 | + Array.set(target, i, convertAmqpMapValue(source[i])); |
| 102 | + } |
| 103 | + return target; |
| 104 | + } catch (IOException e) { |
| 105 | + throw new StreamException("Error while reading SwiftMQ array", e); |
| 106 | + } |
72 | 107 | } else if (value instanceof AMQPNull) {
|
73 | 108 | return null;
|
74 | 109 | } else if (value == null) {
|
75 | 110 | return null;
|
76 | 111 | } else {
|
77 |
| - throw new IllegalArgumentException( |
78 |
| - "Type not supported for an application property: " + value.getClass()); |
| 112 | + throw new IllegalArgumentException("Type not supported: " + value.getClass()); |
79 | 113 | }
|
80 | 114 | }
|
81 | 115 |
|
@@ -320,11 +354,111 @@ protected static AMQPType convertToSwiftMqType(Object value) {
|
320 | 354 | return new AMQPSymbol(value.toString());
|
321 | 355 | } else if (value instanceof UUID) {
|
322 | 356 | return new AMQPUuid((UUID) value);
|
| 357 | + } else if (value instanceof List) { |
| 358 | + List<?> source = (List<?>) value; |
| 359 | + List<AMQPType> target = new ArrayList<>(source.size()); |
| 360 | + for (Object o : source) { |
| 361 | + target.add(convertToSwiftMqType(o)); |
| 362 | + } |
| 363 | + try { |
| 364 | + return new AMQPList(target); |
| 365 | + } catch (IOException e) { |
| 366 | + throw new StreamException("Error while creating SwiftMQ list", e); |
| 367 | + } |
| 368 | + } else if (value instanceof Map) { |
| 369 | + Map<?, ?> source = (Map<?, ?>) value; |
| 370 | + Map<AMQPType, AMQPType> target = new LinkedHashMap<>(source.size()); |
| 371 | + for (Map.Entry<?, ?> entry : source.entrySet()) { |
| 372 | + target.put(convertToSwiftMqType(entry.getKey()), convertToSwiftMqType(entry.getValue())); |
| 373 | + } |
| 374 | + try { |
| 375 | + return new AMQPMap(target); |
| 376 | + } catch (IOException e) { |
| 377 | + throw new StreamException("Error while creating SwiftMQ map", e); |
| 378 | + } |
| 379 | + } else if (value instanceof Object[]) { |
| 380 | + Object[] source = (Object[]) value; |
| 381 | + AMQPType[] target = new AMQPType[source.length]; |
| 382 | + for (int i = 0; i < source.length; i++) { |
| 383 | + target[i] = convertToSwiftMqType(source[i]); |
| 384 | + } |
| 385 | + try { |
| 386 | + int code = source.length == 0 ? AMQPTypeDecoder.UNKNOWN : toSwiftMqTypeCode(source[0]); |
| 387 | + return new AMQPArray(code, target); |
| 388 | + } catch (IOException e) { |
| 389 | + throw new StreamException("Error while creating SwiftMQ list", e); |
| 390 | + } |
323 | 391 | } else if (value == null) {
|
324 | 392 | return AMQPNull.NULL;
|
325 | 393 | } else {
|
326 |
| - throw new IllegalArgumentException( |
327 |
| - "Type not supported for an application property: " + value.getClass()); |
| 394 | + throw new IllegalArgumentException("Type not supported: " + value.getClass()); |
| 395 | + } |
| 396 | + } |
| 397 | + |
| 398 | + protected static int toSwiftMqTypeCode(Object value) { |
| 399 | + if (value instanceof Boolean) { |
| 400 | + return AMQPTypeDecoder.BOOLEAN; |
| 401 | + } else if (value instanceof Byte) { |
| 402 | + return AMQPTypeDecoder.BYTE; |
| 403 | + } else if (value instanceof Short) { |
| 404 | + return AMQPTypeDecoder.SHORT; |
| 405 | + } else if (value instanceof Integer) { |
| 406 | + int v = (Integer) value; |
| 407 | + return (v < -128 || v > 127) ? AMQPTypeDecoder.INT : AMQPTypeDecoder.SINT; |
| 408 | + } else if (value instanceof Long) { |
| 409 | + long v = (Long) value; |
| 410 | + return (v < -128 || v > 127) ? AMQPTypeDecoder.LONG : AMQPTypeDecoder.SLONG; |
| 411 | + } else if (value instanceof UnsignedByte) { |
| 412 | + return AMQPTypeDecoder.UBYTE; |
| 413 | + } else if (value instanceof UnsignedShort) { |
| 414 | + return AMQPTypeDecoder.USHORT; |
| 415 | + } else if (value instanceof UnsignedInteger) { |
| 416 | + return AMQPTypeDecoder.UINT; |
| 417 | + } else if (value instanceof UnsignedLong) { |
| 418 | + return AMQPTypeDecoder.ULONG; |
| 419 | + } else if (value instanceof Float) { |
| 420 | + return AMQPTypeDecoder.FLOAT; |
| 421 | + } else if (value instanceof Double) { |
| 422 | + return AMQPTypeDecoder.DOUBLE; |
| 423 | + } else if (value instanceof byte[]) { |
| 424 | + return ((byte[]) value).length > 255 ? AMQPTypeDecoder.BIN32 : AMQPTypeDecoder.BIN8; |
| 425 | + } else if (value instanceof String) { |
| 426 | + return value.toString().getBytes(StandardCharsets.UTF_8).length > 255 |
| 427 | + ? AMQPTypeDecoder.STR32UTF8 |
| 428 | + : AMQPTypeDecoder.STR8UTF8; |
| 429 | + } else if (value instanceof Character) { |
| 430 | + return AMQPTypeDecoder.CHAR; |
| 431 | + } else if (value instanceof Date) { |
| 432 | + return AMQPTypeDecoder.TIMESTAMP; |
| 433 | + } else if (value instanceof Symbol) { |
| 434 | + return value.toString().getBytes(StandardCharsets.US_ASCII).length > 255 |
| 435 | + ? AMQPTypeDecoder.SYM32 |
| 436 | + : AMQPTypeDecoder.SYM8; |
| 437 | + } else if (value instanceof UUID) { |
| 438 | + return AMQPTypeDecoder.UUID; |
| 439 | + } else if (value instanceof List) { |
| 440 | + List<?> l = (List<?>) value; |
| 441 | + if (l.isEmpty()) { |
| 442 | + return AMQPTypeDecoder.LIST0; |
| 443 | + } else if (l.size() > 255) { |
| 444 | + return AMQPTypeDecoder.LIST32; |
| 445 | + } else { |
| 446 | + return AMQPTypeDecoder.LIST8; |
| 447 | + } |
| 448 | + } else if (value instanceof Map) { |
| 449 | + Map<?, ?> source = (Map<?, ?>) value; |
| 450 | + return source.size() * 2 > 255 ? AMQPTypeDecoder.MAP32 : AMQPTypeDecoder.MAP8; |
| 451 | + } else if (value instanceof Object[]) { |
| 452 | + Object[] source = (Object[]) value; |
| 453 | + if (source.length > 255) { |
| 454 | + return AMQPTypeDecoder.ARRAY32; |
| 455 | + } else { |
| 456 | + return AMQPTypeDecoder.ARRAY8; |
| 457 | + } |
| 458 | + } else if (value == null) { |
| 459 | + return AMQPTypeDecoder.NULL; |
| 460 | + } else { |
| 461 | + throw new IllegalArgumentException("Type not supported: " + value.getClass()); |
328 | 462 | }
|
329 | 463 | }
|
330 | 464 |
|
|
0 commit comments