PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/cdc-deps-core/src/main/java/cdc/deps/io/xml/DAnalysisXmlLoader.java

https://gitlab.com/cdc-java/cdc-deps
Java | 389 lines | 284 code | 25 blank | 80 comment | 62 complexity | 08a8046028be899b8ed547d04a1d4038 MD5 | raw file
  1. package cdc.deps.io.xml;
  2. import java.util.Date;
  3. import java.util.StringTokenizer;
  4. import cdc.deps.DAnalysis;
  5. import cdc.deps.DAnalysisInfo;
  6. import cdc.deps.DDependency;
  7. import cdc.deps.DDependencyLevel;
  8. import cdc.deps.DElement;
  9. import cdc.deps.DElementScope;
  10. import cdc.deps.DGroup;
  11. import cdc.deps.DItem;
  12. import cdc.deps.DNamespace;
  13. import cdc.deps.DPackage;
  14. import cdc.io.data.Child;
  15. import cdc.io.data.Element;
  16. import cdc.io.data.NodeType;
  17. import cdc.io.data.util.AbstractResourceLoader;
  18. import cdc.util.lang.FailureReaction;
  19. public final class DAnalysisXmlLoader extends AbstractResourceLoader<DAnalysis> {
  20. private final DAnalysis analysis;
  21. public DAnalysisXmlLoader(DAnalysis analysis,
  22. FailureReaction reaction) {
  23. super(reaction);
  24. this.analysis = analysis;
  25. }
  26. @Override
  27. protected DAnalysis loadRoot(Element root) {
  28. // First pass
  29. // Load definition of logical elements (packages and items),
  30. // recursively.
  31. for (final Child child : root.getChildren()) {
  32. if (child.getType() == NodeType.ELEMENT) {
  33. final Element element = (Element) child;
  34. switch (element.getName()) {
  35. case DAnalysisXml.INFO:
  36. parseInfo(element);
  37. break;
  38. case DAnalysisXml.PACKAGE:
  39. parsePackageDef(null, element);
  40. break;
  41. case DAnalysisXml.ITEM:
  42. parseItemDef(null, element);
  43. break;
  44. default:
  45. // Ignore
  46. break;
  47. }
  48. }
  49. }
  50. // Second pass
  51. // Load definition of physical elements (groups), recursively.
  52. // They may depend on namespaces (packages and items), which are already
  53. // loaded during first pass
  54. for (final Child child : root.getChildren()) {
  55. if (child.getType() == NodeType.ELEMENT) {
  56. final Element element = (Element) child;
  57. if (DAnalysisXml.GROUP.equals(element.getName())) {
  58. parseGroupDef(null, element);
  59. } else {
  60. // Ignore
  61. }
  62. }
  63. }
  64. // Third pass
  65. // Load dependencies, recursively
  66. for (final Child child : root.getChildren()) {
  67. if (child.getType() == NodeType.ELEMENT) {
  68. final Element element = (Element) child;
  69. switch (element.getName()) {
  70. case DAnalysisXml.GROUP:
  71. parseGroupDeps(null, element);
  72. break;
  73. case DAnalysisXml.PACKAGE:
  74. parsePackageDeps(null, element);
  75. break;
  76. case DAnalysisXml.ITEM:
  77. parseItemDeps(null, element);
  78. break;
  79. default:
  80. // Ignore
  81. break;
  82. }
  83. }
  84. }
  85. return analysis;
  86. }
  87. /**
  88. *
  89. * @param element The data element corresponding to info.
  90. */
  91. private void parseInfo(Element element) {
  92. if (element.hasAttribute(DAnalysisXml.CREATION_DATE)) {
  93. final Date date = DAnalysisInfo.toDate(element.getAttributeValue(DAnalysisXml.CREATION_DATE, null));
  94. analysis.getInfo().setCreationDate(date);
  95. }
  96. for (final Child child : element.getChildren()) {
  97. if (child.getType() == NodeType.ELEMENT) {
  98. final Element e = (Element) child;
  99. if (DAnalysisXml.ANALYZER.equals(e.getName())) {
  100. parseAnalyzer(e);
  101. } else {
  102. // Ignore
  103. }
  104. }
  105. }
  106. }
  107. private void parseAnalyzer(Element element) {
  108. analysis.getInfo().setAnalyzerName(element.getAttributeValue(DAnalysisXml.NAME, null));
  109. for (final Child child : element.getChildren()) {
  110. if (child.getType() == NodeType.ELEMENT) {
  111. final Element e = (Element) child;
  112. if (DAnalysisXml.ARG.equals(e.getName())) {
  113. final String name = e.getAttributeValue(DAnalysisXml.NAME, null);
  114. final String value = e.getAttributeValue(DAnalysisXml.VALUE, null);
  115. analysis.getInfo().addAnalysisArgument(name, value);
  116. } else {
  117. // Ignore
  118. }
  119. }
  120. }
  121. }
  122. /**
  123. * Parse a group definition. <br>
  124. * This will parse children groups and types, recursively.
  125. *
  126. * @param group The parent group. <em>May be null.</em>
  127. * @param element The data element corresponding to the group.
  128. */
  129. private void parseGroupDef(DGroup group,
  130. Element element) {
  131. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  132. final DGroup g = analysis.createGroup(name, group);
  133. parseScope(g, element);
  134. parseCategory(g, element);
  135. parseFeatures(g, element);
  136. for (final Child child : element.getChildren()) {
  137. if (child.getType() == NodeType.ELEMENT) {
  138. final Element e = (Element) child;
  139. switch (e.getName()) {
  140. case DAnalysisXml.GROUP:
  141. parseGroupDef(g, e);
  142. break;
  143. case DAnalysisXml.PACKAGE_REF:
  144. parsePackageRef(g, e);
  145. break;
  146. case DAnalysisXml.ITEM_REF:
  147. parseItemRef(g, e);
  148. break;
  149. default:
  150. // Ignore
  151. break;
  152. }
  153. }
  154. }
  155. }
  156. private void parseGroupDeps(DGroup group,
  157. Element element) {
  158. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  159. final DGroup g = analysis.getGroup(name);
  160. for (final Child child : element.getChildren()) {
  161. if (child.getType() == NodeType.ELEMENT) {
  162. final Element e = (Element) child;
  163. switch (e.getName()) {
  164. case DAnalysisXml.GROUP:
  165. parseGroupDeps(g, e);
  166. break;
  167. case DAnalysisXml.DEP:
  168. parseDep(g, e);
  169. break;
  170. default:
  171. // Ignore
  172. break;
  173. }
  174. }
  175. }
  176. }
  177. /**
  178. * Parse a package reference in a group.
  179. *
  180. * @param group The parent group.<em>Must NOT be null.</em>
  181. * @param element The data element corresponding to the package reference.
  182. */
  183. private void parsePackageRef(DGroup group,
  184. Element element) {
  185. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  186. analysis.findOrCreatePackage(name, group, null);
  187. }
  188. /**
  189. * Parse a type reference in a group.
  190. *
  191. * @param group The parent group.<em>Must NOT be null.</em>
  192. * @param element The data element corresponding to the type reference.
  193. */
  194. private void parseItemRef(DGroup group,
  195. Element element) {
  196. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  197. analysis.findOrCreateItem(null, name, group);
  198. }
  199. /**
  200. * Parse a package definition, ignoring dependencies. <br>
  201. * This will parse children packages and types, recursively.
  202. *
  203. * @param parent The parent package. <em>May be null.</em>
  204. * @param element The data element corresponding to the package.
  205. */
  206. private void parsePackageDef(DPackage parent,
  207. Element element) {
  208. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  209. final DPackage p = analysis.createPackage(name, null, parent);
  210. parseScope(p, element);
  211. parseCategory(p, element);
  212. parseFeatures(p, element);
  213. for (final Child child : element.getChildren()) {
  214. if (child.getType() == NodeType.ELEMENT) {
  215. final Element e = (Element) child;
  216. switch (e.getName()) {
  217. case DAnalysisXml.PACKAGE:
  218. parsePackageDef(p, e);
  219. break;
  220. case DAnalysisXml.ITEM:
  221. parseItemDef(p, e);
  222. break;
  223. default:
  224. // Ignore
  225. break;
  226. }
  227. }
  228. }
  229. }
  230. /**
  231. * Parse package dependencies. This will also parse children packages and
  232. * items dependencies.
  233. *
  234. * @param parent The parent package. <em>May be null.</em>
  235. * @param element The data element corresponding to the package.
  236. */
  237. private void parsePackageDeps(DPackage parent,
  238. Element element) {
  239. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  240. final DPackage p = analysis.getPackage(name);
  241. for (final Child child : element.getChildren()) {
  242. if (child.getType() == NodeType.ELEMENT) {
  243. final Element e = (Element) child;
  244. switch (e.getName()) {
  245. case DAnalysisXml.PACKAGE:
  246. parsePackageDeps(p, e);
  247. break;
  248. case DAnalysisXml.ITEM:
  249. parseItemDeps(p, e);
  250. break;
  251. case DAnalysisXml.DEP:
  252. parseDep(p, e);
  253. break;
  254. default:
  255. // Ignore
  256. break;
  257. }
  258. }
  259. }
  260. }
  261. /**
  262. * Parse an item definition, ignoring dependencies. <br>
  263. * This will parse children items, recursively.
  264. *
  265. * @param parent The parent namespace (package or item).
  266. * <em>May be null.</em>
  267. * @param element The data element corresponding to the item.
  268. */
  269. private void parseItemDef(DNamespace parent,
  270. Element element) {
  271. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  272. final DItem item = analysis.createItem(name, null, parent);
  273. parseScope(item, element);
  274. parseCategory(item, element);
  275. parseFeatures(item, element);
  276. for (final Child child : element.getChildren()) {
  277. if (child.getType() == NodeType.ELEMENT) {
  278. final Element e = (Element) child;
  279. if (DAnalysisXml.ITEM.equals(e.getName())) {
  280. parseItemDef(item, e);
  281. } else {
  282. // Ignore
  283. }
  284. }
  285. }
  286. }
  287. /**
  288. * Parse item dependencies. This will also parse children items
  289. * dependencies.
  290. *
  291. * @param parent The parent namespace (package or type).
  292. * <em>May be null.</em>
  293. * @param element The data element corresponding to the type.
  294. */
  295. private void parseItemDeps(DNamespace parent,
  296. Element element) {
  297. final String name = element.getAttributeValue(DAnalysisXml.NAME, null);
  298. final DItem type = analysis.getItem(name);
  299. for (final Child child : element.getChildren()) {
  300. if (child.getType() == NodeType.ELEMENT) {
  301. final Element e = (Element) child;
  302. switch (e.getName()) {
  303. case DAnalysisXml.ITEM:
  304. parseItemDeps(type, e);
  305. break;
  306. case DAnalysisXml.DEP:
  307. parseDep(type, e);
  308. break;
  309. default:
  310. // Ignore
  311. break;
  312. }
  313. }
  314. }
  315. }
  316. /**
  317. * Parse a dependency definition.
  318. *
  319. * @param source The parent namespace (package or type), declaring the
  320. * dependency. <em>Must NOT be null.</em>
  321. * @param element The data element corresponding to the dependency.
  322. */
  323. private void parseDep(DElement source,
  324. Element element) {
  325. final String targetName = element.getAttributeValue(DAnalysisXml.TARGET, null);
  326. final DElement target = analysis.getElement(targetName);
  327. if (target == null) {
  328. onError("parseDep(" + element + ") FAILED to find target");
  329. } else if (target != source) {
  330. final DDependency dep = analysis.addDependency(source, target);
  331. assert dep != null;
  332. final int primitive = element.getAttributeAsInt(DAnalysisXml.PRIMITIVE_COUNT, 0);
  333. final int derived = element.getAttributeAsInt(DAnalysisXml.DERIVED_COUNT, 0);
  334. dep.setCount(DDependencyLevel.PRIMITIVE, primitive);
  335. dep.setCount(DDependencyLevel.DERIVED, derived);
  336. } else {
  337. onError("parseDep(" + element + ") FAILED self dependency");
  338. }
  339. }
  340. private static void parseScope(DElement delement,
  341. Element element) {
  342. final DElementScope scope = element.getAttributeAsEnum(DAnalysisXml.SCOPE, DElementScope.class, DElementScope.UNKNOWN);
  343. if (delement instanceof DItem) {
  344. ((DItem) delement).setScope(scope);
  345. } else if (delement instanceof DGroup) {
  346. ((DGroup) delement).setScope(scope);
  347. }
  348. }
  349. private static void parseCategory(DElement delement,
  350. Element element) {
  351. delement.setCategory(element.getAttributeValue(DAnalysisXml.CATEGORY, null));
  352. }
  353. private static void parseFeatures(DElement delement,
  354. Element element) {
  355. final String features = element.getAttributeValue(DAnalysisXml.FEATURES, null);
  356. if (features != null) {
  357. final StringTokenizer tokenizer = new StringTokenizer(features, DAnalysisXml.SEPARATOR);
  358. while (tokenizer.hasMoreTokens()) {
  359. final String feature = tokenizer.nextToken();
  360. delement.setEnabled(feature, true);
  361. }
  362. }
  363. }
  364. }