diff --git a/pom.xml b/pom.xml
index 2cc4451cb..4083045f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
'{'
*/
- char DELIM_START = '{';
+ char DELIM_START = '{';
/**
* 字符常量:花括号(右) '}'
*/
- char DELIM_END = '}';
+ char DELIM_END = '}';
/**
* 字符常量:中括号(左) {@code '['}
*/
- char BRACKET_START = '[';
+ char BRACKET_START = '[';
/**
* 字符常量:中括号(右) {@code ']'}
*/
- char BRACKET_END = ']';
+ char BRACKET_END = ']';
/**
* 字符常量:双引号 {@code '"'}
*/
- char DOUBLE_QUOTES = '"';
+ char DOUBLE_QUOTES = '"';
/**
* 字符常量:单引号 {@code '\''}
*/
- char SINGLE_QUOTE = '\'';
+ char SINGLE_QUOTE = '\'';
/**
* 字符常量:与 {@code '&'}
*/
- char AMP = '&';
+ char AMP = '&';
/**
* 字符常量:冒号 {@code ':'}
*/
- char COLON = ':';
+ char COLON = ':';
/**
* 字符常量:艾特 {@code '@'}
*/
- char AT = '@';
+ char AT = '@';
+
+ String EXCLUDE_CHAR = "♠♣♧♡♥❤❥❣♂♀✲☀☼☾☽◐◑☺☻☎☏✿❀№↑↓←→√×÷★℃℉°◆◇⊙■□△▽¿½☯✡㍿卍卐♂♀✚〓㎡♪♫♩♬㊚㊛囍㊒㊖Φ♀♂‖$@*※卍卐Ψ♫♬♭♩♪♯♮⌒¶∮‖€£¥$\n" +
+ "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⓪❶❷❸❹❺❻❼❽❾❿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵\n"
+ +
+ "﹢﹣×÷±/=≌∽≦≧≒﹤﹥≈≡≠=≤≥<>≮≯∷∶∫∮∝∞∧∨∑∏∪∩∈∵∴⊥∥∠⌒⊙√∟⊿㏒㏑%‰⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱øØπ\n" +
+ "♥❣ღ♠♡♤❤❥♚ ♛ ♝ ♞ ♜ ♟ ♔ ♕ ♗ ♘ ♖ ♟°′″$¥〒¢£%@℃℉﹩﹪‰﹫㎡㏕㎜㎝㎞㏎³㎎㎏㏄º○¤%$º¹²³\n" +
+ "€£Ұ₴$₰¢₤¥₳₲₪₵₣₱฿¤₡₮₭₩₢₥₫₦zł﷼₠₧₯₨čर₹ƒ₸¢\n" +
+ "✐✎✏✑✒✍✉✁✂✃✄✆✉☎☏☑✓✔√☐☒✗✘ㄨ✕✖✖☢☠☣✈★☆✡囍㍿☯☰☲☱☴☵☶☳☷☜☞☝✍☚☛☟✌♤♧♡♢♠♣♥♦☀☁☂❄☃♨웃유❖☽☾☪✿♂♀✪✯☭➳卍卐√×■◆●○◐◑✙☺☻❀⚘♔♕♖♗♘♙♚♛♜♝♞♟♧♡♂\n" +
+ "♀♠♣♥❤☜☞☎☏⊙◎☺☻☼▧▨♨◐◑↔↕▪▒◊◦▣▤▥▦▩◘◈◇♬♪♩♭♪の★☆→あぃ£Ю〓§♤♥▶¤✲❈✿✲❈➹☀☂☁【】┱┲❣✚✪✣✤✥✦❉❥❦❧❃❂❁❀✄☪☣☢☠☭ღ▶▷◀◁☀☁☂☃☄★☆☇☈⊙☊☋☌☍ⓛⓞⓥⓔ╬\n" +
+ "『』∴☀♫♬♩♭♪☆∷﹌の★◎▶☺☻►◄▧▨♨◐◑↔↕↘▀▄█▌◦☼♪の☆→♧ぃ£❤▒▬♦◊◦♠♣▣۰•❤•۰►◄▧▨♨◐◑↔↕▪▫☼♦⊙●○①⊕◎Θ⊙¤㊣★☆♀◆◇◣◢◥▲▼△▽⊿◤◥✐✌✍✡✓✔✕✖♂♀♥♡☜☞☎☏⊙◎☺\n" +
+ "☻►◄▧▨♨◐◑↔↕♥♡▪▫☼♦▀▄█▌▐░▒▬♦◊◘◙◦☼♠♣▣▤▥▦▩◘◙◈♫♬♪♩♭♪✄☪☣☢☠♯♩♪♫♬♭♮☎☏☪♈ºº₪¤큐«»™♂✿♥ ◕‿-。 。◕‿◕。\n" +
+ "❤❥웃유♋☮✌☏☢☠✔☑♚▲♪✈✞÷↑↓◆◇⊙■□△▽¿─│♥❣♂♀☿Ⓐ✍✉☣☤✘☒♛▼♫⌘☪≈←→◈◎☉★☆⊿※¡━┃♡ღツ☼☁❅♒✎©®™Σ✪✯☭➳卐√↖↗●◐Θ◤◥︻〖〗┄┆℃℉°✿ϟ☃☂✄¢€£∞✫★½✡×↙↘\n" +
+ "○◑⊕◣◢︼【】┅┇☽☾✚〓▂▃▄▅▆▇█▉▊▋▌▍▎▏↔↕☽☾の•▸◂▴▾┈┊①②③④⑤⑥⑦⑧⑨⑩ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ㍿▓♨♛❖♓☪✙┉┋☹☺☻تヅツッシÜϡﭢ™℠℗©®♥❤❥❣❦❧♡۵웃유ღ♋♂♀☿☼☀☁☂☄\n" +
+ "☾☽❄☃☈⊙☉℃℉❅✺ϟ☇♤♧♡♢♠♣♥♦☜☞☝✍☚☛☟✌✽✾✿❁❃❋❀⚘☑✓✔√☐☒✗✘ㄨ✕✖✖⋆✢✣✤✥❋✦✧✩✰✪✫✬✭✮✯❂✡★✱✲✳✴✵✶✷✸✹✺✻✼❄❅❆❇❈❉❊†☨✞✝☥☦☓☩☯☧☬☸✡♁✙♆。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<__-\\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼☩☨☦✞✛✜✝✙✠✚†‡◉○◌◍◎●◐◑◒◓◔◕◖◗❂☢⊗⊙◘◙◍⅟½⅓⅕⅙⅛⅔⅖⅚⅜¾⅗⅝⅞⅘≂≃≄≅≆≇≈≉≊≋≌≍≎≏≐≑≒≓≔≕≖≗≘≙≚≛≜≝≞≟≠≡≢≣≤≥≦≧≨≩⊰⊱⋛⋚∫∬∭∮∯∰∱∲∳%℅‰‱㊣㊎㊍㊌㊋㊏㊐㊊㊚㊛㊤㊥㊦㊧㊨㊒㊞㊑㊒\n"
+ +
+ "㊓㊔㊕㊖㊗㊘㊜㊝㊟㊠㊡㊢㊩㊪㊫㊬㊭㊮㊯㊰㊙㉿囍♔♕♖♗♘♙♚♛♜♝♞♟ℂℍℕℙℚℝℤℬℰℯℱℊℋℎℐℒℓℳℴ℘ℛℭ℮ℌℑℜℨ♪♫♩♬♭♮♯°øⒶ☮✌☪✡☭✯卐✐✎✏✑✒✍✉✁✂✃✄✆✉☎☏➟➡➢➣➤➥➦➧➨➚➘➙➛➜\n" +
+ "➝➞➸♐➲➳⏎➴➵➶➷➸➹➺➻➼➽←↑→↓↔↕↖↗↘↙↚↛↜↝↞↟↠↡↢↣↤↥↦↧↨➫➬➩➪➭➮➯➱↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹↺↻↼↽↾↿⇀⇁⇂⇃⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇚⇛⇜⇝⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪➀➁➂➃➄\n" +
+ "➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓㊀㊁㊂㊃㊄㊅㊆㊇㊈㊉ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ⒜⒝⒞⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯⒰⒱⒲⒳⒴⒵┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛├┝┞┟\n" +
+ "┠┡┢┣┤┥┦┧┨┩┪┫┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻┼┽┾┿╀╁╂╃╄╅╆╇╈╉╊╋╌╍╎╏═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡╢╣╤╥╦╧╨╩╪╫╬◤◥◄►▶◀◣◢▲▼◥▸◂▴▾△▽▷◁⊿▻◅▵▿▹◃❏❐❑❒▀▁▂▃▄▅▆\n" +
+ "▇▉▊▋█▌▍▎▏▐░▒▓▔▕■□▢▣▤▥▦▧▨▩▪▫▬▭▮▯㋀㋁㋂㋃㋄㋅㋆㋇㋈㋉㋊㋋㏠㏡㏢㏣㏤㏥㏦㏧㏨㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾㍙㍚㍛㍜㍝㍞㍟㍠㍡㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㍘☰☲☱☴\n" +
+ "☵☶☳☷☯\n" +
+ "。,、':∶;?‘’“”〝〞ˆˇ﹕︰﹔﹖﹑•¨….¸;!´?!~—ˉ|‖"〃`@﹫¡¿﹏﹋﹌︴々﹟#﹩$﹠&﹪%*﹡﹢﹦﹤‐ ̄¯―﹨ˆ˜﹍﹎+=<__-\\ˇ~﹉﹊()〈〉‹›﹛﹜『』〖〗[]《》〔〕{}「」【】︵︷︿︹︽_﹁﹃︻︶︸﹀︺︾ˉ﹂﹄︼❝❞\n" +
+ "↑↓←→↖↗↘↙↔↕➻➼➽➸➳➺➻➴➵➶➷➹▶►▷◁◀◄«»➩➪➫➬➭➮➯➱⏎➲➾➔➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨↚↛↜↝↞↟↠↠↡↢↣↤↤↥↦↧↨⇄⇅⇆⇇⇈⇉⇊⇋⇌⇍⇎⇏⇐⇑⇒⇓⇔⇖⇗⇘⇙⇜↩↪↫↬↭↮↯↰↱↲↳↴↵↶↷↸↹☇☈↼↽↾↿⇀⇁⇂⇃⇞⇟⇠⇡⇢⇣⇤⇥⇦⇧⇨⇩⇪↺↻⇚⇛♐\n"
+ +
+ "─ ━│┃╌╍╎╏┄ ┅┆┇┈ ┉┊┋┌┍┎┏┐┑┒┓└ ┕┖┗ ┘┙┚┛├┝┞┟┠┡┢┣ ┤┥┦┧┨┩┪┫┬ ┭ ┮ ┯ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻┼ ┽ ┾ ┿ ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╪ ╫ ╬═║╒╓╔ ╕╖╗╘╙╚ ╛╜╝╞╟╠ ╡╢╣╤ ╥ ╦ ╧ ╨ ╩ ╳╔ ╗╝╚ ╬ ═ ╓ ╩ ┠ ┨┯ ┷┏ ┓┗ ┛┳ ⊥ ﹃ ﹄┌ ╮ ╭ ╯╰\n"
+ +
+ "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ゠ㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ\n"
+ +
+ "āáǎàōóǒòēéěèīíǐìūúǔùǖǘǚǜüêɑ\uE7C7ńň\uE7C8ɡㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ\n" +
+ "БГДЁЖИЙКЛПФЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя|()`";
+
}
diff --git a/src/main/java/com/luna/common/math/MathConvertUtil.java b/src/main/java/com/luna/common/math/MathConvertUtil.java
new file mode 100644
index 000000000..c0c7b500a
--- /dev/null
+++ b/src/main/java/com/luna/common/math/MathConvertUtil.java
@@ -0,0 +1,127 @@
+package com.luna.common.math;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class MathConvertUtil {
+
+ public static boolean asBoolean(Object obj, boolean defaultBoolean) {
+ if (obj == null)
+ return defaultBoolean;
+ try {
+ return Boolean.getBoolean(obj.toString());
+ } catch (Exception ex) {
+ return defaultBoolean;
+ }
+ }
+
+ public static int asInt(String entryStr) {
+ if (StringUtils.isEmpty(entryStr)) {
+ return 0;
+ }
+ try {
+ return Integer.parseInt(entryStr);
+ } catch (Exception ex) {
+ return 0;
+ }
+ }
+
+ public static Integer asInteger(String entryStr) {
+ if (StringUtils.isEmpty(entryStr)) {
+ return null;
+ }
+ try {
+ return Integer.parseInt(entryStr);
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public static long asLong(String entryStr) {
+ if (StringUtils.isEmpty(entryStr)) {
+ return 0L;
+ }
+ try {
+ return Long.parseLong(entryStr);
+ } catch (Exception ex) {
+ return 0L;
+ }
+ }
+
+ /**
+ * 这里保留2未精度
+ * 入参500,出参5
+ *
+ * @param entryStr
+ * @return
+ */
+ public static double longConvert2Double(long entryStr) {
+ try {
+ return BigDecimal.valueOf(entryStr).divide(
+ BigDecimal.valueOf(100), 2,
+ RoundingMode.HALF_UP).doubleValue();
+ } catch (Exception ex) {
+ return 0L;
+ }
+ }
+
+ /**
+ * 转换成精确到2位精度
+ *
+ * @param entryStr
+ * @return
+ */
+ public static long doubleConvert2Long(double entryStr) {
+ try {
+ return BigDecimal.valueOf(entryStr).multiply(
+ BigDecimal.valueOf(100)).longValue();
+ } catch (Exception ex) {
+ return 0L;
+ }
+ }
+
+ public static boolean asBoolean(String entryStr) {
+ try {
+ return Boolean.parseBoolean(entryStr);
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ public static Boolean asBooleanObject(String entryStr) {
+ if (StringUtils.isEmpty(entryStr)) {
+ return null;
+ }
+ try {
+ return Boolean.parseBoolean(entryStr);
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ public static String asString(Object entryStr) {
+ if (null == entryStr)
+ return "";
+ return entryStr.toString();
+ }
+
+ public static boolean isBlank(final CharSequence cs) {
+ int strLen;
+ if (cs == null || (strLen = cs.length()) == 0) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void main(String[] args) {
+
+ }
+
+}
diff --git a/src/main/java/com/luna/common/os/Profiler.java b/src/main/java/com/luna/common/os/Profiler.java
new file mode 100644
index 000000000..11b3df62f
--- /dev/null
+++ b/src/main/java/com/luna/common/os/Profiler.java
@@ -0,0 +1,512 @@
+package com.luna.common.os;
+
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 用来测试并统计线程执行时间的工具。
+ *
+ */
+public final class Profiler {
+ private static final ThreadLocal entryStack = new ThreadLocal();
+
+ /**
+ * 开始计时。
+ */
+ public static void start() {
+ start((String) null);
+ }
+
+ /**
+ * 开始计时。
+ *
+ * @param message 第一个entry的信息
+ */
+ public static void start(String message) {
+ entryStack.set(new Entry(message, null, null));
+ }
+
+ /**
+ * 开始计时。
+ *
+ * @param message 第一个entry的信息
+ */
+ public static void start(Message message) {
+ entryStack.set(new Entry(message, null, null));
+ }
+
+ /**
+ * 清除计时器。
+ *
+ *
+ * 清除以后必须再次调用start
方可重新计时。
+ *
-1
+ */
+ public static long getDuration() {
+ Entry entry = (Entry) entryStack.get();
+
+ if (entry != null) {
+ return entry.getDuration();
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * 列出所有的entry。
+ *
+ * @return 列出所有entry,并统计各自所占用的时间
+ */
+ public static String dump() {
+ return dump("", "");
+ }
+
+ /**
+ * 列出所有的entry。
+ *
+ * @param prefix 前缀
+ *
+ * @return 列出所有entry,并统计各自所占用的时间
+ */
+ public static String dump(String prefix) {
+ return dump(prefix, prefix);
+ }
+
+ /**
+ * 列出所有的entry。
+ *
+ * @param prefix1 首行前缀
+ * @param prefix2 后续行前缀
+ *
+ * @return 列出所有entry,并统计各自所占用的时间
+ */
+ public static String dump(String prefix1, String prefix2) {
+ Entry entry = (Entry) entryStack.get();
+
+ if (entry != null) {
+ return entry.toString(prefix1, prefix2);
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * 取得第一个entry。
+ *
+ * @return 第一个entry,如果不存在,则返回null
+ */
+ public static Entry getEntry() {
+ return (Entry) entryStack.get();
+ }
+
+ /**
+ * 取得最近的一个entry。
+ *
+ * @return 最近的一个entry,如果不存在,则返回null
+ */
+ private static Entry getCurrentEntry() {
+ Entry subEntry = (Entry) entryStack.get();
+ Entry entry = null;
+
+ if (subEntry != null) {
+ do {
+ entry = subEntry;
+ subEntry = entry.getUnreleasedEntry();
+ } while (subEntry != null);
+ }
+
+ return entry;
+ }
+
+ /**
+ * 代表一个计时单元。
+ */
+ public static final class Entry {
+ private final List subEntries = new ArrayList(4);
+ private final Object message;
+ private final Entry parentEntry;
+ private final Entry firstEntry;
+ private final long baseTime;
+ private final long startTime;
+ private long endTime;
+
+ /**
+ * 创建一个新的entry。
+ *
+ * @param message entry的信息,可以是null
+ * @param parentEntry 父entry,可以是null
+ * @param firstEntry 第一个entry,可以是null
+ */
+ private Entry(Object message, Entry parentEntry, Entry firstEntry) {
+ this.message = message;
+ this.startTime = System.currentTimeMillis();
+ this.parentEntry = parentEntry;
+ this.firstEntry = (Entry) defaultIfNull(firstEntry, this);
+ this.baseTime = (firstEntry == null) ? 0
+ : firstEntry.startTime;
+ }
+
+ public static Object defaultIfNull(Object object, Object defaultValue) {
+ return (object != null) ? object
+ : defaultValue;
+ }
+
+ /**
+ * 取得entry的信息。
+ */
+ public String getMessage() {
+ String messageString = null;
+
+ if (message instanceof String) {
+ messageString = (String) message;
+ } else if (message instanceof Message) {
+ Message messageObject = (Message) message;
+ MessageLevel level = MessageLevel.BRIEF_MESSAGE;
+
+ if (isReleased()) {
+ level = messageObject.getMessageLevel(this);
+ }
+
+ if (level == MessageLevel.DETAILED_MESSAGE) {
+ messageString = messageObject.getDetailedMessage();
+ } else {
+ messageString = messageObject.getBriefMessage();
+ }
+ }
+
+ return defaultIfEmpty(messageString, null);
+ }
+
+ private static String defaultIfEmpty(String str, String defaultStr) {
+ return ((str == null) || (str.length() == 0)) ? defaultStr
+ : str;
+ }
+
+ /**
+ * 取得entry相对于第一个entry的起始时间。
+ *
+ * @return 相对起始时间
+ */
+ public long getStartTime() {
+ return (baseTime > 0) ? (startTime - baseTime)
+ : 0;
+ }
+
+ /**
+ * 取得entry相对于第一个entry的结束时间。
+ *
+ * @return 相对结束时间,如果entry还未结束,则返回-1
+ */
+ public long getEndTime() {
+ if (endTime < baseTime) {
+ return -1;
+ } else {
+ return endTime - baseTime;
+ }
+ }
+
+ /**
+ * 取得entry持续的时间。
+ *
+ * @return entry持续的时间,如果entry还未结束,则返回-1
+ */
+ public long getDuration() {
+ if (endTime < startTime) {
+ return -1;
+ } else {
+ return endTime - startTime;
+ }
+ }
+
+ /**
+ * 取得entry自身所用的时间,即总时间减去所有子entry所用的时间。
+ *
+ * @return entry自身所用的时间,如果entry还未结束,则返回-1
+ */
+ public long getDurationOfSelf() {
+ long duration = getDuration();
+
+ if (duration < 0) {
+ return -1;
+ } else if (subEntries.isEmpty()) {
+ return duration;
+ } else {
+ for (int i = 0; i < subEntries.size(); i++) {
+ Entry subEntry = (Entry) subEntries.get(i);
+
+ duration -= subEntry.getDuration();
+ }
+
+ if (duration < 0) {
+ return -1;
+ } else {
+ return duration;
+ }
+ }
+ }
+
+ /**
+ * 取得当前entry在父entry中所占的时间百分比。
+ *
+ * @return 百分比
+ */
+ public double getPecentage() {
+ double parentDuration = 0;
+ double duration = getDuration();
+
+ if ((parentEntry != null) && parentEntry.isReleased()) {
+ parentDuration = parentEntry.getDuration();
+ }
+
+ if ((duration > 0) && (parentDuration > 0)) {
+ return duration / parentDuration;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * 取得当前entry在第一个entry中所占的时间百分比。
+ *
+ * @return 百分比
+ */
+ public double getPecentageOfAll() {
+ double firstDuration = 0;
+ double duration = getDuration();
+
+ if ((firstEntry != null) && firstEntry.isReleased()) {
+ firstDuration = firstEntry.getDuration();
+ }
+
+ if ((duration > 0) && (firstDuration > 0)) {
+ return duration / firstDuration;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * 取得所有子entries。
+ *
+ * @return 所有子entries的列表(不可更改)
+ */
+ public List getSubEntries() {
+ return Collections.unmodifiableList(subEntries);
+ }
+
+ /**
+ * 结束当前entry,并记录结束时间。
+ */
+ private void release() {
+ endTime = System.currentTimeMillis();
+ }
+
+ /**
+ * 判断当前entry是否结束。
+ *
+ * @return 如果entry已经结束,则返回true
+ */
+ private boolean isReleased() {
+ return endTime > 0;
+ }
+
+ /**
+ * 创建一个新的子entry。
+ *
+ * @param message 子entry的信息
+ */
+ private void enterSubEntry(Object message) {
+ Entry subEntry = new Entry(message, this, firstEntry);
+
+ subEntries.add(subEntry);
+ }
+
+ /**
+ * 取得未结束的子entry。
+ *
+ * @return 未结束的子entry,如果没有子entry,或所有entry均已结束,则返回null
+ */
+ private Entry getUnreleasedEntry() {
+ Entry subEntry = null;
+
+ if (!subEntries.isEmpty()) {
+ subEntry = (Entry) subEntries.get(subEntries.size() - 1);
+
+ if (subEntry.isReleased()) {
+ subEntry = null;
+ }
+ }
+
+ return subEntry;
+ }
+
+ /**
+ * 将entry转换成字符串的表示。
+ *
+ * @return 字符串表示的entry
+ */
+ public String toString() {
+ return toString("", "");
+ }
+
+ /**
+ * 将entry转换成字符串的表示。
+ *
+ * @param prefix1 首行前缀
+ * @param prefix2 后续行前缀
+ *
+ * @return 字符串表示的entry
+ */
+ private String toString(String prefix1, String prefix2) {
+ StringBuffer buffer = new StringBuffer();
+
+ toString(buffer, prefix1, prefix2);
+
+ return buffer.toString();
+ }
+
+ /**
+ * 将entry转换成字符串的表示。
+ *
+ * @param buffer 字符串buffer
+ * @param prefix1 首行前缀
+ * @param prefix2 后续行前缀
+ */
+ private void toString(StringBuffer buffer, String prefix1, String prefix2) {
+ buffer.append(prefix1);
+
+ String message = getMessage();
+ long startTime = getStartTime();
+ long duration = getDuration();
+ long durationOfSelf = getDurationOfSelf();
+ double percent = getPecentage();
+ double percentOfAll = getPecentageOfAll();
+
+ Object[] params = new Object[] {
+ message, // {0} - entry信息
+ new Long(startTime), // {1} - 起始时间
+ new Long(duration), // {2} - 持续总时间
+ new Long(durationOfSelf), // {3} - 自身消耗的时间
+ new Double(percent), // {4} - 在父entry中所占的时间比例
+ new Double(percentOfAll) // {5} - 在总时间中所旧的时间比例
+ };
+
+ StringBuffer pattern = new StringBuffer("{1,number} ");
+
+ if (isReleased()) {
+ pattern.append("[{2,number}ms");
+
+ if ((durationOfSelf > 0) && (durationOfSelf != duration)) {
+ pattern.append(" ({3,number}ms)");
+ }
+
+ if (percent > 0) {
+ pattern.append(", {4,number,##%}");
+ }
+
+ if (percentOfAll > 0) {
+ pattern.append(", {5,number,##%}");
+ }
+
+ pattern.append("]");
+ } else {
+ pattern.append("[UNRELEASED]");
+ }
+
+ if (message != null) {
+ pattern.append(" - {0}");
+ }
+
+ buffer.append(MessageFormat.format(pattern.toString(), params));
+
+ for (int i = 0; i < subEntries.size(); i++) {
+ Entry subEntry = (Entry) subEntries.get(i);
+
+ buffer.append('\n');
+
+ if (i == (subEntries.size() - 1)) {
+ subEntry.toString(buffer, prefix2 + "`---", prefix2 + " "); // 最后一项
+ } else if (i == 0) {
+ subEntry.toString(buffer, prefix2 + "+---", prefix2 + "| "); // 第一项
+ } else {
+ subEntry.toString(buffer, prefix2 + "+---", prefix2 + "| "); // 中间项
+ }
+ }
+ }
+ }
+
+ /**
+ * 显示消息的级别。
+ */
+// public static final class MessageLevel extends IntegerEnum {
+// private static final long serialVersionUID = 3257849896026388537L;
+// public static final MessageLevel NO_MESSAGE = (MessageLevel) create();
+// public static final MessageLevel BRIEF_MESSAGE = (MessageLevel) create();
+// public static final MessageLevel DETAILED_MESSAGE = (MessageLevel) create();
+// }
+
+ public enum MessageLevel
+ {
+ NO_MESSAGE,BRIEF_MESSAGE,DETAILED_MESSAGE;
+ }
+
+ /**
+ * 代表一个profiler entry的详细信息。
+ */
+ public interface Message {
+ MessageLevel getMessageLevel(Entry entry);
+
+ String getBriefMessage();
+
+ String getDetailedMessage();
+ }
+}
diff --git a/src/main/java/com/luna/common/text/DataDesensitizationUtils.java b/src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java
similarity index 94%
rename from src/main/java/com/luna/common/text/DataDesensitizationUtils.java
rename to src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java
index 40cca2f96..bca7ef12e 100644
--- a/src/main/java/com/luna/common/text/DataDesensitizationUtils.java
+++ b/src/main/java/com/luna/common/sensitive/DataDesensitizationUtils.java
@@ -1,4 +1,6 @@
-package com.luna.common.text;
+package com.luna.common.sensitive;
+
+import com.luna.common.text.StringTools;
/**
* @author luna
diff --git a/src/main/java/com/luna/common/text/FeatureUtils.java b/src/main/java/com/luna/common/text/FeatureUtils.java
new file mode 100644
index 000000000..8b9e47148
--- /dev/null
+++ b/src/main/java/com/luna/common/text/FeatureUtils.java
@@ -0,0 +1,302 @@
+package com.luna.common.text;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Lists;
+import com.luna.common.constant.StrPoolConstant;
+
+/**
+ * Created by weidian2015090105 on 15/9/27.
+ */
+public class FeatureUtils {
+
+ public static final String FEATURE_SEPERATOR = ";";
+ public static final String KEY_VALUE_SEPERATOR = ":";
+
+ /**
+ * 设置一个feature。如果已经存在,则替换;如果不存在,则添加。origFeatures可以为空,直接返回aKey:aValue。
+ *
+ * @param origFeatures 原始的features字段。可以为空。
+ * @param aKey 需要设置的feature的key
+ * @param aValue 需要设置的feature的value
+ * @return 返回添加或修改后的整个features字段
+ */
+ public static String addOrUpdateAFeature(String origFeatures, String aKey, String aValue) {
+
+ if (null == aKey || aKey.trim().isEmpty()) {
+ return origFeatures;
+ }
+
+ if (null == aValue || aValue.trim().isEmpty()) {
+ return origFeatures;
+ }
+
+ if (origFeatures == null || origFeatures.isEmpty()) {
+ return aKey + KEY_VALUE_SEPERATOR + aValue;
+ }
+
+ List