/*
* © Copyright IBM Corp. 2013
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.ibm.sbt.services.client.base.datahandlers;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaFactory;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.JsonParser;
/**
* This class provides an implementation of the DataHandler class to use data in JSON format.
* @author Carlos Manias
* @author Manish Kataria
*/
public class JsonDataHandler implements DataHandler<JsonJavaObject>{
private JsonJavaObject data;
private static final long serialVersionUID = 1L;
/**
* Default constructor
*/
public JsonDataHandler() {
}
/**
* Constructor
*
* @param jsonObject
*/
public JsonDataHandler(JsonJavaObject jsonObject) {
this.data = jsonObject;
}
/**
* Constructor
*
* @param jsonString
* @throws JsonException
*/
public JsonDataHandler(String jsonString) throws JsonException {
JsonJavaObject jsonObject = (JsonJavaObject)JsonParser.fromJson(JsonJavaFactory.instanceEx, jsonString);
this.data = jsonObject;
}
/**
* @param field
* @return value
*/
@Override
public String getAsString(FieldEntry field) {
return getAsString((String)field.getPath());
}
/**
* @param path
* @return value
*/
public Object getAsObject(String path) {
return path.indexOf("/")==-1 ? data.get(path) : getNested(path);
}
/**
* @param path
* @return {Object}
*/
private Object getNested(String path){
Object value = null;
String[] pathParts = path.split("/");
JsonJavaObject currentObject = data;
int index = 0;
for (String part : pathParts){
if (!containsKey(currentObject,part)) break;
if (index<pathParts.length-1) {
currentObject = currentObject.getJsonObject(part);
} else {
value = currentObject.get(part);
}
index++;
}
return value;
}
/**
* @param path
* @return value
*/
@Override
public String getAsString(String path) {
return path.indexOf("/")==-1 ? data.getString(path) : getNestedField(path);
}
/**
* @param path
* @return {String}
*/
private String getNestedField(String path){
String value = "";
String[] pathParts = path.split("/");
JsonJavaObject currentObject = data;
int index = 0;
for (String part : pathParts){
if (!containsKey(currentObject,part)) break;
if (index<pathParts.length-1) {
currentObject = currentObject.getJsonObject(part);
} else {
value = currentObject.getString(part);
}
index++;
}
return value;
}
private boolean containsKey(JsonJavaObject j, String key) {
Iterator<String> i = j.getProperties();
while(i.hasNext()) {
if(i.next().matches(key)) {
return true;
}
}
return false;
}
private Object getNestedObject(String path){
String[] pathParts = path.split("/");
JsonJavaObject currentObject = data;
int index = 0;
for (String part : pathParts){
if (!containsKey(currentObject, part)) break;
if (index<pathParts.length-1) {
currentObject = currentObject.getJsonObject(part);
}
index++;
}
return currentObject;
}
@Override
public JsonJavaObject getEntry(FieldEntry field) {
return getEntry((String)field.getPath());
}
@Override
public JsonJavaObject getEntry(String path) {
return data.getJsonObject(path);
}
/**
* @param field
* @return {List<JsonJavaObject>} list of entries
*/
@Override
public List<JsonJavaObject> getEntries(FieldEntry field) {
return getEntries((String)field.getPath());
}
/**
* @param path
* @return list of entries
*/
@Override
public List<JsonJavaObject> getEntries(String path) {
return getAsList(path);
}
/**
* @param field
* @return list of entries
*/
public List<JsonJavaObject> getAsList(FieldEntry field){
return getAsList((String)field.getPath());
}
/**
* @param path
* @return list of entries
*/
public List<JsonJavaObject> getAsList(String path){
List<JsonJavaObject> jsonList = new ArrayList<JsonJavaObject>();
if(path.contains("/")){
JsonJavaObject object = (JsonJavaObject) getNestedObject(path);
String pathinfo = path.substring(path.lastIndexOf("/")+1,path.length());
if(containsKey(object, pathinfo)){
List list = (List)object.get(pathinfo);
for (Object obj : list) {
jsonList.add((JsonJavaObject)obj);
}
}else{
return null;
}
} else {
List list = (List)data.get(path);
for (Object obj : list) {
jsonList.add((JsonJavaObject)obj);
}
}
return jsonList;
}
/* (non-Javadoc)
* @see com.ibm.sbt.services.client.base.datahandlers.DataHandler#getAsArray(com.ibm.sbt.services.client.base.datahandlers.FieldEntry)
*/
@Override
public String[] getAsArray(FieldEntry field) {
return getAsArray((String)field.getPath());
}
/* (non-Javadoc)
* @see com.ibm.sbt.services.client.base.datahandlers.DataHandler#getAsArray(java.lang.String)
*/
@Override
public String[] getAsArray(String path) {
List<String> strList = new ArrayList<String>();
if(path.contains("/")){
JsonJavaObject object = (JsonJavaObject) getNestedObject(path);
String pathinfo = path.substring(path.lastIndexOf("/")+1,path.length());
if(containsKey(object,pathinfo)){
for (Object obj : (List)object.get(pathinfo)) {
strList.add((String)obj);
}
}else{
return null;
}
}else{
for (Object obj : (List)data.get(path)) {
strList.add((String)obj);
}
}
return strList.toArray(new String[strList.size()]);
}
/**
* sets the data
*/
@Override
public void setData(final Object data) {
this.data = (JsonJavaObject)data;
}
/**
* @return data
*/
@Override
public JsonJavaObject getData() {
return data;
}
/**
* @param field
* @param locale
* @return value as Date
* @throws DataHandlerException
*/
@Override
public Date getAsDate(FieldEntry field, final Locale locale) throws DataHandlerException {
String value = getAsString(field);
Date date = null;
DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, locale);
try {
date = format.parse(value);
} catch(ParseException e) {
throw new DataHandlerException(e, "Error parsing date string");
}
return date;
}
/**
* @param fieldName
* @param locale
* @return value as Date
* @throws DataHandlerException
*/
@Override
public Date getAsDate(String fieldName, final Locale locale) throws DataHandlerException {
String value = getAsString(fieldName);
Date date = null;
DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, locale);
try {
date = format.parse(value);
} catch(ParseException e) {
throw new DataHandlerException(e, "Error parsing date string");
}
return date;
}
/**
* @param field
* @return value as Date
* @throws DataHandlerException
*/
@Override
public Date getAsDate(FieldEntry field) throws DataHandlerException {
return getAsDate(field, Locale.getDefault());
}
/**
* @param fieldName
* @return value as Date
* @throws DataHandlerException
*/
@Override
public Date getAsDate(String fieldName) throws DataHandlerException {
return getAsDate(fieldName, Locale.getDefault());
}
/**
* @param field
* @return value as int
*/
@Override
public int getAsInt(FieldEntry field) {
return Integer.parseInt(getAsString(field));
}
/**
* @param fieldName
* @return value as int
*/
@Override
public int getAsInt(String fieldName) {
try {
return Integer.parseInt(getAsString(fieldName));
} catch (NumberFormatException e) {
return 0;
}
}
/**
* @param fieldName
* @return value as long
*/
@Override
public Long getAsLong(String fieldName) {
try {
Object value = getAsObject(fieldName);
if (value == null) {
return (long) 0;
}
if (value instanceof Number) {
return ((Number)value).longValue();
}
return Long.parseLong(value.toString());
} catch (NumberFormatException e) {
return (long) 0;
}
}
/**
* @param fieldName
* @return value as long
*/
@Override
public Long getAsLong(FieldEntry fieldName) {
String field = (String)fieldName.getPath();
return getAsLong(field);
}
/**
* @param field
* @return value as float
*/
@Override
public float getAsFloat(FieldEntry field) {
return (float)data.getDouble((String)field.getPath());
}
/**
* @param fieldName
* @return value as float
*/
@Override
public float getAsFloat(String fieldName) {
return (float)data.getDouble(fieldName);
}
/**
* @param field
* @return value as Date
*/
@Override
public boolean getAsBoolean(FieldEntry field) {
return data.getBoolean((String)field.getPath());
}
/**
* @param fieldName
* @return value as boolean
*/
@Override
public boolean getAsBoolean(String fieldName) {
return data.getBoolean(fieldName);
}
}