WxPayOrderNotifyResultConverter.java 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package com.github.binarywang.wxpay.converter;
  2. import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyCoupon;
  3. import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  4. import com.google.common.collect.Lists;
  5. import com.google.common.collect.Maps;
  6. import com.thoughtworks.xstream.annotations.XStreamAlias;
  7. import com.thoughtworks.xstream.converters.MarshallingContext;
  8. import com.thoughtworks.xstream.converters.UnmarshallingContext;
  9. import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter;
  10. import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
  11. import com.thoughtworks.xstream.io.HierarchicalStreamReader;
  12. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
  13. import com.thoughtworks.xstream.mapper.Mapper;
  14. import org.apache.commons.lang3.StringUtils;
  15. import java.beans.PropertyDescriptor;
  16. import java.lang.reflect.Field;
  17. import java.util.ArrayList;
  18. import java.util.Arrays;
  19. import java.util.List;
  20. import java.util.Map;
  21. /**
  22. * The type Wxpay order notify result converter.
  23. *
  24. * @author aimilin
  25. */
  26. public class WxPayOrderNotifyResultConverter extends AbstractReflectionConverter {
  27. /**
  28. * Instantiates a new Wx pay order notify result converter.
  29. *
  30. * @param mapper the mapper
  31. * @param reflectionProvider the reflection provider
  32. */
  33. public WxPayOrderNotifyResultConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
  34. super(mapper, reflectionProvider);
  35. }
  36. @Override
  37. @SuppressWarnings("rawtypes")
  38. public boolean canConvert(Class type) {
  39. return type.equals(WxPayOrderNotifyResult.class);
  40. }
  41. @Override
  42. public void marshal(Object original, HierarchicalStreamWriter writer, MarshallingContext context) {
  43. super.marshal(original, writer, context);
  44. WxPayOrderNotifyResult obj = (WxPayOrderNotifyResult) original;
  45. List<WxPayOrderNotifyCoupon> list = obj.getCouponList();
  46. if (list == null || list.isEmpty()) {
  47. return;
  48. }
  49. for (int i = 0; i < list.size(); i++) {
  50. WxPayOrderNotifyCoupon coupon = list.get(i);
  51. writer.startNode("coupon_id_" + i);
  52. writer.setValue(coupon.getCouponId());
  53. writer.endNode();
  54. writer.startNode("coupon_type_" + i);
  55. writer.setValue(coupon.getCouponType());
  56. writer.endNode();
  57. writer.startNode("coupon_fee_" + i);
  58. writer.setValue(String.valueOf(coupon.getCouponFee()));
  59. writer.endNode();
  60. }
  61. }
  62. @Override
  63. protected void marshallField(MarshallingContext context, Object newObj, Field field) {
  64. if ("couponList".equals(field.getName())) {
  65. return;
  66. }
  67. super.marshallField(context, newObj, field);
  68. }
  69. @Override
  70. public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
  71. WxPayOrderNotifyResult obj = new WxPayOrderNotifyResult();
  72. List<Field> fields = new ArrayList<>(Arrays.asList(obj.getClass().getDeclaredFields()));
  73. fields.addAll(Arrays.asList(obj.getClass().getSuperclass().getDeclaredFields()));
  74. Map<String, Field> fieldMap = getFieldMap(fields);
  75. Map<Integer, WxPayOrderNotifyCoupon> coupons = Maps.newTreeMap();
  76. while (reader.hasMoreChildren()) {
  77. reader.moveDown();
  78. if (fieldMap.containsKey(reader.getNodeName())) {
  79. Field field = fieldMap.get(reader.getNodeName());
  80. this.setFieldValue(context, obj, field);
  81. } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_id_")) {
  82. String id = (String) context.convertAnother(obj, String.class);
  83. this.getElement(coupons, reader.getNodeName()).setCouponId(id);
  84. } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_type_")) {
  85. String type = (String) context.convertAnother(obj, String.class);
  86. this.getElement(coupons, reader.getNodeName()).setCouponType(type);
  87. } else if (StringUtils.startsWith(reader.getNodeName(), "coupon_fee_")) {
  88. Integer fee = (Integer) context.convertAnother(obj, Integer.class);
  89. this.getElement(coupons, reader.getNodeName()).setCouponFee(fee);
  90. }
  91. reader.moveUp();
  92. }
  93. obj.setCouponList(Lists.newArrayList(coupons.values()));
  94. return obj;
  95. }
  96. private void setFieldValue(UnmarshallingContext context, WxPayOrderNotifyResult obj, Field field) {
  97. Object val = context.convertAnother(obj, field.getType());
  98. try {
  99. if (val != null) {
  100. /*
  101. 这里加一个看似多余的(String)强转可解决高jdk版本下的编译报错问题,
  102. 详情见讨论https://github.com/vaadin/framework/issues/10737
  103. */
  104. PropertyDescriptor pd = new PropertyDescriptor((String) field.getName(), obj.getClass());
  105. pd.getWriteMethod().invoke(obj, val);
  106. }
  107. } catch (Exception ignored) {
  108. }
  109. }
  110. private Map<String, Field> getFieldMap(List<Field> fields) {
  111. return Maps.uniqueIndex(fields, field -> {
  112. if (field.isAnnotationPresent(XStreamAlias.class)) {
  113. return field.getAnnotation(XStreamAlias.class).value();
  114. }
  115. return field.getName();
  116. });
  117. }
  118. private WxPayOrderNotifyCoupon getElement(Map<Integer, WxPayOrderNotifyCoupon> coupons, String nodeName) {
  119. Integer index = Integer.valueOf(StringUtils.substringAfterLast(nodeName, "_"));
  120. coupons.computeIfAbsent(index, k -> new WxPayOrderNotifyCoupon());
  121. return coupons.get(index);
  122. }
  123. }