├── src
├── classes
│ ├── JSONReservedSerializer.cls-meta.xml
│ ├── JSONReservedSerializer_Tests.cls-meta.xml
│ ├── JSONReservedSerializer_Tests.cls
│ └── JSONReservedSerializer.cls
└── package.xml
└── README.md
/src/classes/JSONReservedSerializer.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 38.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/JSONReservedSerializer_Tests.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 38.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JSONReservedSerializer
5 | JSONReservedSerializer_Tests
6 | ApexClass
7 |
8 | 38.0
9 |
10 |
--------------------------------------------------------------------------------
/src/classes/JSONReservedSerializer_Tests.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | public class JSONReservedSerializer_Tests {
3 |
4 | @isTest
5 | private static void testRoundTrip(){
6 | String origString = '{"object":{"notReserved":"abc","private":true}}';
7 |
8 | MySerializer myJSON = new MySerializer();
9 |
10 | //deserialization
11 | MyDTO obj = (MyDTO)
12 | myJSON.deserialize(
13 | origString,
14 | MyDTO.class
15 | );
16 |
17 | //serialization
18 | String newString = myJSON.serialize(obj, MyDTO.class);
19 | System.assertEquals(origString, newString);
20 | }
21 |
22 | // CLASS FOR TESTING
23 | public class MySerializer extends JSONReservedSerializer {
24 | public MySerializer() {
25 | //setup mappings
26 | super(new Map>{
27 | MyDTO.class => new Map {
28 | 'obj' => 'object',
29 | 'isPrivate' => 'private'
30 | }
31 | });
32 | }
33 | }
34 |
35 | //define DTO's using mapped names
36 | public class MyDTO {
37 | public MyInnerDTO obj;
38 | }
39 |
40 | public class MyInnerDTO {
41 | public Boolean isPrivate;
42 | public String notReserved;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reserved Keyword Serializer
2 | A Utility class for better control over JSON serialization/deserialization in salesforce apex
3 |
4 | ## Install
5 |
6 | 1. `git clone`
7 | 1. `cd` into folder
8 | 1. `sfdx force:mdapi:deploy -u [username] -d ./src -w 10000`
9 |
10 | ## Usage
11 |
12 | ### extend
13 |
14 | For any JSON you need to Serialize data structure you need to seralize:
15 |
16 | 1. implement a class that `extends JSONReservedSerializer`
17 | 1. pass mappings into the `super()` constructor. Mapping is defined by `Map>` where `Type` is the top level object you are serializing. This allows for seralizaiton of multiple types in a single class.
18 |
19 | ```java
20 | public class MySerializer extends JSONImprovedSerializer {
21 |
22 | private MySerializer() {
23 | //setup mappings
24 | super(new Map>{
25 | MyOuterDTO.class => OUTER_DTO_MAPPINGS
26 | });
27 | }
28 |
29 | //define DTO's using mapped names
30 | static final Map OUTER_DTO_MAPPINGS = new Map {
31 | 'obj' => 'object',
32 | 'isPrivate' => 'private'
33 | };
34 |
35 | public class OuterDTO {
36 | public InnerDTO obj;
37 | }
38 |
39 | public class InnerDTO {
40 | public Boolean isPrivate;
41 | public String notReserved;
42 | }
43 | }
44 | ```
45 |
46 | ### Serialize / Deserialize
47 |
48 | ```java
49 |
50 | String origString = '{"object":{"private":true,"notReserved":"abc"}}';
51 |
52 | //deserialization
53 | MySerializer json = new MySerializer();
54 | MySerializer.OuterDTO dto = (MySerializer.OuterDTO) json.deserialize(
55 | origString,
56 | MySerializer.OuterDTO.class
57 | );
58 |
59 | //serialization
60 | String newString = json.serialize(obj, MySerializer.OuterDTO.class);
61 | System.assertEquals(origString, newString);
62 | ```
63 |
64 | ### Notes
65 |
66 | 1. Serialization mappings are global to the entire object
67 | 1. Likely will fail due to limit exceptions with extremely large strings
68 |
--------------------------------------------------------------------------------
/src/classes/JSONReservedSerializer.cls:
--------------------------------------------------------------------------------
1 | /* Author: Charlie Jonas (charlie@callawaycloudconsulting.com)
2 | * Description: Allows reserved named serialization.
3 | * Usage: See Readme @ https://github.com/ChuckJonas/APEX-JSONReservedNameSerializer
4 | */
5 | public abstract class JSONReservedSerializer {
6 | private final Map> typeMapKeys;
7 |
8 | public JSONReservedSerializer(Map> typeMapKeys){
9 | this.typeMapKeys = typeMapKeys;
10 | }
11 |
12 | public String serialize(Object obj, System.Type type){
13 | return serialize(obj, false, type);
14 | }
15 |
16 | public String serialize(Object obj, Boolean suppressNulls, System.Type type){
17 | String retString = JSON.serialize(obj, suppressNulls);
18 | retString = transformStringForSerilization(retString, typeMapKeys.get(type));
19 | return retString;
20 | }
21 |
22 | public Object deserialize(String jsonString, System.Type type){
23 | jsonString = transformStringForDeserilization(jsonString, typeMapKeys.get(type));
24 | return JSON.deserialize(jsonString, type);
25 | }
26 |
27 | private static String transformStringForSerilization(String s, Map mapKeys){
28 | if(mapKeys == null){
29 | return s;
30 | }
31 | return replaceAll(s, mapKeys);
32 | }
33 |
34 | private static String transformStringForDeserilization(String s, Map mapKeys){
35 | if(mapKeys == null){
36 | return s;
37 | }
38 | Map flippedMap = new Map();
39 | for(String key : mapKeys.keySet()){
40 | flippedMap.put(mapKeys.get(key), key);
41 | }
42 | return replaceAll(s, flippedMap);
43 | }
44 |
45 | private static String replaceAll(String s, Map toFromMap){
46 | for(String key : toFromMap.keySet()){
47 | s = s.replaceAll('"'+key+'"(\\ )*:', '"'+toFromMap.get(key)+'":');
48 | }
49 | return s;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------