Skip to content

Commit 9ec1cbc

Browse files
committed
Correct the type Options
1 parent 18a8490 commit 9ec1cbc

File tree

8 files changed

+71
-31
lines changed

8 files changed

+71
-31
lines changed

ballerina/json_api.bal

+9-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// KIND, either express or implied. See the License for the
1414
// specific language governing permissions and limitations
1515
// under the License.
16-
1716
import ballerina/jballerina.java;
1817

1918
# Convert value of type `json` to subtype of `anydata`.
@@ -56,16 +55,20 @@ public isolated function parseStream(stream<byte[], error?> s, Options options =
5655
#
5756
# + v - Source anydata value
5857
# + return - representation of `v` as value of type json
59-
public isolated function toJson(anydata v)
58+
public isolated function toJson(anydata v)
6059
returns json|Error = @java:Method {'class: "io.ballerina.lib.data.jsondata.json.Native"} external;
6160

6261
# Represent the options that can be used to modify the behaviour of the projection.
6362
#
64-
# + allowDataProjection - enable or disable projection
63+
# + allowDataProjection - Enable or disable projection.
6564
public type Options record {
66-
boolean nilAsOptionalField = false;
67-
boolean absentAsNilableType = false;
68-
}|false;
65+
record {
66+
# If true, nil values will be considered as optional fields in the projection.
67+
boolean nilAsOptionalField = false;
68+
# If true, absent fields will be considered as nilable types in the projection.
69+
boolean absentAsNilableType = false;
70+
}|false allowDataProjection = {};
71+
};
6972

7073
# Represents the error type of the ballerina/data.jsondata module. This error type represents any error that can occur
7174
# during the execution of jsondata APIs.

ballerina/tests/from_json_with_disable_projection_option.bal

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import ballerina/test;
1818

19-
const options = false;
19+
const options = {allowDataProjection: false};
2020

2121
@test:Config
2222
isolated function testDisableDataProjectionInArrayTypeForParseString() {

ballerina/tests/from_json_with_projection_options_test.bal

+30-7
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,38 @@
1515
// under the License.
1616

1717
import ballerina/io;
18-
import ballerina/test;
1918
import ballerina/lang.value;
19+
import ballerina/test;
2020

2121
const PATH = "tests/resources/";
2222

23-
const options1 = {nilAsOptionalField: true, absentAsNilableType: false};
24-
const options2 = {nilAsOptionalField: false, absentAsNilableType: true};
25-
const options3 = {nilAsOptionalField: true, absentAsNilableType: true};
26-
const options4 = {nilAsOptionalField: false, absentAsNilableType: false};
23+
const options1 = {
24+
allowDataProjection: {
25+
nilAsOptionalField: true,
26+
absentAsNilableType: false
27+
}
28+
};
29+
30+
const options2 = {
31+
allowDataProjection: {
32+
nilAsOptionalField: false,
33+
absentAsNilableType: true
34+
}
35+
};
36+
37+
const options3 = {
38+
allowDataProjection: {
39+
nilAsOptionalField: true,
40+
absentAsNilableType: true
41+
}
42+
};
43+
44+
const options4 = {
45+
allowDataProjection: {
46+
nilAsOptionalField: false,
47+
absentAsNilableType: false
48+
}
49+
};
2750

2851
type Sales record {|
2952
@Name {
@@ -251,7 +274,7 @@ type ResponseEcom record {
251274
isolated function testAbsentAsNilableTypeAndAbsentAsNilableTypeForParseString() returns error? {
252275
string jsonData = check io:fileReadString(PATH + "product_list_response.json");
253276
ResponseEcom response = check parseString(jsonData, options3);
254-
277+
255278
test:assertEquals(response.status, "success");
256279
test:assertEquals(response.data.products[0].length(), 6);
257280
test:assertEquals(response.data.products[0].id, 1);
@@ -313,7 +336,7 @@ isolated function testAbsentAsNilableTypeAndAbsentAsNilableTypeForParseString2()
313336
string jsonData = check io:fileReadString(PATH + "product_list_response.json");
314337
json productJson = check value:fromJsonString(jsonData);
315338
ResponseEcom response = check parseAsType(productJson, options3);
316-
339+
317340
test:assertEquals(response.status, "success");
318341
test:assertEquals(response.data.products[0].length(), 6);
319342
test:assertEquals(response.data.products[0].id, 1);

native/src/main/java/io/ballerina/lib/data/jsondata/io/DataReaderTask.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import io.ballerina.runtime.api.types.MethodType;
2525
import io.ballerina.runtime.api.types.ObjectType;
2626
import io.ballerina.runtime.api.utils.TypeUtils;
27+
import io.ballerina.runtime.api.values.BMap;
2728
import io.ballerina.runtime.api.values.BObject;
29+
import io.ballerina.runtime.api.values.BString;
2830
import io.ballerina.runtime.api.values.BTypedesc;
2931

3032
import java.io.InputStreamReader;
@@ -44,9 +46,10 @@ public class DataReaderTask implements Runnable {
4446
private final BObject iteratorObj;
4547
private final Future future;
4648
private final BTypedesc typed;
47-
private final Object options;
49+
private final BMap<BString, Object> options;
4850

49-
public DataReaderTask(Environment env, BObject iteratorObj, Future future, BTypedesc typed, Object options) {
51+
public DataReaderTask(Environment env, BObject iteratorObj, Future future, BTypedesc typed,
52+
BMap<BString, Object> options) {
5053
this.env = env;
5154
this.iteratorObj = iteratorObj;
5255
this.future = future;

native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonParser.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public class JsonParser {
6666
* @return JSON structure
6767
* @throws BError for any parsing error
6868
*/
69-
public static Object parse(Reader reader, Object options, Type type)
69+
public static Object parse(Reader reader, BMap<BString, Object> options, Type type)
7070
throws BError {
7171
StateMachine sm = tlStateMachine.get();
7272
try {
@@ -197,9 +197,8 @@ private void processLocation(char ch) {
197197
}
198198
}
199199

200-
public Object execute(Reader reader, Object options, Type type) throws BError {
200+
public Object execute(Reader reader, BMap<BString, Object> options, Type type) throws BError {
201201
switch (type.getTag()) {
202-
// TODO: Handle readonly and singleton type as expType.
203202
case TypeTags.RECORD_TYPE_TAG -> {
204203
RecordType recordType = (RecordType) type;
205204
expectedTypes.push(recordType);
@@ -249,10 +248,15 @@ public Object execute(Reader reader, Object options, Type type) throws BError {
249248
default -> throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE, type);
250249
}
251250

252-
if (options instanceof BMap<?, ?>) {
253-
allowDataProjection = true;
254-
absentAsNilableType = (Boolean) ((BMap<?, ?>) options).get(Constants.ABSENT_AS_NILABLE_TYPE);
255-
nilAsOptionalField = (Boolean) ((BMap<?, ?>) options).get(Constants.NIL_AS_OPTIONAL_FIELD);
251+
Object allowDataProjection = options.get(Constants.ALLOW_DATA_PROJECTION);
252+
if (allowDataProjection instanceof Boolean) {
253+
this.allowDataProjection = false;
254+
} else if (allowDataProjection instanceof BMap<?, ?>) {
255+
this.allowDataProjection = true;
256+
this.absentAsNilableType =
257+
(Boolean) ((BMap<?, ?>) allowDataProjection).get(Constants.ABSENT_AS_NILABLE_TYPE);
258+
this.nilAsOptionalField =
259+
(Boolean) ((BMap<?, ?>) allowDataProjection).get(Constants.NIL_AS_OPTIONAL_FIELD);
256260
}
257261

258262
State currentState = DOC_START_STATE;

native/src/main/java/io/ballerina/lib/data/jsondata/json/JsonTraverse.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,18 @@ public class JsonTraverse {
5757

5858
private static final ThreadLocal<JsonTree> tlJsonTree = ThreadLocal.withInitial(JsonTree::new);
5959

60-
public static Object traverse(Object json, Object options, Type type) {
60+
public static Object traverse(Object json, BMap<BString, Object> options, Type type) {
6161
JsonTree jsonTree = tlJsonTree.get();
6262
try {
63-
if (options instanceof BMap) {
63+
Object allowDataProjection = options.get(Constants.ALLOW_DATA_PROJECTION);
64+
if (allowDataProjection instanceof Boolean) {
65+
jsonTree.allowDataProjection = false;
66+
} else if (allowDataProjection instanceof BMap<?, ?>) {
6467
jsonTree.allowDataProjection = true;
65-
jsonTree.absentAsNilableType = (Boolean) ((BMap<?, ?>) options).get(Constants.ABSENT_AS_NILABLE_TYPE);
66-
jsonTree.nilAsOptionalField = (Boolean) ((BMap<?, ?>) options).get(Constants.NIL_AS_OPTIONAL_FIELD);
68+
jsonTree.absentAsNilableType =
69+
(Boolean) ((BMap<?, ?>) allowDataProjection).get(Constants.ABSENT_AS_NILABLE_TYPE);
70+
jsonTree.nilAsOptionalField =
71+
(Boolean) ((BMap<?, ?>) allowDataProjection).get(Constants.NIL_AS_OPTIONAL_FIELD);
6772
}
6873
return jsonTree.traverseJson(json, type);
6974
} catch (BError e) {

native/src/main/java/io/ballerina/lib/data/jsondata/json/Native.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.ballerina.runtime.api.utils.JsonUtils;
2626
import io.ballerina.runtime.api.values.BArray;
2727
import io.ballerina.runtime.api.values.BError;
28+
import io.ballerina.runtime.api.values.BMap;
2829
import io.ballerina.runtime.api.values.BObject;
2930
import io.ballerina.runtime.api.values.BStream;
3031
import io.ballerina.runtime.api.values.BString;
@@ -41,23 +42,23 @@
4142
*/
4243
public class Native {
4344

44-
public static Object parseAsType(Object json, Object options, BTypedesc typed) {
45+
public static Object parseAsType(Object json, BMap<BString, Object> options, BTypedesc typed) {
4546
try {
4647
return JsonTraverse.traverse(json, options, typed.getDescribingType());
4748
} catch (BError e) {
4849
return e;
4950
}
5051
}
5152

52-
public static Object parseString(BString json, Object options, BTypedesc typed) {
53+
public static Object parseString(BString json, BMap<BString, Object> options, BTypedesc typed) {
5354
try {
5455
return JsonParser.parse(new StringReader(json.getValue()), options, typed.getDescribingType());
5556
} catch (BError e) {
5657
return e;
5758
}
5859
}
5960

60-
public static Object parseBytes(BArray json, Object options, BTypedesc typed) {
61+
public static Object parseBytes(BArray json, BMap<BString, Object> options, BTypedesc typed) {
6162
try {
6263
byte[] bytes = json.getBytes();
6364
return JsonParser.parse(new InputStreamReader(new ByteArrayInputStream(bytes)), options,
@@ -67,7 +68,7 @@ public static Object parseBytes(BArray json, Object options, BTypedesc typed) {
6768
}
6869
}
6970

70-
public static Object parseStream(Environment env, BStream json, Object options, BTypedesc typed) {
71+
public static Object parseStream(Environment env, BStream json, BMap<BString, Object> options, BTypedesc typed) {
7172
final BObject iteratorObj = json.getIteratorObj();
7273
final Future future = env.markAsync();
7374
DataReaderTask task = new DataReaderTask(env, iteratorObj, future, typed, options);

native/src/main/java/io/ballerina/lib/data/jsondata/utils/Constants.java

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class Constants {
3636
public static final String FIELD = "$field$.";
3737
public static final String FIELD_REGEX = "\\$field\\$\\.";
3838
public static final String NAME = "Name";
39+
public static final BString ALLOW_DATA_PROJECTION = StringUtils.fromString("allowDataProjection");
3940
public static final BString NIL_AS_OPTIONAL_FIELD = StringUtils.fromString("nilAsOptionalField");
4041
public static final BString ABSENT_AS_NILABLE_TYPE = StringUtils.fromString("absentAsNilableType");
4142
public static final String NULL_VALUE = "null";

0 commit comments

Comments
 (0)