GeoTools no such attribute error when parsing GeoJson - java

According to the GeoJson spec (https://www.rfc-editor.org/rfc/rfc7946), features with different sets of properties are allowed, but when i am processing my GeoJson file using FeatureJSON.readFeatureCollection i get an error saying no such attribute:tract_boundary.
here's the part of my file showing the two features with different properties (notice the attribute name "tract_boundary" appears in the second feature properties):
{
"type": "Feature",
"properties": {
"clu_identifier": "3ecc54fc-5077-11d6-8e82-00065b4a19c0",
"clu_alt_id": "{5626C60F-23B1-4172-BCFA-842EBDEE776F}",
"data_source": "danna.steffens",
"clu_status": null,
"tract_number": "768",
"last_change_date": 1352656579000,
"last_chg_user_nm": null,
"creation_date": 1113921633000,
"admin_state": "20",
"clu_calculated_acreage": 152.41,
"OBJECTID": 582,
"cropland_indicator_3CM": 1,
"edit_reason": null,
"GlobalId": "{DE7A11AA-BFB6-4DFE-A1D7-D795D7DD7990}",
"SHAPE_STArea__": 1012852.6422872,
"state_code": "20",
"cdist_fips": "2001",
"highly_erodible_land_type_code": "NHEL",
"admin_county": "171",
"clu_classification_code": "2",
"sap_crp": null,
"farm_number": "4384",
"SHAPE_STLength__": 4161.19756459,
"ESRI_OID": 530,
"clu_number": "1",
"data_source_site_identifier": null,
"comments": " ",
"county_code": "171"
},
"geometry": {...
},
{
"type": "Feature",
"properties": {
"farm_number": "4384",
"admin_state": "20",
"tract_number": "5468",
"admin_county": "171",
"tract_boundary": true
},
"geometry": {...
}
Any ideas?

You can get the "full" schema by calling org.geotools.geojson.feature.FeatureJSON.readFeatureCollectionSchema(Object, boolean) with the 2nd argument set to false so that the whole collection is read rather than just the first item. Then you can set the FeatureType of your features correctly.

Related

How to include validations for key as well as value in a json schema

I need to add validations for a property as well as a value in json schema.
I tried to use the below schema but none of the validations work :
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"add": {
"type": "object",
"patternProperties": {
"^VOF979[0-9]{11}-NDG[0-9]{2}$": {
"description": "Some description",
"type": "string",
"maxLength": 2
}
}
}
}
}
I used below json data and all the validations passes although the key and value both are wrong :
{
"add": {"VOF98999990005235-NDG01": "121"}
}
JSON Schema is constraints based.
patternProperties applies its value schema to the instance location based on the key match (in this case, regex match).
It does not prohibit additional keys in the object.
If you want to prevent additional keys, you need to specify so.
To do this, you need "additionalProperties": false.
Do not allow additional properties to keep strict validation
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"properties": {
"add": {
"type": "object",
"patternProperties": {
"^VOF979[0-9]{11}-NDG[0-9]{2}$": {
"description": "Some description",
"type": "string",
"maxLength": 2
}
},
"additionalProperties": false // This One
}
},
"additionalProperties": false,
"minProperties": 1
}
Reference to Docs Have a look at this

Json response to be deserialized in Apex salesforce lightning

I am getting the below Json Response by hitting a RestAPI.
**
[
{
"index": 0,
"object": {
"attributes": {
"ID": [
{
"type": "configuration/entityTypes/Customer/attributes/ID",
"ov": true,
"value": "5",
"uri": "entities/attributes/ID/2Cqf5xG2"
},
{
"type": "configuration/entityTypes/Customer/attributes/ID",
"ov": true,
"value": "3028",
"uri": "entities/attributes/ID/fto38ZRR"
}
],
"IgpId": [
{
"type": "configuration/entityTypes/Customer/attributes/IgpId",
"ov": true,
"value": "1911",
"uri": "entities/attributes/IgpId/20ft8omYM"
}
],
"IgpName": [
{
"type": "configuration/entityTypes/Customer/attributes/IgpName",
"ov": true,
"value": "Dr. heath",
"uri": "entities/attributes/IgpName/20ft8oe1q"
}
],
"IgpID": [
{
"type": "configuration/entityTypes/Customer/attributes/IgpID",
"ov": true,
"value": "1872",
"uri": "entities/attributes/IgpID/20ft8oiI6"
}
],
"IgpNAME": [
{
"type": "configuration/entityTypes/Customer/attributes/IgpNAME",
"ov": true,
"value": "Dr Jc crook",
"uri": "entities/attributes/IgpNAME/20ft8oqoc"
}
]
}
},
"successful": true
}
]
**
I am trying to save the values for CoachID (3028), IgpID(1872), IgpId(1911), IgpName(Dr. heath), IgpNAME(Dr Jc crook) in String variables in APex class.
I have used a map to do so but unable to get the proper values. I wanted to get the above values in a List & return that list from function.
Can anyone help me on this? I am not supposed to do this using wrapper.
Regards,
Mohit
It can't be done as straight "JSON.deserialize" call because some fields are reserved keywords in Apex. How strict the wrapper ban is? I wouldn't want to type this stuff freehand but you can go to https://json2apex.herokuapp.com/, tick checkbox about explicit parser (again, since you have reserved keywords it'd happen anyway) and well, you have a ready class & cool stab at unit test / example how to use the code. It's battle-tested, if you can't use that then your project has bigger problems ;)
If you really really have to do it alone and with maps it'll be something like https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_System_Json.htm, example for deserializeUntyped

How to fetch different type of documents from a single collection - Mongodb - MongoTemplate

I have a collection with different type of documents. Have different types of network tables & different type of entries of the tables in the single collection. depending of type document is different.I am trying to fetch these document based on some filter queries. As i have different documents i cant create a pojo with fixed fields because fields can vary according to the document so i can query like this. I first want to fetch tables & later their entries based on table selection. Table document does not have "entry" key so i am using query like this - {type:{$exists:true},entry:{$exists:false}}
return mongoTemplate.find(query, NetworkTable.class);
Have tried using Document.class instead of NetworkTable.class. Have tried with BasicQuery & Criteria but its not working. Query used to fetch tables only - Its working on mongodb shell.
//BasicQuery query = new BasicQuery("{role:{$exists:true}}{type:{$exists:true},entry:{$exists:false}}");
Query query = new Query();
query.addCriteria(Criteria.where("entry").exists(flase));
return mongoTemplate.find(query, Document.class,"user"); //user is collection name
Its giving below error when i use Document.class instead of NetworkTable.class -
{
"timestamp": 1591963169373,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.data.mapping.model.MappingInstantiationException",
"message": "Failed to instantiate org.springframework.data.mongodb.core.mapping.Document using constructor NO_CONSTRUCTOR with arguments ",
}
Need quick help to resolve this.
Documents-
{
"_id": {
"$oid": "5ee2313e3694087f868576e2"
},
"_class": "org.json.simple.JSONObject",
"_href": "https://1.1.1.1/config/xyz/2/table/ABC",
"_display_name": " Table \"ABC\",
"_state": "ok",
"name": "ABC",
"description": "",
"type": "type1",
"xyz": "2",
"_short_name": "\"ABC\" "
},
{
"_id": {
"$oid": "5ee2313f3694087f868576e4"
},
"_class": "org.json.simple.JSONObject",
"_href": "https://1.1.1.1/config/xyz/2/table/ABC/entry/1",
"_display_name": "Entry 1",
"apply-destination-number-manipulation": false,
"type": "destination-tgid",
"xyz": "2",
"_children": [
],
"entry": "1",
"_state": "ok",
"apply-traffic-group": false,
"apply-source-number-manipulation": false,
"name": "ABC",
"action": "reject",
"destination-sip-adjacency": {
"_href": ""
},
"match-tgid": "any",
"destination-tgid-manipulation": "none",
"source-tgid-manipulation": "none",
"_short_name": "1"
},
{
"_id": {
"$oid": "5ee2313f3694087f86812344"
},
"_class": "org.json.simple.JSONObject",
"_display_name": "Entry 1",
"_href": "https://1.1.1.1/config/xyz/2/table/LLKORTELCSCS/entry/1",
"_short_name": "1",
"_state": "ok",
"action": "complete",
"apply-destination-number-manipulation": false,
"apply-source-number-manipulation": false,
"apply-traffic-group": false,
"xyz": "2",
"cost": 1,
"destination-adjacency": {
"_display_name": " \"LLKORTELCSCS_A\"",
"_href": "https://1.1.1.1/config/adjacency/sip/LLKORTELCSCS_A",
"_short_name": "LLKORTELCSCS_A"
},
"destination-tgid-manipulation": "none",
"entry": "1",
"name": "LLKORTELCSCS",
"route-on-cost": "set-cost",
"source-tgid-manipulation": "none",
"type": "least-cost",
"weight": 5
}

How to generate json data from Json Schema Programmatically in Java

