All Downloads are FREE. Search and download functionalities are using the official Maven repository.

liquibase.serializer.core.yaml.YamlChangeLogSerializer Maven / Gradle / Ivy

package liquibase.serializer.core.yaml;

import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.serializer.ChangeLogSerializer;
import liquibase.serializer.LiquibaseSerializable;
import liquibase.statement.DatabaseFunction;
import liquibase.statement.SequenceCurrentValueFunction;
import liquibase.statement.SequenceNextValueFunction;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.FieldProperty;
import org.yaml.snakeyaml.introspector.GenericProperty;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;

import java.beans.IntrospectionException;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.*;

public class YamlChangeLogSerializer implements ChangeLogSerializer {

    protected Yaml yaml;

    public YamlChangeLogSerializer() {
        yaml = createYaml();
    }

    protected Yaml createYaml() {
        DumperOptions dumperOptions = new DumperOptions();
        dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        return new Yaml(new LiquibaseRepresenter(), dumperOptions);
    }

    @Override
    public String[] getValidFileExtensions() {
        return new String[]{
                "yaml"
        };
    }

    @Override
    public String serialize(LiquibaseSerializable object, boolean pretty) {
        return yaml.dumpAsMap(toMap(object));
    }

    protected Map toMap(LiquibaseSerializable object) {
        Comparator comparator;
        if (object instanceof ChangeSet) {
            comparator = new ChangeSetComparator();
        } else {
            comparator = new Comparator() {
                @Override
                public int compare(String o1, String o2) {
                    return o1.compareTo(o2);
                }
            };
        }
        Map objectMap = new TreeMap(comparator);

        for (String field : object.getSerializableFields()) {
            Object value = object.getSerializableFieldValue(field);
            if (value != null) {
                if (value instanceof LiquibaseSerializable) {
                    value = toMap((LiquibaseSerializable) value);
                }
                if (value instanceof Collection) {
                    List valueAsList = new ArrayList((Collection) value);
                    if (valueAsList.size() == 0) {
                        continue;
                    }
                    for (int i = 0; i < valueAsList.size(); i++) {
                        if (valueAsList.get(i) instanceof LiquibaseSerializable) {
                            valueAsList.set(i, toMap((LiquibaseSerializable) valueAsList.get(i)));
                        }
                    }
                    value = valueAsList;

                }
                objectMap.put(field, value);
            }
        }

        Map containerMap = new HashMap();
        containerMap.put(object.getSerializedObjectName(), objectMap);
        return containerMap;
    }

    @Override
    public void write(List changeSets, OutputStream out) throws IOException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void append(ChangeSet changeSet, File changeLogFile) throws IOException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public static class LiquibaseRepresenter extends Representer {

        public LiquibaseRepresenter() {
            multiRepresenters.put(DatabaseFunction.class, new AsStringRepresenter());
            multiRepresenters.put(SequenceNextValueFunction.class, new AsStringRepresenter());
            multiRepresenters.put(SequenceCurrentValueFunction.class, new AsStringRepresenter());
        }

        @Override
        protected Tag getTag(Class clazz, Tag defaultTag) {
            return super.getTag(clazz, defaultTag);    //To change body of overridden methods use File | Settings | File Templates.
        }

        @Override
        protected MappingNode representJavaBean(Set properties, Object javaBean) {
            return super.representJavaBean(properties, javaBean);    //To change body of overridden methods use File | Settings | File Templates.
        }

        @Override
        protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
            return super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);    //To change body of overridden methods use File | Settings | File Templates.
        }

        @Override
        public Node represent(Object data) {
            return super.represent(data);    //To change body of overridden methods use File | Settings | File Templates.
        }


        @Override
        protected Set getProperties(Class type) throws IntrospectionException {
            Set returnSet = new HashSet();
            LiquibaseSerializable serialzableType = null;
            try {
                if (type.equals(ChangeSet.class)) {
                    serialzableType = new ChangeSet("x", "y", false, false, null, null, null, null);
                } else if (LiquibaseSerializable.class.isAssignableFrom(type)) {
                    serialzableType = (LiquibaseSerializable) type.newInstance();
                } else {
                    return super.getProperties(type);
                }
            } catch (InstantiationException e) {
                throw new UnexpectedLiquibaseException(e);
            } catch (IllegalAccessException e) {
                throw new UnexpectedLiquibaseException(e);
            }
            for (String property : serialzableType.getSerializableFields()) {
                LiquibaseSerializable.SerializationType fieldType = serialzableType.getSerializableFieldType(property);
                returnSet.add(new LiquibaseProperty(property, String.class, String.class));
            }
            return returnSet;
        }

        private static class LiquibaseProperty extends GenericProperty {

            private LiquibaseProperty(String name, Class aClass, Type aType) {
                super(name, aClass, aType);
            }

            @Override
            public void set(Object object, Object value) throws Exception {
                //not supported
            }

            @Override
            public Object get(Object object) {
                return ((LiquibaseSerializable) object).getSerializableFieldValue(getName());
            }
        }

        private class AsStringRepresenter implements Represent {
            @Override
            public Node representData(Object data) {
                return representScalar(Tag.STR, data.toString());
            }
        }
    }

    private static class ChangeSetComparator implements Comparator {
        private static final Map order = new HashMap();

        static {
            order.put("id", 1);
            order.put("author", 2);
            order.put("changes", Integer.MAX_VALUE);
        }

        @Override
        public int compare(String o1, String o2) {
            Integer o1Order = order.get(o1);
            if (o1Order == null) {
                o1Order = 10;
            }

            Integer o2Order = order.get(o2);
            if (o2Order == null) {
                o2Order = 10;
            }

            int orderCompare = o1Order.compareTo(o2Order);

            if (orderCompare == 0) {
                return o1.compareTo(o2);
            }
            return orderCompare;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy