New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for heterogeneous schemas #173
Comments
From yan...@google.com on January 09, 2013 16:30:28 Labels: -Priority-Medium -Milestone-Version1.15.0 Priority-High Milestone-Version1.14.0 |
From jmcg...@google.com on January 09, 2013 20:47:53 Some initial thoughts: Should LineString be @key List<List> coordinates or @key List coordinates? How would you initialize a Polygon? Does Java have a simple initializer for Lists of Lists of Lists? |
From yan...@google.com on January 12, 2013 07:12:11 James, I think those are good questions. But I hadn't intended for that to be the purpose of this feature request. So if you don't mind let me narrow the focus of this feature request to support for heterogeneous schemas, meaning schemas for whom there is a choice of which schema to use based on the value of a single top-level property. GeoJson is a good example of that, but in our implementation we will suppose that other use cases exist, so we will implement it to work for the most general use cases. I think it may be worthwhile to look at other JSON <-> Java mapping libraries like Jackson or GSON and see how they implement this. Summary: Support for heterogeneous schemas (was: Elegant support for GeoJSON) |
From yan...@google.com on January 17, 2013 19:09:30 Labels: -Milestone-Version1.14.0 Milestone-Version1.15.0 |
From yan...@google.com on January 18, 2013 18:25:31 For reference, GSON allows you to register a JSON deserializer or a type adapter: http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonDeserializer.html http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/TypeAdapter.html Jackson has an even more sophisticated mechanism with even a built-in concept of registering different types based on the value of a property: http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html Sample code snippet copied from the above blog: @JsonTypeInfo( class Dog extends Animal class Cat extends Animal I like this annotation based approach, and that seems to me the most appealing approach for use case at hand. We may have to provide greater customization in the future, but for now this seems like the simplest solution. |
From yan...@google.com on January 24, 2013 05:49:50 Labels: -Milestone-Version1.15.0 Milestone-Version1.14.0 |
From yan...@google.com on February 04, 2013 20:48:22 Labels: -Milestone-Version1.14.0 Milestone-Version1.15.0 |
From yincrash on March 04, 2013 11:28:26 Something I would like to see handled is the unknown case. Supporting a 'default' case if the JSON type is not known to the client. |
From yan...@google.com on March 25, 2013 12:32:37 Owner: ngmic...@google.com |
From ngmic...@google.com on May 28, 2013 08:43:10 https://codereview.appspot.com/9618044/ Status: Started |
From ngmic...@google.com on June 27, 2013 17:10:26 Hi Michael, Status: Fixed |
From yan...@google.com on December 13, 2012 06:11:06
External references, such as a standards document, or specification? http://www.geojson.org/geojson-spec.html Java environments (e.g. Java 6, Android 2.3, App Engine, or All)? All Please describe the feature requested. How can we elegantly support GeoJSON? Example from the spec:
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
},
{ "type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
},
{ "type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
[100.0, 1.0], [100.0, 0.0] ]
]
},
"properties": {
"prop0": "value0",
"prop1": {"this": "that"}
}
}
]
}
Note that "type" is case sensitive and can be any of "Point", "MultiPoint", "LineString", "MultiLineString", "Polygon", "MultiPolygon", "GeometryCollection", "Feature", or "FeatureCollection". Each type corresponds to a different schema. For example for Geometry "coordinates" JSON key has a different type for different geometries. For example, for Point it may be represented as List, for LineString it may be represented as List<List>, and for Polygon it may be represented as List<List<List>>.
What you'd have to do today is to merge the all into something like:
class GeoJsonObject extends GenericJson {
@key String type;
@key List coordinates;
@key Geometry geometry;
@key Map<String, Object> properties;
}
Note for example how coordinates has to be List and in usage it would have to be cast to the appropriate type.
But really we'd ideally like something like
class GeoJsonObject extends GenericJson {
@key String type;
}
class Feature extends GeoJsonObject {
@key Geometry geometry;
@key Map<String, Object> properties;
}
class Geometry extends GeoJsonObject {
@key Object coordinates;
}
public class Point extends Geometry {
@key List coordinates;
}
public class Point extends Geometry {
@key List coordinates;
}
public class LineString extends Geometry {
@key List<List> coordinates;
}
public class Polygon extends Geometry {
@key List<List<List>> coordinates;
}
But the question is how do we cause it to be parsed into the appropriate Java Type based on the "type" JSON key.
One option is we could enable some interface like:
class GeoJsonObject extends GenericJson implements JsonMultiType {
...
Type chooseType(ArrayMap map) {
switch(map.get("type")) {
case "Feature": return Feature.class;
case "Point": return Point.class;
case "LineString": return LineString.class;
case "Polygon": return Polygon.class;
...
}
}
and then internally we would parse it into an ArrayMap first, and then reparse it into the given type afterwards.
Another option is to generalize it a bit more using a post-process step, e.g.:
class GeoJsonObject extends GenericJson implements PostProcess {
...
GeoJsonObject postProcess(ArrayMap map) {
switch(map.get("type")) {
case "Feature": return parseAs(map, Feature.class);
case "Point": return parseAs(map, Point.class);
case "LineString": return parseAs(map, LineString.class);
case "Polygon": return parseAs(map, Polygon.class);
...
}
}
and we'd have to provide this new "parseAs" method.
Of course I'm open to other ideas as well, so feel free to suggest other approaches.
Original issue: http://code.google.com/p/google-http-java-client/issues/detail?id=173
The text was updated successfully, but these errors were encountered: