Skip to content

Commit

Permalink
Merge pull request #13 from relogiclabs/develop
Browse files Browse the repository at this point in the history
Update Exception Handling
  • Loading branch information
zhossain-info authored Aug 31, 2024
2 parents 0b6159f + 8dd016d commit 773f1a7
Show file tree
Hide file tree
Showing 511 changed files with 17,147 additions and 9,261 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ The next example represents an expanded version of the previous one, which bring
```cpp
%title: "Extended User Profile Dashboard API Response"
%version: "2.0.0-extended"
%import: com.relogiclabs.jschema.test.external.ExternalFunctions

%pragma DateDataTypeFormat: "DD-MM-YYYY"
%pragma TimeDataTypeFormat: "DD-MM-YYYY hh:mm:ss"
Expand Down Expand Up @@ -105,6 +106,7 @@ The next example represents an expanded version of the previous one, which bring
"isActive": #boolean, //user account current status
"registeredAt": @after("01-01-2010 00:00:00") #time,
"dataAccess": @checkAccess(&role) #integer,
"ipAddress": @checkIPAddress #string,
"profile": {
"firstName": @regex("[A-Za-z]{3,50}") #string,
"lastName": @regex("[A-Za-z]{3,50}") #string,
Expand Down Expand Up @@ -140,20 +142,21 @@ The next example represents an expanded version of the previous one, which bring
if(role == "user" && target > 5) return fail(
"ERRACCESS01", "Data access incompatible with 'user' role",
expected("an access at most 5 for 'user' role"),
actual("found access " + target + " which is greater than 5"));
actual("found access " + target + " that is greater than 5"));
}
}
```
The subsequent JSON sample is an illustrative example that successfully validates against the expanded schema mentioned earlier. Within this example, recurring JSON structures appear that can be validated by defining components or nested functions and data types. Besides, reusing simple component definitions, you can achieve a clear and concise schema when validating large JSON with repetitive structures. This improves the overall readability and maintainability of the schema.
```json
{
"user": {
"id": 1234,
"id": 1111,
"username": "johndoe",
"role": "admin",
"isActive": true,
"registeredAt": "06-09-2023 15:10:30",
"dataAccess": 10,
"ipAddress": "127.0.0.1",
"profile": {
"firstName": "John",
"lastName": "Doe",
Expand Down Expand Up @@ -183,7 +186,7 @@ The subsequent JSON sample is an illustrative example that successfully validate
"title": "Working with JSON in Java",
"content": "Java provides great support for working with JSON...",
"tags": [
"CSharp",
"Java",
"JSON",
"tutorial"
]
Expand Down
17 changes: 9 additions & 8 deletions doc/content/articles/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,25 @@ weight = 10
# Schema Components
A schema component, also known as a reusable schema fragment or sub-schema, plays a vital role in improving readability, reducing redundancy, and organizing the structure of a Schema document. In JSON validation, a schema component or fragment defines a validation rule that can be recursively composed of multiple nested validation rules, collectively specifying the expected and valid format of a JSON construct.

These schema components are used as an extension of data type validation, as core data types have limited features to validate the internal structure of a composite JSON value or construct. Therefore, a data type is parameterized with a schema component to validate the internal structure of such composite JSON constructs.
These schema components are used as an extension of data type validation, as core data types have limited features to validate the internal structure of a composite JSON value or construct. Therefore, a data type is parameterized with a schema component to validate the internal structure of such composite JSON constructs.

The name or alias of a schema component always starts with `$` which also refers to the fact that they are named schema components or fragments defined elsewhere in the schema. Schema components can be referenced from any other part of the schema document, effectively reducing redundancy and enhancing reusability and readability. The following example defines a simple schema component named `$component` where the validation rule describes an object structure with two key-value pairs:
The name or alias of a schema component always starts with `$` which unambiguously indicates that they are named schema components or fragments defined elsewhere in the schema. Schema components can be referenced from any parts of the schema document, effectively reducing redundancy and enhancing reusability and readability. The following example defines a simple schema component named `$component` where the validation rule describes an object structure with two key-value pairs:
```js
%define $component: { "key1": #integer, "key2": #string }
```

A composite JSON construct is created by combining multiple values as defined by the JSON specification. These nested values can range from simple, like numbers or strings, to more complex, such as arrays or objects. While simple nested values of a composite construct can be validated using only nested data types and functions, handling hierarchical composite constructs with multiple layers of nested structures requires defining schema components.

The second and third rows of the following table illustrate how the component validates the value associated with the data type for which it is used as a parameter. If the associated data type is direct, the component validates the target value itself. Conversely, if the associated data type is nested, the component validates each of the nested values comprising the composite target construct.
The second and third rows of the following table illustrate how the component validates the value associated with the data type for which it is used as a parameter. If the associated data type is direct, the component validates the target value itself. Conversely, if the associated data type is nested, the component validates each of the nested values.

| SN | Component Example | Valid Json |
|----|----------------------------------------------------------------------------------|--------------------|
| 1 | `@range*(1, 10) @length(5) #integer* #array` | `[1, 3, 5, 8, 10]` |
| 2 | `%define $cmp: @range*(1, 10) #integer*` <br> `%schema: @length(5) #array($cmp)` | `[1, 3, 5, 8, 10]` |
| 3 | `%define $cmp: @range(1, 10)` <br> `%schema: @length(5) #integer*($cmp) #array` | `[1, 3, 5, 8, 10]` |
| 1 | `%schema: @range*(1, 10) @length(5) #integer* #array` | `[1, 3, 5, 8, 10]` |
| 2 | `%define $cmp: @range(1, 10)` <br> `%schema: @length(5) #integer*($cmp) #array` | `[1, 3, 5, 8, 10]` |
| 3 | `%define $cmp: @range*(1, 10) #integer*` <br> `%schema: @length(5) #array($cmp)` | `[1, 3, 5, 8, 10]` |
| 4 | `%define $cmp: @range*(1, 10) @length(5) #integer* #array` <br> `%schema: $cmp` | `[1, 3, 5, 8, 10]` |

In the above table, all three rows have identical validation constraints for the input JSON array. This demonstrates that when dealing with simple and primitive nested values in a composite JSON construct, preferring the nested data types and functions is more convenient due to their simplicity and conciseness. However, in cases where the nested values are complex and composite, the schema component syntax becomes more suitable. The following example illustrates how the component syntax can be used to validate elements of a JSON array that are not as straightforward as the previous examples:
In the above table, all four rows have identical validation constraints for the input JSON array. This demonstrates that when dealing with simple and primitive nested values in a composite JSON construct, preferring the nested data types and functions is more convenient due to their simplicity and conciseness. However, in cases where the nested values are complex and composite, the schema component syntax becomes more suitable. The following example illustrates how the component syntax can be used to validate elements of a JSON array that are not as straightforward as the previous examples:
```js
%define $article: {
"id": @range(1, 100) #integer,
Expand All @@ -36,7 +37,7 @@ In the above table, all three rows have identical validation constraints for the
%schema: @length(1, 10) #object*($article) #array
```

In practical scenarios, JSON arrays often hold multiple composite JSON constructs as elements, typically sharing a recurring pattern and structure similar to the example above. To facilitate the validation of such elements, using schema components is highly effective.
In practical scenarios, JSON arrays often hold multiple composite JSON constructs as elements, typically sharing a recurring pattern and structure similar to the example above. To facilitate the validation of such elements, using schema components is highly effective.

By defining a reusable schema component with a clear and descriptive name, one can improve the overall clarity and readability of the Schema document with recurring structures. This clarity not only makes it easier to understand the structure and intent of the schema but also contributes to keeping your complex schema well-organized, concise, and more manageable. For instance, consider the following example of a JSON document which is valid against the schema example provided above, demonstrating the usage of a schema component:
```js
Expand Down
28 changes: 14 additions & 14 deletions doc/content/articles/cscript.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ The `#void` type is reserved for internal operations, including initializing una
## Operators & Precedences
CScript operators are symbols that are used to perform operations on variables and values. The direct operation of any operator that requires a modifiable l-value including `++`, `--` or `=` will raise an exception for the readonly schema nodes. The following table lists the operators according to their precedences from the highest to the lowest:

| SN | Category | Operator |
|----|-------------------------------|-----------------------------------|
| 1 | Property Access & Parentheses | `.`; `[]`; `()` |
| 2 | Unary Minus & Logical Not | `-`; `!` |
| 3 | Postfix Increment/Decrement | `i++`; `i--` |
| 4 | Prefix Increment/Decrement | `++i`; `--i` |
| 5 | Arithmetic Multiplicative | `*`; `/`; `%` |
| 6 | Arithmetic Additive | `+`; `-` |
| 7 | Sequence Range | `..` |
| 8 | Relational Comparison | `>`; `<`; `>=`; `<=` |
| 9 | Equality Comparison | `==`; `!=` |
| 10 | Logical And (Short-Circuit) | `&&` |
| 11 | Logical Or (Short-Circuit) | `\|\|` |
| 12 | Assignment | `=`; `+=`; `-=`; `*=`; `/=`; `%=` |
| SN | Category | Operator |
|----|--------------------------------|-----------------------------------|
| 1 | Property Access & Parentheses | `.`; `[]`; `()` |
| 2 | Unary Plus/Minus & Logical Not | `+`; `-`; `!` |
| 3 | Postfix Increment/Decrement | `i++`; `i--` |
| 4 | Prefix Increment/Decrement | `++i`; `--i` |
| 5 | Arithmetic Multiplicative | `*`; `/`; `%` |
| 6 | Arithmetic Additive | `+`; `-` |
| 7 | Sequence Range | `..` |
| 8 | Relational Comparison | `>`; `<`; `>=`; `<=` |
| 9 | Equality Comparison | `==`; `!=` |
| 10 | Logical And (Short-Circuit) | `&&` |
| 11 | Logical Or (Short-Circuit) | `\|\|` |
| 12 | Assignment (Augmented) | `=`; `+=`; `-=`; `*=`; `/=`; `%=` |

## Function Types
Function types are essential for specifying the executable units that serve as the building-blocks of validation process within CScript. All function types can also accept variable number of arguments, specified by an ellipsis `...` after the last parameter name which is then bound to an array containing the remaining arguments.
Expand Down
16 changes: 14 additions & 2 deletions doc/content/articles/directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ To customize the default format of the `#time` data type, utilize the `TimeDataT
```

### Floating Point Tolerance
The `FloatingPointTolerance` pragma directive allows you to define the tolerance level for relative errors in floating-point numbers during calculations and computations carried out by the validation process. By default, this directive is set to `1E-10`, indicating a small tolerance. However, you have the flexibility to adjust this value to any desired number. To specify a custom tolerance value of `1E-07`, you can use the following notation as an example:
The pragma directive `FloatingPointTolerance` allows you to define the tolerance level for relative errors in floating-point numbers during calculations and computations carried out by the validation process. By default, this directive is set to `1E-10`, indicating a small tolerance. However, you have the flexibility to adjust this value to any desired number. To specify a custom tolerance value of `1E-07`, you can use the following notation as an example:
```js
%pragma FloatingPointTolerance: 1E-07
```
Expand All @@ -66,6 +66,18 @@ The `IgnoreObjectPropertyOrder` pragma directive provides a means to enforce a s
%pragma IgnoreObjectPropertyOrder: false
```

### Enable Contextual Exception
The `EnableContextualException` pragma directive enables an additional type of exception. These exceptions provide supplementary contextual information about the primary exceptions, showing the errors that occurred during the validation process. The default value of this directive is `false`, meaning no contextual exceptions are generated.
```js
%pragma EnableContextualException: true
```

### Outline Maximum Length
The pragma directive `OutlineMaximumLength` specifies the maximum length of tree outlines generated when string representations of large Schema and JSON trees or subtrees are needed. The default maximum length is `200` characters. If the tree or subtree string exceeds this limit, an outline is shown instead of the full string representation. Currently, a basic abbreviation rule is used to create the tree outlines.
```js
%pragma OutlineMaximumLength: 500
```

## Definition / Define Directive
This feature in JSchema allows you to define a name for a schema component or fragment, which can be referenced from various parts of your schema. This means that if you encounter similar validation requirements in different sections of your schema, you can conveniently refer to the named schema component instead of duplicating the same validation rules. For more information about the schema component syntax and format, please refer to the documentation [here](/JSchema-Java/articles/components). Here is a simple example of how to use this directive:
```js
Expand Down Expand Up @@ -102,7 +114,7 @@ The script directive enables the inclusion of CScript code into a JSchema docume
%script: {
constraint function checkAccess(role) {
if(role[0] == "user" && target > 5) return fail(
"ERRACCESS01", "Data access incompatible with 'user' role",
"EX_ERRACCESS01", "Data access incompatible with 'user' role",
expected("an access at most 5 for 'user' role"),
actual("found access " + target + " which is greater than 5"));
}
Expand Down
Loading

0 comments on commit 773f1a7

Please sign in to comment.