I am trying to create Body-parameter(JSON) for my POST Api , which is a JSON request . All I have is the JSON Schema . I am trying to come up with a list of different JSON test data covering Positive and negative flows for it .
Is there any option to generate / create the JSON data programmatic using Java ? . I have attached a small Json schema (just for understanding purpose) but my actual schema is more complicated with lot of Array's and Nested Json's .
My Json Schema :
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"title": "The Root Schema",
"description": "The root schema comprises the entire JSON document.",
"required": [
"FirstName",
"LastName",
"Age",
"Interest"
],
"properties": {
"FirstName": {
"$id": "#/properties/FirstName",
"type": "string",
"title": "The Firstname Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Vijay"
]
},
"LastName": {
"$id": "#/properties/LastName",
"type": "string",
"title": "The Lastname Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Karthik"
]
},
"Age": {
"$id": "#/properties/Age",
"type": "integer",
"title": "The Age Schema",
"description": "An explanation about the purpose of this instance.",
"default": 0,
"examples": [
30
]
},
"Interest": {
"$id": "#/properties/Interest",
"type": "array",
"title": "The Interest Schema",
"description": "An explanation about the purpose of this instance.",
"default": [],
"items": {
"$id": "#/properties/Interest/items",
"type": "string",
"title": "The Items Schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"Food",
"movie",
"Learning",
"VideoGames"
]
}
}
}
}enter code here
My TestData looks like :
{
"FirstName":"Vivi",
"LastName":"Karrri",
"Age":30,
"Interest":["Food","movie","Learning","VideoGames"]
}
Any suggestions how can we achive this ?
Note : I am using Springboot and I have complete POJO for the request object
You can generate fake java-objects and then map them to JSON.
POJOs
If you already have the POJOs matching the schema, then we can skip this step.
If no, to generate a POJO from the schema, for example, can be used this library:
jsonschema2pojo.
Fake objects
Generating of objects with fake data can be done with a special library, some of them are listed here:
easy-random
podam
java-faker
Generating JSON
It's prettry simple and can be done with Jackson:
ObjectMapper objectMapper = new ObjectMapper();
ObjectWriter prettyPrinter = objectMapper.writerWithDefaultPrettyPrinter();
String json = prettyPrinter.writeValueAsString(yourFakeObject);
If you have json schema then you can directly generate a sample JSON message from it.
https://github.com/jignesh-dhua/json-generator

How to populate velocity string with a JSON Object in JAVA?

I am working on velocty and java, I was to take values from an json file (which I took using recursion of JSON OBjects and storing path of recursion(See context below to get idea)
String hhh="I am a ${root.primaryApplicant.firstName} ${firstName} ";
Velocity.init();
VelocityContext vm=new VelocityContext();
for(String m : mp.keySet())
{
vm.put(m,mp.get(m));
}
StringWriter w = new StringWriter();
Velocity.evaluate( vm, w, "mystring", forma );
The map mp is obtained from a json file
{
"id": 45288,
"code": null,
"name": null,
"external": false,
"leadReferenceId": "APPID1573716175142",
"createdBy": null,
"createdDate": "2017-10-26T12:14:17.000Z",
"agentName": null,
"ipAddress": null,
"applicationType": "HOME",
"loanType": "HOME",
"applicantType": {
"id": 269,
"code": "Single",
"name": "Single",
"external": false
},
"relationship": null,
"primaryApplicant": {
"id": 45289,
"code": null,
"name": null,
"external": false,
"existingCustomer": null,
"customerId": null,
"partyRoleType": {
"id": 348,
"code": "0",
"name": "PRIMARY",
"external": false
},
"partyRelationshipType": null,
"salutation": {
"id": 289,
"code": "MR",
"name": "Mr",
"external": false
},
"firstName": "Anuj",
"middleName": "",
"lastName": "singh",
"dateOfBirth": "1986-12-11T18:30:00.000Z",
"genderType": {
using a debugger the context of vm contains
"root.primaryApplicant.firstName" -> "Anuj"
"firstName" -> "Anuj"
after Velocity evaluate I get
"I am a ${root.primaryApplicant.firstName} Anuj ";
i am assuming it cant replace keys with . in between.
Is there any better way to populate the string
----------------
The velocity file has a "root.*" specified and since I cant edit those, I am using the following recursion program to get the keys
private static void rexuse(String a,Map<String, Object> mp,JSONObject js,String parent) throws JSONException {
Iterator<String> keys = js.keys();
while(keys.hasNext()) {
String key = keys.next();
if(key.equals("name"))
{
mp.put(parent,js.get(key));
}
if (js.get(key) instanceof JSONObject) {
rexuse(a+"."+key,mp,js.getJSONObject(key),key);
}
else
{
if(!mp.containsKey(key) ||( mp.containsKey(key) && mp.get(key)==null))
mp.put(key, js.get(key));
mp.put(a+"."+key, js.get(key) );
}
}
}
where a is the prefix and called the above using
String a="root";
rexuse(a,mp,js,"root");
There is an inconsistency, here.
With the Java initialization code you give, the Velocity template should contain:
${primaryApplicant.firstName}
If you want to use ${root.primaryApplicant.firstName}, then the other reference should also be prefixed by root, as in ${root.firstName}, and the Java context initialization code should be:
vm.put("root", mp);
But in both cases you must also check that the json library you are using provides a Json object with a generic getter, so that the 'dot' operator will recursively call the Java method get(<fieldname>) on the json object. There are tons of those.

Categories

Resources