I'm trying to translate yaml files to json, but the translation re-orders the tags... Ex, YAML source:
zzzz:
b: 456
a: dfff
aa:
s10: "dddz"
s3: eeee
bbb:
- b1
- a2
snakeYAML produces:
{
"aa": {
"s3": "eeee",
"s10":"dddz"
},
"bbb":[
"b1",
"a2"
],
"zzzz": {
"a": "dfff",
"b":456
}
}
SnakeYAML allows you to read a YAML file into a simple Map object or parse the file and convert it into a custom Java object. Depending on your requirements you can decide in which format you want to read your YAML files.
Since the implementation is not thread safe, different threads must have their own Yaml instance.
Write Object to YAML Data is in java POJO object, Create an object mapper with yaml implementation class - YAMLFactory writeValue method creates a yaml file using a POJO object.
yml) File: YAML is a configuration language. Languages like Python, Ruby, Java heavily use it for configuring the various properties while developing the applications. If you have ever used Elastic Search instance and MongoDB database, both of these applications use YAML(. yml) as their default configuration format.
Create following class in your code, this is a tweaked version from the SnakeYAML source that uses LinkedHashMap
and LinkedHashSet
that keep the insertion order instead of TreeMap
and TreeSet
which auto-sort them.
import java.beans.FeatureDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.introspector.*;
import org.yaml.snakeyaml.util.PlatformFeatureDetector;
public class CustomPropertyUtils extends PropertyUtils {
private final Map<Class<?>, Map<String, Property>> propertiesCache = new HashMap<Class<?>, Map<String, Property>>();
private final Map<Class<?>, Set<Property>> readableProperties = new HashMap<Class<?>, Set<Property>>();
private BeanAccess beanAccess = BeanAccess.DEFAULT;
private boolean allowReadOnlyProperties = false;
private boolean skipMissingProperties = false;
private PlatformFeatureDetector platformFeatureDetector;
public CustomPropertyUtils() {
this(new PlatformFeatureDetector());
}
CustomPropertyUtils(PlatformFeatureDetector platformFeatureDetector) {
this.platformFeatureDetector = platformFeatureDetector;
/*
* Android lacks much of java.beans (including the Introspector class, used here), because java.beans classes tend to rely on java.awt, which isn't
* supported in the Android SDK. That means we have to fall back on FIELD access only when SnakeYAML is running on the Android Runtime.
*/
if (platformFeatureDetector.isRunningOnAndroid()) {
beanAccess = BeanAccess.FIELD;
}
}
protected Map<String, Property> getPropertiesMap(Class<?> type, BeanAccess bAccess) {
if (propertiesCache.containsKey(type)) {
return propertiesCache.get(type);
}
Map<String, Property> properties = new LinkedHashMap<String, Property>();
boolean inaccessableFieldsExist = false;
switch (bAccess) {
case FIELD:
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)
&& !properties.containsKey(field.getName())) {
properties.put(field.getName(), new FieldProperty(field));
}
}
}
break;
default:
// add JavaBean properties
try {
for (PropertyDescriptor property : Introspector.getBeanInfo(type)
.getPropertyDescriptors()) {
Method readMethod = property.getReadMethod();
if ((readMethod == null || !readMethod.getName().equals("getClass"))
&& !isTransient(property)) {
properties.put(property.getName(), new MethodProperty(property));
}
}
} catch (IntrospectionException e) {
throw new YAMLException(e);
}
// add public fields
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {
if (Modifier.isPublic(modifiers)) {
properties.put(field.getName(), new FieldProperty(field));
} else {
inaccessableFieldsExist = true;
}
}
}
}
break;
}
if (properties.isEmpty() && inaccessableFieldsExist) {
throw new YAMLException("No JavaBean properties found in " + type.getName());
}
System.out.println(properties);
propertiesCache.put(type, properties);
return properties;
}
private static final String TRANSIENT = "transient";
private boolean isTransient(FeatureDescriptor fd) {
return Boolean.TRUE.equals(fd.getValue(TRANSIENT));
}
public Set<Property> getProperties(Class<? extends Object> type) {
return getProperties(type, beanAccess);
}
public Set<Property> getProperties(Class<? extends Object> type, BeanAccess bAccess) {
if (readableProperties.containsKey(type)) {
return readableProperties.get(type);
}
Set<Property> properties = createPropertySet(type, bAccess);
readableProperties.put(type, properties);
return properties;
}
protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess) {
Set<Property> properties = new LinkedHashSet<>();
Collection<Property> props = getPropertiesMap(type, bAccess).values();
for (Property property : props) {
if (property.isReadable() && (allowReadOnlyProperties || property.isWritable())) {
properties.add(property);
}
}
return properties;
}
public Property getProperty(Class<? extends Object> type, String name) {
return getProperty(type, name, beanAccess);
}
public Property getProperty(Class<? extends Object> type, String name, BeanAccess bAccess) {
Map<String, Property> properties = getPropertiesMap(type, bAccess);
Property property = properties.get(name);
if (property == null && skipMissingProperties) {
property = new MissingProperty(name);
}
if (property == null) {
throw new YAMLException(
"Unable to find property '" + name + "' on class: " + type.getName());
}
return property;
}
public void setBeanAccess(BeanAccess beanAccess) {
if (platformFeatureDetector.isRunningOnAndroid() && beanAccess != BeanAccess.FIELD) {
throw new IllegalArgumentException(
"JVM is Android - only BeanAccess.FIELD is available");
}
if (this.beanAccess != beanAccess) {
this.beanAccess = beanAccess;
propertiesCache.clear();
readableProperties.clear();
}
}
public void setAllowReadOnlyProperties(boolean allowReadOnlyProperties) {
if (this.allowReadOnlyProperties != allowReadOnlyProperties) {
this.allowReadOnlyProperties = allowReadOnlyProperties;
readableProperties.clear();
}
}
public boolean isAllowReadOnlyProperties() {
return allowReadOnlyProperties;
}
/**
* Skip properties that are missing during deserialization of YAML to a Java
* object. The default is false.
*
* @param skipMissingProperties
* true if missing properties should be skipped, false otherwise.
*/
public void setSkipMissingProperties(boolean skipMissingProperties) {
if (this.skipMissingProperties != skipMissingProperties) {
this.skipMissingProperties = skipMissingProperties;
readableProperties.clear();
}
}
public boolean isSkipMissingProperties() {
return skipMissingProperties;
}
}
Then, create your Yaml
instance like this:
DumperOptions options = new DumperOptions();
CustomPropertyUtils customPropertyUtils = new CustomPropertyUtils();
Representer customRepresenter = new Representer();
customRepresenter.setPropertyUtils(customPropertyUtils);
Yaml yaml = new Yaml(customRepresenter, options);
Profit!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With