I'm trying to retrieve the json path of a value from a json string with jackson. As I couldn't find any function inside jackson giving me this result, I wanted to create my own function.
So I made this function :
public static String getJsonPath(Map.Entry<String, JsonNode> jsonNode, String valueSearched) {
String res = "";
String key = jsonNode.getKey();
JsonNode value = jsonNode.getValue();
if (value.isValueNode() && value.equals(valueSearched)) { // Here the value change to a ValueNode and the key weirdly equals to "".
return res + key;
} else {
if (value.isContainerNode()) {
if (value.isObject()) {
Iterator<Map.Entry<String, JsonNode>> elements = value.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
res += "." + element.getKey() + generateJsonPathArgumentFromJson(element, valueSearched);
}
} else {
int i = 0;
ArrayNode arrayNode = (ArrayNode) jsonNode;
Iterator<Map.Entry<String,JsonNode>> elements = arrayNode.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
i++;
res += "(" + i + ")" + generateJsonPathArgumentFromJson(element, valueSearched);
}
}
}
}
return "";
}
Why the key gets equal to "" after the first if ? Or there's a better way to construct a json path for a specific value ?
Just get the solutions :
protected static String generateJsonPathArgumentFromJson(JsonNode jsonNode, String valueSearched) {
if (jsonNode.isValueNode() && !jsonNode.asText().equals(valueSearched)) {
return null;
} else {
if (jsonNode.isContainerNode()) {
if (jsonNode.isObject()) {
Iterator<Map.Entry<String, JsonNode>> elements = jsonNode.fields();
while (elements.hasNext()) {
Map.Entry<String, JsonNode> element = elements.next();
String res = generateJsonPathArgumentFromJson(element.getValue(), valueSearched);
if (res != null) {
return "." + element.getKey() + res;
}
}
} else {
int i = 0;
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
JsonNode element = elements.next();
String res = generateJsonPathArgumentFromJson(element, valueSearched);
if (res != null) {
return "(" + i + ")" + res;
}
i++;
}
}
}
}
return "";
}
I'm sure there's better way to do, but at least it works :)
Related
I tried to make an exporting data to PDF but when I try to export it, the pdf can't show up like "no data found"
this code on bean
public JasperPrint exportTo() {
if(this.listReportMaster == null || this.listReportMaster.isEmpty()){
FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found");
RequestContext.getCurrentInstance().showMessageInDialog(messageFailed);
return null;
}
String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/resources/report/PRPKReportPDF.jasper");
JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(this.listReportMaster);
try {
JasperPrint jasperPrint = JasperFillManager.fillReport(path, null, beanCollectionDataSource);
return jasperPrint;
} catch (JRException e) {
e.printStackTrace();
return null;
}
}
public void exportToPdf(ActionEvent actionEvent){
if(this.lazyMasterReportDataModel != null){
System.out.println("masuk exporttopdf");
String sql = ((LazyMasterReportDataModel) this.lazyMasterReportDataModel).getSqlReportPrint();
List<Object> listObject = ((LazyMasterReportDataModel) this.lazyMasterReportDataModel).getObjectSqlListReportPrint();
this.listReportMaster = reportMasterPRPKController.getPRPKForReport(sql, listObject);
JasperPrint jasperPrint = exportTo();
String fileName = "PRPKNew_Report".concat("_").concat(".pdf");
if(jasperPrint != null) reportMasterPRPKController.exportToPDF(fileName, jasperPrint);
else System.out.println("jasperprint null");
}else{
System.out.println("keluar exporttopdf");
FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found");
RequestContext.getCurrentInstance().showMessageInDialog(messageFailed);
}
}
every I try to export it, always show "no data found" which is the program run this code FacesMessage messageFailed = new FacesMessage(FacesMessage.SEVERITY_INFO,"Info","No data found"); and which meam the "this.lazyMasterReportDataModel" is null but when I check it again, there's nothing wrong on code, I don't know if it have a wrong code or deficiency code
this the lazy code
List<ReportMasterPRPK> listMasterPRPK = new ArrayList<>();
ReportMasterPRPKQuery reportMasterPRPKQuery = new ReportMasterPRPKQuery();
Page page = new Page();
String order = "GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY a.created_date ";
String columname = "";
String sql = "";
List<Object> objectSqlList = new ArrayList<>();
String sqlReport = "";
String sqlReportPrint = "";
List<Object> objectSqlListReport = new ArrayList<>();
List<Object> objectSqlListReportPrint = new ArrayList<>();
String flag;
public LazyMasterReportDataModel() {
}
public LazyMasterReportDataModel(String flag) { //ini
this.flag = flag;
}
public LazyMasterReportDataModel(String sqlReport, List<Object> objectSqlListReport) {
this.sqlReport = sqlReport;
this.objectSqlListReport = objectSqlListReport;
}
#Override
public List<ReportMasterPRPK> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
page.setLimit(pageSize);
page.setOffset(first);
if(this.sqlReport != null){
this.sql = this.sqlReport;
this.objectSqlList = this.objectSqlListReport;
}else{
sql = "";
objectSqlList = new ArrayList<>();
//objectSqlList.clear();
}
if(flag != null){ //ini
if(flag.equals("no selected")){
sql = sql+" AND c.is_selected = 'n' ";
}
}
if (filters != null){
for(String key: filters.keySet()){
String filterColumnName = "";
for(Field field : ReportMasterPRPK.class.getDeclaredFields()){
if(field.getName().equals(key)) filterColumnName = field.getAnnotation(Column.class).value();
}
if(filters.get(key) instanceof String){
if("receivedDate".equals(key)){
if(((String)filters.get(key)).trim().length() > 20){
String startDate = "'" + filters.get(key).toString().substring(0, 10) + "'";
String endDate = "'" + filters.get(key).toString().substring(11, 21) + "'";
sql = sql + " AND " + filterColumnName + " BETWEEN " + startDate + " AND " + endDate+ " ";
}
}else{
if(((String) filters.get(key)).trim().length() > 0){
sql = sql+"AND "+filterColumnName+" ILIKE ? ";
String value = "%"+filters.get(key)+"%";
objectSqlList.add(value);
}
}
}else{
if(((String[]) filters.get(key)).length > 0){
sql = sql+" AND "+filterColumnName+" in ";
String value = "(";
for(String string : (String[]) filters.get(key)){
value = value+"'"+string+"',";
}
value = value.substring(0, value.length()-1)+") ";
sql = sql + value;
}
}
}
}
if(sortField != null){
for(Field field : ReportMasterPRPK.class.getDeclaredFields()){
if(field.getName().equals(sortField)) columname = field.getAnnotation(Column.class).value();
}
if(sortOrder.toString().equals("ASCENDING")) order = " ASC";
else order = " DESC";
sql = sql+" GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY "+columname+" "+order;
System.out.println("sql sort: "+sql+" : "+objectSqlList.size());
}else{
sql = sql + order;
}
sqlReportPrint = sql;
objectSqlListReportPrint = objectSqlList;
this.listMasterPRPK = reportMasterPRPKQuery.retrivePage(page, sql, objectSqlList.toArray());
int dataSize = reportMasterPRPKQuery.retrieveMaxRow(sql, objectSqlList.toArray());
this.setRowCount(dataSize);
//objectSqlList.clear();
if(this.sqlReport != null){
this.sql = this.sqlReport;
this.objectSqlList = this.objectSqlListReport;
}else{
sql = "";
objectSqlList.clear();
}
order = "GROUP a.prpk_number, a.prpk_type_id, a.created_date, a.pic_prpk_id, a.business_unit_id, a.pic_department_id, a.prpk_desc, a.prpk_request, a.prpk_background, a.prpk_analysis_benefit, a.priority_level_id, a.cost, b.prpk_type_name, c.business_unit, d.department_name, e.priority_name, f.user_name ORDER BY a.created_date ";
return listMasterPRPK;
}
public List<ReportMasterPRPK> calculateRownum(List<ReportMasterPRPK> listMasterPRPK, int first){
int i = 1;
for (ReportMasterPRPK masterPRPK : listMasterPRPK) {
masterPRPK.setRownum(first + i);
i++;
}
return listMasterPRPK;
}
public String getSqlReportPrint() {
return sqlReportPrint;
}
public void setSqlReportPrint(String sqlReportPrint) {
this.sqlReportPrint = sqlReportPrint;
}
public List<Object> getObjectSqlListReportPrint() {
return objectSqlListReportPrint;
}
public void setObjectSqlListReportPrint(List<Object> objectSqlListReportPrint) {
this.objectSqlListReportPrint = objectSqlListReportPrint;
}
sorry before, if my english is to bad, but I hope you understand about what I mean...
thanks before...
I am printing a value in a file i need to split them onces the first content is finished leave some spaces and then print the next one
public class Test_Json {
public static ArrayList<Object> ls1 = new ArrayList<Object>();
public static ArrayList<Object> ls2 = new ArrayList<Object>();
public static void main(String[] args) throws Exception {
JsonParser parser = new JsonParser();
BufferedWriter bw = null;
FileWriter fw = null;
try {
Gson g = new Gson();
JsonElement jsonElement1 = parser.parse(new FileReader("D://sample1.json"));
JsonElement jsonElement2 = parser.parse(new FileReader("D://sample2.json"));
// System.out.println("Is the two JSON File Same: "+compareJson(jsonElement1,jsonElement2));
if (!compareJson(jsonElement1, jsonElement2)) {
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> firstMap = g
.fromJson(jsonElement1, mapType);
Map<String, Object> secondMap = g.fromJson(jsonElement2,
mapType);
System.out.println(" The Two JSON Files Are Not the Same ");
System.out.println(Maps.difference(firstMap, secondMap));
String s = Maps.difference(firstMap, secondMap).toString();
try{
fw = new FileWriter("D:\\output.txt");
bw = new BufferedWriter(fw);
bw.write(s);
}catch(Exception e){
e.printStackTrace();
}
} else {
System.out.println("The Two JSON Are SAME!!!!!!!!!!!!!!!");
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
public static boolean compareJson(JsonElement json1, JsonElement json2) {
boolean isEqual = true;
if (json1 != null && json2 != null) {
if (json1.isJsonObject() && json2.isJsonObject()) {
Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1)
.entrySet();
Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2)
.entrySet();
JsonObject json2obj = (JsonObject) json2;
if (ens1 != null && ens2 != null
&& (ens2.size() == ens1.size())) {
for (Entry<String, JsonElement> en : ens1) {
isEqual = isEqual
&& compareJson(en.getValue(),
json2obj.get(en.getKey()));
}
} else {
return false;
}
}
else if (json1.isJsonArray() && json2.isJsonArray()) {
JsonArray jarr1 = json1.getAsJsonArray();
JsonArray jarr2 = json2.getAsJsonArray();
if (jarr1.size() != jarr2.size()) {
return false;
} else {
int i = 0;
for (JsonElement je : jarr1) {
isEqual = isEqual && compareJson(je, jarr2.get(i));
i++;
}
if (isEqual) {
ls1.toArray();
ls2.toArray();
isEqual = ls1.containsAll(ls2);
}
}
}
else if (json1.isJsonNull() && json2.isJsonNull()) {
return true;
}
else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
ls1.add(json1);
ls2.add(json2);
return true;
}
else if((json1.isJsonPrimitive() & json2.isJsonArray()) || (json2.isJsonPrimitive() && json1.isJsonArray())){
return false;
}
} else if (json1 == null && json2 == null) {
return true;
} else {
return false;
}
return isEqual;
}
}
Map.difference method gets the difference form the two file and prints them. I need to first print first file difference and then leave some lines of space and print the next file difference. This i am doing to show the contents seperately. At present it is displaying without any spaces so identifying is difficult.
I need something like this
Difference values in first file:
{
"id": 1,
"name": "A green door",
"price": 12.50,
"tags": ["home", "green"]
}
Difference in second file:
{
"id": 14,
"name": "A green door bell",
"price": 127.50,
"tags": ["home", "green"]
}
The method entriesOnlyOnLeft() and entriesOnlyOnRight() is not displaying the differece as the key should be different but here the key are same
If you want to print the map differences with a separation between the left and right sides, you can get them separately from the MapDifference result:
MapDifference diff = Maps.difference(firstMap, secondMap);
bw.write("Only on left: " + diff.entriesOnlyOnLeft());
// add separation
bw.write("Only on right: " + diff.entriesOnlyOnRight());
To include the value differences:
bw.write("Value differences: " + diff.entriesDiffering());
Lets say I gave a JSONObject
{
"person":{"name":"Sam", "surname":"ngonma"},
"car":{"make":"toyota", "model":"yaris"}
}
How do I update some of the values in the JSONObject?
Like below :
String name = jsonArray.getJSONObject(0).getJSONObject("person").getString("name");
name = "Sammie";
Use the put method: https://developer.android.com/reference/org/json/JSONObject.html
JSONObject person = jsonArray.getJSONObject(0).getJSONObject("person");
person.put("name", "Sammie");
Remove key and then add again the modified key, value pair as shown below :
JSONObject js = new JSONObject();
js.put("name", "rai");
js.remove("name");
js.put("name", "abc");
I haven't used your example; but conceptually its same.
Hello I can suggest you universal method. use recursion.
public static JSONObject function(JSONObject obj, String keyMain,String valueMain, String newValue) throws Exception {
// We need to know keys of Jsonobject
JSONObject json = new JSONObject()
Iterator iterator = obj.keys();
String key = null;
while (iterator.hasNext()) {
key = (String) iterator.next();
// if object is just string we change value in key
if ((obj.optJSONArray(key)==null) && (obj.optJSONObject(key)==null)) {
if ((key.equals(keyMain)) && (obj.get(key).toString().equals(valueMain))) {
// put new value
obj.put(key, newValue);
return obj;
}
}
// if it's jsonobject
if (obj.optJSONObject(key) != null) {
function(obj.getJSONObject(key), keyMain, valueMain, newValue);
}
// if it's jsonarray
if (obj.optJSONArray(key) != null) {
JSONArray jArray = obj.getJSONArray(key);
for (int i=0;i<jArray.length();i++) {
function(jArray.getJSONObject(i), keyMain, valueMain, newValue);
}
}
}
return obj;
}
It should work. If you have questions, go ahead.. I'm ready.
Generic way to update the any JSONObjet with new values.
private static void updateJsonValues(JsonObject jsonObj) {
for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
JsonElement element = entry.getValue();
if (element.isJsonArray()) {
parseJsonArray(element.getAsJsonArray());
} else if (element.isJsonObject()) {
updateJsonValues(element.getAsJsonObject());
} else if (element.isJsonPrimitive()) {
jsonObj.addProperty(entry.getKey(), "<provide new value>");
}
}
}
private static void parseJsonArray(JsonArray asJsonArray) {
for (int index = 0; index < asJsonArray.size(); index++) {
JsonElement element = asJsonArray.get(index);
if (element.isJsonArray()) {
parseJsonArray(element.getAsJsonArray());
} else if (element.isJsonObject()) {
updateJsonValues(element.getAsJsonObject());
}
}
}
public static JSONObject updateJson(JSONObject obj, String keyString, String newValue) throws Exception {
JSONObject json = new JSONObject();
// get the keys of json object
Iterator iterator = obj.keys();
String key = null;
while (iterator.hasNext()) {
key = (String) iterator.next();
// if the key is a string, then update the value
if ((obj.optJSONArray(key) == null) && (obj.optJSONObject(key) == null)) {
if ((key.equals(keyString))) {
// put new value
obj.put(key, newValue);
return obj;
}
}
// if it's jsonobject
if (obj.optJSONObject(key) != null) {
updateJson(obj.getJSONObject(key), keyString, newValue);
}
// if it's jsonarray
if (obj.optJSONArray(key) != null) {
JSONArray jArray = obj.getJSONArray(key);
for (int i = 0; i < jArray.length(); i++) {
updateJson(jArray.getJSONObject(i), keyString, newValue);
}
}
}
return obj;
}
Recursive way to update value in depth in Kotlin
Example: setJsonValue("obj1/obj2/keyToUpdate", "new value")
fun setJsonValue(path: String, value: Any?) {
setJsonValueRec(
path = path.split("/"),
index = 0,
obj = jsonObj,
value = value
)
}
private fun setJsonValueRec(path: List<String>, index: Int, obj: JSONObject, value: Any?): JSONObject {
return obj.put(
path[index],
when (index) {
path.lastIndex -> value
else -> setJsonValueRec(
path = path,
index = index + 1,
obj = obj.getJSONObject(path[index]),
value = value
)
}
)
}
Hi I'm trying to do a recursive .pdf url harvest and I'm getting a ConcurrentModificationException.. I don't understand how this is happening, and I don't know much about concurrency; I would greatly appreciate some insight towards how this is occurring and how it can be fixed.
public class urlHarvester {
private URL rootURL;
private String fileExt;
private int depth;
private HashSet<String> targets;
private HashMap<Integer, LinkedList<String>> toVisit;
public urlHarvester(URL rootURL, String fileExt, int depth) {
this.rootURL = rootURL;
this.fileExt = fileExt;
this.depth = depth;
targets = new HashSet<String>();
toVisit = new HashMap<Integer, LinkedList<String>>();
for (int i = 1; i < depth + 1; i++) {
toVisit.put(i, new LinkedList<String>());
}
doHarvest();
}
private void doHarvest() {
try {
harvest(rootURL, depth);
while (depth > 0) {
for (String s : toVisit.get(depth)) {
toVisit.get(depth).remove(s);
harvest(new URL(s),depth-1);
}
depth--;
}
} catch (Exception e) {
System.err.println(e);
e.printStackTrace();
}
for (String s : targets) {
System.out.println(s);
}
}
private void harvest(URL url, int depth) {
try {
URLConnection urlConnection = url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
Scanner scanner = new Scanner(new BufferedInputStream(inputStream));
java.lang.String source = "";
while (scanner.hasNext()) {
source = source + scanner.next();
}
inputStream.close();
scanner.close();
Matcher matcher = Pattern.compile("ahref=\"(.+?)\"").matcher(source);
while(matcher.find()) {
java.lang.String matched = matcher.group(1);
if (!matched.startsWith("http")) {
if (matched.startsWith("/") && url.toString().endsWith("/")) {
matched = url.toString() + matched.substring(1);
} else if ((matched.startsWith("/") && !url.toString().endsWith("/"))
|| (!matched.startsWith("/") && url.toString().endsWith("/"))) {
matched = url.toString() + matched;
} else if (!matched.startsWith("/") && !url.toString().endsWith("/")) {
matched = url.toString() + "/" + matched;
}
}
if (matched.endsWith(".pdf") && !targets.contains(matched)) {
targets.add(matched);System.out.println("ADDED");
}
if (!toVisit.get(depth).contains(matched)) {
toVisit.get(depth).add(matched);
}
}
} catch (Exception e) {
System.err.println(e);
}
}
class with main calls:
urlHarvester harvester = new urlHarvester(new URL("http://anyasdf.com"), ".pdf", 5);
The error probably has nothing to do with concurrency, but is caused by this loop:
for (String s : toVisit.get(depth)) {
toVisit.get(depth).remove(s);
harvest(new URL(s),depth-1);
}
To remove items from a collection while iterating, you need to use the remove method from an iterator:
List<String> list = toVisit.get(depth); //I assume list is not null
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String s = it.next();
it.remove();
harvest(new URL(s),depth-1);
}
A ConcurrentModificationException is thrown when attempting to remove an object directly form a collection while iterating over it.
This is happening when you are attempting to remove an entry from the toVisit HashMap:
for (String s : toVisit.get(depth)) {
toVisit.get(depth).remove(s); <----
...
You can use an iterator instead of attempting to remove directly from your collection:
Iterator<String> iterator = toVisit.get(depth).iterator();
while (iterator.hasNext()) {
String s = iterator.next();
iterator.remove();
harvest(new URL(s),depth-1);
}
I am doing project using Lucen library in here I need to build query dynamically using Json object. so in here I use jettison library. as an example my json like this
{"OR":{"OR": {"fildKey1": "value1","fildKey2": "value2","fildKeyabc": "valueabc"},"AND": {"AND": {"fildKey3": "value3","OR": {"fildKey4": "value4","fildKey5": "value5"}},"fildKeyw": "valuew"}}}
using above json I need to create following query
(( fildKey1 : value1 OR fildKey2 : value2 OR fildKeyabc : valueabc )OR(( fildKey3 : value3 AND( fildKey4 : value4 OR fildKey5 : value5 ))AND fildKeyw : valuew ))
but I can't get the above query.my result is like this
(( fildKey1 : value1 OR fildKey2 : value2 OR fildKeyabc : valueabc )OR(( fildKey3 : value3 AND( fildKey4 : value4 OR fildKey5 : value5 )AND)AND fildKeyw : valuew )OR)
I need to remove above extra 2 operators this is my code
public class JettisionCls {
static Stack s = new Stack();
String operater = null;
static String res = "";
int bracket_counter = 0;
public void getKeyAndValue(JSONObject json_obj) throws JSONException{
Iterator<String> iter = json_obj.keys();
while (iter.hasNext()) {
String obj = iter.next();
if(obj.toLowerCase().equals("and") || obj.toLowerCase().equals("or")){
//System.out.print(obj);
operater = obj;
}
JSONObject temp = null;
try {
temp = new JSONObject(json_obj.get(obj).toString());
} catch (JSONException e) {
e.getStackTrace();
}
if (temp != null) {
//System.out.print("(");
res = res +"(";
bracket_counter=bracket_counter+1;
s.push(operater);
getKeyAndValue(temp);
//System.out.print(")");
res = res +")";
bracket_counter=bracket_counter-1;
if((s.size()) != 0 && bracket_counter != 0){
//System.out.print(s.peek());
s.pop();
res = res +s.peek();
}
else{
s.pop();
}
}
else{
if(iter.hasNext()){
res = res+" "+obj + " : " + json_obj.get(obj) + " " + operater; }
else{
res = res+" "+obj + " : " + json_obj.get(obj)+" ";
}
}
}
}
my main method look like this
String multiLevelQuery = "{\"OR\":{\"OR\": {\"fildKey1\": \"value1\",\"fildKey2\": \"value2\",\"fildKeyabc\": \"valueabc\"},\"AND\": {\"AND\": {\"fildKey3\": \"value3\",\"OR\": {\"fildKey4\": \"value4\",\"fildKey5\": \"value5\"}},\"fildKeyw\": \"valuew\"}}}";
JSONObject jobj = new JSONObject(multiLevelQuery);
JettisionCls obj = new JettisionCls();
obj.getKeyAndValue(jobj);
System.out.println(JettisionCls.res);
if anyone can please help me.
I think you can do this using string replacement.
public void createQry(String s){
String temp = s;
if(temp.contains(")OR)")){
temp = temp.replace(")OR)", "))");
}
if(s.contains(")AND)")){
temp = temp.replace(")AND)", "))");
}
System.out.println(temp);
}
Hmm, this is an interesting problem. But instead of brute force, I would have gone with something more elegant like recursion. The pushing, popping and concatinating will be done by recursion for you. In your code, I can see a lot of places where it can break. Even if you fix this issue, there is a chance that it will fail for another condition.
A sample algorithm with recursion would be
public String generateQuery(JSONObject json_obj) {
if(single_json_obj)
return generated_query_for_single_condition;
//else complex json with inner children
else
return generateQuery(innerJSONObject)
}
}