JsonObjectGenerator.java
package sk.iway.iwcm.system.json;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.beanutils.PropertyUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.utils.Pair;
/**
* Zjednodusuje generovanie zlozitejsich Json objektov
*
*
* @author mbocko
*
*/
public class JsonObjectGenerator
{
private ObjectFormaterFactory formatFactory;
public JsonObjectGenerator setObjectFormaterFactory(ObjectFormaterFactory factory)
{
this.formatFactory = factory;
return this;
}
public JsonObjectGenerator addObject(JSONObject json, String objectName, Object bean, String attrs)
{
if (bean!=null)
{
if (bean instanceof Collection)
{
return addArrayOfObjects(json, objectName, (Collection<?>)bean, attrs);
}
JSONObject jsonObj = new JSONObject();
if (Tools.isEmpty(attrs))
{
//chcem vlozit objekt ako celok
try
{
putToObjectRecursive(json, objectName, formatFactory.format(bean));
}
catch (JSONException e){ sk.iway.iwcm.Logger.error(e);}
return this;
}
Pair<String,String>[] attributes = parseTokens(attrs);
for (Pair<String,String>attribute : attributes)
{
if (attribute.first.contains("{"))
{
String attrName = attribute.first.substring(0,attribute.first.indexOf("{"));
try
{
Object propertyValue = PropertyUtils.getProperty(bean, attrName);
if (propertyValue!=null)
{
if (propertyValue instanceof Collection)
{
String collectionItemAttributes = attribute.first.substring(attribute.first.indexOf("{")+1,attribute.first.lastIndexOf("}"));
addArrayOfObjects(jsonObj, attrName, (Collection<?>)propertyValue, collectionItemAttributes);
}
else
{
String itemAttributes = attribute.first.substring(attribute.first.indexOf("{")+1,attribute.first.lastIndexOf("}"));
addObject(jsonObj, attrName, propertyValue, itemAttributes);
}
}
}
catch (IllegalAccessException e) {sk.iway.iwcm.Logger.error(e); }
catch (InvocationTargetException e) {sk.iway.iwcm.Logger.error(e); }
catch (NoSuchMethodException e) {sk.iway.iwcm.Logger.error(e); }
}
else
{
try
{
Object propertyValue = PropertyUtils.getProperty(bean, attribute.first);
if (propertyValue!=null)
{
jsonObj.put(attribute.second, formatFactory.format(propertyValue));
}
}
catch (IllegalAccessException e) {sk.iway.iwcm.Logger.error(e); }
catch (InvocationTargetException e) {sk.iway.iwcm.Logger.error(e); }
catch (NoSuchMethodException e) {sk.iway.iwcm.Logger.error(e); }
catch (JSONException e) {sk.iway.iwcm.Logger.error(e);}
}
}
try
{
putToObjectRecursive(json, objectName, jsonObj);
}
catch (JSONException e)
{
sk.iway.iwcm.Logger.error(e);
}
}
return this;
}
private void putToObjectRecursive(JSONObject json, String objectName, Object objectToInsert) throws JSONException
{
if (objectName.indexOf(".")!=-1)
{
String key = objectName.substring(0, objectName.indexOf("."));
JSONObject parentJson = null;
try
{
parentJson = json.getJSONObject(key);
}
catch(JSONException e)
{}
if (parentJson==null)
{
parentJson = new JSONObject();
json.put(key, parentJson);
}
putToObjectRecursive(parentJson, Tools.replace(objectName, key+".", ""), objectToInsert);
}
else
{
json.put(objectName, objectToInsert);
}
}
public JsonObjectGenerator addArrayOfObjects(JSONObject json, String arrayName, Collection<?> collection, String attrs)
{
if (collection!=null && attrs!=null)
{
Pair<String,String>[] attributes = parseTokens(attrs);
JSONArray jsonArray = new JSONArray();
Iterator<?> it = collection.iterator();
while (it.hasNext())
{
Object item = it.next();
putToArray(jsonArray, item, attributes);
}
try
{
//json.put(arrayName, jsonArray);
putToObjectRecursive(json, arrayName, jsonArray);
}
catch (JSONException e)
{
sk.iway.iwcm.Logger.error(e);
}
}
return this;
}
@SuppressWarnings("unchecked")
private void putToArray(JSONArray array, Object bean, Pair<String,String>...attributes)
{
JSONObject jsonObj = new JSONObject();
for (Pair<String,String> attribute : attributes)
{
String attrName = attribute.first;
if (attribute.first.contains("{"))
{
attrName = attribute.first.substring(0,attribute.first.indexOf("{"));
try
{
Object propertyValue = PropertyUtils.getProperty(bean, attrName);
if (propertyValue!=null)
{
if (propertyValue instanceof Collection)
{
String collectionAttributes = attribute.first.substring(attribute.first.indexOf("{")+1,attribute.first.lastIndexOf("}"));
addArrayOfObjects(jsonObj, attrName, (Collection<?>)propertyValue, collectionAttributes);
}
else
{
String itemAttributes = attribute.first.substring(attribute.first.indexOf("{")+1,attribute.first.lastIndexOf("}"));
addObject(jsonObj, attrName, propertyValue, itemAttributes);
}
}
}
catch (IllegalAccessException e) {sk.iway.iwcm.Logger.error(e); }
catch (InvocationTargetException e) {sk.iway.iwcm.Logger.error(e); }
catch (NoSuchMethodException e) {sk.iway.iwcm.Logger.error(e); }
}
else
{
try
{
Object propertyValue = PropertyUtils.getProperty(bean, attribute.first);
if (propertyValue!=null)
{
jsonObj.put(attribute.second, formatFactory.format(propertyValue));
}
}
catch (IllegalAccessException e) {sk.iway.iwcm.Logger.error(e); }
catch (InvocationTargetException e) {sk.iway.iwcm.Logger.error(e); }
catch (NoSuchMethodException e) {sk.iway.iwcm.Logger.error(e); }
catch (JSONException e) {sk.iway.iwcm.Logger.error(e);}
}
}
array.put(jsonObj);
}
@SuppressWarnings("unchecked")
private Pair<String,String>[] parseTokens(String toParse)
{
if (toParse==null) return null;
char[] charArray = toParse.toCharArray();
List<Pair<String,String>> resultList = new ArrayList<Pair<String,String>>();
StringBuilder beanPropertyName = new StringBuilder();
StringBuilder jsonPropertyName = null;
//String jsonPropNameString = "";
int deepStatus = 0;
boolean propertyName=false;
for (int i =0; i<charArray.length; i++)
{
char ch = charArray[i];
if (ch == ',' && deepStatus==0)
{
//resultList.add(beanPropertyName.toString());
if (jsonPropertyName!=null) resultList.add(Pair.of(beanPropertyName.toString(), jsonPropertyName.toString()));
else resultList.add(Pair.of(beanPropertyName.toString(), beanPropertyName.toString()));
beanPropertyName = new StringBuilder();
jsonPropertyName=null;
}
else if (ch == ' ') continue;
else
{
if (ch == '{') deepStatus++;
else if (ch == '}') deepStatus--;
if (ch == '(' && deepStatus==0)
{
propertyName=true;
continue;
}
else if (ch == ')' && deepStatus==0)
{
propertyName=false;
//jsonPropNameString = jsonPropertyName.toString();
//skoncila definicia json pola, ale ak som nahodou na konci stringu, musim korektne ukoncit cyklus
if (i==charArray.length-1)
{
//ak som na konci stringu
if (jsonPropertyName!=null) resultList.add(Pair.of(beanPropertyName.toString(), jsonPropertyName.toString()));
else resultList.add(Pair.of(beanPropertyName.toString(), beanPropertyName.toString()));
}
continue;
}
if (propertyName)
{
if (jsonPropertyName==null) jsonPropertyName=new StringBuilder();
jsonPropertyName.append(ch);
}
else
{
beanPropertyName.append(ch);
}
}
if (i==charArray.length-1)
{
//ak som na konci stringu
if (jsonPropertyName!=null) resultList.add(Pair.of(beanPropertyName.toString(), jsonPropertyName.toString()));
else resultList.add(Pair.of(beanPropertyName.toString(), beanPropertyName.toString()));
}
}
return resultList.toArray(new Pair[]{});
}
}