package com.zy.common.utils; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Array; import java.text.SimpleDateFormat; import java.util.*; /** * news stories for zoneyung * Created by vincent on 2022/12/22 */ @Slf4j public class News { public static void main(String[] args) { News.info("info{}", 1); News.warn("warn{}", 2); News.error("error{}", 3); System.out.println(News.print()); } interface NewsSupport { boolean execute(T t); } private static final NewsQueue NEWS_QUEUE = new NewsQueue<>(NewsDomain.class, 1024); @SuppressWarnings({"unchecked"}) static class NewsQueue { private final transient Class cls; private final T[] arr; private final int capacity; private int head; private int tail; { this.head = 0; this.tail = 0; } public NewsQueue(Class cls, int capacity) { this.cls = cls; this.arr = (T[]) Array.newInstance(cls, capacity); this.capacity = capacity; } public synchronized boolean offer(T t) { if (this.tail == this.capacity) { this.peek(); } this.reform(); this.arr[this.tail] = t; this.tail ++; return true; } public synchronized boolean put(T t) { if (this.tail == this.capacity) { return false; } else { this.reform(); } this.arr[this.tail] = t; this.tail ++; return true; } public synchronized T peek() { if (this.head == this.tail) { return null; } T t = this.arr[this.head]; this.head ++; this.reform(); return t; } private void reform() { for (int i = this.head; i < this.tail; i++) { this.arr[i-this.head] = this.arr[i]; } this.tail -= this.head; this.head = 0; } public synchronized int size() { return this.tail - this.head; } public synchronized List data() { T[] ts = (T[]) Array.newInstance(this.cls, size()); if (this.tail - this.head >= 0) { System.arraycopy(this.arr, this.head, ts, 0, this.tail - this.head); } return Arrays.asList(ts); } } public static void info(String format, Object... arguments) { log.info(format, arguments); offer(NewsLevel.INFO, format, arguments); } public static void warn(String format, Object... arguments) { log.warn(format, arguments); offer(NewsLevel.WARN, format, arguments); } public static void error(String format, Object... arguments) { log.error(format, arguments); offer(NewsLevel.ERROR, format, arguments); } public static void infoNoLog(String format, Object... arguments) { offer(NewsLevel.INFO, format, arguments); } public static void warnNoLog(String format, Object... arguments) { offer(NewsLevel.WARN, format, arguments); } public static void errorNoLog(String format, Object... arguments) { offer(NewsLevel.ERROR, format, arguments); } public static String printStr() { StringBuilder sb = new StringBuilder("["); List domains = NEWS_QUEUE.data(); for (int i = 0; i < domains.size(); i++) { NewsDomain domain = domains.get(i); sb.append("{"); sb.append("\"l\":").append(domain.level.idx).append(","); sb.append("\"v\":\"").append(domain.content).append("\"").append(","); sb.append("\"t\":\"").append(domain.date).append("\""); sb.append("}"); if (i < domains.size() - 1) { sb.append(","); } } sb.append("]"); return sb.toString(); } public static List> print() { List> res = new ArrayList<>(); for (NewsDomain datum : NEWS_QUEUE.data()) { Map map = new HashMap<>(); map.put("l", datum.level.idx); map.put("v", datum.content); map.put("t", datum.date); res.add(map); } return res; } private static boolean offer(NewsLevel level, String msg, Object[] args) { return NEWS_QUEUE.offer(new NewsDomain(level, replace(msg, args), (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()))); } private static String replace(String str, Object[] objs){ if (null == objs || objs.length == 0 || null == str || "".equals(str.trim())) { return str; } else { StringBuilder sb = new StringBuilder(str); for (Object obj : objs) { int idx = sb.indexOf("{}"); if (idx == -1) { break; } sb.replace(idx, idx + 2, String.valueOf(obj)); } return sb.toString(); } } static class NewsDomain { public NewsLevel level; public String content; public String date; public NewsDomain(NewsLevel level, String content, String date) { this.level = level; this.content = content; this.date = date; } } enum NewsLevel { INFO(1), WARN(2), ERROR(3), ; public int idx; NewsLevel(int idx) { this.idx = idx; } } }