package com.athena.asm.tool.notifier.markup; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import com.athena.asm.data.Post; import com.athena.asm.tool.notifier.PostField; public class MarkupUtils { /** * 返回一个映射: * 1. 这个映射将markups分门别类排好 * 2. 并且按照从前往后排序 * 3. 将重叠的markup(有公共部分,相邻的不算)合并 * @param markups * @return */ public static Map<PostField, List<Markup>> tidy(List<Markup> markups) { Map<PostField, List<Markup>> ret = new HashMap<PostField, List<Markup>>(); Post post = null; // collect for (Markup m : markups) { if (post != null && m.post != post) { throw new RuntimeException("Markups for multiple post on tidy()."); } else { List<Markup> ms = null; if (ret.containsKey(m.field)) { ms = ret.get(m.field); } else { ms = new ArrayList<Markup>(); ret.put(m.field, ms); } ms.add(m); } } // sort for (PostField field : ret.keySet()) { List<Markup> ms = ret.get(field); Collections.sort(ms, new Comparator<Markup>() { @Override public int compare(Markup m1, Markup m2) { return (m1.start - m2.start); } }); } // merge for (PostField field : ret.keySet()) { List<Markup> ms = ret.get(field); merge(ms); } return ret; } /** * 归并,前提条件: * 1. 所有Markup来自同一个Post * 2. 所有Markup来自同一个Field * 3. 所有Markup已经排序好 * @param ms */ private static List<Markup> merge(List<Markup> markups) { List<Markup> ret = new ArrayList<Markup>(); if (markups.size() <= 1) { return markups; } else { Markup head = markups.get(0); int i = 1; int start = head.start; int end = head.end; while (i < markups.size()) { Markup m = markups.get(i); if (end > m.start) { // 有公共部分 if (m.end > end) { // 扩展 end = m.end; } else { // 被包含 // do nothing } } else { ret.add(new Markup(m.post, m.field, start, end)); // 断开 head = m; start = head.start; end = head.end; } i ++; } return ret; } } }