1+ package jsontotree ;
2+
3+ import com .fasterxml .jackson .databind .JsonNode ;
4+ import com .fasterxml .jackson .databind .node .JsonNodeType ;
5+ import com .mendix .core .Core ;
6+ import com .mendix .core .CoreException ;
7+ import com .mendix .systemwideinterfaces .core .IContext ;
8+ import com .mendix .systemwideinterfaces .core .IMendixObject ;
9+ import com .mendix .thirdparty .org .json .JSONObject ;
10+ import jsontotree .proxies .JSONNode ;
11+
12+ public class Misc {
13+
14+ /**
15+ * Traverse a JSON Tree
16+ *
17+ * @param ctx Context for the current Java Action
18+ * @param rootObject Root object that binds all Node objects
19+ * @param rootNodes Array/Single Tree object
20+ * @param childKey Key that represents the array with child nodes
21+ */
22+ public static void traverseRootObjects (
23+ IContext ctx ,
24+ IMendixObject rootObject ,
25+ JsonNode rootNodes ,
26+ String childKey
27+ ) {
28+ traverse (rootObject , ctx , rootNodes , childKey , null );
29+ }
30+
31+ /**
32+ * Root traverse mode, will traverse through an array or single object
33+ *
34+ * @param rootObject Root object that binds all Node objects
35+ * @param ctx Context for the current Java Action
36+ * @param node current node
37+ * @param childKey Key that represents the array with child nodes
38+ * @param parentMXObject Mendix JSONNode object that is the parent
39+ */
40+ private static void traverse (IMendixObject rootObject , IContext ctx , JsonNode node , String childKey , IMendixObject parentMXObject ) {
41+ if (node .getNodeType () == JsonNodeType .ARRAY ) {
42+ traverseArray (rootObject , ctx , node , childKey , parentMXObject );
43+ } else if (node .getNodeType () == JsonNodeType .OBJECT ) {
44+ traverseObject (rootObject , ctx , node , childKey , parentMXObject );
45+ } else {
46+ throw new com .mendix .systemwideinterfaces .MendixRuntimeException ("Problem with traversing JSON, node type not implemented yet: " + node .getNodeType ().toString ());
47+ }
48+ }
49+
50+ /**
51+ * Traverse through single node
52+ *
53+ * @param rootObject Root object that binds all Node objects
54+ * @param ctx Context for the current Java Action
55+ * @param node current node
56+ * @param childKey Key that represents the array with child nodes
57+ * @param parentMXObject Mendix JSONNode object that is the parent
58+ */
59+ private static void traverseObject (IMendixObject rootObject , IContext ctx , JsonNode node , String childKey , IMendixObject parentMXObject ) {
60+ JsonNode child = node .get (childKey );
61+ boolean hasChild = traversable (child );
62+ JSONObject copy = createJSONObject (node , childKey );
63+ String jsonContent = copy .toString ();
64+
65+ IMendixObject jsonObj = createNodeObject (ctx , rootObject , parentMXObject , jsonContent );
66+
67+ if (hasChild ) {
68+ traverse (rootObject , ctx , child , childKey , jsonObj );
69+ }
70+ }
71+
72+ /**
73+ * Traverse through array of nodes
74+ *
75+ * @param rootObject Root object that binds all Node objects
76+ * @param ctx Context for the current Java Action
77+ * @param node current node
78+ * @param childKey Key that represents the array with child nodes
79+ * @param parentMXObject Mendix JSONNode object that is the parent
80+ */
81+ private static void traverseArray (IMendixObject rootObject , IContext ctx , JsonNode node , String childKey , IMendixObject parentMXObject ) {
82+ for (JsonNode jsonArrayNode : node ) {
83+ if (traversable (jsonArrayNode )) {
84+ traverse (rootObject , ctx , jsonArrayNode , childKey , parentMXObject );
85+ }
86+ }
87+ }
88+
89+ /**
90+ * Check if the node is not empty, not an object (we don't allow that), but an array
91+ *
92+ * @param node
93+ * @return Is this a traversable array?
94+ */
95+ private static boolean traversable (JsonNode node ) {
96+ return !node .isEmpty ()
97+ && (node .getNodeType () == JsonNodeType .OBJECT || node .getNodeType () == JsonNodeType .ARRAY );
98+
99+ }
100+
101+ /**
102+ * Create a JSON object that holds all the fields from the node, with the exception of the children
103+ *
104+ * @param node
105+ * @param childKey
106+ * @return
107+ */
108+ private static JSONObject createJSONObject (JsonNode node , String childKey ) {
109+ JSONObject copy = new JSONObject ();
110+
111+ node .fieldNames ().forEachRemaining ((String fieldName ) -> {
112+ JsonNode childNode = node .get (fieldName );
113+
114+ if (!fieldName .equalsIgnoreCase (childKey )) {
115+ Object value = null ;
116+ if (childNode .isTextual ()) {
117+ value = childNode .textValue ();
118+ } else if (childNode .isNumber ()) {
119+ value = childNode .numberValue ();
120+ } else if (childNode .isDouble ()) {
121+ value = childNode .doubleValue ();
122+ } else if (childNode .isLong ()) {
123+ value = childNode .asLong ();
124+ } else if (childNode .isBoolean ()) {
125+ value = childNode .asBoolean ();
126+ } else {
127+ value = childNode .asText ();
128+ }
129+
130+ copy .put (fieldName , value );
131+ }
132+ });
133+
134+ return copy ;
135+ }
136+
137+ /**
138+ * Create a Mendix JSONNode object
139+ *
140+ * @param ctx
141+ * @param rootObject
142+ * @param parentMXObject
143+ * @param jsonContent
144+ * @return
145+ */
146+ private static IMendixObject createNodeObject (IContext ctx , IMendixObject rootObject , IMendixObject parentMXObject , String jsonContent ) {
147+ IMendixObject JSONRepresentationObject = Core .instantiate (ctx , JSONNode .getType ());
148+
149+ JSONRepresentationObject .setValue (ctx , JSONNode .MemberNames .Content .toString (),
150+ jsonContent );
151+ JSONRepresentationObject .setValue (ctx , JSONNode .MemberNames .JSONNode_Root .toString (),
152+ rootObject .getId ());
153+
154+ if (parentMXObject != null ) {
155+ JSONRepresentationObject .setValue (ctx , JSONNode .MemberNames .Parent .toString (), parentMXObject .getId ());
156+ }
157+
158+ try {
159+ Core .commit (ctx , JSONRepresentationObject );
160+ } catch (CoreException e ) {
161+ throw new com .mendix .systemwideinterfaces .MendixRuntimeException ("Issue with committing temporary JSON Object" );
162+ }
163+
164+ return JSONRepresentationObject ;
165+ }
166+
167+ }
0 commit comments