How to validate values in a YAML configuration file while loading it? - java

Is there a way to validate values in a YAML file while loading it in the code. The requirement is I have some elements in the YAML file which must have values. If the validation fails, then YAML should not be loaded.
I'm using snakeyaml library and heard there is a way to do this via Representer.
Code I'm currently using to load the YAML,
Reader in = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8);
Yaml yaml = new Yaml();
yaml.setBeanAccess(BeanAccess.FIELD);
return yaml.loadAs(in, School.class);

Since you can have any value in a YAML file, you should load the file in a function, test the values and raise an error if the values are not what you want. Return the loaded data if they are.
This may have side-effects if your YAML has tags that create arbitrary objects, but checking during loading will not prevent that, as such object might have been created before you come to the value you want to check.
If you do have tags in your YAML and that is a real problem, then you would have to make a safe_load-er for the YAML file that can handle the tags (by creating normal mapping objects), then check the values and reload with full tag support.

Related

POIXMLProperties read Property Sets

I am trying to read a specific property using Apache POI, my aim is to change its value and save the file in a different location. The issue is that the property in question is not a core, custom or extended one...Its format as shown by Apache Tika is:
<meta name="meta:just-a-name" content="165" />
I have read that with the HPSF API it was possible to read every kind of property in Property Sets, but since my file is a newer version, I cannot use it.
With a custom property I was able to do:
POIXMLProperties properties = document.getProperties();
CTProperty aProperty = properties.getCustomProperties().getProperty("Custom_prop");
aProperty.setI4(12);
properties.commit();
document.write(out);
Do you know how I can do the same thing with the non-standard property?

Spring Batch - a FlatFileItemWriter with dynamic schema

I am building an application that handles the batch processings with using a SpringBatch. As the ItemReaders can handle a dynamic schemas (e.g. reading a JSON files (JsonItemReader), XML files (StaxEventItemReader), getting a data from the MongoDB (MongoItemReader) and so on) I am wondering, how can I leverage a SpringBatch to use dynamically a FlatFileItemWriter as an last stage in the step and produce a CSV file.
Normally, it requires to get a fixed schema once I initialize a Writer (before I even start writing an objects). As the schema can differ in the JSON Objects, each product in each chunk can potentially have a different headers. Is there any workaround that I can use to include a FlatFileItemWriter as an output if the domain objects have a various schemas that are unknown until the Runtime?
That's the current code for initializing a FlatFileItemWriter but with using a static schema, that needs to be provided before I create a Writer.
FlatFileItemWriter<Row> flatFileItemWriter = new FlatFileItemWriter<>();
Resource resource = new FileSystemResource(path);
flatFileItemWriter.setResource(resource);
CSVLineAggregator lineAggregator = CSVLineAggregator.builder()
.schema(schema)
.delimiter(delimiter)
.quoteCharacter(quoteCharacter)
.escapeCharacter(escapeCharacter)
.build();
flatFileItemWriter.setLineAggregator(lineAggregator);
flatFileItemWriter.setEncoding(encoding);
flatFileItemWriter.setLineSeparator(lineSeparator);
flatFileItemWriter.setShouldDeleteIfEmpty(shouldDeleteIfEmpty);
flatFileItemWriter.setHeaderCallback(new HeaderCallback(schema.getColumnNames(), flatFileItemWriter, lineSeparator));
** The Row it's my domain object that is just a Map's based structure that stores the data in the Cells and Columns, along with the schema that can differ between the rows.
Thanks in advance for any tips!

How to read a Iterable nested object - Java

Hi all I have the following yaml file example 'test.yml'
server:
port: 1000
someDate: /abcd
anotherConfig:
host: http://localhost:1000
fileList:
files:
- name: filea
filePath: \filea
- name: fileb
filePath: \fileb
---
anotherdoc:
data: 300
nestedData:
animal:
- name: dog
I read this file like so:
Yaml yaml = new Yaml();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("test.yml");
Iterable<Object> rules = yaml.loadAll(inputStream);
for (Object rule : rules) {
Map<String, Object> map = (Map<String, Object>) rule;
System.out.println("blah");
}
I am wondering how it is possible to get data from the rules object, e.g. if I wanted directly to search fileList/files or nestedData/animal so that I can use the path to get a List directly.
(Note yaml structure varies so cannot seem to use the entities method)
fileList/files is not a path in YAML terms because the YAML spec does not define any kind of path. You can:
use composeAll to get an iterator on Nodes. Nodes represent the YAML's structure and you can navigate through them similar to an XML DOM. You can then write a function that can walk a path.
plug in a modified parser that throws away everything not on your desired path, so that only your path is constructed. This example shows the basics for a slightly different use-case.
Write a custom constructor that throws away everything around the desired path. I am not entirely sure whether this is possible because the constructor API is a bit strange.
I suggest using method 1. It is flexible enough to deal with any kind of YAML structure, while being far less complex than the other methods. When you arrive at your desired Node, you can even use the Constructor class to construct a List or whatever you need from it.

Read a toml file in java 2022

After a quick research, I found the following three libraries for parsing Toml files in java.
toml4j
tomlj
jackson-dataformats-text
What I am looking for is a library that can parse toml files without a corresponding POJO class. While both toml4j, and tomlj can achieve that, they do not seem to be maintained.
jackson-dataformats-text on the other is actively maintained but I can not parse a toml file without the corresponding POJO class.
Is there a way to create a dynamic class in java that I can use to parse any toml file?
If you just need to read a TOML file without a POJO, FasterXML Jackson libraries are a great choice. The simplest method is to just read the content as a java.util.Map:
final var tomlMapper = new TomlMapper();
final var data = tomlMapper.readValue(new File("config.toml"), Map.class);
After that, the content of the file will be available in data.
If you need even lower level parsing, all formats supported by FasterXML Jackson can be read using the stream API. In case you need that, read about the stream API on the core module: FasterXML/jackson-core, just make sure you use the right factory class (TomlFactory instead of JsonFactory).

Load properties file in spring in order

Is there any way to load a properties file in spring in order ? I understand Properties is a Hashtable and maps are unordered. I would like a xml based solution rather than a java based solution. Ideally, this should be configurtable from outside.
Edit:
I mean the contents of the properties file should be read and preserved in the same order as in the properties file. Eg:
fr.wiki=http://fr.wikipedia.org
en.wiki=http://en.wikipedia.org
...
If I read the properties file, fr.wiki should be first, en.wiki should be second and so on.
Getting properties in the order they are written in the properties file is not possible. You can add numbers to your property names:
component.01.key = value1
component.02.key = value2
component.03.key = value3
...
See Pulling values from a Java Properties file in order?

Categories

Resources