What is the Java equivalent to a multi dimensional object in Javascript? - java

I have an Android game in which I want to store levels as a static Java class.
What is the equivalent of the following Javascript object in Java?
var Levels = {
Level1:{
shapes:[
{
bodytype : "dynamic",
h : "50.0000",
nameid : "hofN7-1",
props : {
id : "properties"
},
rotation : "0.0000",
type : "square",
uid : "Av2EZQh",
w : "50.0000",
x : "20.0000",
y : "20.0000"
},
{
bodytype : "dynamic",
h : "50.0000",
nameid : "hofN7-2",
props : {
gravMassScale : "2",
id : "properties",
inertia : "2",
isBullet : true,
torque : "2",
velocity : {
x : "2",
y : "2"
}
}
}
...

If you are looking for something close to how JS stores objects, you can try JSONObject class:
http://json.org/javadoc/org/json/JSONObject.html
Keeping Syntax-to-Syntax mapping aside, from an engineering perspective, I would store levels in a map of Levels like so:
HashMap<String, Level> myLevels = new HashMap<String, Level>();

As the commenters wrote, you can use a Map to create an equivalent object in Java. However, the values in this map are of different types. Some would be Strings. Some would be arrays of some type of Object. Some would be Maps themselves.
The only collection object you could use then is Map<String, Object>, and then you would need to make instanceof checks each time you used it. This would be clumsy.
You could use a JSON binding library, like Jackson. See http://wiki.fasterxml.com/JacksonHome. This has a mode where you create a class, Levels, and annotates its instance variables so Jackson can turn instances into JSON and back. But you need to know your class structure for that. Jackson has a mode where it can use untyped maps.
Finally, you can model Levels by treating it as a tree and using the Composite pattern. You'd have a Node abstract class that holds a name, and concrete subclasses like IntegerNode, StringNode, DoubleNode, MapNode, and ArrayNode.

Take this adjusted version of your JSON and create the classes using jsonschema2pojo:
{
"Levels":{
"shapes":[
{
"bodytype" : "dynamic",
"h" : "50.0000",
"nameid" : "hofN7-1",
"props" : {
"id" : "properties"
},
"rotation" : "0.0000",
"type" : "square",
"uid" : "Av2EZQh",
"w" : "50.0000",
"x" : "20.0000",
"y" : "20.0000"
},
{
"bodytype" : "dynamic",
"h" : "50.0000",
"nameid" : "hofN7-2",
"props" : {
"gravMassScale" : "2",
"id" : "properties",
"inertia" : "2",
"isBullet" : "true",
"torque" : "2",
"velocity" : {
"x" : "2",
"y" : "2"
}
}
}]
}
}
Check JSON for conversion and choose other options as you need them. You can download and use use the converted classes in you Java project.
Hope this helps ... Cheers!

Related

How to have dynamic data type variable in Java data model class?

An API response will send different data type value in different situation. I am using Gson parser to parse json response string.
eg :
1. { "value" : 1 }
2. { "value" : "Hello" }
3. { "value" : { "name" : "name", "email" : "" } }
You can use Map<String, Object> and then manually check where value is digit, String or nested Map

Jackson Polymorphic Lists of Specific types

I am trying to use Jackson to deserialize the folloing JSON.
{
"zooName":"Test Zoo Park",
"animalExhibits" : {
"lions" : [
{
"gender" : "male",
"name" : "simba"
},
{
"gender" : "female",
"name" : "lady"
}
],
"penguins" : [
{
"type":"zipper"
}
]
}
}
animalExhibits is a map. The value of the pair is an interface so I can keep adding animals to my exhibits. The lists extend the interface. But the specific list will always contain the same object (no inner polymorphism).
I want to be able to deserialize based on the field name. I.e. "lions" and "penguins" and more as my zoo grows.
I am unsure if a custom TypeIdResolver is the way to go. The Enum's the Jackson exposes for JsonTypeInfo do not seem to cut it for me at first glance.

Java - MongoDB - Map Json object as Java Array

I've got an XML configuration mapped to a JSON document which has an array of elements, but when there is only one element, the document looks like this:
{
"name" : "test2"
"products" : {
"id" : "prod3"
"value" : "prod_value3"
}
}
{
"name" : "test1"
"products" : [
{
"id" : "prod1"
"value" : "prod_value1"
},
{
"id" : "prod2"
"value" : "prod_value2"
}
]
}
Instead of an array of elements, there is only one element "products"
The JSON is inserted into the MongoDB database and I'm trying to map the "products" as an ArrayList but in the first example, the array returns empty.
My question is: Is there any way to automatically map this case with Java? Maybe a customMapper?
This case in Java is known as overloading methods. Object of some class and array are different types. You can't use one typecast to another etc., but you can use different type of parameter in the method accepting the value.

Tricky #Field description for RetroFit FormUrlEncoded parameter using a List of Objects

I am performing a #POST operation using #FormUrlEncoded, because the API i'm hitting requires HTTP params as input.
The params the target API are expecting to see should look like (simplified):
alist[0][object1]=1&alist[0][object2]=astring&alist[1][object1]=2&alist[2][object2]=bstring
JsonIzed (for clarity) looks like:
{
"alist": [
{
"object1" : "1",
"object2" : "astring"
},
{
"object1" : "2",
"object2" : "bstring"
}
]
}
So essentially, alist[0][object1] is 1, alist[0][object2] is "astring".
The closest I've gotten is using #FieldMap:
...
#FieldMap Map<String,String> myFieldMap
...
I have something like this:
#FormUrlEncoded
#Post("/somewhere")
SearchHandle search(#FieldMap Map<String, String> myMap);
Which gets me:
{
"alist": {
"0" : {
"object1" : "1",
"object2" : "astring"
},
"1" : {
"object1" : "2",
"object2" : "bstring"
}
}
}
Which is close - but the API is expecting an Array. So I need an Array of ... what exactly? Any ideas?
create a class for modeling your data :
class model {
String object1;
int object2;
}
now your alist should be an array of model objects and you can create json object from your array using Gson or jackson or etc.

How to update embedded mongo document using spring mongo data api

I need some help updating property of embedded collection with JSON structure below -
translation
{
"_id" : ObjectId("533d4c73d86b8977fda970a9"),
"_class" : "com.xxx.xxx.translation.domain.Translation",
"locales" : [
{
"_id" : "en-US",
"description" : "English (United States)",
"isActive" : true
},
{
"_id" : "pt-BR",
"description" : "Portuguese (Brazil)",
"isActive" : true
},
{
"_id" : "nl-NL",
"description" : "Dutch (Netherlands)",
"isActive" : true
}
],
"screens" : [
{
"_id" : "caseCodes",
"dictionary" : [
{
"key" : "CS_CAT1",
"parameterizedValue" : "My investigations",
"locale" : "en-US"
},
{
"key" : "MY_INVESTIGATIONS",
"parameterizedValue" : "",
"locale" : "pt-BR"
},
}
]
}
In above structure:
I want to update "parameterizedValue" usinng spring-data-mongo-db API 1.3.4, for screen with _id="caseCodes" and key = "CS_CAT1".
I tried (here 'values' is an collection name for TranslationValue array)
mongoOperations.updateFirst(Query.query(Criteria.where("screens._id")
.is("caseCodes")), new Update().push(
"screens.dictionary.$.values", translationValue),
Translation.class);
but it said, "can't append array to string "dictionary"....
Any pointers or help here? Thanks.
-Sanjeev
There are a few problems with your logic as well as problems with your schema for this type of update.
Firstly what you have are nested arrays, and this causes a problem with updates as described in the documentation for the positional $ operator. What this means is that any condition matching an element of an array on the query side of the update statement will only match the first array index found.
Since you need a specific entry in the inner array you would need to match that as well. But the "catch" says that only the first match will be used in the positional operator so you cannot have both. The query form (if it were possible to work, which it does not) would actually be something like this (native shell):
db.collection.update(
{
"screens._id": "caseCodes",
"screens.dictionary.key": "CS_CAT1"
},
{
"$set": {
"screens.$.dictionary.$.parameterizedValue": "new value"
}
}
)
Now that would "appear" to be more correct than what you are doing, but of course this fails because the positional operator cannot be used more than once. I may just quite stupidly work in this case as it just so happens that the first matched index of the "screens" array (which is 0) happens to be exactly the same as the required index of the inner element. But really that is just "dumb luck".
To illustrate better, what you need to do with these type of updates is already know the indexes of the elements and place those values directly into the update statement using "dot notation". So updating your second "dictionary" element would go like this:
db.collection.update(
{
"screens._id": "caseCodes",
"screens.dictionary.key": "MY_INVESTIGATIONS"
},
{
"$set": {
"screens.0.dictionary.1.parameterizedValue": "new value"
}
}
)
Also noting that the correct operator to use here is $set as you are not appending to either of the arrays, but rather you wish to change an element.
Since that sort of exactness in updates is unlikely to suit what you need, then you should look at changing the schema to accommodate your operations in a much more supported way. So one possibility is that your "screens" data may not possibly need to be an array, and you could change that to a document form like so:
"screens" : {
"caseCodes": [
{
"key" : "CS_CAT1",
"parameterizedValue" : "My investigations",
"locale" : "en-US"
},
{
"key" : "MY_INVESTIGATIONS",
"parameterizedValue" : "",
"locale" : "pt-BR"
},
]
}
This changed the form to:
db.collection.update(
{
"screens.caseCodes.key": "CS_CAT1"
},
{
"$set": {
"screens.caseCodes.$.parameterizedValue": "new value"
}
}
)
That may or may not work for your purposes, but you either live with the limitations of using a nested array or otherwise change your schema in some way.

Categories