package org.timerescue.information;
import java.util.ArrayList;
import java.util.List;
import org.timerescue.exception.InvalidPropertyException;
import org.timerescue.exception.InvalidSerialException;
import org.timerescue.utils.Introspection;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
/**
* A Wrapper for a list of serialized parameter objects
* This class use an active serialization model to include new objects
* which means that every object is serialized when included
* @author chamanx
*/
public class InformationParametersSerials implements InformationParameters{
/*
* Attributes
*/
/**
* Parameters
*/
private JsonObject parameters;
private int size;
/*
* Methods
*/
/**
* Default constructor instance array
* with 1 as initial capacity for the list
*/
public InformationParametersSerials() {
clear();
}
/**
* @param size the size to set
*/
private void setSize(int size) {
this.size = size;
}
/**
* Add a json element to the parameters serials
* @param property
* @param json_elem
*/
private void addProperty(String property, JsonElement json_elem){
this.parameters.add(property, json_elem);
setSize(1);
}
/**
* Get serialized property array
* @param property
* @return
*/
public List<String> getArrayParamSerial(String property){
JsonElement temp = parameters.get(property);
List<String> serial = new ArrayList<String>();
if(temp.isJsonObject()){
//If it's an Object just return null
}else if(temp.isJsonArray()){
//If it's an Array return array of serialized,
JsonArray json_array = temp.getAsJsonArray();
for (int i = 0; i < json_array.size(); i++) {
serial.add(json_array.get(i).getAsJsonObject().get(
Constants.SERIAL_PROPERTY).getAsString());
}
}
return serial;
}
/**
* Get serilized property object
* @param property
* @return
*/
public String getParamSerial(String property){
JsonElement temp = parameters.get(property);
String serial = null;
if(temp.isJsonObject()){
//If it's an Object just returns Serial property
serial = temp.getAsJsonObject().get(
Constants.SERIAL_PROPERTY).getAsString();
}else if(temp.isJsonArray()){
//If it's an Array return null,
//This should be gotten with another method
}
return serial;
}
@Override
public int getSize() {
return size;
}
@Override
public Serializable getParam(String property)
throws InvalidPropertyException{
Serializable data_object = null;
JsonElement temp = parameters.get(property);
if(temp.isJsonObject()){
//If it's an Object just returns property Object
String serial = null;
try {
//Get the requested parameter
JsonObject object = temp.getAsJsonObject();
//Extract serial and class from properties from parameters
String clas_name = object.get(Constants.CLASS_PROPERTY).getAsString();
serial = object.get(Constants.SERIAL_PROPERTY).getAsString();
//Get the new object of the specified class
data_object = Introspection.getSerializableFromClass(clas_name);
//Construct the data object from the serial
data_object.fromSerial(serial);
} catch (ClassNotFoundException e) {
throw new InvalidPropertyException();
} catch (InstantiationException e) {
throw new InvalidPropertyException();
} catch (IllegalAccessException e) {
throw new InvalidPropertyException();
} catch (InvalidSerialException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(temp.isJsonArray()){
//If it's an Array return null,
//This should be gotten with another method
}
return data_object;
}
@Override
public List<Serializable> getArrayParam(String property)
throws InvalidPropertyException{
List<Serializable> data_objects = new ArrayList<Serializable>();
JsonElement temp_property = parameters.get(property);
if(temp_property.isJsonObject()){
//If it's an Object return null
}else if(temp_property.isJsonArray()){
//If it's an Array return property array of Objects
String serial = null;
JsonArray json_array = temp_property.getAsJsonArray();
try {
//Iterate all elements from the array
for (int i = 0; i < json_array.size(); i++) {
//Get the requested parameter
JsonObject object = json_array.get(i).getAsJsonObject();
//Extract serial and class from properties from parameters
//TODO abstract this lines in a method to call in others
//{
String clas_name = object.get(Constants.CLASS_PROPERTY).getAsString();
serial = object.get(Constants.SERIAL_PROPERTY).getAsString();
//Get the new object of the specified class
//TODO check if guice can do this trick
Serializable temp_serial = Introspection.getSerializableFromClass(clas_name);
//Construct the data object from the serial
temp_serial.fromSerial(serial);
//}
//Add it to the list
data_objects.add(temp_serial);
}
} catch (ClassNotFoundException e) {
throw new InvalidPropertyException();
} catch (InstantiationException e) {
throw new InvalidPropertyException();
} catch (IllegalAccessException e) {
throw new InvalidPropertyException();
} catch (InvalidSerialException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return data_objects;
}
@Override
public void addParamData(String property, Serializable data_object) {
String temp_serial = data_object.toSerial();
String clas = data_object.getClass().getName();
JsonObject value = new JsonObject();
value.addProperty(Constants.CLASS_PROPERTY, clas);
value.addProperty(Constants.SERIAL_PROPERTY, temp_serial);
addProperty(property, value);
}
@Override
public void addArrayParamData(String property, List<Serializable> data_objects) {
if (data_objects != null){
if (data_objects.size() > 0){
JsonArray array = new JsonArray();
for (int i = 0; i < data_objects.size(); i++) {
Serializable item = data_objects.get(i);
//Add the Class property
String clas = item.getClass().getName();
//Add serial property
String serial = item.toSerial();
JsonObject temp_object = new JsonObject();
//Both class and serial are used so that each array's element could be of any
//Serializable implementation's type
temp_object.addProperty(Constants.CLASS_PROPERTY, clas);
temp_object.addProperty(Constants.SERIAL_PROPERTY, serial);
array.add(temp_object);
}
addProperty(property, array);
}
}
}
@Override
public void clear() {
this.parameters = new JsonObject();
//This clear size
setSize(0);
}
@Override
public String toSerial() {
JsonObject serial = new JsonObject();
//Serialize size
serial.addProperty( Constants.SIZE_PROPERTY, getSize());
serial.add(Constants.PARAMETERS_PROPERTY, this.parameters);
return gson.toJson(serial);
}
@Override
public void fromSerial(String serialized) throws InvalidSerialException {
JsonObject serial;
try {
serial = parser.parse(serialized).getAsJsonObject();
setSize(serial.get(Constants.SIZE_PROPERTY).getAsInt());
this.parameters = serial.get(
Constants.PARAMETERS_PROPERTY).getAsJsonObject();
} catch (IllegalStateException e) {
throw new InvalidSerialException(e);
} catch (JsonParseException e) {
throw new InvalidSerialException(e);
}
}
/*
* INNER classes
*/
static final class Constants{
public static final String CLASS_PROPERTY = "CLASS";
public static final String SERIAL_PROPERTY = "SERIAL";
public static final String SIZE_PROPERTY = "SIZE";
public static final String PARAMETERS_PROPERTY = "PARAMETERS";
}
}