The text File to read is provided below -
- context:dev
- region:asia
- lob:all
- projects: (This is a list of project)
- name:hub
- topics: (List of Topic inside projects)
- dataType:0
- name:cdc
- plan:dev-rack
- dataType:0.dlq
- name:cdc
- plan:rack
- dataType:0
- name:raw
- plan:dev
- schemas:
- value.schema.file:-data-hub.raw.0-value-v1.json
- value.format:JSON
- dataType:Produce.dlq
- name:raw
- plan:ack
- schemas:
- value.schema.file:hub.raw.0-value-v1.json
- value.format:JSON
- dataType:0
- name:dom
- plan:dev
- schemas:
- value.schema.file:dom.0-value-v1.json
- value.format:JSON
- dataType:Produce.dlq
- name:dom
- plan:de
- schemas:
- value.schema.file:0-value-v1.json
- value.format:JSON
@Getter
@Setter
@ToString
public class Parameter {
private String context;
private String region;
private String lob;
private List<Project> Project;
}
@Getter
@Setter
@ToString
public class Project {
private String name;
private List<Topic> topics;
}
@Getter
@Setter
@ToString
public class Topic {
private String dataType;
private String name;
private String plan;
private Schemas schemas;
public boolean checkDlq(String dataType) {
dataType = getDataType();
if (dataType.contains("dlq")) {
return true;
}else
return false;
}
}
@Getter
@Setter
@ToString
public class Schemas {
private Value value;
}
@Getter
@Setter
@ToString
public class Value {
private Schema schema;
private String format;
}
@Getter
@Setter
@ToString
public class Schema {
private String file;
}
Details : So I have to read above file line by line and add all the details in Parameters class and print it.
Example: context:dev so i have to read the dev part and put it inside parameter.setContext("dev"); but without hard coding it.
I Tried reading it but i was not able to find out how do we apply nested hashMap. As there is a list of project and inside there is list of Topics.
Edit: Purpose of reading this file is that , after reading i have to convert it in Yaml format file.
Edit: Below is the example i.e. I have to convert the text file into Yaml. The example is of yaml file (I have to convert my plain text file into this).
context: "dev"
region: "asia"
lob: "all"
projects:
- name: "hub"
topics:
- dataType: "0"
name: "cdc"
plan: "devrack"
- dataType: "0.dlq"
name: "cdc"
plan: "dev-bronze-rack"
- dataType: "0"
name: "raw"
plan: "rack"
schemas:
value.schema.file: "hub.raw.0-value-v1.json"
value.format: "JSON"
- dataType: "Produce.dlq"
name: "raw"
plan: "devrack"
schemas:
value.schema.file: "raw.0-value-v1.json"
value.format: "JSON"
- dataType: "0"
name: "dom"
plan: "rack"
schemas:
value.schema.file: "0-value-v1.json"
value.format: "JSON"
- dataType: "0.dlq"
name: "dom"
plan: "dev"
schemas:
value.schema.file: "v1.json"
value.format: "JSON"
Edit : I Came up with one solution But there is one Problem i.e -> if there is only one project list(starting from name parameter) line 5, the soluition is working fine, but if i put next list of project (starting with -name itself) after line 36. It is not creating next list of project and adding all the details inside list of topics. Below is the solution code
public class YamlProcessor {
public void addToObject() throws IOException {
Parameter parameter = new Parameter();
FileReader fileReader = new FileReader("C:/Users/zk72/Desktop/schema.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = bufferedReader.readLine();
List<Topic> addTopic = new ArrayList<>();
List<Project> addProject = new ArrayList<>();
//Single Variable
Map<String, String> singleVariable = new HashMap<>();
//For Project list - eg-> project1 , list of project
Map<String, Map<String,String>> projects = new HashMap<>();
Map<String, Map<String,Map<String,String>>> ps = new HashMap<>();
//For Topics List - eg-> topic1, list of project
Map<String, Map<String, String>> topics = new HashMap<>();
while (line != null) {
String s[] = line.split(":");
switch (s[0]) {
case Constants.CONTEXT:
singleVariable.put(s[0],s[1]);
break;
case Constants.REGION:
singleVariable.put(s[0],s[1]);
break;
case Constants.LOB:
singleVariable.put(s[0],s[1]);
break;
case Constants.PROJECTS:
Map<String, String> project = new HashMap<>();
Map<String, String> topic = new HashMap<>();
int projectCount = 1;
while ((line = bufferedReader.readLine()) != null) {
String ss[] = line.split(":");
if (ss[0].equals(Constants.NAME)) {
if (!project.isEmpty() && project != null) {
projects.put("project" projectCount, project);
projectCount ;
project = new HashMap<>();
project.put(ss[0],ss[1]);
}else {
project.put(ss[0],ss[1]);
}
}else if (ss[0].equals(Constants.TOPICS)) {
int topicCount = 1;
while((line = bufferedReader.readLine()) != null){
String str[] = line.split(":");
if (str[0].equals(Constants.DATA_TYPE) && !str[0].equals(Constants.NAME)) {
if(!topic.isEmpty() && topic !=null){
topics.put("topic" topicCount, topic);
topicCount ;
topic = new HashMap<>();
topic.put(str[0],str[1]);
} else {
topic.put(str[0],str[1]);
}
} else {
if(str.length > 1)
topic.put(str[0],str[1]);
}
}
topicCount ;
topics.put("topic" topicCount, topic);
}
}
projectCount ;
projects.put("project" projectCount, project);
}
line = bufferedReader.readLine();
}
parameter.setContext(singleVariable.get(Constants.CONTEXT));
parameter.setRegion(singleVariable.get(Constants.REGION));
parameter.setLob(singleVariable.get(Constants.LOB));
for (Map.Entry<String, Map<String,String>> entry: topics.entrySet()) {
Topic topic = new Topic();
topic.setDataType(entry.getValue().get(Constants.DATA_TYPE));
topic.setName(entry.getValue().get(Constants.NAME));
topic.setPlan(entry.getValue().get(Constants.PLAN));
Schemas schemas = new Schemas();
Value value = new Value();
Schema schema = new Schema();
schema.setFile(entry.getValue().get(Constants.VALUE_SCHEMA_FILE));
value.setSchema(schema);
value.setFormat(entry.getValue().get(Constants.VALUE_FORMAT));
schemas.setValue(value);
topic.setSchemas(schemas);
addTopic.add(topic);
}
for (Map.Entry<String, Map<String, String>> entry: projects.entrySet()) {
Project project = new Project();
project.setName(entry.getValue().get(Constants.NAME));
project.setTopics(addTopic);
addProject.add(project);
}
parameter.setProjects(addProject);
System.out.println(parameter.toString());
DumperOptions options = new DumperOptions();
options.setIndent(2);
options.setPrettyFlow(true);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
PrintWriter writer = new PrintWriter(new File("./src/main/resources/topology3.yml"));
Yaml yaml = new Yaml(options);
yaml.dump(parameter, writer);
bufferedReader.close();
}
public static void main(String[] args) throws IOException {
YamlProcessor processor = new YamlProcessor();
processor.addToObject();
}
}
CodePudding user response:
In yaml you should have nested parameters also. So you should add child parameters to your Parameter class like:
public class Parameter {
private String context;
private String region;
private String lob;
private List<Project> topics;
private Set<Parameter> subParameters;
}
So in line 35,36. They are child of value parameter.
And how Projects and Topics related to each other? Can you give any example for it
CodePudding user response:
If you just want to convert the input file to yaml, you don't need to completely deserialize it into objects first.
You only need to add various prefixes / indenting depending on the key. To distinguish the project from the topic, I simply relied on the order of keys: if name
comes in the line following dataType
I let it be an element of topic, otherwise it's an element of project.
public static void convertToYaml(Reader input, Writer output) throws IOException {
var reader = new BufferedReader(input);
var line = reader.readLine();
var lastLineDataType = false;
while(null != line) {
var pos = line.indexOf(':');
var key = (pos >= 0 ? line.substring(0, pos) : line).trim();
var value = (pos >= 0) && (pos < line.length()) ? line.substring(pos 1) : "";
var prefix = switch(key) {
case "name" -> lastLineDataType ? " " : " - ";
case "topics" -> " ";
case "dataType" -> " - ";
case "plan", "schemas" -> " ";
case "value.schema.file", "value.format" -> " ";
default -> "";
};
lastLineDataType = "dataType".equals(key);
if (!key.isEmpty()) {
output.write(prefix key ": ");
output.write(value.isBlank() ? "" : '"' value.trim() '"');
}
output.write("\n");
line = reader.readLine();
}
}
No validation of the input happens, so the "sh*t in -> sh*t out" principle fully applies ;-)
This code makes use of Java 17 features, so you might have to change the switch
a bit to work with older Java versions.