refactor: rebrand to DynamicFormTools and add i18n support
- 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.
This commit is contained in:
274
DevResources/Message.java
Executable file
274
DevResources/Message.java
Executable file
@@ -0,0 +1,274 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user