- Rebranded plugin from "ActionModelsGenerator" to "Dynamic Form Helper".
- Refactored package structure from "com.sdk.generators" to "com.sdk.dynform.tools".
- Added comprehensive I18n support for Java, XML, and JavaScript:
- Inlay hints and code folding for internationalization keys.
- Completion and reference contributors for "message.xml" keys.
- Configuration settings and UI for i18n tools.
- Introduced support for the ".frml" (DynForm) file type.
- Added specialized DynForm completion and path resolution helpers.
- Updated "build.gradle.kts" with JSP and JavaScript platform dependencies.
- Updated documentation and project metadata to reflect the new name.
275 lines
7.5 KiB
Java
Executable File
275 lines
7.5 KiB
Java
Executable File
package sdk.i18n;
|
|
|
|
import com.apps.Constants;
|
|
import com.apps.SystemFactory;
|
|
import jakarta.servlet.ServletContext;
|
|
import org.jdom2.Document;
|
|
import org.jdom2.Element;
|
|
import org.jdom2.input.SAXBuilder;
|
|
import sdk.config.ApiConfig;
|
|
import sdk.json.JSONObject;
|
|
import sdk.context.AppContext;
|
|
import sdk.utils.JUtils;
|
|
import sdk.utils.SDKLogger;
|
|
|
|
import java.io.InputStream;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.SortedSet;
|
|
import java.util.TreeSet;
|
|
|
|
public class Message {
|
|
private LinkedHashMap<String, LinkedHashMap<String, String>> msgMaps;
|
|
private SystemFactory system;
|
|
private LinkedHashMap<String, String> rescMessage;
|
|
private final SDKLogger logger;
|
|
|
|
public Message() {
|
|
rescMessage = new LinkedHashMap<>();
|
|
logger = new SDKLogger("i18N-Message");
|
|
}
|
|
|
|
public Message(SystemFactory factory) {
|
|
this.system = factory;
|
|
AppContext app = factory.getAppInstance();
|
|
logger = new SDKLogger("i18N-Message");
|
|
|
|
msgMaps = (LinkedHashMap<String, LinkedHashMap<String, String>>) app.getAttribute(Constants._APP_MESSAGE);
|
|
|
|
if (msgMaps != null) {
|
|
for (String key : msgMaps.keySet()) {
|
|
if (msgMaps.get(key) == null) {
|
|
msgMaps = null;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (msgMaps == null || msgMaps.isEmpty() || msgMaps.containsValue(null)) {
|
|
msgMaps = new LinkedHashMap<>();
|
|
ApiConfig msgAPI = factory.getApi("i18n");
|
|
for (ApiConfig.ApiParameter param : msgAPI.getParameters().values()) {
|
|
String rescFile = param.getValue();
|
|
if (!"".equals(rescFile)) {
|
|
LinkedHashMap<String, String> rescMsg = readResource(rescFile);
|
|
String lang = param.getName().toUpperCase();
|
|
msgMaps.put(lang, rescMsg);
|
|
}
|
|
}
|
|
app.setAttribute(Constants._APP_MESSAGE, msgMaps);
|
|
}
|
|
|
|
String lang = factory.getLanguage("TH");
|
|
rescMessage = msgMaps.get(lang.toUpperCase());
|
|
|
|
if (rescMessage == null) {
|
|
rescMessage = msgMaps.get("TH");
|
|
}
|
|
}
|
|
|
|
public LinkedHashMap<String,String> getLang(String lang) {
|
|
return msgMaps.get(lang.toUpperCase());
|
|
}
|
|
|
|
public String parseExp(String inStr) {
|
|
String result = inStr;
|
|
|
|
// String[] ssnToken = JUtils.getRegxToken(inStr, "@\\{[\\s\\S]+?\\}");
|
|
// int idxFactor = 2;
|
|
// if (ssnToken.length > 0) {
|
|
// DTO_SYSTEM_CONFIG sysData= system.getSysData();
|
|
// for (String token : ssnToken) {
|
|
// String ssnKey = token.substring(0, token.length() - 1).substring(idxFactor).trim();
|
|
// String ssnValue = sysData.getValue(ssnKey, "");
|
|
// if (!ssnValue.isBlank()) {
|
|
// result = result.replace(token, ssnValue);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
String[] ssnToken = JUtils.getRegxToken(result, "@[M]\\{[\\s\\S]+?\\}");
|
|
int idxFactor = 3;
|
|
|
|
for (String token : ssnToken) {
|
|
String msgKey = token.substring(0, token.length() - 1).substring(idxFactor).trim();
|
|
result = result.replace(token, this.get(msgKey));
|
|
}
|
|
return result.replaceAll("\\|\\|","");
|
|
}
|
|
|
|
private LinkedHashMap<String, String> readResource(String fileName) {
|
|
LinkedHashMap<String, String> result = new LinkedHashMap<>();
|
|
SAXBuilder formBuilder = new SAXBuilder();
|
|
formBuilder.setFeature("http://xml.org/sax/features/validation", false);
|
|
formBuilder.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
|
|
formBuilder.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
|
|
|
ServletContext context = system.getAppContext();
|
|
InputStream rescFile = context.getResourceAsStream(fileName);
|
|
|
|
try {
|
|
Document rescDoc = formBuilder.build(rescFile);
|
|
Element rescRoot = rescDoc.getRootElement();
|
|
List<Element> msgList = rescRoot.getChildren("entry");
|
|
for (Element elMsg : msgList) {
|
|
String key = elMsg.getAttributeValue("key", "");
|
|
String value = elMsg.getTextTrim();
|
|
if (!"".equals(key)) {
|
|
value = parseExp(value);
|
|
result.put(key.toLowerCase(), value);
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
result = null;
|
|
logger.error(ex);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public String get(String key, String locale) {
|
|
if (key.startsWith("#")) {
|
|
return key.substring(1);
|
|
}
|
|
|
|
LinkedHashMap<String,String> message = null;
|
|
if (locale != null) {
|
|
message = getLang(locale.toUpperCase());
|
|
}
|
|
if (message == null) {
|
|
message = rescMessage;
|
|
}
|
|
if (!message.isEmpty()) {
|
|
boolean useDot = false;
|
|
String msgKey = key.replaceAll("-", "_").toLowerCase();
|
|
String[] keys = msgKey.split(" ");
|
|
if (keys.length == 1) {
|
|
keys = msgKey.split("\\+");
|
|
useDot = keys.length > 1;
|
|
}
|
|
String result;
|
|
if (keys.length > 1) {
|
|
result = msgKey;
|
|
int seq = 0;
|
|
for (String id : keys) {
|
|
if (id.isBlank()) continue;
|
|
String value = message.get(id);
|
|
if (value != null) {
|
|
result = result.replace((seq > 0 && useDot) ? "+" + id : id, value);
|
|
} else {
|
|
value = this.get(id,locale);
|
|
result = result.replace(id, value);
|
|
}
|
|
seq++;
|
|
}
|
|
} else {
|
|
result = message.get(msgKey.toLowerCase());
|
|
if (result == null) {
|
|
result = JUtils.beautify(msgKey.replace("_", " "));
|
|
}
|
|
}
|
|
return result;
|
|
} else {
|
|
return key;
|
|
}
|
|
}
|
|
|
|
public String get(String key) {
|
|
if (key.startsWith("#")||key.startsWith("=")) {
|
|
return key.substring(1);
|
|
}
|
|
|
|
if (!rescMessage.isEmpty()) {
|
|
boolean useDot = false;
|
|
String msgKey = key.toLowerCase();
|
|
String[] keys = key.split(" ");
|
|
if (keys.length == 1) {
|
|
keys = msgKey.split("\\+");
|
|
useDot = keys.length > 1;
|
|
}
|
|
|
|
if (keys.length == 1) {
|
|
keys = msgKey.split("\\|\\|");
|
|
}
|
|
|
|
String result;
|
|
if (keys.length > 1) {
|
|
result = msgKey;
|
|
int seq = 0;
|
|
for (String id : keys) {
|
|
String value;
|
|
String idKey = id;
|
|
|
|
if (id.isBlank()) continue;
|
|
|
|
id = id.replaceAll("-", "_").toLowerCase();
|
|
|
|
if (idKey.startsWith("#")) {
|
|
result = result.replace(id, idKey.substring(1));
|
|
} else {
|
|
if (!id.equals("-")) {
|
|
value = rescMessage.get(id);
|
|
} else {
|
|
value = "-";
|
|
}
|
|
|
|
if (value != null) {
|
|
result = result.replace((seq > 0 && useDot) ? "+" + id : id, value);
|
|
} else {
|
|
value = this.get(id);
|
|
result = result.replace((seq > 0 && useDot) ? "+" + id : id, value);
|
|
result = result.replace(id, value);
|
|
}
|
|
}
|
|
seq ++;
|
|
}
|
|
} else {
|
|
msgKey = key.replaceAll("-","_").toLowerCase();
|
|
result = rescMessage.get(msgKey.toLowerCase());
|
|
if (result == null) {
|
|
if (!msgKey.contains(".")) {
|
|
result = rescMessage.get("sys."+msgKey.toLowerCase());
|
|
} else {
|
|
result = msgKey.substring(msgKey.indexOf(".")+1);
|
|
if (result.isBlank()) {
|
|
result = msgKey;
|
|
}
|
|
result = JUtils.beautify(result.replace("_", " "));
|
|
}
|
|
result = (result == null) ? JUtils.beautify(msgKey.replace("_", " ")) : result;
|
|
}
|
|
}
|
|
return result.replaceAll("\\|\\|","");
|
|
} else {
|
|
return key;
|
|
}
|
|
}
|
|
|
|
public String buildJson(String lang) {
|
|
LinkedHashMap<String, String> langMsg = msgMaps.get(lang.toUpperCase());
|
|
if (langMsg == null) {
|
|
msgMaps.get("TH");
|
|
}
|
|
JSONObject jsResult = new JSONObject();
|
|
SortedSet<String> keys = new TreeSet<>(langMsg.keySet());
|
|
for (String key : keys) {
|
|
String value = langMsg.get(key);
|
|
jsResult.put(key,value);
|
|
}
|
|
return jsResult.toString();
|
|
}
|
|
|
|
public String buildObject(String lang) {
|
|
LinkedHashMap<String, String> langMsg = msgMaps.get(lang.toUpperCase());
|
|
if (langMsg == null) {
|
|
langMsg = msgMaps.get("TH");
|
|
}
|
|
if (langMsg == null) {
|
|
langMsg = msgMaps.firstEntry().getValue();
|
|
}
|
|
|
|
JSONObject jsResult = new JSONObject();
|
|
langMsg.forEach(jsResult::put);
|
|
return jsResult.toString(4);
|
|
}
|
|
}
|