com.atlassian.bamboo.specs.util.Yamlizator Maven / Gradle / Ivy
package com.atlassian.bamboo.specs.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.introspector.BeanAccess;
import org.yaml.snakeyaml.introspector.FieldProperty;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
public final class Yamlizator {
private static final DumperOptions BLOCK_STYLE_DUMPER;
private static final Field FIELD_FIELD;
static {
BLOCK_STYLE_DUMPER = new DumperOptions();
BLOCK_STYLE_DUMPER.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
BLOCK_STYLE_DUMPER.setExplicitStart(true);
BLOCK_STYLE_DUMPER.setExplicitEnd(true);
BLOCK_STYLE_DUMPER.setAllowReadOnlyProperties(true);
try {
FIELD_FIELD = FieldProperty.class.getDeclaredField("field");
FIELD_FIELD.setAccessible(true);
} catch (final NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
}
}
private Yamlizator() {
}
public static Yaml getYaml() {
final Yaml yaml = new Yaml(getConstructor(), getRepresenter(), BLOCK_STYLE_DUMPER);
yaml.setBeanAccess(BeanAccess.FIELD);
return yaml;
}
private static BaseConstructor getConstructor() {
return new Constructor() {
{
for (final CustomYamlers.CustomYamler customYamler : CustomYamlers.YAMLERS) {
this.yamlConstructors.put(new Tag(customYamler.getYamledClass()), customYamler.getConstructor());
}
}
};
}
@NotNull
private static Representer getRepresenter() {
return new Representer() {
{
for (final CustomYamlers.CustomYamler customYamler : CustomYamlers.YAMLERS) {
this.representers.put(customYamler.getYamledClass(), customYamler.getRepresenter());
}
}
@Override
protected Set getProperties(final Class extends Object> type)
throws IntrospectionException {
final Set properties = getPropertyUtils().getProperties(type);
return properties.stream()
.sorted(CLASS_SCOPED_ORDER)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
};
}
private static final Comparator CLASS_SCOPED_ORDER = new Comparator() {
@Override
public int compare(final Property o1, final Property o2) {
final FieldProperty fp1 = asFieldProperty(o1);
final FieldProperty fp2 = asFieldProperty(o2);
if (fp1 == null && fp2 != null) {
return -1;
}
if (fp1 != null && fp2 == null) {
return 1;
}
if (fp1 == null) {
return 0;
}
final Class> class1 = getDeclaringClass(fp1);
final Class> class2 = getDeclaringClass(fp2);
if (!class1.equals(class2)) { //fields from parent class first
if (class2.isAssignableFrom(class1)) {
return 1;
} else if (class1.isAssignableFrom(class2)) {
return -1;
}
}
final int classCompare = class1.getName().compareTo(class2.getName());
if (classCompare != 0) {
return classCompare;
}
return fp1.getName().compareTo(fp2.getName());
}
};
@Nullable
private static FieldProperty asFieldProperty(final Property property) {
if (property instanceof FieldProperty) {
return (FieldProperty) property;
}
return null;
}
@NotNull
private static Class> getDeclaringClass(final FieldProperty fieldProperty) {
try {
return ((Field) FIELD_FIELD.get(fieldProperty)).getDeclaringClass();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy