In the following Android sample, I have a set of JSON objects(referred to as templates) and I’m doing a sort of inheritance processing on them. If a JSON object has a key “extends”, the corresponding value will refer to another JSON object. I just copy the mappings in the referred JSON object to the current one. Each property (referred to as component in the code) will have sub properties, so each sub property is copied individually.
All the JSON objects are stored in a HashMap.
EDIT: Posting sample code which demonstrates the issue.
package com.trial;
import java.util.HashMap;
import java.util.Iterator;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
public class Trial extends Activity {
HashMap<String, JSONObject> templates = new HashMap<String, JSONObject>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
templates.put("entity", new JSONObject("{\"Health\":{\"health\":50,\"maxHealth\":100}}"));
templates.put("unit", new JSONObject("{\"Health\":{\"health\":70},\"extends\":\"entity\"}"));
Iterator<String> templatesIterator = templates.keySet().iterator();
while (templatesIterator.hasNext()) {
String templateName = templatesIterator.next();
JSONObject template = templates.get(templateName);
if (template.has("extends"))
templates.put(templateName, processInheritance(template));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private JSONObject processInheritance(JSONObject template) throws JSONException {
if (template.has("extends")) {
//If current template extends from another template
String parentTemplateName = template.getString("extends");
template.remove("extends");
JSONObject parentTemplate = processInheritance(templates.get(parentTemplateName));
//Create a clone of the parent to which child properties/components can be added
JSONObject processedTemplate = new JSONObject(parentTemplate.toString());
Iterator<String> it = template.keys();
while (it.hasNext()) {
String componentName = it.next();
if (processedTemplate.has(componentName)) {
//Component is already present. Loop through Component properties and make
//specific replacements
JSONObject componentData = template.getJSONObject(componentName);
Iterator<String> it2 = componentData.keys();
JSONObject processedComponentData = processedTemplate.getJSONObject(componentName);
while (it2.hasNext()) {
String propertyName = it2.next();
processedComponentData.put(propertyName, componentData.get(propertyName));
}
processedTemplate.put(componentName, processedComponentData);
} else {
//Component is not already present. Simply copy
processedTemplate.put(componentName, template.get(componentName));
}
}
return processedTemplate;
} else {
return template;
}
}
}
On debugging I noticed that the code executes fine until after the while loop. Soon after the while loop, it jumps across the if/else and returns “template” instead of “processedTemplate”. Even the resulting object indicates that “template” is being returned. I’ve tried clearing the binaries, recreating the emulator, and executing it on the actual device. The weird behavior persists. Could you someone tell me why this happens?
EDIT: The correct object IS being returned. My earlier comment that “template” was being returned was because of a bug where I was not saving the returned process object back into the HashMap.
I was simply doing
if (template.has("extends"))
processInheritance(template));
However the control still seems to jump across. An problem with Eclipse, I suppose.
Changing the code as below seems to have fixed the issue, but the problem with the original code snippet still remains.