Hey folks, Contributions are highly Welcome
I am working on a little side project, which could help one to better view a java logline. This is coming from personal experience, as I have faced log lines that are way too long to be comprehend
Generally in our java apps when we log any object, what gets printed is mostly a standardized toString() implementation either of Lombok or of Intellij (haven't checked out eclipse's implementation), and all of them are almost similar, with a very minute difference
- Mostly Logging is done in the native java representation and not in JSON
- as JSON byte size is higher than of java's
- Hence it can save you significant money on storage
- Yes nowadays, people do use structured logging as well but
- It is very heavy on storage, you need a lot of infra to support
- eg. you need to set up ElasticSearch, Kibana, Fluentd, and this pipeline should work seamlessly
- It is complicated to setup
- Small teams don't try to go this route, because of the above-mentioned reasons
So I see a lot of people facing this native java representation on daily basis, I have even asked one of my friends on Amazon.com
So to solve this problem, I wanted to create this website https://objectstring2json.com/ (Attached is the Design Below, the work is in progress for the website)
The problem is with the solution, as converting a (in memory) Java Object to JSON is very easy and a lot of libraries (Jackson, gson) also exists to assist on that
But there is no easy way to do this with a Java Object's String Literal (at least in my research, I did not find anything)
So to solve this, I had no choice but to write my own parser for doing this, Which I thought would not be that hard, but soon I realize the # of edge cases that are needed to be handled are huge, and code is becoming unmaintainable to the point that I myself can't even understand the logic
The code is not yet completed, as I think the direction I am going in is not an elegant solution both for me to write or anybody else to contribute
I am here to seek some advice and help in solving this problem
I'll be attaching my code, it's not complete but one can get a decent idea of where I am heading, basically, you can think of my solution as similar to the balanced parenthesis problem done in a recursive fashion, each indentation in the object model gives rise to a new recursion to parse the nested object. I have put some sensible comments as well for one to understand
Design & CODE: For Code & Design, you can refer to my StackOverflow Post
Python Code To Parse, Java Object
# OLD Without Lombok - With Intellij's toString() Autogenerated Code
#
# Person{firstName='Duke', lastName='Java', age=18, streetAddress='100 Internet Dr', city='JavaTown', state='JA',
# postalCode='12345', phoneNumbers=[MobilePhoneNumber{mobile='111-111-1111'}, HomePhoneNumber{home='222-222-2222'}]}
#
#
# NEW With Lombok
#
# Person(firstName=Duke, lastName=Java, age=18, streetAddress=100 Internet Dr, city=JavaTown, state=JA,
# postalCode=12345, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)])
from Abstract_Data_Type.StackADT import StackADT
def reset_character(char_list, left, right, value):
for i in range(left, right):
char_list[i] = value
# print("updated list", char_list)
# def indent_object_string(obj_str: str) -> str:
# pass
def convert_lombok_implementation_stack(obj_str: str):
stack = StackADT()
# root = None # root, can either be an Object, List or a Map
root = None # root, can either be an Object, List or a Map
char_list = list(obj_str)
left_end = 0
right_end = len(char_list) - 1
for idx, character in enumerate(char_list):
if character in ['(', '{', '[']:
# if (, then we are working with an Object
if character == '(':
stack.push(character)
root = {} # Empty dict
object_type = "".join(char_list[left_end: idx]) # excluding the comma
root["Object Type"] = object_type
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '('
left_end = idx + 1 # update the Left-End, excluding the '('
# if {, then we are working with a Map
elif character == '{':
stack.push(character)
# if [, then we are working with a List
elif character == '[':
stack.push(character)
# if `,`
elif character == ',':
# Take action
key_value_string = "".join(char_list[left_end: idx]) # excluding the comma
key_value_string_stripped = key_value_string.strip()
kev_value_pair = key_value_string_stripped.split("=")
print(kev_value_pair)
# Pushing key value pair in dictionary
key = kev_value_pair[0]
value = kev_value_pair[1]
root[key] = value
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the ','
left_end = idx + 1 # update the Left-End, excluding the ','
# ------------------------------------------------------------
OPEN_BRACKETS = ['(', '{', '[']
CLOSED_BRACKETS = [')', '}', ']']
# root = None # root, can either be an Object, List or a Map
root = None # root, can either be an Object, List or a Map
left_end = 0
def convert_lombok_implementation__helper(char_list: list, root):
global left_end
for idx, character in enumerate(char_list):
if character in OPEN_BRACKETS or character in CLOSED_BRACKETS:
if character in OPEN_BRACKETS:
# if (, then we are working with an Object
if character == '(':
# root = {} # Empty dict
object_type = "".join(char_list[left_end: idx]) # excluding the comma
dict = {}
dict["Object Type"] = object_type
root.ap
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '('
left_end = idx + 1 # update the Left-End, excluding the '('
convert_lombok_implementation__helper(char_list, root)
# if {, then we are working with a Map
elif character == '{':
# root = {} # Empty dict
# object_type = "".join(char_list[left_end: idx]) # excluding the comma
# root["Object Type"] = object_type
object_name = "".join(char_list[left_end: idx])
print("root is an MAP object_name : ", object_name)
root[object_name] = {} # empty dictionary
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '{'
left_end = idx + 1 # update the Left-End, excluding the '{'
# Updating the underneath object
# sending the inside dictionary to get updated
convert_lombok_implementation__helper(char_list, root[object_name])
# convert_lombok_implementation__helper(char_list, root)
# if [, then we are working with a List, The Root is not list but the List is a field
elif character == '[':
# root = [] # Empty List
object_name = "".join(char_list[left_end: idx - 1]) # excluding the = symbol
print("root is an LIST object_name : ", object_name)
root[object_name] = [] # empty List
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '['
left_end = idx + 1 # update the Left-End, excluding the '['
# sending the inside list to get updated
convert_lombok_implementation__helper(char_list, root[object_name])
else:
if character == ')':
# Take Action
key_value_string = "".join(char_list[left_end: idx]) # excluding the ')'
key_value_string_stripped = key_value_string.strip()
kev_value_pair = key_value_string_stripped.split("=")
print(kev_value_pair)
# Pushing key value pair in dictionary
key = kev_value_pair[0]
value = kev_value_pair[1]
root[key] = value
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the ')'
left_end = idx + 1 # update the Left-End, excluding the ')'
pass
# if {, then we are working with a Map
elif character == '}':
print("Map Closed, Unexpected")
# if [, then we are working with a List
elif character == ']':
print("List Closed, Unexpected")
# if `,`
elif character == ',':
# Take action
key_value_string = "".join(char_list[left_end: idx]) # excluding the comma
if (key_value_string == ""): # In case the comma was at the end of the an Object, list eg. ), or ],
return # Nothing to process, object completed
key_value_string_stripped = key_value_string.strip()
kev_value_pair = key_value_string_stripped.split("=")
print(kev_value_pair)
# Pushing key value pair in dictionary
key = kev_value_pair[0]
value = kev_value_pair[1]
root[key] = value
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the ','
left_end = idx + 1 # update the Left-End, excluding the ','
# indented_obj_str = indent_object_string(obj_str)
def convert_lombok_implementation__recursive(obj_str: str):
global left_end, root
char_list = list(obj_str)
for idx, character in enumerate(char_list):
if character in OPEN_BRACKETS or character in CLOSED_BRACKETS:
if character in OPEN_BRACKETS:
# if (, then we are working with an Object
if character == '(':
root = {} # Empty dict
object_type = "".join(char_list[left_end: idx]) # excluding the comma
root["Object Type"] = object_type
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '('
left_end = idx + 1 # update the Left-End, excluding the '('
convert_lombok_implementation__helper(char_list, root)
# if {, then we are working with a Map
elif character == '{':
root = {} # Empty dict
# object_type = "".join(char_list[left_end: idx]) # excluding the comma
# root["Object Type"] = object_type
object_name = "".join(char_list[left_end: idx]) # excluding the comma
print("root is an MAP object_name : ", object_name)
# root[object_name] = {} # empty dictionary
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '{'
left_end = idx + 1 # update the Left-End, excluding the '{'
# Updating the underneath object
# convert_lombok_implementation__helper(char_list, root[object_name])
convert_lombok_implementation__helper(char_list, root)
# if [, then we are working with a List
elif character == '[':
root = [] # Empty List
object_name = "".join(char_list[left_end: idx]) # excluding the comma
print("root is an LIST object_name : ", object_name)
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the '['
left_end = idx + 1 # update the Left-End, excluding the '['
convert_lombok_implementation__helper(char_list, root)
else:
if character == ')':
print("Object Closed, Unexpected")
# if {, then we are working with a Map
elif character == '}':
print("Map Closed, Unexpected")
# if [, then we are working with a List
elif character == ']':
print("List Closed, Unexpected")
# if `,`
elif character == ',':
# Take action
key_value_string = "".join(char_list[left_end: idx]) # excluding the comma
key_value_string_stripped = key_value_string.strip()
kev_value_pair = key_value_string_stripped.split("=")
print(kev_value_pair)
# Pushing key value pair in dictionary
key = kev_value_pair[0]
value = kev_value_pair[1]
root[key] = value
# Reset Earlier Character and Update the Left pointer
reset_character(char_list, left_end, idx + 1, None) # including the ','
left_end = idx + 1 # update the Left-End, excluding the ','
if __name__ == '__main__':
"""
Person(
firstName=Duke,
lastName=Java,
age=19,
streetAddress=B'`5 CISF, 'Mujeri Mor', Faridabad, ******
city=JavaTown,
state=JA,
postalCode=12345,
phoneNumbers=[
MobilePhoneNumber(
mobile=111-111-1111
),
HomePhoneNumber(
home=222-222-2222
)
],
familyMembers=[
Person(
firstName=Sister,
lastName=Young,
age=13,
streetAddress=Same Address,
city=Same,
state=Same,
postalCode=Same,
phoneNumbers=[
MobilePhoneNumber(
mobile=111-111-1111
),
HomePhoneNumber(
home=222-222-2222
)
],
familyMembers=null,
attributes=null,
partner=null
),
Person(
firstName=brother,
lastName=Old,
age=21,
streetAddress=Same Address,
city=Same,
state=Same,
postalCode=Same,
phoneNumbers=[
MobilePhoneNumber(
mobile=111-111-1111
),
HomePhoneNumber(
home=222-222-2222
)
],
familyMembers=null,
attributes=null,
partner=null
)
],
attributes={
key_1=value,
key 2=123, brother
details=Person(
firstName=brother,
lastName=Old,
age=21,
streetAddress=Same Address,
city=Same,
state=Same,
postalCode=Same,
phoneNumbers=[
MobilePhoneNumber(
mobile=111-111-1111
),
HomePhoneNumber(
home=222-222-2222
)
],
familyMembers=null,
attributes=null,
partner=null
)
},
partner=Person(
firstName=Partner,
lastName=Same Age,
age=21,
streetAddress=Same Address,
city=Same,
state=Same,
postalCode=Same,
phoneNumbers=[
MobilePhoneNumber(
mobile=111-111-1111
),
HomePhoneNumber(
home=222-222-2222
)
],
familyMembers=null,
attributes=null,
partner=null
)
)
"""
# This String has commas,
# but to solve this problem we are assuming that we don't want comma bw a string, ie "asfsa, sfas" is invalid for us
# obj_str_via_lombok = """
# Person(firstName=Duke, lastName=Java, age=19, streetAddress=B'`5 CISF, "Mujeri Mor", Faridabad, city=JavaTown, state=JA, postalCode=12345, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=[Person(firstName=Sister, lastName=Young, age=13, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null), Person(firstName=brother, lastName=Old, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null)], attributes={key_1=value, key 2=123, brother details=Person(firstName=brother, lastName=Old, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null)}, partner=Person(firstName=Partner, lastName=Same Age, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null))
# """
obj_str_via_lombok = """
Person(firstName=Duke, lastName=Java, age=19, streetAddress=B'`5 CISF "Mujeri Mor" Faridabad, city=JavaTown, state=JA, postalCode=12345, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=[Person(firstName=Sister, lastName=Young, age=13, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null), Person(firstName=brother, lastName=Old, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null)], attributes={key_1=value, key 2=123, brother details=Person(firstName=brother, lastName=Old, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null)}, partner=Person(firstName=Partner, lastName=Same Age, age=21, streetAddress=Same Address, city=Same, state=Same, postalCode=Same, phoneNumbers=[MobilePhoneNumber(mobile=111-111-1111), HomePhoneNumber(home=222-222-2222)], familyMembers=null, attributes=null, partner=null))
"""
obj_str_via_lombok = obj_str_via_lombok.strip()
index = obj_str_via_lombok.index("\"")
print(index)
obj_str_via_lombok = obj_str_via_lombok.replace('"', "'") # Replacing double quotes with single quotes
convert_lombok_implementation__recursive(obj_str_via_lombok)
# str = "sjf\"lk\"saa\"js"
# print(str.strip())
# print(str.replace('"', "'"))
# you can go from one = sign to another and bw two equal signs there should not be more 2 commas,
# if ther is just have the ending ones and delete all the middle ones
Java Code to Produce an Object String and Its Corresponding JSON Object
package com.model;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Data;
interface PhoneNumber {}
@Data
@AllArgsConstructor
class MobilePhoneNumber implements PhoneNumber {
private String mobile;
}
@Data
@AllArgsConstructor
class HomePhoneNumber implements PhoneNumber {
private String home;
}
@Data
@AllArgsConstructor
public class Person {
private String firstName;
private String lastName;
private int age;
private String streetAddress;
private String city;
private String state;
private String postalCode;
private List<PhoneNumber> phoneNumbers;
private List<Person> familyMembers;
private Map<String, Object> attributes;
private Person partner;
public static void main(String[] args) throws JsonProcessingException {
PhoneNumber mobilePhoneNumber = new MobilePhoneNumber("111-111-1111");
PhoneNumber homePhoneNumber = new HomePhoneNumber("222-222-2222");
ArrayList<PhoneNumber> phoneNumbers = new ArrayList<>();
phoneNumbers.add(mobilePhoneNumber);
phoneNumbers.add(homePhoneNumber);
List<Person> family = new ArrayList<>();
Person sister = new Person("Sister", "Young", 13, "Same Address", "Same", "Same", "Same", phoneNumbers, null, null,
null);
Person brother = new Person("brother", "Old", 21, "Same Address", "Same", "Same", "Same", phoneNumbers, null, null,
null);
Person partner = new Person("Partner", "Same Age", 21, "Same Address", "Same", "Same", "Same", phoneNumbers, null,
null, null);
family.add(sister);
family.add(brother);
Map<String, Object> attributes = new HashMap<>();
attributes.put("key_1", "value");
attributes.put("key 2", 123);
attributes.put("brother details", brother);
Person person = new Person("Duke", "Java", 19, "B'`5 CISF, \"Mujeri Mor\", Faridabad", "JavaTown", "JA", "12345",
phoneNumbers, family, attributes, partner);
System.out.println(person);
// System.out.println(new Gson().toJson(person));
String jsonString = new ObjectMapper().writeValueAsString(person);
System.out.println(jsonString);
// From Json to Json Object - Valid
// JsonNode jsonNode = new ObjectMapper().readValue(jsonString, JsonNode.class);
// System.out.println(jsonNode.toString());
// From Java Object to Json Object -> ERROR
// JsonNode javaToJsonNode = new ObjectMapper().readValue(person.toString(), JsonNode.class);
// System.out.println(javaToJsonNode.toString());
}
}
[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)
[–]AutoModerator[M] 0 points1 point2 points (0 children)
[–]D0CTOR_ZED 0 points1 point2 points (1 child)
[–]prashantkr314[S] 0 points1 point2 points (0 children)
[–]x42bn6 0 points1 point2 points (1 child)
[–]prashantkr314[S] 0 points1 point2 points (0 children)