Skip to content
Snippets Groups Projects
Commit 75e1da01 authored by Bernhard Johannes Berger's avatar Bernhard Johannes Berger
Browse files

Working on task #3 to implement #7

parent 56273f41
No related branches found
No related tags found
No related merge requests found
Pipeline #243138 passed
package de.evoal.core.main.properties;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.evoal.core.api.properties.Properties;
import de.evoal.core.api.properties.PropertiesSpecification;
import de.evoal.core.api.properties.PropertySpecification;
import de.evoal.core.api.properties.io.PropertiesReader;
import de.evoal.core.api.utils.EvoalIOException;
import de.evoal.core.api.utils.Requirements;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import javax.enterprise.context.Dependent;
import javax.inject.Named;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
@Slf4j
@Dependent
@Named("json-reader")
public class JsonPropertiesReader implements PropertiesReader {
private JsonParser jsonParser;
private Set<String> properties;
private PropertiesSpecification specification;
@Override
public PropertiesReader init(final File inputFile, final PropertiesSpecification specification) throws EvoalIOException {
log.info("Creating JSON properties reader for {}.", specification);
this.specification = specification;
properties = specification.getProperties()
.stream()
.map(PropertySpecification::name)
.collect(Collectors.toSet());
try {
final ObjectMapper mapper = new ObjectMapper();
jsonParser = mapper.createParser(inputFile);
jsonParser.nextToken();
assertStartArray();
} catch (final IOException e) {
log.error("Failed to read JSON file {}.", inputFile, e);
throw new EvoalIOException("Failure while reading " + inputFile, e);
}
return this;
}
private Properties readProperties() throws IOException {
assertStartArray();
final Map<String, Object> entries = new TreeMap<>();
while(!JsonToken.END_ARRAY.equals(jsonParser.currentToken())) {
Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_OBJECT);
String name = null;
Object value = null;
while(!JsonToken.END_OBJECT.equals(jsonParser.currentToken())) {
final String fieldName = jsonParser.nextFieldName();
if("name".equals(fieldName)) {
name = jsonParser.nextTextValue();
} else if("value".equals(fieldName)) {
final JsonToken token = jsonParser.nextValue();
if(token == JsonToken.VALUE_NUMBER_FLOAT) {
value = jsonParser.getDoubleValue();
} else if(token == JsonToken.VALUE_STRING) {
value = jsonParser.getValueAsString();
} else if(token == JsonToken.VALUE_FALSE) {
value = false;
} else if(token == JsonToken.VALUE_TRUE) {
value = true;
} else if(token == JsonToken.VALUE_NUMBER_INT) {
value = jsonParser.getValueAsInt();
} else {
throw new RuntimeException("Unsupported token type " + token);
}
}
}
assertEndObject();
entries.put(name, value);
}
assertEndArray();
try {
final PropertiesSpecification spec =
PropertiesSpecification.builder()
.add(entries.keySet()
.stream()
.filter(properties::contains)
.map(specification::find)
.map(PropertySpecification::type)
)
.build();
return new Properties(spec).putAll(entries);
} catch(final NullPointerException e) {
log.error("Failed to read properties file entry {} for specification {}.", entries, specification);
entries.keySet()
.stream()
.filter(k -> !properties.contains(k))
.forEach(n -> System.err.println("There is no properties specification for " + n));
throw e;
}
}
private void assertEndArray() throws IOException {
Requirements.requireEqual(jsonParser.currentToken(), JsonToken.END_ARRAY);
jsonParser.nextToken();
}
private void assertEndObject() throws IOException {
Requirements.requireEqual(jsonParser.currentToken(), JsonToken.END_OBJECT);
jsonParser.nextToken();
}
private void assertStartArray() throws IOException {
Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_ARRAY);
jsonParser.nextToken();
}
private void assertStartObject() throws IOException {
Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_OBJECT);
jsonParser.nextToken();
}
@Override
public void close() throws Exception {
jsonParser.close();
}
@Override
public boolean hasNext() {
return !JsonToken.END_ARRAY.equals(jsonParser.currentToken());
}
@Override
@SneakyThrows(IOException.class)
public Properties next() {
return readProperties();
}
}
package de.evoal.core.main.properties;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.evoal.core.api.properties.Properties;
import de.evoal.core.api.properties.PropertiesSpecification;
import de.evoal.core.api.properties.PropertySpecification;
import de.evoal.core.api.properties.io.PropertiesWriter;
import de.evoal.core.api.utils.EvoalIOException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import javax.enterprise.context.Dependent;
import javax.inject.Named;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@Slf4j
@Dependent
@Named("json-writer")
public class JsonPropertiesWriter implements PropertiesWriter {
private FileOutputStream outputStream;
private JsonGenerator jsonGenerator;
@Override
public PropertiesWriter init(final File outputFile, final PropertiesSpecification specification) throws EvoalIOException {
try {
outputStream = new FileOutputStream(outputFile);
final ObjectMapper mapper = new ObjectMapper();
jsonGenerator = mapper.createGenerator(outputStream);
jsonGenerator.writeStartArray();
} catch (final IOException e) {
log.error("Failed to write {}.", outputFile, e);
throw new EvoalIOException("Failed to write " + outputFile, e);
}
return this;
}
@Override
public void add(final Properties properties) throws EvoalIOException {
try {
jsonGenerator.writeStartArray();
for (final PropertySpecification spec : properties.getSpecification().getProperties()) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("name", spec.name());
final Object value = properties.get(spec);
if (value instanceof Double || value instanceof Float) {
jsonGenerator.writeNumberField("value", ((Number) properties.get(spec)).doubleValue());
} else if (value instanceof Integer) {
jsonGenerator.writeNumberField("value", ((Number) properties.get(spec)).longValue());
} else if (value instanceof Boolean) {
jsonGenerator.writeBooleanField("value", (Boolean) properties.get(spec));
} else if (value instanceof String) {
jsonGenerator.writeStringField("value", (String) properties.get(spec));
}
jsonGenerator.writeEndObject();
}
jsonGenerator.writeEndArray();
} catch(final IOException e) {
log.error("Failure while writing properties.", e);
throw new EvoalIOException("Failure while writing properties.", e);
}
}
@Override
public void close() throws Exception {
jsonGenerator.writeEndArray();
jsonGenerator.close();
outputStream.close();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment