Skip to content

Commit 45ee5fa

Browse files
author
JelteMX
committed
🔥 First setup
0 parents  commit 45ee5fa

File tree

13 files changed

+308
-0
lines changed

13 files changed

+308
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
dist/tmp

LICENSE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
The Apache License v2.0
2+
3+
Copyright Jelte Lagendijk <[email protected]> 2020
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[![Support](https://img.shields.io/badge/Support-Community%20(no%20active%20support)-orange.svg)](https://docs.mendix.com/developerportal/app-store/app-store-content-support)
2+
[![Studio](https://img.shields.io/badge/Studio%20version-8.0%2B-blue.svg)](https://appstore.home.mendix.com/link/modeler/)
3+
![GitHub release](https://img.shields.io/github/release/JelteMX/mendix-jsontotree-module)
4+
![GitHub issues](https://img.shields.io/github/issues/JelteMX/mendix-jsontotree-module)
5+
6+
# JSON To Tree Module for Mendix
7+
8+
![Icon](/assets/AppStoreIcon.png)
9+
10+
You have a simple JSON that has a nested structure (children) and you want to import this into Mendix?
11+
12+
## Java Actions
13+
14+
- Convert JSON to Mendix Object Tree (non-persistent)
15+
16+
This will create a tree of non-persistent Node objects that each have a parent, and are bound to a Tree object. See Domain-model:
17+
18+
![Domain](/assets/DomainModel.png)
19+
20+
How you follow up with that is up to you. The module includes a few examples of how you can create a Tree structure. This is showcased in the test-project:
21+
22+
[https://treecreatortestapp-sandbox.mxapps.io/](https://treecreatortestapp-sandbox.mxapps.io/)
23+
24+
## Libraries used
25+
26+
- Jackson Core
27+
- Version 2.10.2
28+
- License: Apache 2.0
29+
- [link](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.10.2)
30+
- Jackson Annotations
31+
- Version 2.10.2
32+
- License: Apache 2.0
33+
- [link](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations/2.10.2)
34+
- Jackson Databind
35+
- Version 2.10.2
36+
- License: Apache 2.0
37+
- [link](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.10.2)
38+
39+
## License
40+
41+
Apache 2

assets/AppStoreIcon.png

11.1 KB
Loading

assets/DomainModel.png

22.4 KB
Loading

dist/JSONToTree.mpk

1.61 MB
Binary file not shown.
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// This file was generated by Mendix Studio Pro.
2+
//
3+
// WARNING: Only the following code will be retained when actions are regenerated:
4+
// - the import list
5+
// - the code between BEGIN USER CODE and END USER CODE
6+
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
7+
// Other code you write will be lost the next time you deploy the project.
8+
// Special characters, e.g., é, ö, à, etc. are supported in comments.
9+
10+
package jsontotree.actions;
11+
12+
import com.fasterxml.jackson.databind.JsonNode;
13+
import com.fasterxml.jackson.databind.ObjectMapper;
14+
import com.fasterxml.jackson.databind.node.JsonNodeType;
15+
import com.mendix.core.Core;
16+
import com.mendix.systemwideinterfaces.core.IContext;
17+
import com.mendix.webui.CustomJavaAction;
18+
import jsontotree.Misc;
19+
import com.mendix.systemwideinterfaces.core.IMendixObject;
20+
21+
public class ConvertJSONToRootTree extends CustomJavaAction<IMendixObject>
22+
{
23+
private java.lang.String JSON;
24+
private java.lang.String childKey;
25+
26+
public ConvertJSONToRootTree(IContext context, java.lang.String JSON, java.lang.String childKey)
27+
{
28+
super(context);
29+
this.JSON = JSON;
30+
this.childKey = childKey;
31+
}
32+
33+
@java.lang.Override
34+
public IMendixObject executeAction() throws Exception
35+
{
36+
// BEGIN USER CODE
37+
IContext ctx = this.getContext();
38+
39+
if (this.JSON == "" || this.JSON == null) {
40+
throw new com.mendix.systemwideinterfaces.MendixRuntimeException("JSON is empty");
41+
}
42+
43+
ObjectMapper mapper = new ObjectMapper();
44+
JsonNode rootNode = mapper.readTree(this.JSON);
45+
46+
if (rootNode.getNodeType() != JsonNodeType.ARRAY) {
47+
throw new com.mendix.systemwideinterfaces.MendixRuntimeException("JSON is not an array!");
48+
}
49+
50+
IMendixObject result = Core.instantiate(ctx, jsontotree.proxies.Root.getType());
51+
52+
Misc.traverseRootObjects(ctx, result, rootNode, this.childKey);
53+
54+
return result;
55+
// END USER CODE
56+
}
57+
58+
/**
59+
* Returns a string representation of this action
60+
*/
61+
@java.lang.Override
62+
public java.lang.String toString()
63+
{
64+
return "ConvertJSONToRootTree";
65+
}
66+
67+
// BEGIN EXTRA CODE
68+
// END EXTRA CODE
69+
}

src/package.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mendix.com/package/1.0/">
3+
<modelerProject xmlns="http://www.mendix.com/modelerProject/1.0/">
4+
<module name="JSONToTree" />
5+
<projectFile path="project.mpr" />
6+
<files>
7+
<file path="javasource\jsontotree\Misc.java" />
8+
<file path="userlib\jackson-annotations-2.10.2.jar" />
9+
<file path="userlib\jackson-core-2.10.2.jar" />
10+
<file path="userlib\jackson-databind-2.10.2.jar" />
11+
<file path="javasource\jsontotree\actions\ConvertJSONToRootTree.java" />
12+
</files>
13+
</modelerProject>
14+
</package>

src/project.mpr

96 KB
Binary file not shown.

0 commit comments

Comments
 (0)