Class JsonToDataConverter
- java.lang.Object
-
- org.openbravo.service.json.JsonToDataConverter
-
public class JsonToDataConverter extends Object
Converts json data to Openbravo business object(s). This class can translate single aBaseOBObject
as well as lists ofBaseOBObject
instances. A single JSONObject is assumed to represent oneBaseOBObject
. The conversion process goes through the following steps for each JSONObject. First it is checked if the JSONObject has an id and entityName value. If so the logic tries to find the object in the internal key-to-object map (maintained during the conversion). If not found then the database is search. if not found there then a new BaseOBObject is created.If the object has an id then it is put in the key-to-object map so that it can be found if later objects refer to it.Then the next step is to convert/set the values. the logic walks through the properties of the object (the properties are defined by the entity of the object (see
BaseOBObject.getEntity()
andEntity.getProperties()
. For primitive values, the property name (Property.getName()
) is used to search a value in the JSONObject. The value is retrieved converted and then set in the business object.Reference/foreign key properties are handled differently. In this case the property name is appended with the ".id" postfix and this name is used to search for a value in the JSONObject. If there is no such value present then the property name is used. The id value is used to search in the key-to-object map and in the database (in this order). If not found then a new object is created as it may be present later in the overall json string. The system later tracks that there are no such maverick objects present (call
getErrors()
to check this).This class also handles a special type of property/keys. It can handle setting values in related objects also. For example say that the json object represents a sales order and has these keys (and their values):
- businessPartner.paymentTerm.name
- businessPartner.paymentTerm.id
- businessPartner.id
- set the businesspartner object in the sales order using the businesspartner.id
- set the paymentTerm in the business partner using the businessPartner.paymentTerm.id
- set the name of the paymentTerm using the businessPartner.paymentTerm.name
- This class holds state during the conversion process. It can not be shared by multiple threads.
- After calling one of the toBaseOBObject* methods the conversion errors can be retrieved using
the
getErrors()
method. - When calling toBaseOBObject* multiple times you can clear the internal state by calling
clearState()
.
- Author:
- mtaal
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
JsonToDataConverter.JsonConversionError
Is created when setting a value for a specific property fails.
-
Constructor Summary
Constructors Constructor Description JsonToDataConverter()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description protected boolean
areDatesEqual(Date d1, Date d2, boolean isDatetime)
protected boolean
areDatesEqual(Date d1, Date d2, boolean isDatetime, boolean isTime)
The json conversion looses precision in milliseconds and seconds.void
clearState()
static Object
convertJsonToPropertyValue(Property property, Object value)
Gets a value from json and converts it to a valid value for the DAL.protected BaseOBObject
getBaseOBObjectFromId(Entity entity, String referencedId)
protected BaseOBObject
getBaseOBObjectFromId(Entity entity, Property property, String referencedId)
Tries to find an object first in the internal map which is maintained to first resolve id's internally within the complete json string.List<JsonToDataConverter.JsonConversionError>
getErrors()
protected void
handleMultiPathProperty(String previousPath, String remainingPath, BaseOBObject obObject, org.codehaus.jettison.json.JSONObject jsonObject, Object value)
Handles the complex case of keys in the JSONObject which consists of multiple steps.boolean
hasErrors()
protected boolean
isNotConvertable(BaseOBObject obObject, Property property)
Determines if a property can be converted from json to a value stored in the database.protected void
logError(BaseOBObject obObject, String msg)
Creates aJsonToDataConverter.JsonConversionError
and adds it to the internal error list (getErrors()
).protected void
setData(org.codehaus.jettison.json.JSONObject jsonObject, BaseOBObject obObject)
Sets the data in the BaseOBObject by converting data from the json object and finding the correct properties to set.protected void
setValue(BaseOBObject obObject, Property property, Object jsonValue)
Checks if the property is settable (isNotConvertable(BaseOBObject, Property)
.BaseOBObject
toBaseOBObject(org.codehaus.jettison.json.JSONObject jsonObject)
Converts a single JSONObject to a BaseOBObject.List<BaseOBObject>
toBaseOBObjects(List<org.codehaus.jettison.json.JSONObject> jsonObjects)
Converts a list with JSONObjects to a list of BaseOBObject instances.List<BaseOBObject>
toBaseOBObjects(org.codehaus.jettison.json.JSONArray jsonArray)
Converts a JSONArray to a list of BaseOBObject instances.
-
-
-
Method Detail
-
convertJsonToPropertyValue
public static Object convertJsonToPropertyValue(Property property, Object value)
Gets a value from json and converts it to a valid value for the DAL.
-
clearState
public void clearState()
-
toBaseOBObjects
public List<BaseOBObject> toBaseOBObjects(org.codehaus.jettison.json.JSONArray jsonArray)
Converts a JSONArray to a list of BaseOBObject instances. The JSONArray is assumed to contain only JSONObjects which represent each a BaseOBObject. See the conversion logic description in the class header for more information.- Parameters:
jsonArray
- the array with JSONObjects- Returns:
- the list of BaseOBObjects.
-
toBaseOBObjects
public List<BaseOBObject> toBaseOBObjects(List<org.codehaus.jettison.json.JSONObject> jsonObjects)
Converts a list with JSONObjects to a list of BaseOBObject instances. See the conversion logic description in the class header for more information.- Parameters:
jsonObjects
- the list with JSONObjects- Returns:
- the list of BaseOBObjects.
-
toBaseOBObject
public BaseOBObject toBaseOBObject(org.codehaus.jettison.json.JSONObject jsonObject) throws Exception
Converts a single JSONObject to a BaseOBObject. See the conversion logic description in the class header for more information.- Parameters:
jsonObject
- the jsonObject to convert- Returns:
- the BaseOBObject (new or retrieved from the database)
- Throws:
Exception
-
setData
protected void setData(org.codehaus.jettison.json.JSONObject jsonObject, BaseOBObject obObject) throws org.codehaus.jettison.json.JSONException
Sets the data in the BaseOBObject by converting data from the json object and finding the correct properties to set.- Parameters:
jsonObject
- the source of the dataobObject
- the target of the data- Throws:
org.codehaus.jettison.json.JSONException
-
handleMultiPathProperty
protected void handleMultiPathProperty(String previousPath, String remainingPath, BaseOBObject obObject, org.codehaus.jettison.json.JSONObject jsonObject, Object value) throws org.codehaus.jettison.json.JSONException
Handles the complex case of keys in the JSONObject which consists of multiple steps. For example businessPartner.paymentTerm.name. To handle these keys the system has to walk the path and find the object at the end of the path to set the value. The system should take into account that not all objects along the path already exists, for example the paymentTerm in the businessPartner maybe null. In that case a new PaymentTerm needs to be set in the businessPartner. The system should also check if there is an id passed in for the paymentTerm: businessPartner.paymentTerm.id. If so then that one should be used to create/read the PaymentTerm. The previousPath and remainingPath parameters are used to keep track of the path walked. For example if the system is processing the part of the paymentTerm then the previousPath will be: 'businessPartner' and the remaining path will be: 'paymentTerm.name'.- Parameters:
previousPath
- see part of the path which has been 'walked', is initially empty.remainingPath
- the part which needs to be handled.obObject
- the current BaseOBObject to setjsonObject
- the jsonObject containing the valuesvalue
- the value to set when the end of the path has been reached.- Throws:
org.codehaus.jettison.json.JSONException
-
getBaseOBObjectFromId
protected BaseOBObject getBaseOBObjectFromId(Entity entity, String referencedId)
-
getBaseOBObjectFromId
protected BaseOBObject getBaseOBObjectFromId(Entity entity, Property property, String referencedId)
Tries to find an object first in the internal map which is maintained to first resolve id's internally within the complete json string. If not found there then the database is queried using the entity and referenceId. If not found there (or the referenceId == null) then create a new instance of the entity.- Parameters:
entity
- the entity to retrieve/createproperty
- the property referencing to the entityreferencedId
- the id of the entity- Returns:
- an existing of new BaseOBObject
-
setValue
protected void setValue(BaseOBObject obObject, Property property, Object jsonValue)
Checks if the property is settable (isNotConvertable(BaseOBObject, Property)
. If so the jsonValue is converted (convertJsonToPropertyValue(Property, Object)
, in case of a primitive), or in case of a reference property the referenced object is read/created.- Parameters:
obObject
- the object to setproperty
- the property of the object to setjsonValue
- the value as it is present in the original JSONObject
-
areDatesEqual
protected boolean areDatesEqual(Date d1, Date d2, boolean isDatetime, boolean isTime)
The json conversion looses precision in milliseconds and seconds. This comparison method only compares the other parts of the date object. Depending if a date or a date time is set.- Parameters:
d1
- the first date to compared2
- the second date to compareisDatetime
- is it a datetime- Returns:
- true if d1 and d2 have equal values for year, month and day and for date time also same values for hour, minutes and seconds.
-
isNotConvertable
protected boolean isNotConvertable(BaseOBObject obObject, Property property)
Determines if a property can be converted from json to a value stored in the database. Properties which are not updatable (and the object is not new) are not converted, the same for properties which are expired etc.- Parameters:
obObject
- the object for which the property is setproperty
- the property to set- See Also:
Property.isInactive()
,Property.isUpdatable()
,Property.isAuditInfo()
,Property.isClientOrOrganization()
,Property.isOneToMany()
-
hasErrors
public boolean hasErrors()
-
logError
protected void logError(BaseOBObject obObject, String msg)
Creates aJsonToDataConverter.JsonConversionError
and adds it to the internal error list (getErrors()
). As no property instance is passed the first id property of the obObject is set as the property in the JsonConversionError (JsonToDataConverter.JsonConversionError.setProperty(Property)
).- Parameters:
obObject
- the object to which the error condition appliesmsg
- the message to log
-
getErrors
public List<JsonToDataConverter.JsonConversionError> getErrors()
-
-