PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src_configDesign/org/hxzon/configdesigner/core/CfgParser.java

https://gitlab.com/BGCX261/zk-full-demo-git
Java | 354 lines | 323 code | 23 blank | 8 comment | 122 complexity | b5bec3c7ed50b7e5398bea93344d50dc MD5 | raw file
  1. package org.hxzon.configdesigner.core;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.concurrent.atomic.AtomicInteger;
  7. import org.dom4j.Element;
  8. import org.hxzon.util.Dom4jUtil;
  9. import org.hxzon.util.Dt;
  10. import com.alibaba.fastjson.JSONArray;
  11. import com.alibaba.fastjson.JSONObject;
  12. public class CfgParser {
  13. public static final Object Null = null;//JSONObject.NULL;//有定义,值为null
  14. public static final Object Undefined = null;//未定义
  15. private static Map<String, CfgInfo> typeInfos = new HashMap<String, CfgInfo>();
  16. private static Map<String, CfgInfo> entityTypeInfos = new HashMap<String, CfgInfo>();
  17. private static Map<String, AtomicInteger> entityIdSeqs = new HashMap<String, AtomicInteger>();
  18. public static CfgInfo parseSchema(String xmlStr) {
  19. Element root = Dom4jUtil.getRoot(xmlStr);
  20. return toCfgInfo_root(root);
  21. }
  22. private static CfgInfo toCfgInfo_root(Element e) {
  23. CfgInfo cfgInfo = new CfgInfo();
  24. String id = Dom4jUtil.getText(e, "@id");
  25. if (id == null) {
  26. id = e.getName();
  27. }
  28. cfgInfo.setId(id);
  29. cfgInfo.setLabel(Dom4jUtil.getText(e, "@label"));
  30. //
  31. cfgInfo.setType(CfgType.Struct);
  32. fillPartsInfo(cfgInfo, e);
  33. return cfgInfo;
  34. }
  35. private static CfgInfo toCfgInfo(Element e) {
  36. CfgInfo cfgInfo = new CfgInfo();
  37. String typeDef = Dom4jUtil.getText(e, "@typeDef");
  38. if (typeDef != null) {//类型定义
  39. if (!typeDef.isEmpty()) {
  40. cfgInfo.setId(typeDef);
  41. } else {
  42. cfgInfo.setId(e.getName());
  43. }
  44. typeInfos.put(cfgInfo.getId(), cfgInfo);
  45. } else {//非类型定义
  46. String id = Dom4jUtil.getText(e, "@id");
  47. if (id == null || id.isEmpty()) {
  48. id = e.getName();
  49. }
  50. cfgInfo.setId(id);
  51. }
  52. cfgInfo.setLabel(Dom4jUtil.getText(e, "@label"));
  53. String typeStr = Dom4jUtil.getText(e, "@type");
  54. CfgInfo typeRef = typeInfos.get(typeStr);
  55. if (typeRef != null) {
  56. cfgInfo.setTypeRef(typeRef);
  57. cfgInfo.setType(typeRef.getType());
  58. } else {
  59. CfgType type = CfgType.parseCfgType(typeStr);
  60. if (type == null) {
  61. type = CfgType.Struct;
  62. }
  63. cfgInfo.setType(type);
  64. if (type.isStruct()) {
  65. fillPartsInfo(cfgInfo, e);
  66. }
  67. if (type.isElementContainer()) {
  68. cfgInfo.setElementInfo(toCfgInfo(Dom4jUtil.getElement(e)));
  69. }
  70. }
  71. CfgType type = cfgInfo.getType();
  72. if (type.isSimple()) {
  73. cfgInfo.setDefaultValue(converValue(type, Dom4jUtil.getText(e, "@value")));
  74. String limit = Dom4jUtil.getText(e, "@limit");
  75. if (limit != null) {
  76. cfgInfo.setValidator(new CfgValueValidator(cfgInfo.getType(), limit));
  77. }
  78. }
  79. if (type == CfgType.Struct) {
  80. //vst不能直接作为元素的类型,所以不需要 labelKey
  81. cfgInfo.setLabelKey(Dom4jUtil.getText(e, "@labelKey"));
  82. cfgInfo.setKeyKey(Dom4jUtil.getText(e, "@keyKey"));
  83. }
  84. if (type == CfgType.String) {
  85. cfgInfo.setTextArea(tristateValue(e, "@textarea"));
  86. }
  87. cfgInfo.setEmbed(tristateValue(e, "@embed"));
  88. cfgInfo.setOptional(tristateValue(e, "@optional"));
  89. //
  90. if (typeDef != null) {
  91. return null;//not part
  92. }
  93. //实体定义
  94. String idPrefix = Dom4jUtil.getText(e, "@idPrefix");
  95. if (idPrefix != null) {
  96. cfgInfo.setIdPrefix(idPrefix);
  97. entityTypeInfos.put(cfgInfo.getId(), cfgInfo);
  98. entityIdSeqs.put(idPrefix, new AtomicInteger(0));
  99. //实体不能作为类型,否则导致实体在别处定义?
  100. CfgInfo listMapInfo = new CfgInfo();
  101. listMapInfo.setType(CfgType.ListMap);
  102. listMapInfo.setElementInfo(cfgInfo);
  103. listMapInfo.setId(cfgInfo.getId());
  104. listMapInfo.setLabel(cfgInfo.getLabel());
  105. return listMapInfo;
  106. }
  107. return cfgInfo;
  108. }
  109. private static String tristateValue(Element e, String path) {
  110. String value = Dom4jUtil.getText(e, path);
  111. if (value == null) {
  112. return null;
  113. }
  114. return CfgInfo.True.equals(value) ? CfgInfo.True : CfgInfo.False;
  115. }
  116. private static void fillPartsInfo(CfgInfo cfgInfo, Element e) {
  117. List<CfgInfo> partsInfo = new ArrayList<CfgInfo>();
  118. List<Element> childrenEle = Dom4jUtil.getElements(e);
  119. for (Element childEle : childrenEle) {
  120. CfgInfo partInfo = toCfgInfo(childEle);
  121. if (partInfo != null) {
  122. partsInfo.add(partInfo);
  123. }
  124. }
  125. cfgInfo.setPartsInfo(partsInfo);
  126. }
  127. public static Object converValue(CfgType type, String strValue) {
  128. if (type == CfgType.Boolean) {
  129. return "true".equals(strValue);
  130. }
  131. if (type == CfgType.Integer) {
  132. return strValue == null ? 0 : Integer.valueOf(strValue);
  133. }
  134. if (type == CfgType.Real) {
  135. return strValue == null ? 0.0 : Double.valueOf(strValue);
  136. }
  137. if (type == CfgType.String) {
  138. return strValue;
  139. }
  140. return Undefined;
  141. }
  142. //==============
  143. public static CfgValue buildCfgValue(CfgInfo cfgInfo, Object json, //
  144. int notNullValueDeep, int nullValueDeep) {
  145. if (cfgInfo.isOptional() && notNullValueDeep <= 0) {
  146. return null;
  147. }
  148. if (cfgInfo.isOptional() && json == null && nullValueDeep <= 0) {
  149. return null;
  150. }
  151. CfgType type = cfgInfo.getType();
  152. if (type.isSimple()) {
  153. return buildSimpleCfgValue(cfgInfo, json, notNullValueDeep, nullValueDeep);
  154. }
  155. if (type == CfgType.List) {
  156. return buildListCfgValue(cfgInfo, json, notNullValueDeep, nullValueDeep);
  157. }
  158. if (type == CfgType.ListMap) {
  159. return buildListMapCfgValue(cfgInfo, json, notNullValueDeep, nullValueDeep);
  160. }
  161. if (type == CfgType.Map) {
  162. return buildMapCfgValue(cfgInfo, json, notNullValueDeep, nullValueDeep);
  163. }
  164. if (type.isStruct()) {
  165. return buildStructCfgValue(cfgInfo, json, notNullValueDeep, nullValueDeep);
  166. }
  167. throw new RuntimeException("type error");
  168. }
  169. private static CfgValue buildSimpleCfgValue(CfgInfo cfgInfo, Object json, //
  170. int notNullValueDeep, int nullValueDeep) {
  171. CfgValue cfgValue = new CfgValue(cfgInfo);
  172. cfgValue.setValue(json != null ? json : cfgInfo.getDefaultValue());
  173. return cfgValue;
  174. }
  175. private static CfgValue buildStructCfgValue(CfgInfo mapCfgInfo, Object mapJson, //
  176. int notNullValueDeep, int nullValueDeep) {
  177. CfgValue cfgValue = new CfgValue(mapCfgInfo);
  178. for (CfgInfo partInfo : mapCfgInfo.getPartsInfo()) {
  179. Object partJson = null;
  180. if (partInfo.getType() == CfgType.ViewStruct) {
  181. partJson = mapJson;
  182. } else if (mapJson != null && mapJson instanceof JSONObject) {
  183. JSONObject jsonObj = (JSONObject) mapJson;
  184. partJson = jsonObj.get(partInfo.getId());
  185. }
  186. CfgValue part = buildCfgValue(partInfo, partJson, notNullValueDeep - 1, nullValueDeep - 1);
  187. if (part != null) {
  188. cfgValue.addValue(part);//add part
  189. }
  190. }
  191. return cfgValue;
  192. }
  193. private static CfgValue buildListCfgValue(CfgInfo listCfgInfo, Object listJson, //
  194. int notNullValueDeep, int nullValueDeep) {
  195. CfgValue listCfgValue = new CfgValue(listCfgInfo);
  196. CfgInfo eCfgInfo = listCfgInfo.getElementInfo();
  197. if (listJson != null && listJson instanceof JSONArray) {
  198. JSONArray jsonArray = (JSONArray) listJson;
  199. for (Object eleJson : jsonArray) {
  200. CfgValue e = buildCfgValue(eCfgInfo, eleJson, notNullValueDeep - 1, nullValueDeep - 1);
  201. listCfgValue.addValue(e);//add element
  202. }
  203. }
  204. return listCfgValue;
  205. }
  206. private static CfgValue buildMapCfgValue(CfgInfo mapsCfgInfo, Object mapsJson, //
  207. int notNullValueDeep, int nullValueDeep) {
  208. CfgValue mapsCfgValue = new CfgValue(mapsCfgInfo);
  209. CfgInfo eCfgInfo = mapsCfgInfo.getElementInfo();
  210. if (mapsJson != null && mapsJson instanceof JSONObject) {
  211. JSONObject jsonObj = (JSONObject) mapsJson;
  212. for (String key : jsonObj.keySet()) {
  213. CfgValue e = buildCfgValue(eCfgInfo, jsonObj.get(key), notNullValueDeep - 1, nullValueDeep - 1);
  214. e.setKey(key);
  215. mapsCfgValue.addValue(e);//add element
  216. }
  217. }
  218. return mapsCfgValue;
  219. }
  220. private static CfgValue buildListMapCfgValue(CfgInfo listMapsCfgInfo, Object mapsJson, //
  221. int notNullValueDeep, int nullValueDeep) {
  222. CfgValue listMapsCfgValue = new CfgValue(listMapsCfgInfo);
  223. CfgInfo eCfgInfo = listMapsCfgInfo.getElementInfo();
  224. if (mapsJson != null && mapsJson instanceof JSONObject) {
  225. JSONObject jsonObj = (JSONObject) mapsJson;
  226. for (String key : jsonObj.keySet()) {
  227. CfgValue e = buildCfgValue(eCfgInfo, jsonObj.get(key), notNullValueDeep - 1, nullValueDeep - 1);
  228. //e.setKey(key);//not use
  229. listMapsCfgValue.addValue(e);//add element
  230. }
  231. }
  232. return listMapsCfgValue;
  233. }
  234. public static CfgValue buildListElementCfgValue(CfgValue parent, int deep) {
  235. if (deep <= 0) {
  236. return null;
  237. }
  238. CfgInfo listCfgInfo = parent.getCfgInfo();
  239. if (listCfgInfo.getType().isElementContainer()) {
  240. CfgInfo eCfgInfo = listCfgInfo.getElementInfo();
  241. CfgValue r = buildCfgValue(eCfgInfo, null, 1, deep);
  242. r.setParent(parent);
  243. return r;
  244. }
  245. throw new RuntimeException("type error");
  246. }
  247. public static Object toJson(CfgValue root, boolean trim) {
  248. CfgInfo cfgInfo = root.getCfgInfo();
  249. CfgType type = cfgInfo.getType();
  250. if (type == CfgType.Boolean) {
  251. boolean rb = Dt.toBoolean(root.getValue(), false);
  252. return (trim && !rb) ? Undefined : rb;
  253. }
  254. if (type == CfgType.Integer) {
  255. long rl = Dt.toLong(root.getValue(), 0);
  256. return (trim && rl == 0) ? Undefined : rl;
  257. }
  258. if (type == CfgType.Real) {
  259. double rr = Dt.toDouble(root.getValue(), 0);
  260. return (trim && rr == 0) ? Undefined : rr;
  261. }
  262. if (type == CfgType.String) {
  263. String rs = Dt.toString(root.getValue(), "");
  264. return (trim && rs.isEmpty()) ? Undefined : rs;//new MyString(rs);
  265. }
  266. if (type.isStruct()) {
  267. JSONObject json = new JSONObject();
  268. for (CfgValue e : root.getValues()) {
  269. Object re = toJson(e, trim);
  270. if (!trim || re != Undefined) {
  271. if (e.getCfgInfo().getType() == CfgType.ViewStruct) {
  272. JSONObject jsonRe = (JSONObject) re;
  273. for (String key : jsonRe.keySet()) {
  274. json.put(key, jsonRe.get(key));
  275. }
  276. } else {
  277. json.put(e.getCfgInfo().getId(), re);
  278. }
  279. }
  280. }
  281. return (trim && json.isEmpty()) ? Undefined : json;
  282. }
  283. if (type == CfgType.List) {
  284. JSONArray jsonA = new JSONArray();
  285. for (CfgValue e : root.getValues()) {
  286. jsonA.add(toJson(e, trim));
  287. }
  288. return (trim && jsonA.isEmpty()) ? Undefined : jsonA;
  289. }
  290. if (type == CfgType.Map) {
  291. JSONObject json = new JSONObject();
  292. for (CfgValue e : root.getValues()) {
  293. json.put(e.getKey(), toJson(e, trim));
  294. }
  295. return (trim && json.isEmpty()) ? Undefined : json;
  296. }
  297. if (type == CfgType.ListMap) {
  298. JSONObject json = new JSONObject();
  299. for (CfgValue e : root.getValues()) {
  300. CfgValue keyValue = e.findCfgValue(cfgInfo.getElementInfo().getKeyKey());
  301. Object key = (keyValue == null) ? null : keyValue.getValue();
  302. json.put(Dt.toString(key, "error"), toJson(e, trim));
  303. }
  304. return (trim && json.isEmpty()) ? Undefined : json;
  305. }
  306. return Undefined;
  307. }
  308. public static CfgValue copy(CfgValue origCfgValue) {
  309. CfgInfo cfgInfo = origCfgValue.getCfgInfo();
  310. CfgValue r = new CfgValue(cfgInfo);
  311. if (cfgInfo.getType().isCombo()) {
  312. for (CfgValue childCfgValue : origCfgValue.getValues()) {
  313. r.addValue(copy(childCfgValue));
  314. }
  315. } else {
  316. r.setValue(origCfgValue.getValue());
  317. }
  318. if (origCfgValue.isMapElement()) {
  319. r.setKey(origCfgValue.getKey());
  320. }
  321. r.setParent(origCfgValue.getParent());
  322. return r;
  323. }
  324. //===========
  325. public static CfgInfo getEntityCfgInfo(String id) {
  326. return entityTypeInfos.get(id);
  327. }
  328. public static int nextEntityId(String idPrefix) {
  329. return entityIdSeqs.get(idPrefix).incrementAndGet();
  330. }
  331. }