281 lines
8.5 KiB
Java
281 lines
8.5 KiB
Java
package org.gcube.portlets.user.geoportaldataentry.server;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
|
|
import org.gcube.application.geoportalcommon.shared.geoportal.config.GcubeProfileDV;
|
|
import org.gcube.portlets.user.geoportaldataentry.shared.GeoNaFormDataObject;
|
|
import org.gcube.portlets.user.geoportaldataentry.shared.Tree_Node;
|
|
import org.gcube.portlets.widgets.mpformbuilder.shared.GenericDatasetBean;
|
|
import org.json.JSONArray;
|
|
import org.json.JSONException;
|
|
import org.json.JSONObject;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* The Class FormDataObjectToJSON.
|
|
*
|
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
|
*
|
|
* Mar 10, 2022
|
|
*/
|
|
public class FormDataObjectToJSON {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(FormDataObjectToJSON.class);
|
|
|
|
|
|
/**
|
|
* Convert.
|
|
*
|
|
* @param tree_Node the tree node
|
|
* @return the JSON object
|
|
* @throws JSONException the JSON exception
|
|
*/
|
|
public JSONObject convert(Tree_Node<GeoNaFormDataObject> tree_Node, JSONObject theDocument) throws JSONException {
|
|
|
|
//JSONObject theDocument = JSONObjecOrdered.instance();
|
|
|
|
if(tree_Node==null)
|
|
return theDocument;
|
|
|
|
//the root, instancing new json document
|
|
if(tree_Node.isRoot()) {
|
|
theDocument = JSONObjecOrdered.instance();
|
|
}
|
|
|
|
for (Tree_Node<GeoNaFormDataObject> treeNodeChild : tree_Node.getChildren()) {
|
|
|
|
//Building the JSON section
|
|
List<GenericDatasetBean> listGDB = tree_Node.getData().getListGDB();
|
|
GcubeProfileDV profile = tree_Node.getData().getGcubeProfileDV();
|
|
LOG.debug("The profile is: " + profile);
|
|
|
|
String parentPath = profile.getParentName().endsWith(".")?profile.getParentName():profile.getParentName()+".";
|
|
String jsonPathExp = String.format("%s%s", parentPath, profile.getSectionName());
|
|
LOG.debug("The json path to build: " + jsonPathExp);
|
|
// jsonPathExp = "$.chidl1.child2.child3";
|
|
|
|
String toJsonPathExp = jsonPathExp.replaceFirst("\\$", "");
|
|
String[] jsonPathDeep = toJsonPathExp.split("\\.");
|
|
List<JSONObject> listJSONObject = toListJonObject(listGDB, jsonPathDeep);
|
|
|
|
// adding as JSONObject to theDocument at first deep level (under the root or at section specified)
|
|
if (listJSONObject.size() == 1) {
|
|
theDocument = deepMerge(listJSONObject.get(0), theDocument);
|
|
//theDocument = theDocument.put(listJSONObject.get(0), jsonArray);
|
|
} else {
|
|
// adding as JSONArray to theDocument under the section specified
|
|
// to jsonPathDeep[1]
|
|
JSONArray jsonArray = new JSONArray();
|
|
for (JSONObject jsonObject : listJSONObject) {
|
|
// reading the i-mo JSONObject created in the list with the key as
|
|
// jsonPathDeep[1]
|
|
jsonArray.put(jsonObject.get(jsonPathDeep[1]));
|
|
}
|
|
theDocument.put(jsonPathDeep[1], jsonArray);
|
|
|
|
}
|
|
|
|
//recursive call...
|
|
theDocument = convert(treeNodeChild,theDocument);
|
|
}
|
|
|
|
LOG.debug("Partial Root Document is: " + theDocument);
|
|
return theDocument;
|
|
|
|
}
|
|
|
|
/**
|
|
* Convert.
|
|
*
|
|
* @param tree_Node the tree node
|
|
* @return the JSON object
|
|
* @throws JSONException the JSON exception
|
|
*/
|
|
/*public JSONObject convert(Tree_Node<GeoNaFormDataObject> tree_Node) throws JSONException {
|
|
|
|
JSONObject theDocument = JSONObjecOrdered.instance();
|
|
for (GeoNaFormDataObject geoNaFormDataObject : tree_Node) {
|
|
|
|
List<GenericDatasetBean> listGDB = geoNaFormDataObject.getListGDB();
|
|
|
|
GcubeProfileDV profile = geoNaFormDataObject.getGcubeProfileDV();
|
|
LOG.debug("The profile is: " + profile);
|
|
|
|
String jsonPathExp = String.format("%s%s", profile.getParentName(), profile.getSectionName());
|
|
LOG.debug("The json path to build: " + jsonPathExp);
|
|
// jsonPathExp = "$.chidl1.child2.child3";
|
|
|
|
String toJsonPathExp = jsonPathExp.replaceFirst("\\$", "");
|
|
String[] jsonPathDeep = toJsonPathExp.split("\\.");
|
|
List<JSONObject> listJSONObject = toListJonObject(listGDB, jsonPathDeep);
|
|
|
|
// adding as JSONObject to theDocument at first deep level (under the root or at section specified)
|
|
if (listJSONObject.size() == 1) {
|
|
theDocument = deepMerge(listJSONObject.get(0), theDocument);
|
|
//theDocument = theDocument.put(listJSONObject.get(0), jsonArray);
|
|
} else {
|
|
// adding as JSONArray to theDocument under the section specified
|
|
// to jsonPathDeep[1]
|
|
JSONArray jsonArray = new JSONArray();
|
|
for (JSONObject jsonObject : listJSONObject) {
|
|
// reading the i-mo JSONObject created in the list with the key as
|
|
// jsonPathDeep[1]
|
|
jsonArray.put(jsonObject.get(jsonPathDeep[1]));
|
|
}
|
|
theDocument.put(jsonPathDeep[1], jsonArray);
|
|
|
|
}
|
|
LOG.debug("Partial Root Document is: " + theDocument);
|
|
}
|
|
|
|
LOG.debug("Final JSON Document is: " + theDocument);
|
|
return theDocument;
|
|
}*/
|
|
|
|
/**
|
|
* Generic dataset bean to JSON.
|
|
*
|
|
* @param gdb the gdb
|
|
* @return the JSON object
|
|
* @throws JSONException the JSON exception
|
|
*/
|
|
private JSONObject genericDatasetBeanToJSON(GenericDatasetBean gdb) throws JSONException {
|
|
|
|
JSONObject sectJSONObject = JSONObjecOrdered.instance();
|
|
|
|
LinkedHashMap<String, List<String>> mapFields = gdb.getFormDataEntryFields();
|
|
LOG.debug("Map ordered: " + mapFields);
|
|
for (String key : mapFields.keySet()) {
|
|
List<String> listValues = mapFields.get(key);
|
|
if (listValues == null || listValues.isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
// key/value as string
|
|
if (listValues.size() == 1) {
|
|
sectJSONObject.put(key, listValues.get(0));
|
|
continue;
|
|
}
|
|
|
|
// value is a list
|
|
JSONArray array = new JSONArray();
|
|
for (String value : listValues) {
|
|
array.put(value);
|
|
}
|
|
|
|
sectJSONObject.put(key, array);
|
|
}
|
|
|
|
return sectJSONObject;
|
|
|
|
}
|
|
|
|
/**
|
|
* To list jon object.
|
|
*
|
|
* @param listGDB the list GDB
|
|
* @param jsonPathDeep the json path deep
|
|
* @return the list
|
|
* @throws JSONException the JSON exception
|
|
*/
|
|
private List<JSONObject> toListJonObject(List<GenericDatasetBean> listGDB, String[] jsonPathDeep)
|
|
throws JSONException {
|
|
|
|
List<JSONObject> listJSONObject = new ArrayList<JSONObject>();
|
|
|
|
for (GenericDatasetBean gdb : listGDB) {
|
|
JSONObject sectRootObject = JSONObjecOrdered.instance();
|
|
JSONObject jsonObject = genericDatasetBeanToJSON(gdb);
|
|
LOG.debug("Adding section : " + jsonObject);
|
|
LOG.trace("jsonPathDeep: " + Arrays.asList(jsonPathDeep) + " size: " + jsonPathDeep.length);
|
|
|
|
// Adding JSONObject to ROOT DOCUMENT POSITION (using PLACEHOLDER_ROOT_POINTER_JSON_DOC)
|
|
if (jsonPathDeep.length == 0) {
|
|
sectRootObject = deepMerge(jsonObject, sectRootObject);
|
|
} else {
|
|
|
|
// DEPTH >= 1
|
|
sectRootObject.put(jsonPathDeep[jsonPathDeep.length - 1], jsonObject);
|
|
JSONObject deepJSON = sectRootObject;
|
|
System.out.println("sectRootObject: " + sectRootObject.toString());
|
|
for (int i = jsonPathDeep.length - 2; i > 0; i--) {
|
|
JSONObject newOne = JSONObjecOrdered.instance();
|
|
newOne.put(jsonPathDeep[i], deepJSON);
|
|
deepJSON = newOne;
|
|
}
|
|
sectRootObject = deepJSON;
|
|
}
|
|
|
|
listJSONObject.add(sectRootObject);
|
|
|
|
}
|
|
|
|
LOG.info("For listGDB : " + listGDB);
|
|
LOG.info("returning : " + listJSONObject);
|
|
return listJSONObject;
|
|
|
|
}
|
|
|
|
/**
|
|
* Merge "source" into "target". If fields have equal name, merge them
|
|
* recursively.
|
|
*
|
|
* @param source the source
|
|
* @param target the target
|
|
* @return the merged object (target).
|
|
* @throws JSONException the JSON exception
|
|
*/
|
|
public static JSONObject deepMerge(JSONObject source, JSONObject target) throws JSONException {
|
|
for (String key : JSONObject.getNames(source)) {
|
|
Object value = source.get(key);
|
|
if (!target.has(key)) {
|
|
// new value for "key":
|
|
target.put(key, value);
|
|
} else {
|
|
// existing value for "key" - recursively deep merge:
|
|
if (value instanceof JSONObject) {
|
|
JSONObject valueJson = (JSONObject) value;
|
|
deepMerge(valueJson, target.getJSONObject(key));
|
|
} else {
|
|
target.put(key, value);
|
|
}
|
|
}
|
|
}
|
|
return target;
|
|
}
|
|
|
|
|
|
/**
|
|
* The Class JSONObjecOrdered.
|
|
*
|
|
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
|
|
*
|
|
* Mar 10, 2022
|
|
*/
|
|
public static class JSONObjecOrdered {
|
|
|
|
/**
|
|
* Instance.
|
|
*
|
|
* @return the JSON object
|
|
*/
|
|
public static JSONObject instance() {
|
|
JSONObject jsonObject = new JSONObject();
|
|
try {
|
|
Field changeMap = jsonObject.getClass().getDeclaredField("map");
|
|
changeMap.setAccessible(true);
|
|
changeMap.set(jsonObject, new LinkedHashMap<>());
|
|
changeMap.setAccessible(false);
|
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
|
}
|
|
return jsonObject;
|
|
}
|
|
}
|
|
|
|
}
|