ResponsibilityChainProcessor.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package cn.nosum.support.processor;
  2. import cn.nosum.support.chain.BaseResponsibilityChainHandler;
  3. import cn.nosum.support.chain.Processor;
  4. import cn.nosum.support.chain.ResponsibilityChainException;
  5. import cn.nosum.support.chain.ResponsibilityChainHandlerFactory;
  6. import cn.nosum.support.core.utils.CheckUtil;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.util.CollectionUtils;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.function.Consumer;
  14. import java.util.function.Predicate;
  15. /**
  16. * 负责生产责任链中的节点。
  17. *
  18. * @author Young
  19. */
  20. @Slf4j
  21. public class ResponsibilityChainProcessor<T extends Processor> {
  22. /**
  23. * 处理链
  24. */
  25. private final Map<String, List<BaseResponsibilityChainHandler<T>>> MULTI_CHAINS = new ConcurrentHashMap<>(64);
  26. /**
  27. * 添加处理节点到链路中,会根据返回的值决定是否继续执行链
  28. *
  29. * @param hitPredicate 提供给外部注册的判断是否命中当前责任链节点的逻辑块
  30. * @param handleAction 提供给外部注册的责任链上下文处理的逻辑块, 返回值为true时,将会继续执行下一个节点
  31. */
  32. protected void addChain(String name, Predicate<T> hitPredicate,
  33. Predicate<T> handleAction, int order, String groupName) {
  34. verification(hitPredicate, handleAction);
  35. BaseResponsibilityChainHandler<T> chain;
  36. chain = new BaseResponsibilityChainHandler<T>(name, hitPredicate, handleAction, null);
  37. setNodeAndSort(order, groupName, chain);
  38. }
  39. /**
  40. * 添加处理节点到链路中,用户无法干预链表的执行,会一直执行结束
  41. *
  42. * @param hitPredicate 提供给外部注册的判断是否命中当前责任链节点的逻辑块
  43. * @param handleAction 提供给外部注册的责任链上下文处理的逻辑块,
  44. */
  45. protected void addChainFromConsumer(String name, Predicate<T> hitPredicate,
  46. Consumer<T> handleAction, int order, String groupName) {
  47. verification(hitPredicate, handleAction);
  48. BaseResponsibilityChainHandler<T> chain;
  49. chain = ResponsibilityChainHandlerFactory.generate(name, hitPredicate, (context) -> {
  50. handleAction.accept(context);
  51. return true;
  52. }, null);
  53. setNodeAndSort(order, groupName, chain);
  54. }
  55. /**
  56. * 往组中放入节点并且排序
  57. *
  58. * @param order 排序
  59. * @param groupName 组名
  60. * @param chain 链中的节点
  61. */
  62. private void setNodeAndSort(int order, String groupName, BaseResponsibilityChainHandler<T> chain) {
  63. List<BaseResponsibilityChainHandler<T>> chains = MULTI_CHAINS.get(groupName);
  64. if (CollectionUtils.isEmpty(chains)) {
  65. chains = new ArrayList<>();
  66. MULTI_CHAINS.put(groupName, chains);
  67. }
  68. chain.setSort(order);
  69. if (!chains.isEmpty()) {
  70. // 存在相同的顺序的接口直接返回
  71. chains.forEach(a -> {
  72. if (a.getSort() == order) {
  73. throw new ResponsibilityChainException(String.format("节点:[%s]与节点:[%s] order:[%s]相同", a.getName(), chain.getName(), order));
  74. }
  75. });
  76. chains.get(chains.size() - 1).setNext(chain);
  77. }
  78. chains.add(chain);
  79. // 排序
  80. sort(chains);
  81. }
  82. /**
  83. * 转换器
  84. *
  85. * @param source 源节点
  86. * @param target 目标节点
  87. */
  88. private static <T extends Processor> void covert(BaseResponsibilityChainHandler<T> source, BaseResponsibilityChainHandler<T> target) {
  89. target.setSort(source.getSort());
  90. target.setHandleAction(source.getHandleAction());
  91. target.setHitPredicate(source.getHitPredicate());
  92. target.setId(source.getId());
  93. target.setName(source.getName());
  94. }
  95. /**
  96. * 链表排序
  97. *
  98. * @param chains 执行链
  99. */
  100. private void sort(List<BaseResponsibilityChainHandler<T>> chains) {
  101. BaseResponsibilityChainHandler<T> temp, p;
  102. for (int i = 0; i < chains.size(); i++) {
  103. p = chains.get(0);
  104. for (int j = 0; j < chains.size() - i; j++) {
  105. CheckUtil.checkNotNull(p,"chains is null,check your configuration!!");
  106. if (p.getNext() != null && p.getSort() > p.getNext().getSort()) {
  107. temp = new BaseResponsibilityChainHandler<>(p.getName(), p.getHitPredicate(), p.getHandleAction(), p.getNext());
  108. temp.setSort(p.getSort());
  109. covert(p.getNext(), p);
  110. covert(temp, p.getNext());
  111. }
  112. p = p.getNext();
  113. }
  114. }
  115. }
  116. /**
  117. * 责任链上下文处理
  118. *
  119. * @param context {@link T} 当前处理的上下文信息
  120. */
  121. public void handle(T context, String groupName) {
  122. List<BaseResponsibilityChainHandler<T>> chains = MULTI_CHAINS.get(groupName);
  123. if (chains.isEmpty()) {
  124. return;
  125. }
  126. context.clearLog();
  127. chains.get(0).handle(context);
  128. }
  129. /**
  130. * 校验参数
  131. */
  132. private <THandleAction> void verification(Predicate<T> hitPredicate,
  133. THandleAction handleAction) {
  134. if (hitPredicate == null) {
  135. throw new IllegalArgumentException("hitPredicate");
  136. }
  137. if (handleAction == null) {
  138. throw new IllegalArgumentException("handleAction");
  139. }
  140. }
  141. }