|
|
@@ -20,10 +20,8 @@ import java.time.Instant;
|
|
|
import java.time.ZoneOffset;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.Date;
|
|
|
-import java.util.IllegalFormatConversionException;
|
|
|
import java.util.Locale;
|
|
|
import java.util.Map;
|
|
|
-import java.util.Objects;
|
|
|
import java.util.function.BiFunction;
|
|
|
import java.util.function.Function;
|
|
|
import net.ranides.assira.collection.maps.Cache;
|
|
|
@@ -34,6 +32,7 @@ import net.ranides.assira.generic.ValueUtils;
|
|
|
import net.ranides.assira.reflection.IAttribute;
|
|
|
import net.ranides.assira.reflection.IClass;
|
|
|
import net.ranides.assira.reflection.Resolver;
|
|
|
+import static net.ranides.assira.text.FormatNumber.MP;
|
|
|
import net.ranides.assira.text.FormatNumber.UnitPrefix;
|
|
|
|
|
|
/**
|
|
|
@@ -68,7 +67,7 @@ public final class ResolveDialect {
|
|
|
Locale locale = new Locale(name);
|
|
|
DecimalFormatSymbols us = DecimalFormatSymbols.getInstance(Locale.US);
|
|
|
|
|
|
- put("", "", r -> new FGeneric(r));
|
|
|
+ putFormat("", "", r -> new FGeneric(r));
|
|
|
|
|
|
// number : 2 + 3 5
|
|
|
// date : 2 + 8 10
|
|
|
@@ -77,58 +76,60 @@ public final class ResolveDialect {
|
|
|
// metric : 1 + 4 5
|
|
|
// binary : 1 + 6 7
|
|
|
// : 40 x language
|
|
|
-
|
|
|
- put("number", (r,p) -> new FNumber(r, new DecimalFormat(p,us)));
|
|
|
- put("number", "", r -> new FNumber(r, DecimalFormat.getInstance(locale)));
|
|
|
- put("number", "integer", r -> new FNumber(r, DecimalFormat.getIntegerInstance(locale)));
|
|
|
- put("number", "currency", r -> new FNumber(r, getCurrencyFormat(locale)));
|
|
|
- put("number", "percent", r -> new FNumber(r, DecimalFormat.getPercentInstance(locale)));
|
|
|
-
|
|
|
- put("date", (r,p) -> new FDateTime(r, new SimpleDateFormat(p,locale)));
|
|
|
- put("date", "", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.DEFAULT,locale)));
|
|
|
- put("date", "short", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.SHORT,locale)));
|
|
|
- put("date", "medium", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.MEDIUM,locale)));
|
|
|
- put("date", "long", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.LONG,locale)));
|
|
|
- put("date", "full", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.FULL,locale)));
|
|
|
- put("date", "iso", r -> new FDateTime8(r, "yyyy-MM-dd'T'HH:mmX"));
|
|
|
- put("date", "gnu", r -> new FDateTime(r, new SimpleDateFormat("yyyyMMddHHmm",Locale.ROOT)));
|
|
|
- put("date", "trace", r -> new FDateTime(r, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS",Locale.ROOT)));
|
|
|
- put("date", "local", r -> new FDateTime(r, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ROOT)));
|
|
|
-
|
|
|
- put("time", (r,p) -> new FDateTime(r, new SimpleDateFormat(p,locale)));
|
|
|
- put("time", "", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.DEFAULT,locale)));
|
|
|
- put("time", "short", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.SHORT,locale)));
|
|
|
- put("time", "medium", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.MEDIUM,locale)));
|
|
|
- put("time", "long", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.LONG,locale)));
|
|
|
- put("time", "full", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.FULL,locale)));
|
|
|
- put("time", "iso", r -> new FDateTime8(r, "HH:mm:ssX"));
|
|
|
- put("time", "gnu", r -> new FDateTime(r, new SimpleDateFormat("HHmmss",Locale.ROOT)));
|
|
|
- put("time", "trace", r -> new FDateTime(r, new SimpleDateFormat("HH:mm:ss.SSS",Locale.ROOT)));
|
|
|
- put("time", "local", r -> new FDateTime(r, new SimpleDateFormat("HH:mm:ss",Locale.ROOT)));
|
|
|
-
|
|
|
- put("hex", "", r -> new FHexArray(r));
|
|
|
- put("hex", "array", r -> new FHexArray(r));
|
|
|
- put("hex", "stream", r -> new FHexStream(r));
|
|
|
-
|
|
|
- put("metric", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.MP));
|
|
|
- put("metric/si", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.MP));
|
|
|
- put("metric/e", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.ME));
|
|
|
- put("metric", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.MP));
|
|
|
- put("metric/si", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.MP));
|
|
|
- put("metric/e", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.ME));
|
|
|
-
|
|
|
- put("binary", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BP));
|
|
|
- put("binary/iec", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BP));
|
|
|
- put("binary/e", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BE));
|
|
|
- put("binary/knuth", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BK));
|
|
|
- put("binary", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BP));
|
|
|
- put("binary/iec", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BP));
|
|
|
- put("binary/e", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BE));
|
|
|
- put("binary/knuth", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BK));
|
|
|
-
|
|
|
- put("choice", (r,p) -> new FChoice(r, new ChoiceFormat(p)));
|
|
|
- }
|
|
|
|
|
|
+ putFormat("number", (r,p) -> new FNumber(r, new DecimalFormat(p,us)));
|
|
|
+ putFormat("number", "", r -> new FNumber(r, DecimalFormat.getInstance(locale)));
|
|
|
+ putFormat("number", "integer", r -> new FNumber(r, DecimalFormat.getIntegerInstance(locale)));
|
|
|
+ putFormat("number", "c++", r -> new FNumber(r, getDecimalFormat(Locale.US, '.','\'')));
|
|
|
+ putFormat("number", "java", r -> new FNumber(r, getDecimalFormat(Locale.US, '.','_')));
|
|
|
+ putFormat("number", "currency", r -> new FNumber(r, getCurrencyFormat(locale)));
|
|
|
+ putFormat("number", "percent", r -> new FNumber(r, DecimalFormat.getPercentInstance(locale)));
|
|
|
+
|
|
|
+ putFormat("date", (r,p) -> new FDateTime(r, new SimpleDateFormat(p,locale)));
|
|
|
+ putFormat("date", "", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.DEFAULT,locale)));
|
|
|
+ putFormat("date", "short", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.SHORT,locale)));
|
|
|
+ putFormat("date", "medium", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.MEDIUM,locale)));
|
|
|
+ putFormat("date", "long", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.LONG,locale)));
|
|
|
+ putFormat("date", "full", r -> new FDateTime(r, DateFormat.getDateInstance(DateFormat.FULL,locale)));
|
|
|
+ putFormat("date", "iso", r -> new FDateTime8(r, "yyyy-MM-dd'T'HH:mmX"));
|
|
|
+ putFormat("date", "gnu", r -> new FDateTime(r, new SimpleDateFormat("yyyyMMddHHmm",Locale.ROOT)));
|
|
|
+ putFormat("date", "trace", r -> new FDateTime(r, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS",Locale.ROOT)));
|
|
|
+ putFormat("date", "local", r -> new FDateTime(r, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.ROOT)));
|
|
|
+
|
|
|
+ putFormat("time", (r,p) -> new FDateTime(r, new SimpleDateFormat(p,locale)));
|
|
|
+ putFormat("time", "", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.DEFAULT,locale)));
|
|
|
+ putFormat("time", "short", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.SHORT,locale)));
|
|
|
+ putFormat("time", "medium", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.MEDIUM,locale)));
|
|
|
+ putFormat("time", "long", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.LONG,locale)));
|
|
|
+ putFormat("time", "full", r -> new FDateTime(r, DateFormat.getTimeInstance(DateFormat.FULL,locale)));
|
|
|
+ putFormat("time", "iso", r -> new FDateTime8(r, "HH:mm:ssX"));
|
|
|
+ putFormat("time", "gnu", r -> new FDateTime(r, new SimpleDateFormat("HHmmss",Locale.ROOT)));
|
|
|
+ putFormat("time", "trace", r -> new FDateTime(r, new SimpleDateFormat("HH:mm:ss.SSS",Locale.ROOT)));
|
|
|
+ putFormat("time", "local", r -> new FDateTime(r, new SimpleDateFormat("HH:mm:ss",Locale.ROOT)));
|
|
|
+
|
|
|
+ putFormat("hex", "", r -> new FHexArray(r));
|
|
|
+ putFormat("hex", "array", r -> new FHexArray(r));
|
|
|
+ putFormat("hex", "stream", r -> new FHexStream(r));
|
|
|
+
|
|
|
+ putFormat("metric", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.MP));
|
|
|
+ putFormat("metric/si", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.MP));
|
|
|
+ putFormat("metric/e", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.ME));
|
|
|
+ putFormat("metric", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.MP));
|
|
|
+ putFormat("metric/si", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.MP));
|
|
|
+ putFormat("metric/e", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.ME));
|
|
|
+
|
|
|
+ putFormat("binary", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BP));
|
|
|
+ putFormat("binary/iec", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BP));
|
|
|
+ putFormat("binary/e", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BE));
|
|
|
+ putFormat("binary/knuth", (r,p) -> new FEngineer(r, new DecimalFormat(p,us), FormatNumber.BK));
|
|
|
+ putFormat("binary", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BP));
|
|
|
+ putFormat("binary/iec", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BP));
|
|
|
+ putFormat("binary/e", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BE));
|
|
|
+ putFormat("binary/knuth", "", r -> new FEngineer(r, DecimalFormat.getInstance(Locale.US), FormatNumber.BK));
|
|
|
+
|
|
|
+ putFormat("choice", (r,p) -> new FChoice(r, new ChoiceFormat(p)));
|
|
|
+ }
|
|
|
+
|
|
|
public static ResolveDialect getDefault() {
|
|
|
return Li.DEFAULT;
|
|
|
}
|
|
|
@@ -166,12 +167,11 @@ public final class ResolveDialect {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
- void put(String format, String pattern, Function<Resolver,ResolveFormat.Token> token) {
|
|
|
+ private void putFormat(String format, String pattern, Function<Resolver,ResolveFormat.Token> token) {
|
|
|
mDefined.put(new TokenKey(format, pattern), token);
|
|
|
}
|
|
|
|
|
|
- void put(String format, BiFunction<Resolver,String,ResolveFormat.Token> token) {
|
|
|
+ private void putFormat(String format, BiFunction<Resolver,String,ResolveFormat.Token> token) {
|
|
|
mPattern.put(format, token);
|
|
|
}
|
|
|
|
|
|
@@ -198,6 +198,16 @@ public final class ResolveDialect {
|
|
|
return nf;
|
|
|
}
|
|
|
|
|
|
+ private DecimalFormat getDecimalFormat(Locale locale, char dseparator, char gseparator) {
|
|
|
+ DecimalFormat fmt = (DecimalFormat)DecimalFormat.getInstance(locale);
|
|
|
+ DecimalFormatSymbols dfs = fmt.getDecimalFormatSymbols();
|
|
|
+ dfs.setDecimalSeparator(dseparator);
|
|
|
+ dfs.setGroupingSeparator(gseparator);
|
|
|
+ fmt.setGroupingUsed(true);
|
|
|
+ fmt.setDecimalFormatSymbols(dfs);
|
|
|
+ return fmt;
|
|
|
+ }
|
|
|
+
|
|
|
private static StrBuffer asHex(StrBuffer target, byte value) {
|
|
|
int ivalue = value & 0xFF;
|
|
|
target.append( HC_TABLE[ivalue >>> 4] );
|
|
|
@@ -268,6 +278,34 @@ public final class ResolveDialect {
|
|
|
this.format = nf;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ if(format instanceof DecimalFormat) {
|
|
|
+ DecimalFormatSymbols dfs = ((DecimalFormat)format).getDecimalFormatSymbols();
|
|
|
+ StrBuilder s = new StrBuilder();
|
|
|
+ s.append("(");
|
|
|
+ digits(s, dfs);
|
|
|
+ s.append("(?:")
|
|
|
+ .append(dfs.getExponentSeparator())
|
|
|
+ .append("|")
|
|
|
+ .append(dfs.getExponentSeparator().toLowerCase(Locale.ROOT))
|
|
|
+ .append(")?");
|
|
|
+ digits(s, dfs);
|
|
|
+ s.append(")");
|
|
|
+ return s.toString();
|
|
|
+ } else {
|
|
|
+ return "((?:0x)?[0-9.,'A-Fa-f]+)";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private StrBuilder digits(StrBuilder s, DecimalFormatSymbols dfs) {
|
|
|
+ s.append("[0-9");
|
|
|
+ s.append(dfs.getDecimalSeparator());
|
|
|
+ s.append(dfs.getGroupingSeparator());
|
|
|
+ s.append("]+");
|
|
|
+ return s;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
target.append(format.format(get(context)));
|
|
|
@@ -289,6 +327,11 @@ public final class ResolveDialect {
|
|
|
this.format = nf;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "(.+)";
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
target.append(format.format(get(context,Date.class)));
|
|
|
@@ -309,6 +352,11 @@ public final class ResolveDialect {
|
|
|
super(resolver);
|
|
|
this.format = DateTimeFormatter.ofPattern(pattern).withZone(ZoneOffset.UTC);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "(.+)";
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
@@ -332,6 +380,11 @@ public final class ResolveDialect {
|
|
|
super(resolver);
|
|
|
this.format = nf;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "(.+)";
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
@@ -350,6 +403,11 @@ public final class ResolveDialect {
|
|
|
public FHexArray(Resolver resolver) {
|
|
|
super(resolver);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "(\\[[0-9]+\\]\\{(?:0x[0-9]{2}?)?(?:,0x[0-9]{2})*\\})";
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
@@ -386,6 +444,11 @@ public final class ResolveDialect {
|
|
|
public FHexStream(Resolver resolver) {
|
|
|
super(resolver);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "((?:[0-9A-F]{2})?(?: [0-9A-F]{2})*)";
|
|
|
+ }
|
|
|
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
@@ -421,6 +484,11 @@ public final class ResolveDialect {
|
|
|
this.units = units;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "([0-9,]+(?:\\.[0-9,]+)?(?:" + StringUtils.join(MP, "|", b -> b.text()) + "))";
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
Object object = get(context);
|
|
|
@@ -509,6 +577,11 @@ public final class ResolveDialect {
|
|
|
this.resolver = resolver;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String regex() {
|
|
|
+ return "(.+)";
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void append(Appendable target, Object context) throws IOException {
|
|
|
target.append(String.valueOf(resolver.get(context)));
|