gdxapp4d/gdxapp4d-lib-bassboonyd/src/main/java/ᒢᐩᐩ/ᔆʸᔆᐪᓫᔿ/ᒃᣔᒃᓫᒻ/BabelLocalizer.java

177 lines
9.8 KiB
Java
Raw Normal View History

2022-11-05 13:41:48 +01:00
package ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ;
2022-10-30 08:26:14 +01:00
2022-10-30 16:59:24 +01:00
import java.lang.reflect.Method;
2022-10-30 08:26:14 +01:00
import java.util.Locale;
2022-10-30 09:53:44 +01:00
import java.util.Optional;
2022-10-30 08:26:14 +01:00
2022-11-05 13:31:16 +01:00
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.Bãß;
2022-10-31 04:39:32 +01:00
import ᒢᐩᐩ.ᒃᣔᔆᔆᒃᐤᐤᣕ.DefaultBȍőnLoader;
2022-11-05 13:31:16 +01:00
import ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ObjectScopeLimitΔ;
2022-11-05 13:41:48 +01:00
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocAuthor注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocMethod注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocThrows注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocType注;
import ᒢᐩᐩ.ᔆʸᔆᐪᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsFlüstern注;
2022-10-30 08:26:14 +01:00
2022-10-30 16:59:24 +01:00
@DuytsDocAuthor注(name = "للَّٰهِilLצسُو", copyright = "©Δ∞ 仙上主天")
2022-11-05 13:31:16 +01:00
@DuytsDocType注(sea = {BabelLocalizer.ẞDuyts.ẞDocTypeᴬᵖᶦ.ₐₜType班.class})
public interface BabelLocalizer {
2022-10-30 08:26:14 +01:00
2022-11-05 13:31:16 +01:00
enum Ꝑŕḯṿª implements ObjectScopeLimitΔ.ƉěꬵḭȵᶒModifier.Ꝑŕḯṿª {
;
private static final Locale FALLBACK_I18N_LOCALE = Locale.ENGLISH; // Kill the default jvm locale, humans and stupid bugs
@BabelStringTower注(babel = { @BabelString注(iso= "en", txt = "Missing required annotation @BabelLocalizer注 on interface: ") })
private interface ₜₓₜMissing注Localizer extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ {}
@BabelStringTower注(babel = { @BabelString注(iso= "en", txt = "Missing annotation @DuytsDocMethod注 on: %s") })
private interface ₜₓₜMissing注DuytsDocMethod extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ {}
@BabelStringTower注(babel = { @BabelString注(iso= "en", txt = "Missing exception id: %s in @DuytsDocMethod注 on: %s") })
private interface ₜₓₜNoDuytsDocIdFound extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ {}
@BabelStringTower注(babel = { @BabelString注(iso= "en", txt = "Can't search babel message with null selector") })
private interface ₜₓₜNullExceptionId extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ {}
//@BabelStringTower注(babel = { @BabelString注(iso= "en", txt = "No searchable stack frame returned") })
//private interface ₜₓₜNoStackFrame extends Babelizeբ.ẞStringᵗˣᵗ {}
}
enum Ꝑŕᱜṫèƈ implements ObjectScopeLimitΔ.ƉěꬵḭȵᶒModifier.Ꝑŕᱜṫèƈ {
;
protected static final String FALLBACK_I18N_CODE = "en"; //todo; move < and \/ to Jlocale interface
}
enum ẞDuyts implements Babelizeբ.ẞType.ẞDuytsᴬᵖᶦ {
;
enum ẞDocTypeᴬᵖᶦ implements Babelizeբ.ẞDuyts.ẞDocTypeᴬᵖᶦ {
;
@DuytsFlüstern注(
code = @BabelStringTower注(babel = {
@BabelString注(iso= "zh", txt = "通天塔龸定位器"),
@BabelString注(iso= "hi", txt = "कोलाहलꣻलोकलाइज़र")
}),
purpose = @BabelStringTower注(babel = {
@BabelString注(iso= "en", txt = "Base package interface from which a local language extends"),
@BabelString注(iso= "zh", txt = "本地語言擴展的基礎包接口"),
@BabelString注(iso= "hi", txt = "बेस पैकेज इंटरफ़ेस जिससे एक स्थानीय भाषा का विस्तार होता है")
})
)
public interface ₐₜType班 extends Babelizeբ.ẞDoc.ẞDuytsType班ᵃᵗ {}
}
enum ẞDocMethodᴬᵖᶦ implements Babelizeբ.ẞDuyts.ẞDocMethodᴬᵖᶦ {
;
@DuytsFlüstern注(
code = @BabelStringTower注(babel = {
@BabelString注(iso= "zh", txt = "至龸通天塔龸定位器龸界面"),
@BabelString注(iso= "hi", txt = "बेबेलꣻलोकलाइज़रꣻकेꣻलिएꣻएपीआई")
}),
purpose = @BabelStringTower注(babel = {
@BabelString注(iso= "en", txt = "Retrieves the locale information"),
@BabelString注(iso= "zh", txt = "检索语言环境信息"),
@BabelString注(iso= "hi", txt = "स्थानीय जानकारी प्राप्त करता है")
})
)
protected interface ₐₜToBabelLocalizerApi例 extends Babelizeբ.ẞDoc.ẞDuytsMethod例ᵃᵗ {}
@DuytsFlüstern注(
code = @BabelStringTower注(babel = {
@BabelString注(iso= "zh", txt = "到塔異常消息"),
@BabelString注(iso= "hi", txt = "टावरꣻकरनेꣻकेꣻलिएꣻअपवादꣻसंदेश")
}),
purpose = @BabelStringTower注(babel = {
@BabelString注(iso= "en", txt = "Finds the locale text for an exception"),
@BabelString注(iso= "zh", txt = "查找異常的語言環境文本"),
@BabelString注(iso= "hi", txt = "अपवाद के लिए स्थानीय पाठ ढूँढता है")
2022-10-31 00:32:01 +01:00
})
2022-11-05 13:31:16 +01:00
)
protected interface ₐₜToBabelExceptionMessage例 extends Babelizeբ.ẞDoc.ẞDuytsMethod例ᵃᵗ {}
}
enum ẞDocExceptionᴬᵖᶦ implements Babelizeբ.ẞDuyts.ẞDocExceptionᴬᵖᶦ {
;
@BabelStringTower注(babel = {
@BabelString注(iso= "en", txt = "Gets thrown in case the @BabelLocalizer注 annotation is not found on this interface"),
@BabelString注(iso= "zh", txt = "在此接口上找不到 @BabelLocalizer 註解時拋出"),
@BabelString注(iso= "hi", txt = "इस इंटरफ़ेस पर @BabelLocalizer注 एनोटेशन नहीं मिलने की स्थिति में फेंक दिया जाता है"),
2022-10-30 16:59:24 +01:00
})
2022-11-05 13:31:16 +01:00
private interface ₜₓₜToBabelLocalizerApiMissingLocalizer蹉 extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ {}
@DuytsDocThrows注(type = RuntimeException.class, code = Ꝑŕḯṿª.ₜₓₜMissing注Localizer.class, reason = ₜₓₜToBabelLocalizerApiMissingLocalizer蹉.class)
protected interface ₐₜToBabelLocalizerApiMissingLocalizer蹉 extends Babelizeբ.ẞDoc.ẞDuytsException蹉ᵃᵗ {}
}
}
@DuytsDocMethod注(sea = {ẞDuyts.ẞDocMethodᴬᵖᶦ.ₐₜToBabelLocalizerApi例.class}, exceptions = {ẞDuyts.ẞDocExceptionᴬᵖᶦ.ₐₜToBabelLocalizerApiMissingLocalizer蹉.class })
2022-10-30 08:26:14 +01:00
default BabelLocalizerᴬᵖᶦ toBabelLocalizerᴬᵖᶦ() {
2022-10-30 16:59:24 +01:00
Optional<Class<?>> loc = DefaultBȍőnLoader.findInterfaceByAnnotation(getClass(), BabelLocalizer注.class);
2022-10-30 09:53:44 +01:00
if (loc.isEmpty()) {
2022-11-05 13:31:16 +01:00
throw new RuntimeException(toBabelExceptionMessage(Ꝑŕḯṿª.ₜₓₜMissing注Localizer.class, (String) null, this));
2022-10-30 09:53:44 +01:00
}
2022-10-30 16:59:24 +01:00
BabelLocalizer注 anno = loc.get().getAnnotation(BabelLocalizer注.class);
2022-10-31 00:32:01 +01:00
return BabelLocalizerᴬᵖᶦ.Ꝑŕᱜṫèƈ.instanceᴺᵉʷ(anno.name(), new Locale(anno.locale()), anno.target());
2022-10-30 08:26:14 +01:00
}
2022-11-05 13:31:16 +01:00
@DuytsDocMethod注(sea = {ẞDuyts.ẞDocMethodᴬᵖᶦ.ₐₜToBabelExceptionMessage例.class},
exceptions = {
ẞDuyts.ẞDocExceptionᴬᵖᶦ.ₐₜToBabelLocalizerApiMissingLocalizer蹉.class
})
public static String toBabelExceptionMessage(Class<? extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ> exceptionId, BabelLocalizer loc, Object...msgArgs) {
2022-10-30 16:59:24 +01:00
BabelLocalizerᴬᵖᶦ api = loc.toBabelLocalizerᴬᵖᶦ();
2022-11-05 13:31:16 +01:00
return toBabelExceptionMessage(Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE, exceptionId, api.getLocale().getLanguage(), msgArgs);
}
@DuytsDocMethod注(sea = {ẞDuyts.ẞDocMethodᴬᵖᶦ.ₐₜToBabelExceptionMessage例.class},
exceptions = {
ẞDuyts.ẞDocExceptionᴬᵖᶦ.ₐₜToBabelLocalizerApiMissingLocalizer蹉.class
})
public static String toBabelExceptionMessage(Class<? extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ> exceptionId, String localeId, Object...msgArgs) {
return toBabelExceptionMessage(Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE, exceptionId, localeId, msgArgs);
2022-10-30 08:26:14 +01:00
}
2022-11-05 13:31:16 +01:00
private static String toBabelExceptionMessage(int stackDepth, Class<? extends Babelizeբ.ẞType.ẞTextᴬᵖᶦ> exceptionId, String localeId, Object...msgArgs) {
if (exceptionId == null) {
throw new NullPointerException(toBabelExceptionMessage(stackDepth+Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE, Ꝑŕḯṿª.ₜₓₜNullExceptionId.class, localeId));
}
String putinLocaleId = localeId; // The put in locale id
if (putinLocaleId == null) {
putinLocaleId = Ꝑŕḯṿª.FALLBACK_I18N_LOCALE.getLanguage();
}
2022-10-30 16:59:24 +01:00
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
2022-11-05 13:31:16 +01:00
StackWalker.StackFrame frame = walker.walk(stream1 -> stream1.skip(stackDepth).findFirst().orElse(null));
2022-10-30 16:59:24 +01:00
if (frame == null) {
2022-11-05 13:31:16 +01:00
throw new RuntimeException(); // lets not call ourself here
2022-10-30 16:59:24 +01:00
}
Class<?> callerClass = frame.getDeclaringClass();
Method callerMethod = null;
try {
callerMethod = callerClass.getMethod(frame.getMethodName(), frame.getMethodType().parameterArray());
} catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
DuytsDocMethod注 anno = callerMethod.getAnnotation(DuytsDocMethod注.class);
if (anno == null) {
2022-11-05 13:31:16 +01:00
throw new RuntimeException(toBabelExceptionMessage(stackDepth+Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE, Ꝑŕḯṿª.ₜₓₜMissing注DuytsDocMethod.class, putinLocaleId, callerMethod));
2022-10-30 16:59:24 +01:00
}
2022-11-05 13:31:16 +01:00
for (Class<? extends Babelizeբ.ẞDoc.ẞDuytsException蹉ᵃᵗ> exceptionDoc:anno.exceptions()) {
DuytsDocThrows注 error = exceptionDoc.getAnnotation(DuytsDocThrows注.class);
if (error == null) {
throw new RuntimeException("doc me");
}
if (!error.code().equals(exceptionId)) {
continue;
}
BabelStringTower注 errorMessages = error.code().getAnnotation(BabelStringTower注.class);
if (errorMessages == null) {
throw new RuntimeException("doc me");
}
for (BabelString注 duyts:errorMessages.babel()) {
if (duyts.iso().equals(putinLocaleId)) {
return String.format(duyts.txt(), msgArgs);
2022-10-30 16:59:24 +01:00
}
}
}
2022-11-05 13:31:16 +01:00
throw new RuntimeException(toBabelExceptionMessage(stackDepth+Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE, Ꝑŕḯṿª.ₜₓₜNoDuytsDocIdFound.class, putinLocaleId, exceptionId, callerMethod));
2022-10-30 08:26:14 +01:00
}
}